📄 drainlinkestm.nc
字号:
//$Id: DrainLinkEstM.nc,v 1.1 2005/10/27 21:31:04 gtolle Exp $/* * Copyright (c) 2000-2005 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." */includes Drain;/** * @author Gilman Tolle <get@cs.berkeley.edu> */module DrainLinkEstM { provides { interface StdControl; interface DrainLinkEst; interface Drain; interface RouteControl; } uses { interface Timer; interface Random; interface SendMsg; interface ReceiveMsg; interface DrainGroup; interface Leds; }}implementation { DrainRouteEntry routes[DRAIN_MAX_ROUTES]; uint8_t seqNo; bool msgBufBusy; TOS_Msg msgBuf; bool timerRunning;#define MAX(a_,b_) (a_ > b_ ? a_ : b_)#define MIN(a_,b_) (a_ < b_ ? a_ : b_)#define BIT_GET(x, i) ((x) & (1 << (i)))#define BIT_SET(x, i) ((x) | (1 << (i)))#define BIT_CLEAR(x, i) ((x) & ~(1 << (i))) uint16_t adjustLQI(uint8_t val); DrainRouteEntry* newRoute(uint16_t dest, bool defaultRoute); void clearRoute(DrainRouteEntry* route); DrainRouteEntry* getRoute(uint16_t dest); DrainRouteEntry* getDefaultRoute(uint16_t dest); DrainRouteEntry* getReadyRoute(); void sendRoute(DrainRouteEntry* route); bool isGroup(uint16_t dest); void startTimer(); command result_t StdControl.init() { uint8_t i; msgBufBusy = FALSE; seqNo = 0; for(i = 0; i < DRAIN_MAX_ROUTES; i++) { clearRoute(&routes[i]); } return SUCCESS; } command result_t StdControl.start() { return SUCCESS; } command result_t StdControl.stop() { call Timer.stop(); return SUCCESS; } command result_t DrainLinkEst.initializeFields(TOS_MsgPtr Msg, uint8_t id, uint16_t dest, uint8_t length) { DrainMsg *pMHMsg = (DrainMsg *)&Msg->data[0]; Msg->addr = 0; Msg->length = offsetof(DrainMsg,data) + length; if (dest == TOS_DEFAULT_ADDR) { if (routes[0].dest == DRAIN_INVALID_DEST) { dest = TOS_BCAST_ADDR; } else { dest = routes[0].dest; } } pMHMsg->type = id; pMHMsg->ttl = DRAIN_MAX_TTL - 1; pMHMsg->seqNo = seqNo++; pMHMsg->source = TOS_LOCAL_ADDRESS; pMHMsg->dest = dest; return SUCCESS; } command result_t DrainLinkEst.forwardFields(TOS_MsgPtr Msg) { DrainMsg *pMHMsg = (DrainMsg *)&Msg->data[0]; Msg->addr = 0; pMHMsg->ttl--; if (pMHMsg->ttl == 0) return FAIL; return SUCCESS; } command result_t DrainLinkEst.selectRoute(TOS_MsgPtr Msg) { DrainMsg* pMHMsg = (DrainMsg *)&Msg->data[0]; DrainRouteEntry* route; if (pMHMsg->dest == TOS_BCAST_ADDR) { Msg->addr = TOS_BCAST_ADDR; } else if (pMHMsg->dest == TOS_UART_ADDR) { Msg->addr = TOS_UART_ADDR; } else { if (isGroup(pMHMsg->dest)) { route = getDefaultRoute(pMHMsg->dest); } else { route = getRoute(pMHMsg->dest); } if (route != NULL) { Msg->addr = route->nextHop; } else { Msg->addr = TOS_BCAST_ADDR; } } Msg->ack = 0; return SUCCESS; } DrainRouteEntry* getRoute(uint16_t dest) { DrainRouteEntry* route; uint8_t i; for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest != DRAIN_INVALID_DEST && route->dest == dest) { return route; } } return NULL; } DrainRouteEntry* getDefaultRoute(uint16_t dest) { DrainRouteEntry* route; uint8_t i; for(i = 0; i < DRAIN_MAX_ROUTES; i++) { route = &routes[i]; if (route->dest != DRAIN_INVALID_DEST && route->defaultRoute == TRUE) { return route; } } return NULL; } bool isGroup(uint16_t dest) { return (dest >= 0xFE00 && dest <= 0xFEFF); } command result_t DrainLinkEst.messageSent(TOS_MsgPtr msg, result_t success) { DrainMsg* drainMsg = (DrainMsg*) &msg->data[0]; DrainRouteEntry* route = getRoute(drainMsg->dest); route->sentPackets++; if (success) { route->successPackets++; } return SUCCESS; } command bool DrainLinkEst.isRoot() { return (getRoute(TOS_LOCAL_ADDRESS) != NULL); } command result_t Drain.buildTree() { return call Drain.buildTreeInstance(call Random.rand() & 0xFF, FALSE); } command result_t Drain.buildTreeDefaultRoute() { return call Drain.buildTreeInstance(call Random.rand() & 0xFF, TRUE); } command result_t Drain.buildTreeInstance(uint8_t instance, bool defaultRoute) { DrainRouteEntry* route = newRoute(TOS_LOCAL_ADDRESS, defaultRoute); if (route == NULL) return FAIL; dbg(DBG_ROUTE, "DrainLinkEstM: buildTree(instance=%d,defaultRoute=%d)\n", instance, defaultRoute); route->treeInstance = instance; route->announceSeqno = 0; route->announceDelay = 1; route->nextHop = TOS_LOCAL_ADDRESS; route->nextHopCost = 0; route->nextHopLinkEst = 0; route->destDistance = 0; route->sendWaiting = TRUE; call Timer.start(TIMER_ONE_SHOT, 10); return SUCCESS; } event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr Msg) { DrainBeaconMsg *pRP = (DrainBeaconMsg *)&Msg->data[0]; DrainRouteEntry *route; uint16_t linkEst = 0; uint32_t curCost, newCost; bool retransmit = FALSE;#if defined(_CC2420CONST_H) linkEst = adjustLQI(Msg->lqi);#elif defined(PLATFORM_PC) linkEst = abs(pRP->linkSource % 10 - TOS_LOCAL_ADDRESS % 10) + abs(pRP->linkSource / 10 - TOS_LOCAL_ADDRESS / 10);// dbg(DBG_ROUTE, "DrainLinkEstM: source=%d, dest=%d, est=%d\n",// pRP->linkSource, TOS_LOCAL_ADDRESS, linkEst);#else linkEst = Msg->strength;#endif dbg(DBG_ROUTE,"DrainLinkEstM: receive DrainBeaconMsg(linkSource=%d,source=%d,parent=%d,cost=%d,ttl=%d,seqno=%d,delay=%d,instance=%d,linkEst=%d)\n", pRP->linkSource, pRP->source, pRP->parent, pRP->cost, pRP->ttl, pRP->beaconSeqno, pRP->beaconDelay, pRP->treeInstance, linkEst); if (pRP->source == TOS_LOCAL_ADDRESS) { return Msg; } route = getRoute(pRP->source); if (route == NULL) { route = newRoute(pRP->source, pRP->defaultRoute); if (route == NULL) { dbg(DBG_ROUTE, "DrainLinkEstM: no slot for new route to dest=%d\n", pRP->source); return Msg; } dbg(DBG_ROUTE, "DrainLinkEstM: new route 0x%x to dest=%d\n", route, route->dest); } /*** Retransmission stuff (check for new, set the retransmit timer) ***/ // If it's a new tree instance, discard the old sequence numbering // Always retransmit if (pRP->treeInstance != route->treeInstance) { if (pRP->beaconSeqno == 0) { // reset the sequence number to 1 route->announceSeqno = 1; } else { // always take the sequence number route->announceSeqno = pRP->beaconSeqno; } retransmit = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -