treeroutingenginep.nc
来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 524 行 · 第 1/2 页
NC
524 行
dbg("TreeRouting", "%s parent: %d hopcount: %d metric: %d\n", __FUNCTION__, beaconMsg->parent, beaconMsg->hopcount, beaconMsg->metric); call CollectionDebug.logEventRoute(NET_C_TREE_SENT_BEACON, beaconMsg->parent, beaconMsg->hopcount, beaconMsg->metric); eval = call BeaconSend.send(AM_BROADCAST_ADDR, &beaconMsgBuffer, sizeof(beacon_msg_t)); if (eval == SUCCESS) { sending = TRUE; } else if (eval == EOFF) { radioOn = FALSE; dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn); } } event void BeaconSend.sendDone(message_t* msg, error_t error) { if ((msg != &beaconMsgBuffer) || !sending) { //something smells bad around here return; } sending = FALSE; } event void BeaconTimer.fired() { if (radioOn && running) { // determine next interval uint16_t nextInt; nextInt = call Random.rand16() % BEACON_INTERVAL; nextInt += BEACON_INTERVAL >> 1; call BeaconTimer.startOneShot(nextInt); post updateRouteTask(); post sendBeaconTask(); } } event message_t* BeaconReceive.receive(message_t* msg, void* payload, uint8_t len) { am_addr_t from; beacon_msg_t* rcvBeacon; // Received a beacon, but it's not from us. if (len != sizeof(beacon_msg_t)) { dbg("LITest", "%s, received beacon of size %hhu, expected %i\n", __FUNCTION__, len, (int)sizeof(beacon_msg_t)); return msg; } //need to get the am_addr_t of the source from = call LinkSrcPacket.getSrc(msg); rcvBeacon = (beacon_msg_t*)payload; dbg("TreeRouting","%s from: %d [ parent: %d hopcount: %d metric: %d]\n", __FUNCTION__, from, rcvBeacon->parent, rcvBeacon->hopcount, rcvBeacon->metric); //call CollectionDebug.logEventRoute(NET_C_TREE_RCV_BEACON, rcvBeacon->parent, rcvBeacon->hopcount, rcvBeacon->metric); //update neighbor table if (rcvBeacon->parent != INVALID_ADDR) { //TODO: also, if better than my current parent's path metric, insert if (rcvBeacon->hopcount == 0) { dbg("TreeRouting","from a root, inserting if not in table\n"); call LinkEstimator.insertNeighbor(from); call LinkEstimator.pinNeighbor(from); } routingTableUpdateEntry(from, rcvBeacon->parent, rcvBeacon->hopcount, rcvBeacon->metric); } //post updateRouteTask(); return msg; } /* signals that a neighbor is no longer reachable. need special care if * that neighbor is our parent */ event void LinkEstimator.evicted(am_addr_t neighbor) { routingTableEvict(neighbor); dbg("TreeRouting","%s\n",__FUNCTION__); if (routeInfo.parent == neighbor) { routeInfoInit(&routeInfo); justEvicted = TRUE; post updateRouteTask(); } } /* Interface UnicastNameFreeRouting */ /* Simplest implementation: return the current routeInfo */ command am_addr_t Routing.nextHop() { return routeInfo.parent; } command bool Routing.hasRoute() { return (routeInfo.parent != INVALID_ADDR); } /* TreeRoutingInspect interface */ command error_t TreeRoutingInspect.getParent(am_addr_t* parent) { if (parent == NULL) return FAIL; if (routeInfo.parent == INVALID_ADDR) return FAIL; *parent = routeInfo.parent; return SUCCESS; } command error_t TreeRoutingInspect.getHopcount(uint8_t* hopcount) { if (hopcount == NULL) return FAIL; if (routeInfo.parent == INVALID_ADDR) return FAIL; *hopcount= routeInfo.hopcount; return SUCCESS; } command error_t TreeRoutingInspect.getMetric(uint16_t* metric) { if (metric == NULL) return FAIL; if (routeInfo.parent == INVALID_ADDR) return FAIL; *metric = routeInfo.metric; return SUCCESS; } command void TreeRoutingInspect.triggerRouteUpdate() { // Random time in interval 64-127ms uint16_t time = call Random.rand16(); time &= 0x3f; time += 64; if (call BeaconTimer.gett0() + call BeaconTimer.getdt() - call BeaconTimer.getNow() >= time) { call BeaconTimer.stop(); call BeaconTimer.startOneShot(time); } } /* RootControl interface */ /** sets the current node as a root, if not already a root */ /* returns FAIL if it's not possible for some reason */ command error_t RootControl.setRoot() { bool route_found = FALSE; route_found = (routeInfo.parent == INVALID_ADDR); atomic { state_is_root = 1; routeInfo.parent = my_ll_addr; //myself routeInfo.hopcount = 0; routeInfo.metric = 0; } if (route_found) signal Routing.routeFound(); dbg("TreeRouting","%s I'm a root now!\n",__FUNCTION__); call CollectionDebug.logEventRoute(NET_C_TREE_NEW_PARENT, routeInfo.parent, routeInfo.hopcount, routeInfo.metric); return SUCCESS; } command error_t RootControl.unsetRoot() { atomic { state_is_root = 0; routeInfoInit(&routeInfo); } dbg("TreeRouting","%s I'm not a root now!\n",__FUNCTION__); post updateRouteTask(); return SUCCESS; } command bool RootControl.isRoot() { return state_is_root; } default event void Routing.noRoute() { } default event void Routing.routeFound() { } /************************************************************/ /* Routing Table Functions */ /* The routing table keeps info about neighbor's route_info, * and is used when choosing a parent. * The table is simple: * - not fragmented (all entries in 0..routingTableActive) * - not ordered * - no replacement: eviction follows the LinkEstimator table */ void routingTableInit() { routingTableActive = 0; } /* Returns the index of parent in the table or * routingTableActive if not found */ uint8_t routingTableFind(am_addr_t neighbor) { uint8_t i; if (neighbor == INVALID_ADDR) return routingTableActive; for (i = 0; i < routingTableActive; i++) { if (routingTable[i].neighbor == neighbor) break; } return i; } error_t routingTableUpdateEntry(am_addr_t from, am_addr_t parent, uint8_t hopcount, uint16_t metric) { uint8_t idx; uint16_t linkMetric; linkMetric = evaluateMetric(call LinkEstimator.getLinkQuality(from)); idx = routingTableFind(from); if (idx == routingTableSize) { //not found and table is full //if (passLinkMetricThreshold(linkMetric)) //TODO: add replacement here, replace the worst //} dbg("TreeRouting", "%s FAIL, table full\n", __FUNCTION__); return FAIL; } else if (idx == routingTableActive) { //not found and there is space if (passLinkMetricThreshold(linkMetric)) { atomic { routingTable[idx].neighbor = from; routingTable[idx].info.parent = parent; routingTable[idx].info.hopcount = hopcount; routingTable[idx].info.metric = metric; routingTableActive++; } dbg("TreeRouting", "%s OK, new entry\n", __FUNCTION__); } else { dbg("TreeRouting", "%s Fail, link quality (%hu) below threshold\n", __FUNCTION__, linkMetric); } } else { //found, just update atomic { routingTable[idx].neighbor = from; routingTable[idx].info.parent = parent; routingTable[idx].info.hopcount = hopcount; routingTable[idx].info.metric = metric; } dbg("TreeRouting", "%s OK, updated entry\n", __FUNCTION__); } return SUCCESS; } /* if this gets expensive, introduce indirection through an array of pointers */ error_t routingTableEvict(am_addr_t neighbor) { uint8_t idx,i; idx = routingTableFind(neighbor); if (idx == routingTableActive) return FAIL; routingTableActive--; for (i = idx; i < routingTableActive; i++) { routingTable[i] = routingTable[i+1]; } return SUCCESS; } /*********** end routing table functions ***************/}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?