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 + -
显示快捷键?