1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

AndroidGCS: Start supporting NAK and having uavTalk emit a transaction failed

and succeeded call.  Had to change the mask on the AndroidGCS side to match the
FC side.
This commit is contained in:
James Cotton 2012-08-09 08:54:02 -05:00
parent c7abc42c5e
commit 5443dbb4ca
3 changed files with 83 additions and 17 deletions

View File

@ -173,7 +173,7 @@ public class ObjectBrowser extends ObjectManagerActivity implements OnSharedPref
selected_index = position; selected_index = position;
allObjects.get(position).addUpdatedObserver(updatedObserver); allObjects.get(position).addUpdatedObserver(updatedObserver);
allObjects.get(position).updateRequested(); allObjects.get(position).updateRequested();
updateObject(); //updateObject();
} }
}); });

View File

@ -87,9 +87,9 @@ public class Telemetry {
/** /**
* Constructor * Constructor
*/ */
public Telemetry(UAVTalk utalk, UAVObjectManager objMngr) public Telemetry(UAVTalk utalkIn, UAVObjectManager objMngr)
{ {
this.utalk = utalk; this.utalk = utalkIn;
this.objMngr = objMngr; this.objMngr = objMngr;
// Process all objects in the list // Process all objects in the list
@ -113,16 +113,28 @@ public class Telemetry {
}); });
// Listen to transaction completions // Listen to transaction completions
utalk.addObserver(new Observer() { this.utalk.setOnTransactionCompletedListener(
this.utalk.new OnTransactionCompletedListener() {
@Override @Override
public void update(Observable observable, Object data) { void TransactionSucceeded(UAVObject data) {
try { try {
transactionCompleted((UAVObject) data); transactionCompleted(data);
} catch (IOException e) { } catch (IOException e) {
// Disconnect when stream fails // Disconnect when stream fails
observable.deleteObserver(this); utalk.setOnTransactionCompletedListener(null);
} }
} }
@Override
void TransactionFailed(UAVObject data) {
try {
Log.d(TAG, "TransactionFailed(" + data.getName() + ")");
transactionCompleted(data);
} catch (IOException e) {
// Disconnect when stream fails
utalk.setOnTransactionCompletedListener(null);
}
}
}); });
// Get GCS stats object // Get GCS stats object

View File

@ -33,14 +33,17 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.Observable; import java.util.Observable;
import junit.framework.Assert;
import android.util.Log; import android.util.Log;
public class UAVTalk extends Observable { public class UAVTalk extends Observable {
static final String TAG = "UAVTalk"; static final String TAG = "UAVTalk";
public static int LOGLEVEL = 0; public static int LOGLEVEL = 0;
public static boolean WARN = LOGLEVEL > 1; public static boolean VERBOSE = LOGLEVEL > 3;
public static boolean DEBUG = LOGLEVEL > 0; public static boolean WARN = LOGLEVEL > 2;
public static boolean DEBUG = LOGLEVEL > 1;
public static boolean ERROR = LOGLEVEL > 0;
private Thread inputProcessingThread = null; private Thread inputProcessingThread = null;
@ -102,12 +105,13 @@ public class UAVTalk extends Observable {
STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS
}; };
static final int TYPE_MASK = 0xFC; static final int TYPE_MASK = 0xF8;
static final int TYPE_VER = 0x20; static final int TYPE_VER = 0x20;
static final int TYPE_OBJ = (TYPE_VER | 0x00); static final int TYPE_OBJ = (TYPE_VER | 0x00);
static final int TYPE_OBJ_REQ = (TYPE_VER | 0x01); static final int TYPE_OBJ_REQ = (TYPE_VER | 0x01);
static final int TYPE_OBJ_ACK = (TYPE_VER | 0x02); static final int TYPE_OBJ_ACK = (TYPE_VER | 0x02);
static final int TYPE_ACK = (TYPE_VER | 0x03); static final int TYPE_ACK = (TYPE_VER | 0x03);
static final int TYPE_NACK = (TYPE_VER | 0x04);
static final int MIN_HEADER_LENGTH = 8; // sync(1), type (1), size(2), static final int MIN_HEADER_LENGTH = 8; // sync(1), type (1), size(2),
// object ID(4) // object ID(4)
@ -271,6 +275,8 @@ public class UAVTalk extends Observable {
// Send object depending on if a response is needed // Send object depending on if a response is needed
if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ) { if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ) {
if (transmitObject(obj, type, allInstances)) { if (transmitObject(obj, type, allInstances)) {
if(type == TYPE_OBJ_REQ)
if (ERROR) Log.e(TAG, "Sending obj req");
respObj = obj; respObj = obj;
respAllInstances = allInstances; respAllInstances = allInstances;
return true; return true;
@ -290,7 +296,7 @@ public class UAVTalk extends Observable {
* @throws IOException * @throws IOException
*/ */
public synchronized boolean processInputByte(int rxbyte) throws IOException { public synchronized boolean processInputByte(int rxbyte) throws IOException {
assert (objMngr != null); Assert.assertNotNull(objMngr);
// Update stats // Update stats
stats.rxBytes++; stats.rxBytes++;
@ -318,12 +324,13 @@ public class UAVTalk extends Observable {
rxCS = updateCRC(rxCS, rxbyte); rxCS = updateCRC(rxCS, rxbyte);
if ((rxbyte & TYPE_MASK) != TYPE_VER) { if ((rxbyte & TYPE_MASK) != TYPE_VER) {
Log.e(TAG, "Unknown UAVTalk type:" + rxbyte);
rxState = RxStateType.STATE_SYNC; rxState = RxStateType.STATE_SYNC;
break; break;
} }
rxType = rxbyte; rxType = rxbyte;
if (VERBOSE) Log.v(TAG, "Received packet type: " + rxType);
packetSize = 0; packetSize = 0;
rxState = RxStateType.STATE_SIZE; rxState = RxStateType.STATE_SIZE;
@ -380,7 +387,7 @@ public class UAVTalk extends Observable {
} }
// Determine data length // Determine data length
if (rxType == TYPE_OBJ_REQ || rxType == TYPE_ACK) if (rxType == TYPE_OBJ_REQ || rxType == TYPE_ACK || rxType == TYPE_NACK)
rxLength = 0; rxLength = 0;
else else
rxLength = rxObj.getNumBytes(); rxLength = rxObj.getNumBytes();
@ -565,6 +572,24 @@ public class UAVTalk extends Observable {
error = true; error = true;
} }
break; break;
case TYPE_NACK:
if (DEBUG) Log.d(TAG, "Received NAK: " + objId + " " + objMngr.getObject(objId).getName());
// All instances, not allowed for NACK messages
if (!allInstances)
{
// Get object
obj = objMngr.getObject(objId, instId);
// Check if object exists:
if (obj != null)
{
updateNack(obj);
}
else
{
error = true;
}
}
break;
case TYPE_ACK: case TYPE_ACK:
// All instances, not allowed for ACK messages // All instances, not allowed for ACK messages
if (!allInstances) { if (!allInstances) {
@ -636,15 +661,34 @@ public class UAVTalk extends Observable {
} }
} }
/**
* Check if a transaction is pending and if yes complete it.
*/
void updateNack(UAVObject obj)
{
if (DEBUG) Log.d(TAG, "NACK received: " + obj.getName());
Assert.assertNotNull(obj);
//obj.transactionCompleted(false);
if (respObj != null && respObj.getObjID() == obj.getObjID() &&
(respObj.getInstID() == obj.getInstID() || respAllInstances)) {
if (transactionListener != null)
transactionListener.TransactionFailed(obj);
}
}
/** /**
* Check if a transaction is pending and if yes complete it. * Check if a transaction is pending and if yes complete it.
*/ */
synchronized void updateAck(UAVObject obj) { synchronized void updateAck(UAVObject obj) {
if (DEBUG) Log.d(TAG, "ACK received: " + obj.getName());
Assert.assertNotNull(obj);
if (respObj != null && respObj.getObjID() == obj.getObjID() if (respObj != null && respObj.getObjID() == obj.getObjID()
&& (respObj.getInstID() == obj.getInstID() || respAllInstances)) { && (respObj.getInstID() == obj.getInstID() || respAllInstances)) {
respObj = null; if (transactionListener != null)
transactionListener.TransactionSucceeded(obj);
/*respObj = null;
setChanged(); setChanged();
notifyObservers(obj); notifyObservers(obj);*/
} }
} }
@ -784,4 +828,14 @@ public class UAVTalk extends Observable {
return crc; return crc;
} }
private OnTransactionCompletedListener transactionListener = null;
abstract class OnTransactionCompletedListener {
abstract void TransactionSucceeded(UAVObject data);
abstract void TransactionFailed(UAVObject data);
};
void setOnTransactionCompletedListener(OnTransactionCompletedListener onTransactionListener) {
this.transactionListener = onTransactionListener;
}
} }