📄 drainlinkestm.nc
字号:
} else { // If it's a refinement of my current tree instance, only // retransmit if it has a newer sequence number // If it wants me to bump my sequence number, do it. if (pRP->beaconSeqno == 0) { // increment the sequence number route->announceSeqno++; if (route->announceSeqno == 0) route->announceSeqno++; retransmit = TRUE; } else if ((int8_t)(pRP->beaconSeqno - route->announceSeqno) > 0) { // if it's newer, take the sequence number route->announceSeqno = pRP->beaconSeqno; retransmit = TRUE; } } /*** Routing stuff ***/ curCost = (uint32_t) route->nextHopCost + (uint32_t) route->nextHopLinkEst; newCost = (uint32_t) pRP->cost + (uint32_t) linkEst; /* When to update my route: * - If it's a new tree. * - If it's from my parent. * - If it's from a lower-cost node that's not my child. */ if (pRP->treeInstance != route->treeInstance || pRP->linkSource == route->nextHop || ( pRP->parent != TOS_LOCAL_ADDRESS && newCost < curCost )) { if (pRP->treeInstance != route->treeInstance) { route->parentSwitches = 0; } else { if (route->nextHop != pRP->linkSource) { route->parentSwitches++; } } dbg(DBG_ROUTE, "DrainLinkEstM: route update(dest=%d, treeInstance=%d, oldNextHop=%d, nextHop=%d, oldCost=%d, newCost=%d, distance=%d)\n", pRP->source, pRP->treeInstance, route->nextHop, pRP->linkSource, curCost, newCost, DRAIN_MAX_TTL - pRP->ttl); if (route->nextHop != pRP->linkSource) { route->sentPackets = 0; route->successPackets = 0; } route->dest = pRP->source; route->destDistance = DRAIN_MAX_TTL - pRP->ttl; route->nextHop = pRP->linkSource; route->nextHopCost = pRP->cost; route->nextHopLinkEst = linkEst; route->treeInstance = pRP->treeInstance; } if (retransmit) { dbg(DBG_ROUTE, "DrainLinkEstM: Preparing to retransmit beacon:dest=%d,instance=%d,seqno=%d\n", route->dest, route->treeInstance, route->announceSeqno); route->announceDelay = pRP->beaconDelay; route->announceOffset = (call Random.rand() % (1024 * route->announceDelay)) + 1; route->sendWaiting = TRUE; route->announceCountdown = pRP->beaconOffset + route->announceOffset; startTimer(); } return Msg; } uint16_t adjustLQI(uint8_t val) { uint16_t result = (80 - (val - 50)); result = (((result * result) >> 3) * result) >> 3; /* experimenting with alternate scalings for LQI */// uint16_t result = 110 - val;// result = result * result; return result; } void startTimer() { DrainRouteEntry* route; uint16_t minCountdown = 0xFFFF; uint8_t i; if (timerRunning) { dbg(DBG_ROUTE, "startTimer() - timer running. Returning.\n"); return; } for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; dbg(DBG_ROUTE, "route[%d] 0x%x - dest=%d, sendWaiting=%d\n", i, route, route->dest, route->sendWaiting); if (route->dest != DRAIN_INVALID_DEST && route->sendWaiting == TRUE) { dbg(DBG_ROUTE, "route[%d] fires in %d ms\n", i, route->announceCountdown); if (route->announceCountdown < minCountdown) { minCountdown = route->announceCountdown; } } } if (minCountdown < 0xFFFF) { timerRunning = TRUE; for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest != DRAIN_INVALID_DEST && route->sendWaiting == TRUE) { route->announceCountdown -= minCountdown; } } if (minCountdown == 0) { minCountdown = 5; } call Timer.start(TIMER_ONE_SHOT, minCountdown); } } event result_t Timer.fired() { DrainRouteEntry *route; timerRunning = FALSE; route = getReadyRoute(); if (route != NULL) { sendRoute(route); } startTimer(); return SUCCESS; } DrainRouteEntry* getReadyRoute() { DrainRouteEntry* route; uint8_t i; for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest != DRAIN_INVALID_DEST && route->sendWaiting == TRUE && route->announceCountdown == 0) { return route; } } return NULL; } void sendRoute(DrainRouteEntry* route) { TOS_MsgPtr pMsgBuf = &msgBuf; DrainBeaconMsg *pRP = (DrainBeaconMsg *)&pMsgBuf->data[0];#ifdef DRAIN_ENDPOINT_ONLY return;#endif dbg(DBG_ROUTE, "DrainLinkEstM: sending route update\n"); if (route->dest == DRAIN_INVALID_DEST || route->destDistance == DRAIN_MAX_TTL) { dbg(DBG_ROUTE, "DrainLinkEstM: couldn't send route (dest=%d, destDistance=%d)\n", route->dest, route->destDistance); route->sendWaiting = FALSE; return; } if (msgBufBusy) { return; } atomic msgBufBusy = TRUE; pRP->linkSource = TOS_LOCAL_ADDRESS; pRP->source = route->dest; pRP->parent = route->nextHop; pRP->cost = route->nextHopCost + route->nextHopLinkEst; pRP->ttl = DRAIN_MAX_TTL - route->destDistance - 1; pRP->treeInstance = route->treeInstance; pRP->beaconSeqno = route->announceSeqno; pRP->beaconDelay = route->announceDelay; pRP->beaconOffset = (route->announceDelay * 1024) - route->announceOffset; pRP->defaultRoute = route->defaultRoute; if (call SendMsg.send(TOS_BCAST_ADDR, sizeof(DrainBeaconMsg), pMsgBuf)) { dbg(DBG_ROUTE,"DrainLinkEstM: send DrainBeaconMsg(linkSource=%d,source=%d,parent=%d,cost=%d,ttl=%d,seqno=%d,delay=%d,instance=%d)\n", pRP->linkSource, pRP->source, pRP->parent, pRP->cost, pRP->ttl, pRP->beaconSeqno, pRP->beaconDelay, pRP->treeInstance); route->sendWaiting = FALSE; } else { dbg(DBG_ROUTE, "send DrainBeaconMsg FAILED\n"); // how to handle the retries if the radio is busy? atomic msgBufBusy = FALSE; } } event result_t SendMsg.sendDone(TOS_MsgPtr pMsg, result_t success) { if (pMsg == &msgBuf) { atomic msgBufBusy = FALSE; } return SUCCESS; } DrainRouteEntry* newRoute(uint16_t dest, bool defaultRoute) { DrainRouteEntry* route; uint8_t i; uint8_t slot = DRAIN_INVALID_SLOT; if (defaultRoute) { for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest != DRAIN_INVALID_DEST && route->defaultRoute == TRUE) { slot = i; break; } } } if (slot == DRAIN_INVALID_SLOT) { for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest == DRAIN_INVALID_DEST) { slot = i; break; } } } if (slot == DRAIN_INVALID_SLOT) { for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest != DRAIN_INVALID_DEST && route->defaultRoute == FALSE) { slot = i; break; } } } if (slot == DRAIN_INVALID_SLOT) { return NULL; } dbg(DBG_ROUTE, "DrainLinkEstM: new route in slot %d 0x%x\n", slot, &routes[slot]); route = &routes[slot]; clearRoute(route); route->dest = dest; route->defaultRoute = defaultRoute; return route; } void clearRoute(DrainRouteEntry* route) { route->dest = DRAIN_INVALID_DEST; route->nextHop = TOS_BCAST_ADDR; route->nextHopCost = 0xFFFF; route->nextHopLinkEst = 0xFFFF; route->destDistance = 0; route->treeInstance = 0; route->announceSeqno = 1; route->announceDelay = 0; route->defaultRoute = 0; } command uint16_t RouteControl.getParent() { return routes[0].nextHop; } command uint8_t RouteControl.getDepth() { return routes[0].destDistance; } command uint16_t RouteControl.getSender(TOS_MsgPtr msg) { return 0; } command uint8_t RouteControl.getOccupancy() { return 0; } command uint8_t RouteControl.getQuality() { return 0; } command result_t RouteControl.setUpdateInterval(uint16_t Interval) { return FAIL; } command result_t RouteControl.manualUpdate() { return FAIL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -