X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Flib%2Fnet%2Fle%2FLinkEstimatorP.nc;h=c83727bf1ba5f88392708f3c0be2db4e4adbd3b9;hb=adf1de6c009d13b7b52e68535c63b28f59c97400;hp=58ab66c64321993afcc308dfb7ce9388be77fb97;hpb=8fd9a98abba7601189a8ce8871b9f6a8981ea7ef;p=tinyos-2.x.git diff --git a/tos/lib/net/le/LinkEstimatorP.nc b/tos/lib/net/le/LinkEstimatorP.nc index 58ab66c6..c83727bf 100644 --- a/tos/lib/net/le/LinkEstimatorP.nc +++ b/tos/lib/net/le/LinkEstimatorP.nc @@ -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, @@ -91,18 +96,19 @@ implementation { // get the link estimation header in the packet linkest_header_t* getHeader(message_t* m) { - return (linkest_header_t*)call SubPacket.getPayload(m, NULL); + return (linkest_header_t*)call SubPacket.getPayload(m, sizeof(linkest_header_t)); } // get the link estimation footer (neighbor entries) in the packet - linkest_footer_t* getFooter(message_t* m, uint8_t len) { - return (linkest_footer_t*)(len + (uint8_t *)call Packet.getPayload(m,NULL)); + 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* 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; @@ -125,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++; } } @@ -246,14 +262,15 @@ implementation { if (ne->data_success == 0) { // if there were no successful packet transmission in the - // last window, assign a large EETX estimate - estETX = LARGE_EETX_VALUE; + // last window, our current estimate is the number of failed + // transmissions + estETX = (ne->data_total - 1)* 10; } else { estETX = (10 * ne->data_total) / ne->data_success - 10; + ne->data_success = 0; + ne->data_total = 0; } updateEETX(ne, estETX); - ne->data_success = 0; - ne->data_total = 0; } @@ -265,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; } } @@ -428,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) @@ -584,14 +613,14 @@ implementation { return call Packet.maxPayloadLength(); } - command void* Send.getPayload(message_t* msg) { - return call Packet.getPayload(msg, NULL); + command void* Send.getPayload(message_t* msg, uint8_t len) { + return call Packet.getPayload(msg, len); } // 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; @@ -600,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); @@ -647,19 +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* 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*) ((uint8_t *)call SubPacket.getPayload(msg, NULL) - + call SubPacket.payloadLength(msg) - - num_entries*sizeof(linkest_footer_t)); + + footer = TCAST(linkest_footer_t* COUNT(num_entries), (payloadEnd - (num_entries*sizeof(linkest_footer_t)))); { - uint8_t i, my_ll_addr; + 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); } } } @@ -680,18 +728,10 @@ implementation { dbg("LI", "Received upper packet. Will signal up\n"); processReceivedMessage(msg, payload, len); return signal Receive.receive(msg, - call Packet.getPayload(msg, NULL), + call Packet.getPayload(msg, call Packet.payloadLength(msg)), call Packet.payloadLength(msg)); } - command void* Receive.getPayload(message_t* msg, uint8_t* len) { - return call Packet.getPayload(msg, len); - } - - command uint8_t Receive.payloadLength(message_t* msg) { - return call Packet.payloadLength(msg); - } - command void Packet.clear(message_t* msg) { call SubPacket.clear(msg); } @@ -722,14 +762,12 @@ implementation { } // application payload pointer is just past the link estimation header - command void* Packet.getPayload(message_t* msg, uint8_t* len) { - uint8_t* payload = call SubPacket.getPayload(msg, len); - linkest_header_t *hdr; - hdr = getHeader(msg); - if (len != NULL) { - *len = *len - sizeof(linkest_header_t) - sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags); + command void* Packet.getPayload(message_t* msg, uint8_t len) { + void* payload = call SubPacket.getPayload(msg, len + sizeof(linkest_header_t)); + if (payload != NULL) { + payload += sizeof(linkest_header_t); } - return payload + sizeof(linkest_header_t); + return payload; } }