]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/ctp/CtpRoutingEngineP.nc
The big interface switchover for Packet, Send, Receive, and AMSend.
[tinyos-2.x.git] / tos / lib / net / ctp / CtpRoutingEngineP.nc
index 0044233b4d9008d97d5d6f0760a9d5fd2cf5fc28..7c8810302b35322bda842609ddf59ae6532f7414 100644 (file)
@@ -107,7 +107,6 @@ generic module CtpRoutingEngineP(uint8_t routingTableSize, uint16_t minInterval,
         interface Receive as BeaconReceive;
         interface LinkEstimator;
         interface AMPacket;
-        interface LinkSrcPacket;
         interface SplitControl as RadioControl;
         interface Timer<TMilli> as BeaconTimer;
         interface Timer<TMilli> as RouteTimer;
@@ -200,7 +199,7 @@ implementation {
 
     command error_t Init.init() {
         uint8_t maxLength;
-       routeUpdateTimerCount = 0;
+        routeUpdateTimerCount = 0;
         radioOn = FALSE;
         running = FALSE;
         parentChanges = 0;
@@ -208,7 +207,7 @@ implementation {
         routeInfoInit(&routeInfo);
         routingTableInit();
         my_ll_addr = call AMPacket.address();
-        beaconMsg = call BeaconSend.getPayload(&beaconMsgBuffer);
+        beaconMsg = call BeaconSend.getPayload(&beaconMsgBuffer, call BeaconSend.maxPayloadLength());
         maxLength = call BeaconSend.maxPayloadLength();
         dbg("TreeRoutingCtl","TreeRouting initialized. (used payload:%d max payload:%d!\n", 
               sizeof(beaconMsg), maxLength);
@@ -265,7 +264,6 @@ implementation {
     /* updates the routing information, using the info that has been received
      * from neighbor beacons. Two things can cause this info to change: 
      * neighbor beacons, changes in link estimates, including neighbor eviction */
-    /* TODO: take into account congested state to select parents */ 
     task void updateRouteTask() {
         uint8_t i;
         routing_table_entry* entry;
@@ -313,6 +311,9 @@ implementation {
                 }
                 continue;
             }
+            /* Ignore links that are congested */
+            if (entry->info.congested)
+                continue;
             /* Ignore links that are bad */
             if (!passLinkEtxThreshold(linkEtx)) {
               dbg("TreeRouting", "   did not pass threshold.\n");
@@ -328,8 +329,19 @@ implementation {
         //call CollectionDebug.logEventDbg(NET_C_DBG_3, routeInfo.parent, currentEtx, minEtx);  
 
         /* Now choose between the current parent and the best neighbor */
+        /* Requires that: 
+            1. at least another neighbor was found with ok quality and not congested
+            2. the current parent is congested and the other best route is at least as good
+            3. or the current parent is not congested and the neighbor quality is better by 
+               the PARENT_SWITCH_THRESHOLD.
+          Note: if our parent is congested, in order to avoid forming loops, we try to select
+                a node which is not a descendent of our parent. routeInfo.ext is our parent's
+                etx. Any descendent will be at least that + 10 (1 hop), so we restrict the 
+                selection to be less than that.
+        */
         if (minEtx != MAX_METRIC) {
             if (currentEtx == MAX_METRIC ||
+                (routeInfo.congested && (minEtx < (routeInfo.etx + 10))) ||
                 minEtx + PARENT_SWITCH_THRESHOLD < currentEtx) {
                 // routeInfo.metric will not store the composed metric.
                 // since the linkMetric may change, we will compose whenever
@@ -442,7 +454,7 @@ implementation {
 
 
     ctp_routing_header_t* getHeader(message_t* m) {
-      return (ctp_routing_header_t*)call BeaconReceive.getPayload(m, NULL);
+      return (ctp_routing_header_t*)call BeaconSend.getPayload(m, call BeaconSend.maxPayloadLength());
     }
     
     
@@ -464,8 +476,9 @@ implementation {
         }
         
         //need to get the am_addr_t of the source
-        from = call LinkSrcPacket.getSrc(msg);
+        from = call AMPacket.source(msg);
         rcvBeacon = (ctp_routing_header_t*)payload;
+
         congested = call CtpRoutingPacket.getOption(msg, CTP_OPT_ECN);
 
         dbg("TreeRouting","%s from: %d  [ parent: %d etx: %d]\n",
@@ -542,39 +555,37 @@ implementation {
 
     command void CtpInfo.triggerRouteUpdate() {
       // Random time in interval 64-127ms
-      uint16_t time = call Random.rand16();
-      time &= 0x3f; 
-      time += 64;
+      uint16_t beaconDelay = call Random.rand16();
+      beaconDelay &= 0x3f; 
+      beaconDelay += 64;
       if (call BeaconTimer.gett0() + call BeaconTimer.getdt() -
-                                     call BeaconTimer.getNow() >= time) {
+                                     call BeaconTimer.getNow() >= beaconDelay) {
          call BeaconTimer.stop();
-         call BeaconTimer.startOneShot(time);
+         call BeaconTimer.startOneShot(beaconDelay);
         }
      }
 
     command void CtpInfo.triggerImmediateRouteUpdate() {
       // Random time in interval 4-11ms
-      uint16_t time = call Random.rand16();
-      time &= 0x7; 
-      time += 4;
+      uint16_t beaconDelay = call Random.rand16();
+      beaconDelay &= 0x7; 
+      beaconDelay += 4;
       call BeaconTimer.stop();
-      call BeaconTimer.startOneShot(time);
+      call BeaconTimer.startOneShot(beaconDelay);
     }
 
     command void CtpInfo.setNeighborCongested(am_addr_t n, bool congested) {
         uint8_t idx;    
+        if (ECNOff)
+            return;
         idx = routingTableFind(n);
         if (idx < routingTableActive) {
             routingTable[idx].info.congested = congested;
         }
-        /* TODO:  (this only makes sense if routeUpdateTask takes congestion into
-         *         account for selecting routes.)
-         *   if (routeInfo.congested && !congested) 
-         *       post routeUpdateTask() 
-         *   else if (routeInfo.parent == n && congested) {
-         *       post routeUpdateTask()
-         *
-         */
+        if (routeInfo.congested && !congested) 
+            post updateRouteTask();
+        else if (routeInfo.parent == n && congested) 
+            post updateRouteTask();
     }
 
     command bool CtpInfo.isNeighborCongested(am_addr_t n) {
@@ -679,7 +690,8 @@ implementation {
                     routingTable[idx].neighbor = from;
                     routingTable[idx].info.parent = parent;
                     routingTable[idx].info.etx = etx;
-                   routingTable[idx].info.haveHeard = 1;
+                    routingTable[idx].info.haveHeard = 1;
+                    routingTable[idx].info.congested = FALSE;
                     routingTableActive++;
                 }
                 dbg("TreeRouting", "%s OK, new entry\n", __FUNCTION__);
@@ -692,7 +704,7 @@ implementation {
                 routingTable[idx].neighbor = from;
                 routingTable[idx].info.parent = parent;
                 routingTable[idx].info.etx = etx;
-               routingTable[idx].info.haveHeard = 1;
+                       routingTable[idx].info.haveHeard = 1;
             }
             dbg("TreeRouting", "%s OK, updated entry\n", __FUNCTION__);
         }