treeroutingenginep.nc

来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 524 行 · 第 1/2 页

NC
524
字号
#include <Timer.h>#include <TreeRouting.h>#include <CollectionDebugMsg.h>/* $Id: TreeRoutingEngineP.nc,v 1.1.2.18 2006/06/23 20:24:38 kasj78 Exp $ *//* * "Copyright (c) 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." * *//* *  @author Rodrigo Fonseca *  Acknowledgment: based on MintRoute, by Philip Buonadonna, Alec Woo, Terence Tong, Crossbow *                           MultiHopLQI *                            *  @date   $Date: 2006/06/23 20:24:38 $ *  @see Net2-WG */generic module TreeRoutingEngineP(uint8_t routingTableSize) {    provides {        interface UnicastNameFreeRouting as Routing;        interface RootControl;        interface TreeRoutingInspect;        interface StdControl;        interface Init;    }     uses {        interface AMSend as BeaconSend;        interface Receive as BeaconReceive;        interface LinkEstimator;        interface AMPacket;        interface LinkSrcPacket;        interface SplitControl as RadioControl;        interface Timer<TMilli> as BeaconTimer;        interface Random;        interface CollectionDebug;    }}implementation {    //No sense updating or sending beacons if radio is off    bool radioOn = FALSE;    //Start and stop control this. Stops updating and sending beacons    bool running = FALSE;    //Guards the beacon buffer    bool sending = FALSE;    //Tells updateNeighbor that the parent was just evicted    bool justEvicted = FALSE;    route_info_t routeInfo;    bool state_is_root;    am_addr_t my_ll_addr;    message_t beaconMsgBuffer;    beacon_msg_t* beaconMsg;    /* routing table -- routing info about neighbors */    routing_table_entry routingTable[routingTableSize];    uint8_t routingTableActive;    /* statistics */    uint32_t parentChanges;    /* end statistics */    // forward declarations    void routingTableInit();    uint8_t routingTableFind(am_addr_t);    error_t routingTableUpdateEntry(am_addr_t, am_addr_t , uint8_t, uint16_t);    error_t routingTableEvict(am_addr_t neighbor);    command error_t Init.init() {        uint8_t maxLength;        radioOn = FALSE;        running = FALSE;        parentChanges = 0;        state_is_root = 0;        routeInfoInit(&routeInfo);        routingTableInit();        my_ll_addr = call AMPacket.address();        beaconMsg = call BeaconSend.getPayload(&beaconMsgBuffer);        maxLength = call BeaconSend.maxPayloadLength();        dbg("TreeRoutingCtl","TreeRouting initialized. (used payload:%d max payload:%d!\n",               sizeof(beaconMsg), maxLength);        return SUCCESS;    }    command error_t StdControl.start() {        //start will (re)start the sending of messages        uint16_t nextInt;        if (!running) {            running = TRUE;            nextInt = call Random.rand16() % BEACON_INTERVAL;            nextInt += BEACON_INTERVAL >> 1;            call BeaconTimer.startOneShot(nextInt);            dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);        }             return SUCCESS;    }    command error_t StdControl.stop() {        running = FALSE;        dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);        return SUCCESS;    }     event void RadioControl.startDone(error_t error) {        radioOn = TRUE;        dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);        if (running) {            uint16_t nextInt;            nextInt = call Random.rand16() % BEACON_INTERVAL;            nextInt += BEACON_INTERVAL >> 1;            call BeaconTimer.startOneShot(nextInt);        }    }     event void RadioControl.stopDone(error_t error) {        radioOn = FALSE;        dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);    }    /* Is this quality measure better than the minimum threshold? */    // Implemented assuming quality is EETX    bool passLinkMetricThreshold(uint16_t metric) {        return (metric < ETX_THRESHOLD);    }    /* Converts the output of the link estimator to path metric     * units, that can be *added* to form path metric measures */    uint16_t evaluateMetric(uint8_t quality) {        //dbg("TreeRouting","%s %d -> %d\n",__FUNCTION__,quality, quality+10);        return (quality + 10);    }    /* updates the routing information, using the info that has been received     * from neighbor beacons. Two things can cause this info to change:      * neighbor beacons, changes in link estimates, including neighbor eviction */    task void updateRouteTask() {        uint8_t i;        routing_table_entry* entry;        routing_table_entry* best;        uint16_t minMetric;        uint16_t currentMetric;        uint16_t linkMetric, pathMetric;        if (state_is_root)            return;        best = NULL;        minMetric = MAX_METRIC;        currentMetric = MAX_METRIC;        dbg("TreeRouting","%s\n",__FUNCTION__);         //find best path in table, other than our current        for (i = 0; i < routingTableActive; i++) {            entry = &routingTable[i];            // Avoid bad entries and 1-hop loops            if (entry->info.parent == INVALID_ADDR || entry->info.parent == my_ll_addr) {              dbg("TreeRouting", "routingTable[%d]: neighbor: [id: %d parent: %d hopcount: %d metric: NO ROUTE]\n",  i, entry->neighbor, entry->info.parent, entry->info.hopcount);              continue;            }                        linkMetric = evaluateMetric(call LinkEstimator.getLinkQuality(entry->neighbor));            dbg("TreeRouting",                 "routingTable[%d]: neighbor: [id: %d parent: %d hopcount: %d metric: %d]\n",                  i, entry->neighbor, entry->info.parent,                 entry->info.hopcount, linkMetric);            dbg_clear("TreeRouting", "   metric: %hu.\n", linkMetric);            pathMetric = linkMetric + entry->info.metric;            //for current parent            if (entry->neighbor == routeInfo.parent) {                dbg("TreeRouting", "   already parent.\n");                currentMetric = pathMetric;                //update routeInfo with parent's current info                atomic {                    routeInfo.metric = entry->info.metric;                    routeInfo.hopcount = entry->info.hopcount + 1;                }                continue;            }            if (!passLinkMetricThreshold(linkMetric)) {              dbg("TreeRouting", "   did not pass threshold.\n");              continue;            }                        if (pathMetric < minMetric) {                minMetric = pathMetric;                best = entry;            }          }        //now choose between current/best        if (minMetric != MAX_METRIC) {            if (currentMetric == MAX_METRIC ||                minMetric + PARENT_SWITCH_THRESHOLD < currentMetric) {                // routeInfo.metric will not store the composed metric.                // since the linkMetric may change, we will compose whenever                // we need it: i. when choosing a parent (here);                 //            ii. when choosing a next hop                parentChanges++;                dbg("TreeRouting","Changed parent. from %d to %d\n", routeInfo.parent, best->neighbor);                call CollectionDebug.logEventRoute(NET_C_TREE_NEW_PARENT, best->neighbor, best->info.hopcount + 1, best->info.metric);                 call LinkEstimator.unpinNeighbor(routeInfo.parent);                call LinkEstimator.pinNeighbor(best->neighbor);                atomic {                    routeInfo.parent = best->neighbor;                    routeInfo.metric = best->info.metric;                    routeInfo.hopcount = best->info.hopcount + 1;                 }            }        }            //finally, tell people what happened        if (justEvicted && routeInfo.parent == INVALID_ADDR)             signal Routing.noRoute();        else if (!justEvicted && minMetric != MAX_METRIC)            signal Routing.routeFound();        justEvicted = FALSE;     }    /* Inspection interface implementations */        /* send a beacon advertising this node's routeInfo */    // only posted if running and radioOn    task void sendBeaconTask() {        error_t eval;        if (sending) {            return;        }        beaconMsg->parent = routeInfo.parent;        beaconMsg->hopcount = routeInfo.hopcount;        if (state_is_root || routeInfo.parent == INVALID_ADDR) {            beaconMsg->metric = routeInfo.metric;        } else {            beaconMsg->metric = routeInfo.metric +                                evaluateMetric(call LinkEstimator.getLinkQuality(routeInfo.parent));         }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?