diff --git a/androidgcs/AndroidManifest.xml b/androidgcs/AndroidManifest.xml
index 7a96a6600..8b3a9e4b3 100644
--- a/androidgcs/AndroidManifest.xml
+++ b/androidgcs/AndroidManifest.xml
@@ -5,8 +5,18 @@
android:versionName="1.0">
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/androidgcs/default.properties b/androidgcs/default.properties
index 46769a720..66db0d159 100644
--- a/androidgcs/default.properties
+++ b/androidgcs/default.properties
@@ -8,4 +8,4 @@
# project structure.
# Project target.
-target=android-7
+target=android-10
diff --git a/androidgcs/res/layout/main.xml b/androidgcs/res/layout/main.xml
index 3a5f117d3..7e4a852bf 100644
--- a/androidgcs/res/layout/main.xml
+++ b/androidgcs/res/layout/main.xml
@@ -7,6 +7,5 @@
diff --git a/androidgcs/res/values/strings.xml b/androidgcs/res/values/strings.xml
index 0d9f93bc2..52fa56534 100644
--- a/androidgcs/res/values/strings.xml
+++ b/androidgcs/res/values/strings.xml
@@ -1,5 +1,4 @@
- Hello World!
OpenPilot GCS
diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java b/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java
new file mode 100644
index 000000000..3c6231258
--- /dev/null
+++ b/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java
@@ -0,0 +1,129 @@
+package org.openpilot.androidgcs;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.UUID;
+
+import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import org.openpilot.androidgcs.*;
+import org.openpilot.uavtalk.Telemetry;
+import org.openpilot.uavtalk.TelemetryMonitor;
+import org.openpilot.uavtalk.UAVObjectManager;
+import org.openpilot.uavtalk.UAVTalk;
+import org.openpilot.uavtalk.uavobjects.UAVObjectsInitialize;
+
+public class ObjectBrowser extends Activity {
+
+ private final String TAG = "ObjectBrower";
+ private final String DEVICE_NAME = "RN42-222D";
+ private final int REQUEST_ENABLE_BT = 0;
+ private UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
+ BluetoothAdapter mBluetoothAdapter;
+ UAVObjectManager objMngr;
+ UAVTalk uavTalk;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ Log.d(TAG, "Launching Object Browser");
+
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
+ // Device does not support Bluetooth
+ Log.d(TAG, "Device does not support Bluetooth");
+ return;
+ }
+
+ if (!mBluetoothAdapter.isEnabled()) {
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+ } else {
+ queryDevices();
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if(requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_OK) {
+ Log.d(TAG, "Bluetooth started succesfully");
+ queryDevices();
+ }
+ if(requestCode == REQUEST_ENABLE_BT && resultCode != RESULT_OK)
+ Log.d(TAG, "Bluetooth could not be started");
+
+ }
+
+ public void queryDevices() {
+ Log.d(TAG, "Searching for devices");
+ 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.getName());
+ if(device.getName().compareTo(DEVICE_NAME) == 0) {
+ openTelmetryBluetooth(device);
+ openTelmetryBluetooth(device);
+ }
+ }
+ }
+
+ }
+
+ private void openTelmetryBluetooth(BluetoothDevice device) {
+ Log.d(TAG, "Opening conncetion to " + device.getName());
+ BluetoothSocket socket = null;
+ try {
+ socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
+ } catch (IOException e) {
+ Log.e(TAG,"Unable to create Rfcomm socket");
+ e.printStackTrace();
+ }
+
+ mBluetoothAdapter.cancelDiscovery();
+
+ try {
+ socket.connect();
+ }
+ catch (IOException e) {
+ 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);
+ }
+ return;
+ }
+
+ objMngr = new UAVObjectManager();
+ UAVObjectsInitialize.register(objMngr);
+
+ try {
+ uavTalk = new UAVTalk(socket.getInputStream(), socket.getOutputStream(), objMngr);
+ } catch (IOException e) {
+ Log.e(TAG,"Error starting UAVTalk");
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return;
+ }
+
+ Thread inputStream = uavTalk.getInputProcessThread();
+ inputStream.start();
+
+ Telemetry tel = new Telemetry(uavTalk, objMngr);
+ TelemetryMonitor mon = new TelemetryMonitor(objMngr,tel);
+
+ }
+}
diff --git a/androidgcs/src/org/openpilot/uavtalk/Telemetry.java b/androidgcs/src/org/openpilot/uavtalk/Telemetry.java
index 7f04e344b..b403f85e3 100644
--- a/androidgcs/src/org/openpilot/uavtalk/Telemetry.java
+++ b/androidgcs/src/org/openpilot/uavtalk/Telemetry.java
@@ -12,8 +12,12 @@ import java.util.TimerTask;
import org.openpilot.uavtalk.UAVObject.Acked;
+import android.util.Log;
+
public class Telemetry {
+ private final String TAG = "Telemetry";
+
public class TelemetryStats {
public int txBytes;
public int rxBytes;
@@ -133,7 +137,7 @@ public class Telemetry {
/**
* Register a new object for periodic updates (if enabled)
*/
- private void registerObject(UAVObject obj)
+ private synchronized void registerObject(UAVObject obj)
{
// Setup object for periodic updates
addObject(obj);
@@ -145,7 +149,7 @@ public class Telemetry {
/**
* Add an object in the list used for periodic updates
*/
- private void addObject(UAVObject obj)
+ private synchronized void addObject(UAVObject obj)
{
// Check if object type is already in the list
ListIterator li = objList.listIterator();
@@ -169,7 +173,7 @@ public class Telemetry {
/**
* Update the object's timers
*/
- private void setUpdatePeriod(UAVObject obj, int periodMs)
+ private synchronized void setUpdatePeriod(UAVObject obj, int periodMs)
{
// Find object type (not instance!) and update its period
ListIterator li = objList.listIterator();
@@ -186,7 +190,7 @@ public class Telemetry {
/**
* Connect to all instances of an object depending on the event mask specified
*/
- private void connectToObjectInstances(UAVObject obj, int eventMask)
+ private synchronized void connectToObjectInstances(UAVObject obj, int eventMask)
{
List objs = objMngr.getObjectInstances(obj.getObjID());
ListIterator li = objs.listIterator();
@@ -235,7 +239,7 @@ public class Telemetry {
/**
* Update an object based on its metadata properties
*/
- private void updateObject(UAVObject obj)
+ private synchronized void updateObject(UAVObject obj)
{
// Get metadata
UAVObject.Metadata metadata = obj.getMetadata();
@@ -287,12 +291,12 @@ public class Telemetry {
/**
* Called when a transaction is successfully completed (uavtalk event)
*/
- private void transactionCompleted(UAVObject obj)
+ private synchronized void transactionCompleted(UAVObject obj)
{
// Check if there is a pending transaction and the objects match
if ( transPending && transInfo.obj.getObjID() == obj.getObjID() )
{
- // qDebug() << QString("Telemetry: transaction completed for %1").arg(obj->getName());
+ Log.d(TAG,"Telemetry: transaction completed for " + obj.getName());
// Complete transaction
transTimer.cancel();
transPending = false;
@@ -302,16 +306,16 @@ public class Telemetry {
processObjectQueue();
} else
{
- // qDebug() << "Error: received a transaction completed when did not expect it.";
+ Log.e(TAG,"Error: received a transaction completed when did not expect it.");
}
}
/**
* Called when a transaction is not completed within the timeout period (timer event)
*/
- private void transactionTimeout()
+ private synchronized void transactionTimeout()
{
-// qDebug() << "Telemetry: transaction timeout.";
+ Log.d(TAG,"Telemetry: transaction timeout.");
transTimer.cancel();
// Proceed only if there is a pending transaction
if ( transPending )
@@ -340,11 +344,11 @@ public class Telemetry {
/**
* Start an object transaction with UAVTalk, all information is stored in transInfo
*/
- private void processObjectTransaction()
+ private synchronized void processObjectTransaction()
{
if (transPending)
{
- // qDebug() << tr("Process Object transaction for %1").arg(transInfo.obj->getName());
+ Log.d(TAG, "Process Object transaction for " + transInfo.obj.getName());
// Initiate transaction
if (transInfo.objRequest)
{
@@ -366,17 +370,17 @@ public class Telemetry {
}
} else
{
- // qDebug() << "Error: inside of processObjectTransaction with no transPending";
+ Log.e(TAG,"Error: inside of processObjectTransaction with no transPending");
}
}
/**
* Process the event received from an object
*/
- private void processObjectUpdates(UAVObject obj, int event, boolean allInstances, boolean priority)
+ private synchronized void processObjectUpdates(UAVObject obj, int event, boolean allInstances, boolean priority)
{
// Push event into queue
-// qDebug() << "Push event into queue for obj " << QString("%1 event %2").arg(obj->getName()).arg(event);
+ Log.d(TAG, "Push event into queue for obj " + obj.getName() + " event " + event);
ObjectQueueInfo objInfo = new ObjectQueueInfo();
objInfo.obj = obj;
objInfo.event = event;
@@ -391,7 +395,7 @@ public class Telemetry {
{
++txErrors;
obj.transactionCompleted(false);
- //qxtLog->warning(tr("Telemetry: priority event queue is full, event lost (%1)").arg(obj->getName()));
+ Log.w(TAG,"Telemetry: priority event queue is full, event lost " + obj.getName());
}
}
else
@@ -410,25 +414,26 @@ public class Telemetry {
// If there is no transaction in progress then process event
if (!transPending)
{
- // qDebug() << "No transaction pending, process object queue...";
+
processObjectQueue();
+
} else
{
- // qDebug() << "Transaction pending, DO NOT process object queue...";
+ Log.d(TAG,"Transaction pending, DO NOT process object queue...");
}
}
/**
* Process events from the object queue
*/
- private void processObjectQueue()
+ private synchronized void processObjectQueue()
{
- // qDebug() << "Process object queue " << tr("- Depth (%1 %2)").arg(objQueue.length()).arg(objPriorityQueue.length());
+ Log.d(TAG, "Process object queue - Depth " + objQueue.size() + " priority " + objPriorityQueue.size());
// Don nothing if a transaction is already in progress (should not happen)
if (transPending)
{
-// qxtLog->error("Telemetry: Dequeue while a transaction pending!");
+ Log.e(TAG,"Dequeue while a transaction pending");
return;
}
diff --git a/androidgcs/src/org/openpilot/uavtalk/TelemetryMonitor.java b/androidgcs/src/org/openpilot/uavtalk/TelemetryMonitor.java
index eb406923d..e2050fc25 100644
--- a/androidgcs/src/org/openpilot/uavtalk/TelemetryMonitor.java
+++ b/androidgcs/src/org/openpilot/uavtalk/TelemetryMonitor.java
@@ -55,7 +55,7 @@ public class TelemetryMonitor {
/**
* Initiate object retrieval, initialize queue with objects to be retrieved.
*/
- public void startRetrievingObjects()
+ public synchronized void startRetrievingObjects()
{
// Clear object queue
queue.clear();
@@ -108,7 +108,7 @@ public class TelemetryMonitor {
/**
* Retrieve the next object in the queue
*/
- public void retrieveNextObject()
+ public synchronized void retrieveNextObject()
{
// If queue is empty return
if ( queue.isEmpty() )
@@ -120,7 +120,12 @@ public class TelemetryMonitor {
// Get next object from the queue
UAVObject obj = queue.remove(0);
-// Log.d(TAG, "Retrieving object: " + obj.getName()) ;
+ if(obj == null) {
+ Log.e(TAG, "Got null object forom transaction queue");
+ return;
+ }
+
+ Log.d(TAG, "Retrieving object: " + obj.getName()) ;
// Connect to object
obj.addTransactionCompleted(new Observer() {
public void update(Observable observable, Object data) {
@@ -137,10 +142,12 @@ public class TelemetryMonitor {
/**
* Called by the retrieved object when a transaction is completed.
*/
- public void transactionCompleted(UAVObject obj, boolean success)
+ public synchronized void transactionCompleted(UAVObject obj, boolean success)
{
//QMutexLocker locker(mutex);
// Disconnect from sending object
+ Log.d(TAG,"transactionCompleted");
+ // TODO: Need to be able to disconnect signals
//obj->disconnect(this);
objPending = null;
diff --git a/androidgcs/src/org/openpilot/uavtalk/UAVObject.java b/androidgcs/src/org/openpilot/uavtalk/UAVObject.java
index fac67cabc..b74df9218 100644
--- a/androidgcs/src/org/openpilot/uavtalk/UAVObject.java
+++ b/androidgcs/src/org/openpilot/uavtalk/UAVObject.java
@@ -17,12 +17,16 @@ public abstract class UAVObject {
}
public void event () {
- setChanged();
- notifyObservers(parent);
+ synchronized(this) {
+ setChanged();
+ notifyObservers(parent);
+ }
}
public void event (Object data) {
- setChanged();
- notifyObservers(data);
+ synchronized(this) {
+ setChanged();
+ notifyObservers(data);
+ }
}
}