]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/le/LinkEstimatorP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / lib / net / le / LinkEstimatorP.nc
index 43b75f7066947ed05dfeeee9d785b0704cdee317..5a0f1b62be1a8f338a2f6ea4af873d58d8f8c232 100644 (file)
@@ -39,6 +39,7 @@ module LinkEstimatorP {
     interface LinkEstimator;
     interface Init;
     interface Packet;
+    interface CompareBit;
   }
 
   uses {
@@ -46,6 +47,8 @@ module LinkEstimatorP {
     interface AMPacket as SubAMPacket;
     interface Packet as SubPacket;
     interface Receive as SubReceive;
+    interface LinkPacketMetadata;
+    interface Random;
   }
 }
 
@@ -64,10 +67,12 @@ implementation {
     BEST_EETX = 0,
     INVALID_RVAL = 0xff,
     INVALID_NEIGHBOR_ADDR = 0xff,
-    INFINITY = 0xff,
+    // if we don't know the link quality, we need to return a value so
+    // large that it will not be used to form paths
+    VERY_LARGE_EETX_VALUE = 0xff,
     // decay the link estimate using this alpha
     // we use a denominator of 10, so this corresponds to 0.2
-    ALPHA = 2,
+    ALPHA = 9,
     // number of packets to wait before computing a new
     // DLQ (Data-driven Link Quality)
     DLQ_PKT_WINDOW = 5,
@@ -95,15 +100,15 @@ implementation {
   }
 
   // get the link estimation footer (neighbor entries) in the packet
-  linkest_footer_t* getFooter(message_t* m, uint8_t len) {
+  linkest_footer_t* getFooter(message_t* ONE m, uint8_t len) {
     // To get a footer at offset "len", the payload must be len + sizeof large.
-    return (linkest_footer_t*)(len + (uint8_t *)call Packet.getPayload(m,len + sizeof(linkest_footer_t)));
+    return (linkest_footer_t* ONE)(len + (uint8_t *)call Packet.getPayload(m,len + sizeof(linkest_footer_t)));
   }
 
   // add the link estimation header (seq no) and link estimation
   // footer (neighbor entries) in the packet. Call just before sending
   // the packet.
-  uint8_t addLinkEstHeaderAndFooter(message_t *msg, uint8_t len) {
+  uint8_t addLinkEstHeaderAndFooter(message_t * ONE msg, uint8_t len) {
     uint8_t newlen;
     linkest_header_t *hdr;
     linkest_footer_t *footer;
@@ -126,13 +131,23 @@ implementation {
     j = 0;
     newPrevSentIdx = 0;
     for (i = 0; i < NEIGHBOR_TABLE_SIZE && j < maxEntries; i++) {
+      uint8_t neighborCount;
+      neighbor_stat_entry_t * COUNT(neighborCount) neighborLists;
+      if(maxEntries <= NEIGHBOR_TABLE_SIZE)
+        neighborCount = maxEntries;
+      else
+        neighborCount = NEIGHBOR_TABLE_SIZE;
+      
+      neighborLists = TCAST(neighbor_stat_entry_t * COUNT(neighborCount), footer->neighborList);
+
       k = (prevSentIdx + i + 1) % NEIGHBOR_TABLE_SIZE;
-      if (NeighborTable[k].flags & VALID_ENTRY) {
-       footer->neighborList[j].ll_addr = NeighborTable[k].ll_addr;
-       footer->neighborList[j].inquality = NeighborTable[k].inquality;
+      if ((NeighborTable[k].flags & VALID_ENTRY) &&
+         (NeighborTable[k].flags & MATURE_ENTRY)) {
+       neighborLists[j].ll_addr = NeighborTable[k].ll_addr;
+       neighborLists[j].inquality = NeighborTable[k].inquality;
        newPrevSentIdx = k;
-       dbg("LI", "Loaded on footer: %d %d %d\n", j, footer->neighborList[j].ll_addr,
-           footer->neighborList[j].inquality);
+       dbg("LI", "Loaded on footer: %d %d %d\n", j, neighborLists[j].ll_addr,
+           neighborLists[j].inquality);
        j++;
       }
     }
@@ -237,7 +252,7 @@ implementation {
   // called when new beacon estimate is done
   // also called when new DEETX estimate is done
   void updateEETX(neighbor_table_entry_t *ne, uint16_t newEst) {
-    ne->eetx = (ALPHA * ne->eetx + (10 - ALPHA) * newEst)/10;
+    ne->eetx = (ALPHA * ne->eetx + (10 - ALPHA) * newEst + 5)/10;
   }
 
 
@@ -267,11 +282,11 @@ implementation {
     if (q1 > 0) {
       q =  2550 / q1 - 10;
       if (q > 255) {
-       q = INFINITY;
+       q = VERY_LARGE_EETX_VALUE;
       }
       return (uint8_t)q;
     } else {
-      return INFINITY;
+      return VERY_LARGE_EETX_VALUE;
     }
   }
 
@@ -326,8 +341,8 @@ implementation {
              ne->inquality = (ALPHA * ne->inquality) / 10;
            } else {
              newEst = (255 * ne->rcvcnt) / totalPkt;
-             dbg("LI,LITest", "  %hu: %hhu -> %hhu", ne->ll_addr, ne->inquality, (ALPHA * ne->inquality + (10-ALPHA) * newEst)/10);
-             ne->inquality = (ALPHA * ne->inquality + (10-ALPHA) * newEst)/10;
+             dbg("LI,LITest", "  %hu: %hhu -> %hhu", ne->ll_addr, ne->inquality, (ALPHA * ne->inquality + (10-ALPHA) * newEst + 5)/10);
+             ne->inquality = (ALPHA * ne->inquality + (10-ALPHA) * newEst + 5)/10;
            }
            ne->rcvcnt = 0;
            ne->failcnt = 0;
@@ -430,36 +445,48 @@ implementation {
   }
 
   // return bi-directional link quality to the neighbor
-  command uint8_t LinkEstimator.getLinkQuality(am_addr_t neighbor) {
+  command uint16_t LinkEstimator.getLinkQuality(am_addr_t neighbor) {
     uint8_t idx;
     idx = findIdx(neighbor);
     if (idx == INVALID_RVAL) {
-      return INFINITY;
+      return VERY_LARGE_EETX_VALUE;
     } else {
-      return NeighborTable[idx].eetx;
-    };
+      if (NeighborTable[idx].flags & MATURE_ENTRY) {
+       return NeighborTable[idx].eetx;
+      } else {
+       return VERY_LARGE_EETX_VALUE;
+      }
+    }
   }
 
   // return the quality of the link: neighor->self
-  command uint8_t LinkEstimator.getReverseQuality(am_addr_t neighbor) {
+  command uint16_t LinkEstimator.getReverseQuality(am_addr_t neighbor) {
     uint8_t idx;
     idx = findIdx(neighbor);
     if (idx == INVALID_RVAL) {
-      return INFINITY;
+      return VERY_LARGE_EETX_VALUE;
     } else {
-      return computeEETX(NeighborTable[idx].inquality);
-    };
+      if (NeighborTable[idx].flags & MATURE_ENTRY) {
+       return computeEETX(NeighborTable[idx].inquality);
+      } else {
+       return VERY_LARGE_EETX_VALUE;
+      }
+    }
   }
 
   // return the quality of the link: self->neighbor
-  command uint8_t LinkEstimator.getForwardQuality(am_addr_t neighbor) {
+  command uint16_t LinkEstimator.getForwardQuality(am_addr_t neighbor) {
     uint8_t idx;
     idx = findIdx(neighbor);
     if (idx == INVALID_RVAL) {
-      return INFINITY;
+      return VERY_LARGE_EETX_VALUE;
     } else {
-      return computeEETX(NeighborTable[idx].outquality);
-    };
+      if (NeighborTable[idx].flags & MATURE_ENTRY) {
+       return computeEETX(NeighborTable[idx].outquality);
+      } else {
+       return VERY_LARGE_EETX_VALUE;
+      }
+    }
   }
 
   // insert the neighbor at any cost (if there is a room for it)
@@ -593,7 +620,7 @@ implementation {
   // called when link estimator generator packet or
   // packets from upper layer that are wired to pass through
   // link estimator is received
-  void processReceivedMessage(message_t* msg, void* payload, uint8_t len) {
+  void processReceivedMessage(message_t* ONE msg, void* COUNT_NOK(len) payload, uint8_t len) {
     uint8_t nidx;
     uint8_t num_entries;
 
@@ -602,7 +629,7 @@ implementation {
 
     if (call SubAMPacket.destination(msg) == AM_BROADCAST_ADDR) {
       linkest_header_t* hdr = getHeader(msg);
-      linkest_footer_t* footer;
+      linkest_footer_t* ONE footer;
       am_addr_t ll_addr;
 
       ll_addr = call SubAMPacket.source(msg);
@@ -649,22 +676,38 @@ implementation {
        }
       }
 
+
+      /* Graphical explanation of how we get to the head of the
+       * footer in the following code 
+       * <---------------------- payloadLen ------------------->
+       * -------------------------------------------------------
+       * linkest_header_t  | payload  | linkest_footer_t* ...|
+       * -------------------------------------------------------
+       * ^                              ^                      ^
+       * |                              |                      |
+       * subpayload                     |                      payloadEnd
+       *                                |
+       *                                payloadEnd - footersize*num footers
+      */
+
       if ((nidx != INVALID_RVAL) && (num_entries > 0)) {
        uint8_t payloadLen = call SubPacket.payloadLength(msg);
-       void* subPayload = call SubPacket.getPayload(msg, payloadLen);
+       void* COUNT_NOK(payloadLen) subPayload = call SubPacket.getPayload(msg, payloadLen);
        void* payloadEnd = subPayload + payloadLen;
        dbg("LI", "Number of footer entries: %d\n", num_entries);
        
-       footer = (linkest_footer_t*) (payloadEnd - (num_entries*sizeof(linkest_footer_t)));
+       footer = TCAST(linkest_footer_t* COUNT(num_entries), (payloadEnd - (num_entries*sizeof(linkest_footer_t))));
        {
          uint8_t i;
          am_addr_t my_ll_addr;
+          neighbor_stat_entry_t * COUNT(num_entries) neighborLists;
          my_ll_addr = call SubAMPacket.address();
+          neighborLists = TCAST(neighbor_stat_entry_t * COUNT(num_entries), footer->neighborList);
          for (i = 0; i < num_entries; i++) {
-           dbg("LI", "%d %d %d\n", i, footer->neighborList[i].ll_addr,
-               footer->neighborList[i].inquality);
-           if (footer->neighborList[i].ll_addr == my_ll_addr) {
-             updateReverseQuality(ll_addr, footer->neighborList[i].inquality);
+           dbg("LI", "%d %d %d\n", i, neighborLists[i].ll_addr,
+               neighborLists[i].inquality);
+           if (neighborLists[i].ll_addr == my_ll_addr) {
+             updateReverseQuality(ll_addr, neighborLists[i].inquality);
            }
          }
        }
@@ -720,9 +763,7 @@ implementation {
 
   // application payload pointer is just past the link estimation header
   command void* Packet.getPayload(message_t* msg, uint8_t len) {
-    linkest_header_t *hdr = getHeader(msg);
-    uint8_t footerLen = (hdr->flags & NUM_ENTRIES_FLAG) * sizeof(linkest_header_t);
-    void* payload = call SubPacket.getPayload(msg, len + footerLen);
+    void* payload = call SubPacket.getPayload(msg, len +  sizeof(linkest_header_t));
     if (payload != NULL) {
       payload += sizeof(linkest_header_t);
     }