]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/lqi/LqiForwardingEngineP.nc
Call is needed.
[tinyos-2.x.git] / tos / lib / net / lqi / LqiForwardingEngineP.nc
index e3dc5d003f27145af7478874dfd85fe09309eab5..c52e80b412467859b2155afc82445ace9d04cc04 100644 (file)
@@ -1,6 +1,5 @@
 // $Id$
 
-
 /* Copyright (c) 2007 Stanford University.
  * All rights reserved.
  *
@@ -78,6 +77,7 @@
 
 #include "AM.h"
 #include "MultiHopLqi.h"
+#include "CollectionDebugMsg.h"
 
 module LqiForwardingEngineP {
   provides {
@@ -94,13 +94,16 @@ module LqiForwardingEngineP {
   uses {
     interface Receive as SubReceive;
     interface AMSend as SubSend;
+    interface AMSend as SubSendMine;
     interface RouteControl as RouteSelectCntl;
     interface RouteSelect;
     interface Leds;
     interface Packet as SubPacket;
     interface AMPacket;
     interface RootControl;
+    interface Random;
     interface PacketAcknowledgements;
+    interface CollectionDebug;
   }
 }
 
@@ -118,7 +121,8 @@ implementation {
   uint8_t iFwdBufHead, iFwdBufTail;
   uint16_t sendFailures = 0;
   uint8_t fail_count = 0;
-
+  int fwdbusy = 0;
+  
   lqi_header_t* getHeader(message_t* msg) {
     return (lqi_header_t*) call SubPacket.getPayload(msg, NULL);
   }
@@ -152,21 +156,18 @@ implementation {
   command error_t Send.send(message_t* pMsg, uint8_t len) {
     len += sizeof(lqi_header_t);
     if (len > call SubPacket.maxPayloadLength()) {
-      call Leds.led0On();
       return ESIZE;
     }
     if (call RootControl.isRoot()) {
-      call Leds.led1On();
       return FAIL;
     }
     call RouteSelect.initializeFields(pMsg);
     
     if (call RouteSelect.selectRoute(pMsg, 0) != SUCCESS) {
-      call Leds.led2On();
       return FAIL;
     }
     call PacketAcknowledgements.requestAck(pMsg);
-    if (call SubSend.send(call AMPacket.destination(pMsg), pMsg, len) != SUCCESS) {
+    if (call SubSendMine.send(call AMPacket.destination(pMsg), pMsg, len) != SUCCESS) {
       sendFailures++;
       return FAIL;
     }
@@ -199,36 +200,62 @@ implementation {
     } 
     return -1;
   }
+
+  static char* fields(message_t* msg) {
+#ifdef TOSSIM
+    static char mbuf[1024];
+    lqi_header_t* hdr = getHeader(msg);
+    sprintf(mbuf, "origin = %hu, seqno = %hu, oseqno = %hu, hopcount =%hu", hdr->originaddr, hdr->seqno, hdr->originseqno, hdr->hopcount);
+    return mbuf;
+#else
+    return NULL;
+#endif
+  }
+
+  static void forward(message_t* msg);
   
   static message_t* mForward(message_t* msg) {
-    message_t* newMsg = msg;
     int8_t buf = get_buff();
-    call Leds.led2Toggle();
-    
+    dbg("LQI", " Asked to forward packet @%s:\t%s\n", sim_time_string(), fields(msg));
     if (buf == -1) {
-      dbg("LQI", "Dropped packet due to no space in queue.\n");
+      dbg("LQI", "%s Dropped packet due to no space in queue.\n", __FUNCTION__);
+      call CollectionDebug.logEvent(NET_C_FE_SEND_QUEUE_FULL);
       return msg;
     }
-    
     if ((call RouteSelect.selectRoute(msg, 0)) != SUCCESS) {
       FwdBufBusy[(uint8_t)buf] = 0;
+      call CollectionDebug.logEvent(NET_C_FE_NO_ROUTE);
+      dbg("LQI", "%s Dropped packet due to no route.\n", __FUNCTION__);
       return msg;
     }
+    else {
+      message_t* newMsg = FwdBufList[(uint8_t)buf];
+      FwdBufList[(uint8_t)buf] = msg;
+      forward(msg);
+      return newMsg;
+    }
+  }
+  
+  static void forward(message_t* msg) {
     // Failures at the send level do not cause the seq. number space to be 
     // rolled back properly.  This is somewhat broken.
-    call PacketAcknowledgements.requestAck(msg);
-    if (call SubSend.send(call AMPacket.destination(msg),
-                         msg,
-                         call SubPacket.payloadLength(msg) == SUCCESS)) {
-      newMsg = FwdBufList[(uint8_t)buf];
-      FwdBufList[(uint8_t)buf] = msg;
+    if (fwdbusy) {
+      dbg("LQI", "%s forwarding busy, wait for later.\n", __FUNCTION__);
+      return;
     }
-    else{
-      FwdBufBusy[(uint8_t)buf] = 0;
-      sendFailures++;
+    else {
+      call PacketAcknowledgements.requestAck(msg);
+      if (call SubSend.send(call AMPacket.destination(msg),
+                           msg,
+                           call SubPacket.payloadLength(msg)) == SUCCESS) {
+       call CollectionDebug.logEventMsg(NET_C_DBG_1, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                        call AMPacket.destination(msg));
+       dbg("LQI", "%s: Send to %hu success.\n", __FUNCTION__, call AMPacket.destination(msg));
+      }
+      fwdbusy = TRUE;
     }
-    return newMsg;    
   }
 
   event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) {
@@ -236,10 +263,19 @@ implementation {
     payload += sizeof(lqi_header_t);
     len -= sizeof(lqi_header_t);
 
+    call CollectionDebug.logEventMsg(NET_C_FE_RCV_MSG, 
+                                    call CollectionPacket.getSequenceNumber(msg), 
+                                    call CollectionPacket.getOrigin(msg), 
+                                    call AMPacket.destination(msg));
     if (call RootControl.isRoot()) {
+      dbg("LQI,LQIDeliver", "LQI Root is receiving packet from node %hu @%s\n", getHeader(msg)->originaddr, sim_time_string());
       return signal Receive.receive[id](msg, payload, len);
     }
+    else if (call AMPacket.destination(msg) != call AMPacket.address()) {
+      return msg;
+    }
     else if (signal Intercept.forward[id](msg, payload, len)) {
+      dbg("LQI,LQIDeliver", "LQI fwd is forwarding packet from node %hu @%s\n", getHeader(msg)->originaddr, sim_time_string());
       return mForward(msg);
     }
     else {
@@ -247,31 +283,120 @@ implementation {
     }
   }
   
-
+  message_t* nextMsg() {
+    int i;
+    uint16_t inc = call Random.rand16() & 0xfff;
+    for (i = 0; i < FWD_QUEUE_SIZE; i++) {
+      int pindex = (i + inc) % FWD_QUEUE_SIZE;
+      if (FwdBufBusy[pindex]) {
+       return FwdBufList[pindex];
+      }
+    }
+    return NULL;
+  }
+  
   event void SubSend.sendDone(message_t* msg, error_t success) {
     int8_t buf;
+    message_t* nextToSend;
     if (!call PacketAcknowledgements.wasAcked(msg) &&
        call AMPacket.destination(msg) != TOS_BCAST_ADDR &&
        fail_count < 5){
       call RouteSelect.selectRoute(msg, 1);
+      call PacketAcknowledgements.requestAck(msg);
       if (call SubSend.send(call AMPacket.destination(msg),
                            msg,
                            call SubPacket.payloadLength(msg)) == SUCCESS) {
+       dbg("LQI", "Packet not acked, retransmit @%s:\n\t%s\n", sim_time_string(), fields(msg));
+        call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_WAITACK, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
        fail_count ++;
+       return;
       } else {
+       call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+       dbg("LQI", "Packet not acked, retransmit fail @%s:\n\t%s\n", sim_time_string(), fields(msg));
        sendFailures++;
+       return;
       }
     }
+    else if (fail_count >= 5) {
+      call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL_ACK_FWD, 
+                                      call CollectionPacket.getSequenceNumber(msg), 
+                                      call CollectionPacket.getOrigin(msg), 
+                                      call AMPacket.destination(msg));
+      dbg("LQI", "Packet failed:\t%s\n", fields(msg));
+    }
+    else if (call PacketAcknowledgements.wasAcked(msg)) {
+      dbg("LQI", "Packet acked:\t%s\n", fields(msg));
+      call CollectionDebug.logEventMsg(NET_C_FE_FWD_MSG, 
+                                      call CollectionPacket.getSequenceNumber(msg), 
+                                      call CollectionPacket.getOrigin(msg), 
+                                      call AMPacket.destination(msg));
+    }
     
     fail_count = 0;
-
     buf = is_ours(msg);
-
-    if (buf != -1) { // Msg was from forwarding queue
+    if (buf != -1) {
       FwdBufBusy[(uint8_t)buf] = 0;
-    } else {
-      signal Send.sendDone(msg, success);
-    } 
+    }
+    
+    nextToSend = nextMsg();
+    fwdbusy = FALSE;
+         
+    if (nextToSend != NULL) {
+      forward(nextToSend);
+    }
+    
+    dbg("LQI", "Packet not longer busy:\t%s\n", fields(msg));
+  }
+
+  event void SubSendMine.sendDone(message_t* msg, error_t success) {
+    if (!call PacketAcknowledgements.wasAcked(msg) &&
+       call AMPacket.destination(msg) != TOS_BCAST_ADDR &&
+       fail_count < 5){
+      call RouteSelect.selectRoute(msg, 1);
+      call PacketAcknowledgements.requestAck(msg);
+      if (call SubSendMine.send(call AMPacket.destination(msg),
+                           msg,
+                           call SubPacket.payloadLength(msg)) == SUCCESS) {
+       dbg("LQI", "Packet not acked, retransmit (%hhu) @%s:\n\t%s\n", fail_count, sim_time_string(), fields(msg));
+       call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_WAITACK, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+       fail_count ++;
+       return;
+      } else {
+       call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+       dbg("LQI", "Packet not acked, retransmit fail @%s:\n\t%s\n", sim_time_string(), fields(msg));
+       sendFailures++;
+       return;
+      }
+    }
+    else if (fail_count >= 5) {
+      call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL_ACK_SEND, 
+                                      call CollectionPacket.getSequenceNumber(msg), 
+                                      call CollectionPacket.getOrigin(msg), 
+                                      call AMPacket.destination(msg));
+      dbg("LQI", "Packet failed:\t%s\n", fields(msg));
+    }
+    else if (call PacketAcknowledgements.wasAcked(msg)) {
+      dbg("LQI", "Packet acked:\t%s\n", fields(msg));
+      call CollectionDebug.logEventMsg(NET_C_FE_SENT_MSG, 
+                                      call CollectionPacket.getSequenceNumber(msg), 
+                                      call CollectionPacket.getOrigin(msg), 
+                                      call AMPacket.destination(msg));
+    }
+
+    fail_count = 0;
+    signal Send.sendDone(msg, success);
   }
 
 
@@ -350,7 +475,9 @@ implementation {
   }
   command void* Packet.getPayload(message_t* msg, uint8_t* len) {
     void* rval = call SubPacket.getPayload(msg, len);
-    *len -= sizeof(lqi_header_t);
+    if (len != NULL) {
+      *len -= sizeof(lqi_header_t);
+    }
     rval += sizeof(lqi_header_t);
     return rval;
   }
@@ -382,6 +509,8 @@ implementation {
     lqi_header_t* hdr = getHeader(msg);
     hdr->originseqno = seqno;
   }
+
+
   
  default event void Send.sendDone(message_t* pMsg, error_t success) {}
  default event message_t* Snoop.receive[collection_id_t id](message_t* pMsg, void* payload, uint8_t len) {return pMsg;}