linkestimatorp.nc
来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 740 行 · 第 1/2 页
NC
740 行
command error_t StdControl.stop() { call Timer.stop(); return SUCCESS; } // initialize the link estimator command error_t Init.init() { dbg("LI", "Link estimator init\n"); initNeighborTable(); return SUCCESS; } // originate the beacon by the link estimator // this happens only if the user of this // component did not send an outgoing message // fast enough (at least once every BEACON_INTERVAL) task void sendLinkEstBeacon() { uint8_t newlen; linkest_header_t *hdr; if (!beaconBusy) { newlen = addLinkEstHeaderAndFooter(&linkEstPkt, 0); hdr = getHeader(&linkEstPkt); dbg("LI", "Sending seq because noone sent: %d\n", linkEstSeq); print_packet(&linkEstPkt, newlen); if (call AMSendLinkEst.send(AM_BROADCAST_ADDR, &linkEstPkt, newlen) == SUCCESS) { beaconBusy = TRUE; } } } // link estimation timer, update the estimate or // send beacon if it is time event void Timer.fired() { dbg("LI,LITest", "Linkestimator timer fired\n"); curEstInterval = (curEstInterval + 1) % TABLEUPDATE_INTERVAL; if (curEstInterval == 0) { dbg("LI", "updating neighbor table\n"); print_neighbor_table(); updateNeighborTableEst(); print_neighbor_table(); } curBeaconInterval = (curBeaconInterval + 1) % BEACON_INTERVAL; if (curBeaconInterval == (BEACON_INTERVAL - 1)) { dbg("LI", "Sending LinkEst beacon\n"); curBeaconInterval = 0; post sendLinkEstBeacon(); } } // EETX (Extra Expected number of Transmission) // EETX = ETX - 1 // computeEETX returns EETX*10 uint8_t computeEETX(uint8_t q1) { uint16_t q; if (q1 > 0) { q = 2550 / q1 - 10; if (q > 255) { q = INFINITY; } return (uint8_t)q; } else { return INFINITY; } } // BidirETX = 1 / (q1*q2) // BidirEETX = BidirETX - 1 // computeBidirEETX return BidirEETX*10 uint8_t computeBidirEETX(uint8_t q1, uint8_t q2) { uint16_t q; if ((q1 > 0) && (q2 > 0)) { q = 65025u / q1; q = (10*q) / q2 - 10; if (q > 255) { q = INFINITY; } return (uint8_t)q; } else { return INFINITY; } } // return bi-directional link quality to the neighbor command uint8_t LinkEstimator.getLinkQuality(am_addr_t neighbor) { uint8_t idx; idx = findIdx(neighbor); if (idx == INVALID_RVAL) { return INFINITY; } else { return computeBidirEETX(NeighborTable[idx].inquality, NeighborTable[idx].outquality); }; } // return the quality of the link: neighor->self command uint8_t LinkEstimator.getReverseQuality(am_addr_t neighbor) { uint8_t idx; idx = findIdx(neighbor); if (idx == INVALID_RVAL) { return INFINITY; } else { return computeEETX(NeighborTable[idx].inquality); }; } // return the quality of the link: self->neighbor command uint8_t LinkEstimator.getForwardQuality(am_addr_t neighbor) { uint8_t idx; idx = findIdx(neighbor); if (idx == INVALID_RVAL) { return INFINITY; } else { return computeEETX(NeighborTable[idx].outquality); }; } // insert the neighbor at any cost (if there is a room for it) // even if eviction of a perfectly fine neighbor is called for command error_t LinkEstimator.insertNeighbor(am_addr_t neighbor) { uint8_t nidx; nidx = findIdx(neighbor); if (nidx != INVALID_RVAL) { dbg("LI", "insert: Found the entry, no need to insert\n"); return SUCCESS; } nidx = findEmptyNeighborIdx(); if (nidx != INVALID_RVAL) { dbg("LI", "insert: inserted into the empty slot\n"); initNeighborIdx(nidx, neighbor); return SUCCESS; } else { nidx = findWorstNeighborIdx(MAX_QUALITY); if (nidx != INVALID_RVAL) { dbg("LI", "insert: inserted by replacing an entry for neighbor: %d\n", NeighborTable[nidx].ll_addr); signal LinkEstimator.evicted(NeighborTable[nidx].ll_addr); initNeighborIdx(nidx, neighbor); return SUCCESS; } } return FAIL; } // pin a neighbor so that it does not get evicted */ command error_t LinkEstimator.pinNeighbor(am_addr_t neighbor) { uint8_t nidx = findIdx(neighbor); if (nidx == INVALID_RVAL) { return FAIL; } NeighborTable[nidx].flags |= PINNED_ENTRY; return SUCCESS; } // pin a neighbor so that it does not get evicted command error_t LinkEstimator.unpinNeighbor(am_addr_t neighbor) { uint8_t nidx = findIdx(neighbor); if (nidx == INVALID_RVAL) { return FAIL; } NeighborTable[nidx].flags &= ~PINNED_ENTRY; return SUCCESS; } // get the link layer source address for the incoming packet command am_addr_t LinkSrcPacket.getSrc(message_t* msg) { linkest_header_t* hdr = getHeader(msg); return hdr->ll_addr; } // user of link estimator calls send here // slap the header and footer before sending the message command error_t Send.send(am_addr_t addr, message_t* msg, uint8_t len) { uint8_t newlen; curBeaconInterval = 0; newlen = addLinkEstHeaderAndFooter(msg, len); dbg("LITest", "%s packet of length %hhu became %hhu\n", __FUNCTION__, len, newlen); dbg("LI", "Sending seq: %d\n", linkEstSeq); print_packet(msg, newlen); return call AMSend.send(addr, msg, newlen); } // done sending the linkestimation beacone originated // by the estimator. event void AMSendLinkEst.sendDone(message_t *msg, error_t error) { beaconBusy = FALSE; } // done sending the message that originated by // the user of this component event void AMSend.sendDone(message_t* msg, error_t error ) { return signal Send.sendDone(msg, error); } // cascade the send call down if (call Packet.payloadLength command uint8_t Send.cancel(message_t* msg) { return call AMSend.cancel(msg); } command uint8_t Send.maxPayloadLength() { return call Packet.maxPayloadLength(); } command void* Send.getPayload(message_t* msg) { return call Packet.getPayload(msg, NULL); } // 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) { uint8_t nidx; uint8_t num_entries; dbg("LI", "LI receiving packet, buf addr: %x\n", payload); print_packet(msg, len); if (call SubAMPacket.destination(msg) == AM_BROADCAST_ADDR) { linkest_header_t* hdr = getHeader(msg); linkest_footer_t* footer; dbg("LI", "Got seq: %d from link: %d\n", hdr->seq, hdr->ll_addr); num_entries = hdr->flags & NUM_ENTRIES_FLAG; print_neighbor_table(); // update neighbor table with this information // find the neighbor // if found // update the entry // else // find an empty entry // if found // initialize the entry // else // find a bad neighbor to be evicted // if found // evict the neighbor and init the entry // else // we can not accomodate this neighbor in the table nidx = findIdx(hdr->ll_addr); if (nidx != INVALID_RVAL) { dbg("LI", "Found the entry so updating\n"); updateNeighborEntryIdx(nidx, hdr->seq); } else { nidx = findEmptyNeighborIdx(); if (nidx != INVALID_RVAL) { dbg("LI", "Found an empty entry\n"); initNeighborIdx(nidx, hdr->ll_addr); updateNeighborEntryIdx(nidx, hdr->seq); } else { nidx = findWorstNeighborIdx(EVICT_QUALITY_THRESHOLD); if (nidx != INVALID_RVAL) { dbg("LI", "Evicted neighbor %d at idx %d\n", NeighborTable[nidx].ll_addr, nidx); signal LinkEstimator.evicted(NeighborTable[nidx].ll_addr); initNeighborIdx(nidx, hdr->ll_addr); } else { dbg("LI", "No room in the table\n"); } } } if ((nidx != INVALID_RVAL) && (num_entries > 0)) { 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)); { uint8_t i, my_ll_addr; my_ll_addr = call SubAMPacket.address(); 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) { dbg("LI", "Found my reverse link to %d\n", hdr->ll_addr); updateReverseQuality(hdr->ll_addr, footer->neighborList[i].inquality); } } } } print_neighbor_table(); } } // new messages are received here // update the neighbor table with the header // and footer in the message // then signal the user of this component event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) { 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.payloadLength(msg)); } // handler for packets that were generated by the link estimator event message_t* ReceiveLinkEst.receive(message_t* msg, void* payload, uint8_t len) { dbg("LI", "Received self packet. Will not signal up\n"); processReceivedMessage(msg, payload, len); return 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); } // subtract the space occupied by the link estimation // header and footer from the incoming payload size command uint8_t Packet.payloadLength(message_t* msg) { linkest_header_t *hdr; hdr = getHeader(msg); return call SubPacket.payloadLength(msg) - sizeof(linkest_header_t) - sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags); } // account for the space used by header and footer // while setting the payload length command void Packet.setPayloadLength(message_t* msg, uint8_t len) { linkest_header_t *hdr; hdr = getHeader(msg); call SubPacket.setPayloadLength(msg, len + sizeof(linkest_header_t) + sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags)); } command uint8_t Packet.maxPayloadLength() { return call SubPacket.maxPayloadLength() - sizeof(linkest_header_t); } // 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); } return payload + sizeof(linkest_header_t); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?