public bool sendObject(UAVObject obj, bool acked, bool allInstances) { if (acked) { return objectTransaction(obj, uavConsts.TYPE_OBJ_ACK, allInstances); } else { return objectTransaction(obj, uavConsts.TYPE_OBJ, allInstances); } }
TreeNode addNode(UAVObject b) { if (InvokeRequired) return (TreeNode)this.Invoke(new addnodeDelegate(addNode), b); else { TreeNode n = treeView1.Nodes.Add(b.name); foreach (var prop in b.GetType().GetFields().Where(j => j.FieldType.BaseType == typeof(UAVObjectField))) { UAVObjectField f = (UAVObjectField)prop.GetValue(b); TreeNode newnode = n.Nodes.Add(f.getName()); if (f.getNumElements() > 1) { for (int i = 0; i < f.getNumElements(); i++) { newnode.Nodes.Add(i.ToString()); } } /*if (fields.ContainsKey(f)) { int n = f.getNumElements(); if (n == 1) fields[f] = f.getValue(); else { object[] vals = new object[n]; for (int i = 0; i < n; i++) vals[i] = f.getValue(i); fields[f] = vals; } }*/ } return n; } }
private bool objectTransaction(UAVObject obj, int type, bool allInstances) { if (type == uavConsts.TYPE_OBJ_ACK || type == uavConsts.TYPE_OBJ_REQ || type == uavConsts.TYPE_OBJ) { return transmitObject(obj, type, allInstances); } else { return false; } }
public UAVMetaObject(long objID, String name, UAVDataObject parent) : base(objID, true, name) { this.parent = parent; ownMetadata = new Metadata(); ownMetadata.flags = 0; // TODO: Fix flags ownMetadata.gcsTelemetryUpdatePeriod = 0; ownMetadata.loggingUpdatePeriod = 0; List<String> modesBitField = new List<String>(); modesBitField.Add("FlightReadOnly"); modesBitField.Add("GCSReadOnly"); modesBitField.Add("FlightTelemetryAcked"); modesBitField.Add("GCSTelemetryAcked"); modesBitField.Add("FlightUpdatePeriodic"); modesBitField.Add("FlightUpdateOnChange"); modesBitField.Add("GCSUpdatePeriodic"); modesBitField.Add("GCSUpdateOnChange"); List<UAVObjectField> fields = new List<UAVObjectField>(); fields.Add( new UAVObjectField<bool>("Modes", "", 1, modesBitField, parent) ); fields.Add(new UAVObjectField<UInt16>("Flight Telemetry Update Period", "ms", 1, null, parent)); fields.Add(new UAVObjectField<UInt16>("GCS Telemetry Update Period", "ms", 1, null, parent)); fields.Add(new UAVObjectField<UInt16>("Logging Update Period", "ms", 1, null, parent)); int numBytes = fields.Sum(j=>j.getNumBytes()); // Initialize object // Initialize parent base.initialize(0); initializeFields(fields, new ByteBuffer(numBytes), numBytes); // Setup metadata of parent parentMetadata = parent.getDefaultMetadata(); }
public abstract void initialize(UAVObject obj);
public abstract void TransactionFailed(UAVObject data);
public abstract void TransactionSucceeded(UAVObject data);
public bool sendObjectRequest(UAVObject obj, bool allInstances) { return objectTransaction(obj, uavConsts.TYPE_OBJ_REQ, allInstances); }
private void updateObjReq(UAVObject obj) { bool succeeded = false; // The lock on UAVTalk must be release before the transaction succeeded signal is sent // 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) lock (updateObjReqSyncLock) { if(respObj != null && respType == uavConsts.TYPE_OBJ_REQ && respObj.getObjID() == obj.getObjID() && ((respObj.getInstID() == obj.getInstID() || !respAllInstances))) { // Indicate complete respObj = null; succeeded = true; } } // Notify listener if (succeeded && transactionListener != null) transactionListener.TransactionSucceeded(obj); }
/** * UAVTalk takes care of it's own transactions but if the caller knows * it wants to give up on one (after a timeout) then it can cancel it * @return True if that object was pending, False otherwise */ public bool cancelPendingTransaction(UAVObject obj) { lock (respObj) { if(respObj != null && respObj.getObjID() == obj.getObjID()) { if(transactionListener != null) { Debug.WriteLine("Canceling transaction: " + respObj.getName()); transactionListener.TransactionFailed(respObj); } respObj = null; return true; } else return false; } }
/** * This is the code that sets up a new UAVTalk packet that expects a response. */ private void setupTransaction(UAVObject obj, bool allInstances, int type) { lock(this) { // Only cancel if it is for a different object if(respObj != null && respObj.getObjID() != obj.getObjID()) cancelPendingTransaction(obj); respObj = obj; respAllInstances = allInstances; respType = type; } }
/** * Send an object through the telemetry link. * @throws IOException * @param[in] obj Object handle to send * @param[in] type Transaction type \return Success (true), Failure (false) */ private bool transmitSingleObject(UAVObject obj, int type, bool allInstances) { int length; int allInstId = uavConsts.ALL_INSTANCES; ByteBuffer bbuf = new ByteBuffer(uavConsts.MAX_PACKET_LENGTH); // Determine data length if (type == uavConsts.TYPE_OBJ_REQ || type == uavConsts.TYPE_ACK) { length = 0; } else { length = obj.getNumBytes(); } // Setup type and object id fields bbuf.put((byte)(uavConsts.SYNC_VAL & 0xff)); bbuf.put((byte)(type & 0xff)); bbuf.putShort((UInt16)(length + 2 /* SYNC, Type */+ 2 /* Size */+ 4 /* ObjID */+ (obj .isSingleInstance() ? 0 : 2))); bbuf.putUint32((UInt32)obj.getObjID()); // Setup instance ID if one is required if (!obj.isSingleInstance()) { // Check if all instances are requested if (allInstances) bbuf.putShort((UInt16)(allInstId & 0xffff)); else bbuf.putShort((UInt16)(obj.getInstID() & 0xffff)); } // Check length if (length >= uavConsts.MAX_PAYLOAD_LENGTH) return false; // Copy data (if any) if (length > 0) try { if (obj.pack(bbuf) == 0) return false; } catch (Exception e) { // TODO Auto-generated catch block Debug.Write(e.Message); return false; } // Calculate checksum bbuf.put((byte)(CRC.updateCRC(0, bbuf.array(), bbuf.position()) & 0xff)); int packlen = bbuf.position(); bbuf.position(0); byte[] dst = new byte[packlen]; bbuf.get(dst, 0, packlen); if (type == uavConsts.TYPE_OBJ_ACK || type == uavConsts.TYPE_OBJ_REQ) { // Once we send a UAVTalk packet that requires an ack or object let's set up // the transaction here setupTransaction(obj, allInstances, type); } ch.write(dst); // Update stats ++txStats.Objects; txStats.Bytes += bbuf.position(); txStats.ObjectBytes += length; // Done return true; }
/** * Send an object through the telemetry link. * @param[in] obj Object to send * @param[in] type Transaction type * @param[in] allInstances True is all instances of the object are to be sent * @return Success (true), Failure (false) * @throws IOException */ private bool transmitObject(UAVObject obj, int type, bool allInstances) { // If all instances are requested on a single instance object it is an // error if (allInstances && obj.isSingleInstance()) { allInstances = false; } // Process message type if (type == uavConsts.TYPE_OBJ || type == uavConsts.TYPE_OBJ_ACK) { if (allInstances) { // Get number of instances int numInst = objMgr.getNumInstances(obj.getObjID()); // Send all instances for (int instId = 0; instId < numInst; ++instId) { // TODO: This code is buggy probably. We should send each request // and wait for an ack in the case of an TYPE_OBJ_ACK Debug.Assert(type != uavConsts.TYPE_OBJ_ACK); // catch any buggy calls UAVObject inst = objMgr.getObject(obj.getObjID(), instId); transmitSingleObject(inst, type, false); } return true; } else { return transmitSingleObject(obj, type, false); } } else if (type == uavConsts.TYPE_OBJ_REQ) { return transmitSingleObject(obj, uavConsts.TYPE_OBJ_REQ, allInstances); } else if (type == uavConsts.TYPE_ACK) { if (!allInstances) { return transmitSingleObject(obj, uavConsts.TYPE_ACK, false); } else { return false; } } else { return false; } }
private void updateAck(UAVObject obj) { lock (updateAckSyncLock) { Debug.WriteLine("Received ack: " + obj.getName()); //Assert.assertNotNull(obj); if (respObj != null && respObj.getObjID() == obj.getObjID() && (respObj.getInstID() == obj.getInstID() || respAllInstances)) { // Indicate complete respObj = null; // Notify listener if (transactionListener != null) transactionListener.TransactionSucceeded(obj); } } }
private void receivedNack(UAVObject obj) { lock (receivedNackSyncLock) { if (respObj != null && (respType == uavConsts.TYPE_OBJ_REQ || respType == uavConsts.TYPE_OBJ_ACK) && respObj.getObjID() == obj.getObjID()) { Debug.WriteLine("NAK: " + obj.getName()); // Indicate complete respObj = null; // Notify listener if (transactionListener != null) transactionListener.TransactionFailed(obj); } } }