From a75e4e4e6ff0f2c5ac0f976db90b8395f8b32022 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sun, 26 Aug 2012 22:05:53 -0500 Subject: [PATCH 1/8] AndroidGCS: Suppress some warnings from Controller.java --- androidgcs/src/org/openpilot/androidgcs/Controller.java | 1 - 1 file changed, 1 deletion(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/Controller.java b/androidgcs/src/org/openpilot/androidgcs/Controller.java index 3ef291d4d..62b7d0c31 100644 --- a/androidgcs/src/org/openpilot/androidgcs/Controller.java +++ b/androidgcs/src/org/openpilot/androidgcs/Controller.java @@ -70,7 +70,6 @@ public class Controller extends ObjectManagerActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.controller); - TextView manualView = (TextView) findViewById(R.id.manualControlValues); } Observer settingsUpdated = new Observer() { From 8cc49d125a0d88358ae05841c1bc326a8ab05cf8 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sun, 26 Aug 2012 22:26:34 -0500 Subject: [PATCH 2/8] AndroidGCS: Suppress some warnings related to not implementing the STRING uavfield type properly. --- .../openpilot/androidgcs/ObjectEditView.java | 26 ++++++++++++------- .../org/openpilot/uavtalk/UAVObjectField.java | 25 +++++++++++------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java b/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java index 7946a357b..401a26978 100644 --- a/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java +++ b/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java @@ -22,22 +22,22 @@ public class ObjectEditView extends GridLayout { public List fields; public ObjectEditView(Context context) { - super(context); + super(context); initObjectEditView(); } - public ObjectEditView(Context context, AttributeSet ats, int defaultStyle) { + public ObjectEditView(Context context, AttributeSet ats, int defaultStyle) { super(context, ats); initObjectEditView(); } - public ObjectEditView(Context context, AttributeSet ats) { + public ObjectEditView(Context context, AttributeSet ats) { super(context, ats); initObjectEditView(); } public void initObjectEditView() { - // Set orientation of layout to vertical + // Set orientation of layout to vertical setOrientation(LinearLayout.VERTICAL); setColumnCount(2); fields = new ArrayList(); @@ -51,11 +51,11 @@ public class ObjectEditView extends GridLayout { for (int i = 0; i < field.getNumElements(); i++) addRow(getContext(), field, i); } - - + + public void addRow(Context context, UAVObjectField field, int idx) { int row = getRowCount(); - + TextView fieldName = new TextView(context); if(field.getNumElements() == 1) { fieldName.setText(field.getName()); @@ -65,7 +65,7 @@ public class ObjectEditView extends GridLayout { addView(fieldName, new GridLayout.LayoutParams(spec(row), spec(0))); View fieldValue = null; - switch(field.getType()) + switch(field.getType()) { case FLOAT32: fieldValue = new EditText(context); @@ -93,8 +93,16 @@ public class ObjectEditView extends GridLayout { ((Spinner) fieldValue).setAdapter(adapter); ((Spinner) fieldValue).setSelection((int) field.getDouble(idx)); break; + case BITFIELD: + fieldValue = new EditText(context); + ((EditText)fieldValue).setText(field.getValue(idx).toString()); + ((EditText)fieldValue).setInputType(InputType.TYPE_CLASS_NUMBER); + break; + case STRING: + fieldValue = new EditText(context); + ((EditText)fieldValue).setText(field.getValue(idx).toString()); } - + addView(fieldValue, new GridLayout.LayoutParams(spec(row), spec(1))); fields.add(fieldValue); } diff --git a/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java b/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java index d07fdf6fd..7fea950f0 100644 --- a/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java +++ b/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java @@ -578,6 +578,12 @@ public class UAVObjectField { ((ArrayList) data).add((byte) 0); } break; + case STRING: + ((ArrayList) data).clear(); + for(int index = 0; index < numElements; ++index) { + ((ArrayList) data).add((byte) 0); + } + break; } } @@ -633,7 +639,7 @@ public class UAVObjectField { numBytesPerElement = 1; break; case STRING: - data = new ArrayList(this.numElements); + data = new ArrayList(this.numElements); numBytesPerElement = 1; break; default: @@ -650,15 +656,9 @@ public class UAVObjectField { */ protected Long bound (Object val) { - switch(type) { - case ENUM: - case STRING: - return 0L; - case FLOAT32: - return ((Number) val).longValue(); - } - - long num = ((Number) val).longValue(); + long num = 0; + if (isNumeric()) + num = ((Number) val).longValue(); switch(type) { case INT8: @@ -703,6 +703,11 @@ public class UAVObjectField { if(num > 255) return (long) 255; return num; + case FLOAT32: + return ((Number) val).longValue(); + case ENUM: + case STRING: + return 0L; } return num; From 6cd9a9b0afb687be0c730977789bf66edde13074 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Tue, 28 Aug 2012 11:09:50 -0500 Subject: [PATCH 3/8] AndroidGCS Bluetooth: Make bluetooth use the new connection system. --- .../telemetry/BluetoothUAVTalk.java | 109 ++++++++++-------- .../telemetry/OPTelemetryService.java | 3 +- 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/telemetry/BluetoothUAVTalk.java b/androidgcs/src/org/openpilot/androidgcs/telemetry/BluetoothUAVTalk.java index db3d44134..5c1028cb3 100644 --- a/androidgcs/src/org/openpilot/androidgcs/telemetry/BluetoothUAVTalk.java +++ b/androidgcs/src/org/openpilot/androidgcs/telemetry/BluetoothUAVTalk.java @@ -28,10 +28,6 @@ import java.io.IOException; import java.util.Set; import java.util.UUID; -import org.openpilot.uavtalk.UAVObjectManager; -import org.openpilot.uavtalk.UAVTalk; - -import android.annotation.TargetApi; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -43,11 +39,13 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; -@TargetApi(10) public class BluetoothUAVTalk { +public class BluetoothUAVTalk extends TelemetryTask { + private final String TAG = "BluetoothUAVTalk"; - public static int LOGLEVEL = 2; - public static boolean WARN = LOGLEVEL > 1; - public static boolean DEBUG = LOGLEVEL > 0; + public static final int LOGLEVEL = 4; + public static final boolean DEBUG = LOGLEVEL > 2; + public static final boolean WARN = LOGLEVEL > 1; + public static final boolean ERROR = LOGLEVEL > 0; // Temporarily define fixed device name private String device_name = "RN42-222D"; @@ -56,30 +54,35 @@ import android.util.Log; private BluetoothAdapter mBluetoothAdapter; private BluetoothSocket socket; private BluetoothDevice device; - private UAVTalk uavTalk; - private boolean connected; - public BluetoothUAVTalk(Context caller) { + public BluetoothUAVTalk(OPTelemetryService caller) { + super(caller); + } - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(caller); + @Override + boolean attemptConnection() { + + if( getConnected() ) + return true; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(telemService); device_name = prefs.getString("bluetooth_mac",""); if (DEBUG) Log.d(TAG, "Trying to open UAVTalk with " + device_name); - connected = false; device = null; mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { // Device does not support Bluetooth Log.e(TAG, "Device does not support Bluetooth"); - return; + return false; } if (!mBluetoothAdapter.isEnabled()) { // Enable bluetooth if it isn't already Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); - caller.sendOrderedBroadcast(enableBtIntent, "android.permission.BLUETOOTH_ADMIN", new BroadcastReceiver() { + telemService.sendOrderedBroadcast(enableBtIntent, "android.permission.BLUETOOTH_ADMIN", new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e(TAG,"Received " + context + intent); @@ -90,60 +93,60 @@ import android.util.Log; } else { queryDevices(); } - } - public boolean connect(UAVObjectManager objMngr) { - if( getConnected() ) - return true; - if( !getFoundDevice() ) - return false; - if( !openTelemetryBluetooth(objMngr) ) - return false; return true; } - public boolean getConnected() { - return connected; + @Override + public void disconnect() { + super.disconnect(); + if(socket != null) { + try { + socket.close(); + } catch (IOException e) { + if (ERROR) Log.e(TAG, "Unable to close BT socket"); + } + socket = null; + } } public boolean getFoundDevice() { return (device != null); } - public UAVTalk getUavtalk() { - return uavTalk; - } private void queryDevices() { - Log.d(TAG, "Searching for devices"); + if (DEBUG) Log.d(TAG, "Searching for devices matching the selected preference"); + Set pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { - // Add the name and address to an array adapter to show in a ListView - //mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); - Log.d(TAG, "Paired device: " + device.getAddress() + " compared to " + device_name); + if(device.getAddress().compareTo(device_name) == 0) { - Log.d(TAG, "Found device: " + device.getName()); + if (DEBUG) Log.d(TAG, "Found selected device: " + device.getName()); this.device = device; + + openTelemetryBluetooth(); return; } } } + attemptedFailed(); } - private boolean openTelemetryBluetooth(UAVObjectManager objMngr) { - Log.d(TAG, "Opening connection to " + device.getName()); + private boolean openTelemetryBluetooth() { + if (DEBUG) Log.d(TAG, "Opening connection to " + device.getName()); + socket = null; - connected = false; + try { socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { - Log.e(TAG,"Unable to create Rfcomm socket"); + if (ERROR) Log.e(TAG,"Unable to create Rfcomm socket"); return false; - //e.printStackTrace(); } mBluetoothAdapter.cancelDiscovery(); @@ -152,26 +155,40 @@ import android.util.Log; socket.connect(); } catch (IOException e) { - Log.e(TAG,"Unable to connect to requested device", e); + if (ERROR) Log.e(TAG,"Unable to connect to requested device", e); try { socket.close(); } catch (IOException e2) { - Log.e(TAG, "unable to close() socket during connection failure", e2); + if (ERROR) Log.e(TAG, "unable to close() socket during connection failure", e2); } + + attemptedFailed(); return false; } - connected = true; - try { - uavTalk = new UAVTalk(socket.getInputStream(), socket.getOutputStream(), objMngr); + inStream = socket.getInputStream(); + outStream = socket.getOutputStream(); } catch (IOException e) { - Log.e(TAG,"Error starting UAVTalk"); - // TODO Auto-generated catch block - //e.printStackTrace(); + try { + socket.close(); + } catch (IOException e2) { + + } + attemptedFailed(); return false; } + telemService.toastMessage("Bluetooth device connected"); + + // Post message to call attempt succeeded on the parent class + handler.post(new Runnable() { + @Override + public void run() { + BluetoothUAVTalk.this.attemptSucceeded(); + } + }); + return true; } diff --git a/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java b/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java index 4698900ef..261082f99 100644 --- a/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java +++ b/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java @@ -121,7 +121,8 @@ public class OPTelemetryService extends Service { break; case 2: Toast.makeText(getApplicationContext(), "Attempting BT connection", Toast.LENGTH_SHORT).show(); - //activeTelem = new BTTelemetryThread(); + telemTask = new BluetoothUAVTalk(this); + activeTelem = new Thread(telemTask, "Bluetooth telemetry thread"); break; case 3: Toast.makeText(getApplicationContext(), "Attempting TCP connection", Toast.LENGTH_SHORT).show(); From f01edc5d72d3eb582ebe846f3a146ba6ba25a589 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Mon, 27 Aug 2012 09:53:23 -0500 Subject: [PATCH 4/8] AndroidGCS: Make sure the telemetry sevice checks there is a telemetry task AND it's connected before sending the OPConnected service. Otherwise the objMngr is undefined. --- .../org/openpilot/androidgcs/telemetry/OPTelemetryService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java b/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java index 261082f99..9edd8a628 100644 --- a/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java +++ b/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java @@ -259,7 +259,7 @@ public class OPTelemetryService extends Service { mServiceHandler.sendMessage(msg); } public boolean isConnected() { - return activeTelem != null; + return (activeTelem != null) && (telemTask != null) && (telemTask.getConnected()); } }; From 120f9298b4a7282d40915870fc4a4d783dbd554a Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sun, 26 Aug 2012 22:26:34 -0500 Subject: [PATCH 5/8] AndroidGCS: Suppress some warnings related to not implementing the STRING uavfield type properly. --- .../openpilot/androidgcs/ObjectEditView.java | 26 ++++++++++++------- .../org/openpilot/uavtalk/UAVObjectField.java | 25 +++++++++++------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java b/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java index 7946a357b..401a26978 100644 --- a/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java +++ b/androidgcs/src/org/openpilot/androidgcs/ObjectEditView.java @@ -22,22 +22,22 @@ public class ObjectEditView extends GridLayout { public List fields; public ObjectEditView(Context context) { - super(context); + super(context); initObjectEditView(); } - public ObjectEditView(Context context, AttributeSet ats, int defaultStyle) { + public ObjectEditView(Context context, AttributeSet ats, int defaultStyle) { super(context, ats); initObjectEditView(); } - public ObjectEditView(Context context, AttributeSet ats) { + public ObjectEditView(Context context, AttributeSet ats) { super(context, ats); initObjectEditView(); } public void initObjectEditView() { - // Set orientation of layout to vertical + // Set orientation of layout to vertical setOrientation(LinearLayout.VERTICAL); setColumnCount(2); fields = new ArrayList(); @@ -51,11 +51,11 @@ public class ObjectEditView extends GridLayout { for (int i = 0; i < field.getNumElements(); i++) addRow(getContext(), field, i); } - - + + public void addRow(Context context, UAVObjectField field, int idx) { int row = getRowCount(); - + TextView fieldName = new TextView(context); if(field.getNumElements() == 1) { fieldName.setText(field.getName()); @@ -65,7 +65,7 @@ public class ObjectEditView extends GridLayout { addView(fieldName, new GridLayout.LayoutParams(spec(row), spec(0))); View fieldValue = null; - switch(field.getType()) + switch(field.getType()) { case FLOAT32: fieldValue = new EditText(context); @@ -93,8 +93,16 @@ public class ObjectEditView extends GridLayout { ((Spinner) fieldValue).setAdapter(adapter); ((Spinner) fieldValue).setSelection((int) field.getDouble(idx)); break; + case BITFIELD: + fieldValue = new EditText(context); + ((EditText)fieldValue).setText(field.getValue(idx).toString()); + ((EditText)fieldValue).setInputType(InputType.TYPE_CLASS_NUMBER); + break; + case STRING: + fieldValue = new EditText(context); + ((EditText)fieldValue).setText(field.getValue(idx).toString()); } - + addView(fieldValue, new GridLayout.LayoutParams(spec(row), spec(1))); fields.add(fieldValue); } diff --git a/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java b/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java index d07fdf6fd..7fea950f0 100644 --- a/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java +++ b/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java @@ -578,6 +578,12 @@ public class UAVObjectField { ((ArrayList) data).add((byte) 0); } break; + case STRING: + ((ArrayList) data).clear(); + for(int index = 0; index < numElements; ++index) { + ((ArrayList) data).add((byte) 0); + } + break; } } @@ -633,7 +639,7 @@ public class UAVObjectField { numBytesPerElement = 1; break; case STRING: - data = new ArrayList(this.numElements); + data = new ArrayList(this.numElements); numBytesPerElement = 1; break; default: @@ -650,15 +656,9 @@ public class UAVObjectField { */ protected Long bound (Object val) { - switch(type) { - case ENUM: - case STRING: - return 0L; - case FLOAT32: - return ((Number) val).longValue(); - } - - long num = ((Number) val).longValue(); + long num = 0; + if (isNumeric()) + num = ((Number) val).longValue(); switch(type) { case INT8: @@ -703,6 +703,11 @@ public class UAVObjectField { if(num > 255) return (long) 255; return num; + case FLOAT32: + return ((Number) val).longValue(); + case ENUM: + case STRING: + return 0L; } return num; From 846f488eb1ff6f98995e5d7837add943f9c06764 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sun, 26 Aug 2012 22:05:53 -0500 Subject: [PATCH 6/8] AndroidGCS: Suppress some warnings from Controller.java --- androidgcs/src/org/openpilot/androidgcs/Controller.java | 1 - 1 file changed, 1 deletion(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/Controller.java b/androidgcs/src/org/openpilot/androidgcs/Controller.java index 0d3a3c911..39a86639c 100644 --- a/androidgcs/src/org/openpilot/androidgcs/Controller.java +++ b/androidgcs/src/org/openpilot/androidgcs/Controller.java @@ -70,7 +70,6 @@ public class Controller extends ObjectManagerActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.controller); - TextView manualView = (TextView) findViewById(R.id.manualControlValues); } Observer settingsUpdated = new Observer() { From ee97390ade5c99139efebe642158c8a76bf2419b Mon Sep 17 00:00:00 2001 From: James Cotton Date: Tue, 28 Aug 2012 11:23:24 -0500 Subject: [PATCH 7/8] AndroidGCS TelemetryTask: Make sure the telemetry task shuts down the reading thread on disconnect --- .../androidgcs/telemetry/TelemetryTask.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/telemetry/TelemetryTask.java b/androidgcs/src/org/openpilot/androidgcs/telemetry/TelemetryTask.java index 3d16d94f9..c9a44d6e1 100644 --- a/androidgcs/src/org/openpilot/androidgcs/telemetry/TelemetryTask.java +++ b/androidgcs/src/org/openpilot/androidgcs/telemetry/TelemetryTask.java @@ -68,6 +68,9 @@ public abstract class TelemetryTask implements Runnable { //! The telemetry monitor which takes care of high level connects / disconnects private TelemetryMonitor mon; + //! Thread to process the input stream + Thread inputProcessThread; + //! Flag to indicate a shut down was requested. Derived classes should take care to respect this. boolean shutdown; @@ -146,6 +149,14 @@ public abstract class TelemetryTask implements Runnable { } }); + if (inputProcessThread != null) { + inputProcessThread.interrupt(); + try { + inputProcessThread.join(); + } catch (InterruptedException e) { + } + } + // TODO: Make sure the input and output stream is closed // TODO: Make sure any threads for input and output are closed @@ -157,7 +168,8 @@ public abstract class TelemetryTask implements Runnable { * to read from the input stream. */ private void startInputProcessing() { - new Thread(new processUavTalk(), "Process UAV talk").start(); + inputProcessThread = new Thread(new processUavTalk(), "Process UAV talk"); + inputProcessThread.start(); } //! Runnable to process input stream From b9663ba666ba4767f53dc7023806e6898b4bbf23 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Tue, 28 Aug 2012 11:29:50 -0500 Subject: [PATCH 8/8] AndroidGCS: Fix typo in telem debug messages --- .../org/openpilot/androidgcs/telemetry/OPTelemetryService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java b/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java index 9edd8a628..69ab6e0d8 100644 --- a/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java +++ b/androidgcs/src/org/openpilot/androidgcs/telemetry/OPTelemetryService.java @@ -227,7 +227,7 @@ public class OPTelemetryService extends Service { public void onDestroy() { if (telemTask != null) { - Log.d(TAG, "onDestory() shutting down telemetry task"); + Log.d(TAG, "onDestroy() shutting down telemetry task"); telemTask.disconnect(); telemTask = null;