mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
Merge branch 'android-uavo-fix' into next
This commit is contained in:
commit
1c89b24329
@ -294,6 +294,7 @@ public class OPTelemetryService extends Service {
|
|||||||
numRead = inputStream.read(buffer);
|
numRead = inputStream.read(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyAssets(String JAR_DIR, String JAR_NAME)
|
private void copyAssets(String JAR_DIR, String JAR_NAME)
|
||||||
{
|
{
|
||||||
File jarsDir = getDir(JAR_DIR, MODE_WORLD_READABLE);
|
File jarsDir = getDir(JAR_DIR, MODE_WORLD_READABLE);
|
||||||
@ -320,6 +321,19 @@ public class OPTelemetryService extends Service {
|
|||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
Log.e(TAG, e.toString(), e);
|
Log.e(TAG, e.toString(), e);
|
||||||
|
String[] list;
|
||||||
|
try {
|
||||||
|
list = assetManager.list("uavos/");
|
||||||
|
Log.i(TAG, "Listing found uavos");
|
||||||
|
for(int i = 0; i < list.length; i++) {
|
||||||
|
Log.i(TAG, "Found: " + list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,6 +365,10 @@ public class OPTelemetryService extends Service {
|
|||||||
final String JAR_DIR = "jars";
|
final String JAR_DIR = "jars";
|
||||||
final String DEX_DIR = "optimized_dex";
|
final String DEX_DIR = "optimized_dex";
|
||||||
|
|
||||||
|
File jarsDir = getDir(JAR_DIR, MODE_WORLD_READABLE);
|
||||||
|
if (jarsDir.exists())
|
||||||
|
deleteDirectoryContents(jarsDir);
|
||||||
|
|
||||||
copyAssets(JAR_DIR, jar);
|
copyAssets(JAR_DIR, jar);
|
||||||
|
|
||||||
Log.d(TAG, "Starting dex loader");
|
Log.d(TAG, "Starting dex loader");
|
||||||
@ -360,7 +378,6 @@ public class OPTelemetryService extends Service {
|
|||||||
if (dexDir.exists())
|
if (dexDir.exists())
|
||||||
deleteDirectoryContents(dexDir);
|
deleteDirectoryContents(dexDir);
|
||||||
|
|
||||||
File jarsDir = getDir(JAR_DIR, MODE_WORLD_READABLE);
|
|
||||||
String classpath = new File(jarsDir, jar).getAbsolutePath();
|
String classpath = new File(jarsDir, jar).getAbsolutePath();
|
||||||
|
|
||||||
DexClassLoader loader = new DexClassLoader(classpath, dexDir.getAbsolutePath(), null, getClassLoader());
|
DexClassLoader loader = new DexClassLoader(classpath, dexDir.getAbsolutePath(), null, getClassLoader());
|
||||||
|
@ -8,8 +8,6 @@ import java.util.Observer;
|
|||||||
|
|
||||||
import org.openpilot.uavtalk.Telemetry;
|
import org.openpilot.uavtalk.Telemetry;
|
||||||
import org.openpilot.uavtalk.TelemetryMonitor;
|
import org.openpilot.uavtalk.TelemetryMonitor;
|
||||||
import org.openpilot.uavtalk.UAVObject;
|
|
||||||
import org.openpilot.uavtalk.UAVObjectField;
|
|
||||||
import org.openpilot.uavtalk.UAVObjectManager;
|
import org.openpilot.uavtalk.UAVObjectManager;
|
||||||
import org.openpilot.uavtalk.UAVTalk;
|
import org.openpilot.uavtalk.UAVTalk;
|
||||||
import org.openpilot.uavtalk.uavobjects.TelemObjectsInitialize;
|
import org.openpilot.uavtalk.uavobjects.TelemObjectsInitialize;
|
||||||
@ -93,32 +91,6 @@ public abstract class TelemetryTask implements Runnable {
|
|||||||
*/
|
*/
|
||||||
abstract boolean attemptConnection();
|
abstract boolean attemptConnection();
|
||||||
|
|
||||||
private final Observer firmwareIapUpdated = new Observer() {
|
|
||||||
@Override
|
|
||||||
public void update(Observable observable, Object data) {
|
|
||||||
if (DEBUG) Log.d(TAG, "Received firmware IAP Updated message");
|
|
||||||
|
|
||||||
UAVObject obj = objMngr.getObject("FirmwareIAPObj");
|
|
||||||
UAVObjectField description = obj.getField("Description");
|
|
||||||
if(description == null || description.getNumElements() < 100) {
|
|
||||||
telemService.toastMessage("Failed to determine UAVO set");
|
|
||||||
} else {
|
|
||||||
final int HASH_SIZE_USED = 8;
|
|
||||||
String jarName = new String();
|
|
||||||
for(int i = 0; i < HASH_SIZE_USED; i++)
|
|
||||||
jarName += Integer.toHexString((int) description.getDouble(i+60));
|
|
||||||
jarName += ".jar";
|
|
||||||
if (DEBUG) Log.d(TAG, "Attempting to load: " + jarName);
|
|
||||||
if (telemService.loadUavobjects(jarName, objMngr) ) {
|
|
||||||
telemService.toastMessage("Loaded appropriate UAVO set");
|
|
||||||
} else
|
|
||||||
telemService.toastMessage("Failed to determine UAVO set");
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.removeUpdatedObserver(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a physical channel is opened
|
* Called when a physical channel is opened
|
||||||
*
|
*
|
||||||
@ -133,11 +105,6 @@ public abstract class TelemetryTask implements Runnable {
|
|||||||
objMngr = new UAVObjectManager();
|
objMngr = new UAVObjectManager();
|
||||||
TelemObjectsInitialize.register(objMngr);
|
TelemObjectsInitialize.register(objMngr);
|
||||||
|
|
||||||
// Register to get an update from FirmwareIAP in order to register
|
|
||||||
// the appropriate objects
|
|
||||||
UAVObject obj = objMngr.getObject("FirmwareIAPObj");
|
|
||||||
obj.addUpdatedObserver(firmwareIapUpdated);
|
|
||||||
|
|
||||||
// Create the required telemetry objects attached to this
|
// Create the required telemetry objects attached to this
|
||||||
// data stream
|
// data stream
|
||||||
uavTalk = new UAVTalk(inStream, outStream, objMngr);
|
uavTalk = new UAVTalk(inStream, outStream, objMngr);
|
||||||
|
@ -202,7 +202,7 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Register a new object for periodic updates (if enabled)
|
* Register a new object for periodic updates (if enabled)
|
||||||
*/
|
*/
|
||||||
private synchronized void registerObject(UAVObject obj) {
|
private void registerObject(UAVObject obj) {
|
||||||
// Setup object for periodic updates
|
// Setup object for periodic updates
|
||||||
addObject(obj);
|
addObject(obj);
|
||||||
|
|
||||||
@ -213,24 +213,27 @@ public class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Add an object in the list used for periodic updates
|
* Add an object in the list used for periodic updates
|
||||||
*/
|
*/
|
||||||
private synchronized void addObject(UAVObject obj) {
|
private void addObject(UAVObject obj) {
|
||||||
// Check if object type is already in the list
|
|
||||||
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
|
||||||
while (li.hasNext()) {
|
|
||||||
ObjectTimeInfo n = li.next();
|
|
||||||
if (n.obj.getObjID() == obj.getObjID()) {
|
|
||||||
// Object type (not instance!) is already in the list, do
|
|
||||||
// nothing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this point is reached, then the object type is new, let's add it
|
synchronized (objList) {
|
||||||
ObjectTimeInfo timeInfo = new ObjectTimeInfo();
|
// Check if object type is already in the list
|
||||||
timeInfo.obj = obj;
|
ListIterator<ObjectTimeInfo> li = objList.listIterator();
|
||||||
timeInfo.timeToNextUpdateMs = 0;
|
while (li.hasNext()) {
|
||||||
timeInfo.updatePeriodMs = 0;
|
ObjectTimeInfo n = li.next();
|
||||||
objList.add(timeInfo);
|
if (n.obj.getObjID() == obj.getObjID()) {
|
||||||
|
// Object type (not instance!) is already in the list, do
|
||||||
|
// nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this point is reached, then the object type is new, let's add it
|
||||||
|
ObjectTimeInfo timeInfo = new ObjectTimeInfo();
|
||||||
|
timeInfo.obj = obj;
|
||||||
|
timeInfo.timeToNextUpdateMs = 0;
|
||||||
|
timeInfo.updatePeriodMs = 0;
|
||||||
|
objList.add(timeInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,7 +284,7 @@ public class Telemetry {
|
|||||||
* Connect to all instances of an object depending on the event mask
|
* Connect to all instances of an object depending on the event mask
|
||||||
* specified
|
* specified
|
||||||
*/
|
*/
|
||||||
private synchronized void connectToObjectInstances(UAVObject obj,
|
private void connectToObjectInstances(UAVObject obj,
|
||||||
int eventMask) {
|
int eventMask) {
|
||||||
List<UAVObject> objs = objMngr.getObjectInstances(obj.getObjID());
|
List<UAVObject> objs = objMngr.getObjectInstances(obj.getObjID());
|
||||||
ListIterator<UAVObject> li = objs.listIterator();
|
ListIterator<UAVObject> li = objs.listIterator();
|
||||||
@ -312,43 +315,46 @@ public class Telemetry {
|
|||||||
* Update an object based on its metadata properties
|
* Update an object based on its metadata properties
|
||||||
*/
|
*/
|
||||||
private void updateObject(UAVObject obj) {
|
private void updateObject(UAVObject obj) {
|
||||||
// Get metadata
|
|
||||||
UAVObject.Metadata metadata = obj.getMetadata();
|
|
||||||
|
|
||||||
// Setup object depending on update mode
|
synchronized(obj) {
|
||||||
int eventMask;
|
// Get metadata
|
||||||
if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_PERIODIC) {
|
UAVObject.Metadata metadata = obj.getMetadata();
|
||||||
// Set update period
|
|
||||||
setUpdatePeriod(obj, metadata.gcsTelemetryUpdatePeriod);
|
|
||||||
// Connect signals for all instances
|
|
||||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
|
||||||
if (obj.isMetadata())
|
|
||||||
eventMask |= EV_UNPACKED; // we also need to act on remote
|
|
||||||
// updates (unpack events)
|
|
||||||
|
|
||||||
connectToObjectInstances(obj, eventMask);
|
// Setup object depending on update mode
|
||||||
} else if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_ONCHANGE) {
|
int eventMask;
|
||||||
// Set update period
|
if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_PERIODIC) {
|
||||||
setUpdatePeriod(obj, 0);
|
// Set update period
|
||||||
// Connect signals for all instances
|
setUpdatePeriod(obj, metadata.gcsTelemetryUpdatePeriod);
|
||||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
// Connect signals for all instances
|
||||||
if (obj.isMetadata())
|
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||||
eventMask |= EV_UNPACKED; // we also need to act on remote
|
if (obj.isMetadata())
|
||||||
// updates (unpack events)
|
eventMask |= EV_UNPACKED; // we also need to act on remote
|
||||||
|
// updates (unpack events)
|
||||||
|
|
||||||
connectToObjectInstances(obj, eventMask);
|
connectToObjectInstances(obj, eventMask);
|
||||||
} else if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_THROTTLED) {
|
} else if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_ONCHANGE) {
|
||||||
// TODO
|
// Set update period
|
||||||
} else if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_MANUAL) {
|
setUpdatePeriod(obj, 0);
|
||||||
// Set update period
|
// Connect signals for all instances
|
||||||
setUpdatePeriod(obj, 0);
|
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||||
// Connect signals for all instances
|
if (obj.isMetadata())
|
||||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
eventMask |= EV_UNPACKED; // we also need to act on remote
|
||||||
if (obj.isMetadata())
|
// updates (unpack events)
|
||||||
eventMask |= EV_UNPACKED; // we also need to act on remote
|
|
||||||
// updates (unpack events)
|
|
||||||
|
|
||||||
connectToObjectInstances(obj, eventMask);
|
connectToObjectInstances(obj, eventMask);
|
||||||
|
} else if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_THROTTLED) {
|
||||||
|
// TODO
|
||||||
|
} else if (metadata.GetGcsTelemetryUpdateMode() == UAVObject.UpdateMode.UPDATEMODE_MANUAL) {
|
||||||
|
// Set update period
|
||||||
|
setUpdatePeriod(obj, 0);
|
||||||
|
// Connect signals for all instances
|
||||||
|
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||||
|
if (obj.isMetadata())
|
||||||
|
eventMask |= EV_UNPACKED; // we also need to act on remote
|
||||||
|
// updates (unpack events)
|
||||||
|
|
||||||
|
connectToObjectInstances(obj, eventMask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +454,7 @@ public class Telemetry {
|
|||||||
registerObject(obj);
|
registerObject(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void newInstance(UAVObject obj) {
|
private void newInstance(UAVObject obj) {
|
||||||
registerObject(obj);
|
registerObject(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,11 +638,7 @@ public class Telemetry {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store this as the active transaction
|
if (DEBUG) Log.d(TAG, "Process Object transaction for " + newTrans.obj.getName());
|
||||||
transPending = newTransactionPending;
|
|
||||||
transInfo = newTrans;
|
|
||||||
|
|
||||||
if (DEBUG) Log.d(TAG, "Process Object transaction for " + transInfo.obj.getName());
|
|
||||||
|
|
||||||
// Remove this one from the list of pending transactions
|
// Remove this one from the list of pending transactions
|
||||||
handler.removeActivatedQueue(objInfo);
|
handler.removeActivatedQueue(objInfo);
|
||||||
@ -644,12 +646,12 @@ public class Telemetry {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
// 3. Execute transaction by sending the appropriate UAVTalk command
|
// 3. Execute transaction by sending the appropriate UAVTalk command
|
||||||
if (transInfo.objRequest) {
|
if (newTrans.objRequest) {
|
||||||
if (DEBUG) Log.d(TAG, "Sending object request " + transInfo.obj.getName());
|
if (DEBUG) Log.d(TAG, "Sending object request " + newTrans.obj.getName());
|
||||||
utalk.sendObjectRequest(transInfo.obj, transInfo.allInstances);
|
utalk.sendObjectRequest(newTrans.obj, newTrans.allInstances);
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) Log.d(TAG, "Sending object " + transInfo.obj.getName());
|
if (DEBUG) Log.d(TAG, "Sending object " + newTrans.obj.getName());
|
||||||
utalk.sendObject(transInfo.obj, transInfo.acked, transInfo.allInstances);
|
utalk.sendObject(newTrans.obj, newTrans.acked, newTrans.allInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -657,9 +659,17 @@ public class Telemetry {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post a timeout timer if a response is epxected
|
// Store this as the active transaction. However in the case
|
||||||
if (transPending)
|
// of transPending && !newTransactionPending we need ot not
|
||||||
|
// override the previous pending transaction
|
||||||
|
if (!transPending && newTransactionPending) {
|
||||||
|
transPending = newTransactionPending;
|
||||||
|
transInfo = newTrans;
|
||||||
|
|
||||||
|
// Post a timeout timer if a response is epxected
|
||||||
handler.postDelayed(transactionTimeout, REQ_TIMEOUT_MS);
|
handler.postDelayed(transactionTimeout, REQ_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -744,7 +754,7 @@ public class Telemetry {
|
|||||||
//Send signal
|
//Send signal
|
||||||
obj.transactionCompleted(result);
|
obj.transactionCompleted(result);
|
||||||
} else {
|
} else {
|
||||||
if (ERROR) Log.e(TAG, "Error: received a transaction completed when did not expect it.");
|
if (ERROR) Log.e(TAG, "Error: received a transaction completed when did not expect it. " + obj.getName());
|
||||||
transPending = false;
|
transPending = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,12 @@ public class TelemetryMonitor extends Observable {
|
|||||||
|
|
||||||
private final UAVObjectManager objMngr;
|
private final UAVObjectManager objMngr;
|
||||||
private final Telemetry tel;
|
private final Telemetry tel;
|
||||||
|
|
||||||
|
private boolean objectsRegistered;
|
||||||
// private UAVObject objPending;
|
// private UAVObject objPending;
|
||||||
private UAVObject gcsStatsObj;
|
private UAVObject gcsStatsObj;
|
||||||
private UAVObject flightStatsObj;
|
private UAVObject flightStatsObj;
|
||||||
|
private final UAVObject firmwareIapObj;
|
||||||
private Timer periodicTask;
|
private Timer periodicTask;
|
||||||
private int currentPeriod;
|
private int currentPeriod;
|
||||||
private long lastUpdateTime;
|
private long lastUpdateTime;
|
||||||
@ -74,7 +77,8 @@ public class TelemetryMonitor extends Observable {
|
|||||||
return objects_updated;
|
return objects_updated;
|
||||||
};
|
};
|
||||||
|
|
||||||
public TelemetryMonitor(UAVObjectManager objMngr, Telemetry tel, OPTelemetryService s) {
|
public TelemetryMonitor(UAVObjectManager objMngr, Telemetry tel,
|
||||||
|
OPTelemetryService s) {
|
||||||
this(objMngr, tel);
|
this(objMngr, tel);
|
||||||
telemService = s;
|
telemService = s;
|
||||||
}
|
}
|
||||||
@ -85,9 +89,15 @@ public class TelemetryMonitor extends Observable {
|
|||||||
// this.objPending = null;
|
// this.objPending = null;
|
||||||
queue = new ArrayList<UAVObject>();
|
queue = new ArrayList<UAVObject>();
|
||||||
|
|
||||||
|
objectsRegistered = false;
|
||||||
|
|
||||||
// Get stats objects
|
// Get stats objects
|
||||||
gcsStatsObj = objMngr.getObject("GCSTelemetryStats");
|
gcsStatsObj = objMngr.getObject("GCSTelemetryStats");
|
||||||
flightStatsObj = objMngr.getObject("FlightTelemetryStats");
|
flightStatsObj = objMngr.getObject("FlightTelemetryStats");
|
||||||
|
firmwareIapObj = objMngr.getObject("FirmwareIAPObj");
|
||||||
|
|
||||||
|
// The first update of the firmwareIapObj will trigger registering the objects
|
||||||
|
firmwareIapObj.addUpdatedObserver(firmwareIapUpdated);
|
||||||
|
|
||||||
flightStatsObj.addUpdatedObserver(new Observer() {
|
flightStatsObj.addUpdatedObserver(new Observer() {
|
||||||
@Override
|
@Override
|
||||||
@ -360,8 +370,13 @@ public class TelemetryMonitor extends Observable {
|
|||||||
setPeriod(STATS_UPDATE_PERIOD_MS);
|
setPeriod(STATS_UPDATE_PERIOD_MS);
|
||||||
connected = true;
|
connected = true;
|
||||||
objects_updated = false;
|
objects_updated = false;
|
||||||
startRetrievingObjects();
|
if (objectsRegistered)
|
||||||
if (HANDSHAKE_IS_CONNECTED) setChanged(); // Enabling this line makes the opConnected signal occur whenever we get a handshake
|
startRetrievingObjects();
|
||||||
|
else
|
||||||
|
firmwareIapObj.updateRequested();
|
||||||
|
if (HANDSHAKE_IS_CONNECTED)
|
||||||
|
setChanged(); // Enabling this line makes the opConnected signal
|
||||||
|
// occur whenever we get a handshake
|
||||||
}
|
}
|
||||||
if (gcsDisconnected && gcsStatusChanged) {
|
if (gcsDisconnected && gcsStatusChanged) {
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
@ -405,4 +420,37 @@ public class TelemetryMonitor extends Observable {
|
|||||||
periodicTask = null;
|
periodicTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Observer firmwareIapUpdated = new Observer() {
|
||||||
|
@Override
|
||||||
|
public void update(Observable observable, Object data) {
|
||||||
|
if (DEBUG) Log.d(TAG, "Received firmware IAP Updated message");
|
||||||
|
|
||||||
|
UAVObjectField description = firmwareIapObj.getField("Description");
|
||||||
|
if (description == null || description.getNumElements() < 100) {
|
||||||
|
telemService.toastMessage("Failed to determine UAVO set");
|
||||||
|
} else {
|
||||||
|
final int HASH_SIZE_USED = 8;
|
||||||
|
String jarName = new String();
|
||||||
|
for (int i = 0; i < HASH_SIZE_USED; i++) {
|
||||||
|
jarName += String.format("%02x", (int) description.getDouble(i + 60));
|
||||||
|
}
|
||||||
|
jarName += ".jar";
|
||||||
|
if (DEBUG) Log.d(TAG, "Attempting to load: " + jarName);
|
||||||
|
if (telemService.loadUavobjects(jarName, objMngr)) {
|
||||||
|
telemService.toastMessage("Loaded appropriate UAVO set");
|
||||||
|
objectsRegistered = true;
|
||||||
|
try {
|
||||||
|
startRetrievingObjects();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
telemService.toastMessage("Failed to load UAVO set: " + jarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
firmwareIapObj.removeUpdatedObserver(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -269,16 +269,18 @@ public class UAVTalk {
|
|||||||
* it wants to give up on one (after a timeout) then it can cancel it
|
* it wants to give up on one (after a timeout) then it can cancel it
|
||||||
* @return True if that object was pending, False otherwise
|
* @return True if that object was pending, False otherwise
|
||||||
*/
|
*/
|
||||||
public synchronized boolean cancelPendingTransaction(UAVObject obj) {
|
public boolean cancelPendingTransaction(UAVObject obj) {
|
||||||
if(respObj != null && respObj.getObjID() == obj.getObjID()) {
|
synchronized (respObj) {
|
||||||
if(transactionListener != null) {
|
if(respObj != null && respObj.getObjID() == obj.getObjID()) {
|
||||||
Log.d(TAG,"Canceling transaction: " + respObj.getName());
|
if(transactionListener != null) {
|
||||||
transactionListener.TransactionFailed(respObj);
|
Log.d(TAG,"Canceling transaction: " + respObj.getName());
|
||||||
}
|
transactionListener.TransactionFailed(respObj);
|
||||||
respObj = null;
|
}
|
||||||
return true;
|
respObj = null;
|
||||||
} else
|
return true;
|
||||||
return false;
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -296,15 +298,16 @@ public class UAVTalk {
|
|||||||
/**
|
/**
|
||||||
* This is the code that sets up a new UAVTalk packet that expects a response.
|
* This is the code that sets up a new UAVTalk packet that expects a response.
|
||||||
*/
|
*/
|
||||||
private synchronized void setupTransaction(UAVObject obj, boolean allInstances, int type) {
|
private void setupTransaction(UAVObject obj, boolean allInstances, int type) {
|
||||||
|
synchronized (this) {
|
||||||
|
// Only cancel if it is for a different object
|
||||||
|
if(respObj != null && respObj.getObjID() != obj.getObjID())
|
||||||
|
cancelPendingTransaction(obj);
|
||||||
|
|
||||||
// Only cancel if it is for a different object
|
respObj = obj;
|
||||||
if(respObj != null && respObj.getObjID() != obj.getObjID())
|
respAllInstances = allInstances;
|
||||||
cancelPendingTransaction(obj);
|
respType = type;
|
||||||
|
}
|
||||||
respObj = obj;
|
|
||||||
respAllInstances = allInstances;
|
|
||||||
respType = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -315,7 +318,7 @@ public class UAVTalk {
|
|||||||
* Success (true), Failure (false)
|
* Success (true), Failure (false)
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private synchronized boolean objectTransaction(UAVObject obj, int type, boolean allInstances) throws IOException {
|
private boolean objectTransaction(UAVObject obj, int type, boolean allInstances) throws IOException {
|
||||||
if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ || type == TYPE_OBJ) {
|
if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ || type == TYPE_OBJ) {
|
||||||
return transmitObject(obj, type, allInstances);
|
return transmitObject(obj, type, allInstances);
|
||||||
} else {
|
} else {
|
||||||
@ -415,7 +418,7 @@ public class UAVTalk {
|
|||||||
{
|
{
|
||||||
UAVObject rxObj = objMngr.getObject(rxObjId);
|
UAVObject rxObj = objMngr.getObject(rxObjId);
|
||||||
if (rxObj == null) {
|
if (rxObj == null) {
|
||||||
if (DEBUG) Log.d(TAG, "Unknown ID: " + rxObjId);
|
if (WARN) Log.w(TAG, "Unknown ID: " + rxObjId);
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = RxStateType.STATE_SYNC;
|
rxState = RxStateType.STATE_SYNC;
|
||||||
break;
|
break;
|
||||||
@ -429,17 +432,7 @@ public class UAVTalk {
|
|||||||
|
|
||||||
// Check length and determine next state
|
// Check length and determine next state
|
||||||
if (rxLength >= MAX_PAYLOAD_LENGTH) {
|
if (rxLength >= MAX_PAYLOAD_LENGTH) {
|
||||||
stats.rxErrors++;
|
if (WARN) Log.w(TAG, "Greater than max payload length");
|
||||||
rxState = RxStateType.STATE_SYNC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the lengths match
|
|
||||||
if ((rxPacketLength + rxLength) != packetSize) { // packet error
|
|
||||||
// -
|
|
||||||
// mismatched
|
|
||||||
// packet
|
|
||||||
// size
|
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = RxStateType.STATE_SYNC;
|
rxState = RxStateType.STATE_SYNC;
|
||||||
break;
|
break;
|
||||||
@ -503,7 +496,7 @@ public class UAVTalk {
|
|||||||
rxCSPacket = rxbyte;
|
rxCSPacket = rxbyte;
|
||||||
|
|
||||||
if (rxCS != rxCSPacket) { // packet error - faulty CRC
|
if (rxCS != rxCSPacket) { // packet error - faulty CRC
|
||||||
if (DEBUG) Log.d(TAG,"Bad crc");
|
if (WARN) Log.w(TAG,"Bad crc");
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = RxStateType.STATE_SYNC;
|
rxState = RxStateType.STATE_SYNC;
|
||||||
break;
|
break;
|
||||||
@ -512,7 +505,7 @@ public class UAVTalk {
|
|||||||
if (rxPacketLength != (packetSize + 1)) { // packet error -
|
if (rxPacketLength != (packetSize + 1)) { // packet error -
|
||||||
// mismatched packet
|
// mismatched packet
|
||||||
// size
|
// size
|
||||||
if (DEBUG) Log.d(TAG,"Bad size");
|
if (WARN) Log.w(TAG,"Bad size");
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = RxStateType.STATE_SYNC;
|
rxState = RxStateType.STATE_SYNC;
|
||||||
break;
|
break;
|
||||||
@ -529,6 +522,7 @@ public class UAVTalk {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (WARN) Log.w(TAG, "Bad state");
|
||||||
rxState = RxStateType.STATE_SYNC;
|
rxState = RxStateType.STATE_SYNC;
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
}
|
}
|
||||||
@ -701,21 +695,30 @@ public class UAVTalk {
|
|||||||
* Called when an object is received to check if this completes
|
* Called when an object is received to check if this completes
|
||||||
* a UAVTalk transaction
|
* a UAVTalk transaction
|
||||||
*/
|
*/
|
||||||
private synchronized void updateObjReq(UAVObject obj) {
|
private void updateObjReq(UAVObject obj) {
|
||||||
// Check if this is not a possible candidate
|
// Check if this is not a possible candidate
|
||||||
Assert.assertNotNull(obj);
|
Assert.assertNotNull(obj);
|
||||||
|
|
||||||
if(respObj != null && respType == TYPE_OBJ_REQ && respObj.getObjID() == obj.getObjID() &&
|
boolean succeeded = false;
|
||||||
((respObj.getInstID() == obj.getInstID() || !respAllInstances))) {
|
|
||||||
|
|
||||||
// Indicate complete
|
// The lock on UAVTalk must be release before the transaction succeeded signal is sent
|
||||||
respObj = null;
|
// because otherwise if a transaction timeout occurs at the same time we can get a
|
||||||
|
// deadlock:
|
||||||
|
// 1. processInputStream -> updateObjReq (locks uavtalk) -> tranactionCompleted (locks transInfo)
|
||||||
|
// 2. transactionTimeout (locks transInfo) -> sendObjectRequest -> É -> setupTransaction (locks uavtalk)
|
||||||
|
synchronized(this) {
|
||||||
|
if(respObj != null && respType == TYPE_OBJ_REQ && respObj.getObjID() == obj.getObjID() &&
|
||||||
|
((respObj.getInstID() == obj.getInstID() || !respAllInstances))) {
|
||||||
|
|
||||||
// Notify listener
|
// Indicate complete
|
||||||
if (transactionListener != null)
|
respObj = null;
|
||||||
transactionListener.TransactionSucceeded(obj);
|
succeeded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify listener
|
||||||
|
if (succeeded && transactionListener != null)
|
||||||
|
transactionListener.TransactionSucceeded(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user