[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/rwth/mobnets/MultiHopLQI
LQIMultiHopRouter.nc, NONE, 1.1 MultiHop.h, NONE,
1.1 MultiHopEngineM.nc, NONE, 1.1 MultiHopLQI.nc, NONE,
1.1 RouteSelect.nc, NONE, 1.1 RouteStats.nc, NONE, 1.1
Krisakorn Rerkrai
krerkrai at users.sourceforge.net
Wed Jan 16 13:50:25 PST 2008
Update of /cvsroot/tinyos/tinyos-1.x/contrib/rwth/mobnets/MultiHopLQI
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv29674
Added Files:
LQIMultiHopRouter.nc MultiHop.h MultiHopEngineM.nc
MultiHopLQI.nc RouteSelect.nc RouteStats.nc
Log Message:
--- NEW FILE: LQIMultiHopRouter.nc ---
includes MultiHop;
configuration LQIMultiHopRouter {
provides {
interface StdControl;
// The interface are as parameterised by the active message id
// only the 10 active message ids defined MultiHop.h are supported.
interface Receive[uint8_t id];
interface Intercept[uint8_t id];
interface Intercept as Snoop[uint8_t id];
interface Send[uint8_t id];
interface RouteControl;
interface RouteStats;
}
uses {
interface ReceiveMsg[uint8_t id];
}
}
implementation {
components
MultiHopEngineM,
MultiHopLQI,
SimpleTime,
GenericComm as Comm,
TimerC,
#ifdef MHOP_LEDS
LedsC,
#else
NoLeds as LedsC,
#endif
RandomLFSR;
components CC2420RadioC as RadioCoord;
StdControl = MultiHopEngineM;
Receive = MultiHopEngineM;
Send = MultiHopEngineM;
Intercept = MultiHopEngineM.Intercept;
Snoop = MultiHopEngineM.Snoop;
RouteControl = MultiHopEngineM;
RouteStats = MultiHopEngineM;
ReceiveMsg = MultiHopEngineM;
#ifdef TIMESYNC
MultiHopEngineM.SubControl -> SimpleTime.StdControl;
#endif
MultiHopEngineM.SubControl -> MultiHopLQI.StdControl;
MultiHopEngineM.CommStdControl -> Comm;
MultiHopEngineM.RouteSelectCntl -> MultiHopLQI.RouteControl;
MultiHopEngineM.RouteSelect -> MultiHopLQI;
MultiHopEngineM.SendMsg -> Comm.SendMsg;
MultiHopLQI.Timer -> TimerC.Timer[unique("Timer")];
MultiHopEngineM.Leds -> LedsC;
MultiHopLQI.SendMsg -> Comm.SendMsg[AM_BEACONMSG];
MultiHopLQI.ReceiveMsg -> Comm.ReceiveMsg[AM_BEACONMSG];
MultiHopLQI.Random -> RandomLFSR;
MultiHopLQI.RouteStats -> MultiHopEngineM;
// TimeSync-related Components
#ifdef TIMESYNC
MultiHopLQI.Time -> SimpleTime.Time;
MultiHopLQI.TimeUtil -> SimpleTime.TimeUtil;
MultiHopLQI.TimeSet -> SimpleTime.TimeSet;
MultiHopLQI.RadioCoordinator -> RadioCoord.RadioSendCoordinator;
#endif
}
--- NEW FILE: MultiHop.h ---
// $Id: MultiHop.h,v 1.1 2008/01/16 21:50:22 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 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."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
*
* Authors: Philip Buonadonna, Crossbow, Gilman Tolle
* Date last modified: 2/20/03
*
*/
/**
* @author Philip Buonadonna
*/
#ifndef _TOS_MULTIHOP_H
#define _TOS_MULTIHOP_H
#ifndef MHOP_QUEUE_SIZE
#define MHOP_QUEUE_SIZE 2
#endif
#ifndef MHOP_HISTORY_SIZE
#define MHOP_HISTORY_SIZE 4
#endif
#include "AM.h"
enum {
AM_BEACONMSG = 250,
AM_MULTIHOPMSG = 250,
AM_DEBUGPACKET = 3
};
/* Fields of neighbor table */
typedef struct TOS_MHopNeighbor {
uint16_t addr; // state provided by nbr
uint16_t recv_count; // since last goodness update
uint16_t fail_count; // since last goodness, adjusted by TOs
uint16_t hopcount;
uint8_t goodness;
uint8_t timeouts; // since last recv
} TOS_MHopNeighbor;
typedef struct MultihopMsg {
uint16_t sourceaddr;
uint16_t originaddr;
int16_t seqno;
int16_t originseqno;
uint16_t hopcount;
uint8_t data[(TOSH_DATA_LENGTH - 10)];
} TOS_MHopMsg;
typedef struct BeaconMsg {
uint16_t parent;
uint16_t cost;
uint16_t hopcount;
uint32_t timestamp;
} BeaconMsg;
typedef struct DBGEstEntry {
uint16_t id;
uint8_t hopcount;
uint8_t sendEst;
} DBGEstEntry;
typedef struct DebugPacket {
// uint16_t seqno;
uint16_t estEntries;
DBGEstEntry estList[0];
} DebugPacket;
#endif /* _TOS_MULTIHOP_H */
--- NEW FILE: MultiHopEngineM.nc ---
// $Id: MultiHopEngineM.nc,v 1.1 2008/01/16 21:50:22 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 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."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* A simple module that handles multihop packet movement. It accepts
* messages from both applications and the network and does the necessary
* interception and forwarding.
* It interfaces to an algorithmic componenet via RouteSelect. It also acts
* as a front end for RouteControl
*/
/*
* Authors: Philip Buonadonna, Alec Woo, Crossbow Inc.
*
*/
includes AM;
includes MultiHop;
module MultiHopEngineM {
provides {
interface StdControl;
interface Receive[uint8_t id];
interface Send[uint8_t id];
interface Intercept[uint8_t id];
interface Intercept as Snoop[uint8_t id];
interface RouteControl;
interface RouteStats;
}
uses {
interface ReceiveMsg[uint8_t id];
interface SendMsg[uint8_t id];
interface RouteControl as RouteSelectCntl;
interface RouteSelect;
interface StdControl as SubControl;
interface StdControl as CommStdControl;
interface Leds;
}
}
implementation {
enum {
FWD_QUEUE_SIZE = MHOP_QUEUE_SIZE, // Forwarding Queue
EMPTY = 0xff
};
/* Routing status of local node */
/* Internal storage and scheduling state */
struct TOS_Msg FwdBuffers[FWD_QUEUE_SIZE];
struct TOS_Msg *FwdBufList[FWD_QUEUE_SIZE];
uint8_t FwdBufBusy[FWD_QUEUE_SIZE];
uint8_t iFwdBufHead, iFwdBufTail;
uint16_t sendFailures = 0;
/***********************************************************************
* Initialization
***********************************************************************/
static void initialize() {
int n;
for (n=0; n < FWD_QUEUE_SIZE; n++) {
FwdBufList[n] = &FwdBuffers[n];
FwdBufBusy[n] = 0;
}
iFwdBufHead = iFwdBufTail = 0;
sendFailures = 0;
}
command result_t StdControl.init() {
initialize();
call CommStdControl.init();
return call SubControl.init();
}
command result_t StdControl.start() {
call CommStdControl.start();
return call SubControl.start();
}
command result_t StdControl.stop() {
call SubControl.stop();
// XXX message doesn't get received if we stop then start radio
return call CommStdControl.stop();
}
/***********************************************************************
* Commands and events
***********************************************************************/
command result_t Send.send[uint8_t id](TOS_MsgPtr pMsg, uint16_t PayloadLen) {
uint16_t usMHLength = offsetof(TOS_MHopMsg,data) + PayloadLen;
if (usMHLength > TOSH_DATA_LENGTH) {
return FAIL;
}
// dbg(DBG_ROUTE,"MHop: send\n");
call RouteSelect.initializeFields(pMsg,id);
if (call RouteSelect.selectRoute(pMsg,id, 0) != SUCCESS) {
return FAIL;
}
/*
dbg(DBG_ROUTE,"MHop: out dest %d pkt 0x%x\n",
pMsg->addr,
((TOS_MHopMsg *)pMsg->data)->seqno);
*/
if (call SendMsg.send[id](pMsg->addr, usMHLength, pMsg) != SUCCESS) {
sendFailures++;
return FAIL;
}
return SUCCESS;
}
command void *Send.getBuffer[uint8_t id](TOS_MsgPtr pMsg, uint16_t* length) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)pMsg->data;
*length = TOSH_DATA_LENGTH - offsetof(TOS_MHopMsg,data);
return (&pMHMsg->data[0]);
}
int8_t get_buff(){
uint8_t n;
for (n=0; n < FWD_QUEUE_SIZE; n++) {
uint8_t done = 0;
atomic{
if(FwdBufBusy[n] == 0){
FwdBufBusy[n] = 1;
done = 1;
}
}
if(done == 1) return n;
}
return -1;
}
int8_t is_ours(TOS_MsgPtr ptr){
uint8_t n;
for (n=0; n < FWD_QUEUE_SIZE; n++) {
if(FwdBufList[n] == ptr){
return n;
}
}
return -1;
}
static TOS_MsgPtr mForward(TOS_MsgPtr pMsg, uint8_t id) {
TOS_MHopMsg* pMHMsg;
int8_t buf;
TOS_MsgPtr pNewBuf;
pNewBuf = pMsg;
buf = get_buff();
pMHMsg = (TOS_MHopMsg*)pMsg->data;
if (buf == -1)
return pNewBuf;
if ((call RouteSelect.selectRoute(pMsg,id, 0)) != SUCCESS) {
FwdBufBusy[(uint8_t)buf] = 0;
return pNewBuf;
}
// Failures at the send level do not cause the seq. number space to be
// rolled back properly. This is somewhat broken.
if (call SendMsg.send[id](pMsg->addr,pMsg->length,pMsg) == SUCCESS) {
call Leds.yellowOn();
pNewBuf = FwdBufList[(uint8_t)buf];
FwdBufList[(uint8_t)buf] = pMsg;
}else{
FwdBufBusy[(uint8_t)buf] = 0;
sendFailures++;
}
return pNewBuf;
}
event TOS_MsgPtr ReceiveMsg.receive[uint8_t id](TOS_MsgPtr pMsg) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)pMsg->data;
uint16_t PayloadLen = pMsg->length - offsetof(TOS_MHopMsg,data);
#if 0
dbg(DBG_ROUTE, "MHop: Msg Rcvd, src 0x%02x, org 0x%02x, parent 0x%02x\n",
pMHMsg->sourceaddr, pMHMsg->originaddr, 0 /*pMHMsg->parentaddr*/);
#endif
// Ordinary message requiring forwarding
if (pMsg->addr == TOS_LOCAL_ADDRESS) { // Addressed to local node
if ((signal Intercept.intercept[id](pMsg,&pMHMsg->data[0],PayloadLen)) == SUCCESS) {
pMsg = mForward(pMsg,id);
}
}
// Snoop the packet for permiscuous applications
signal Snoop.intercept[id](pMsg,&pMHMsg->data[0],PayloadLen);
return pMsg;
}
uint8_t fail_count;
event result_t SendMsg.sendDone[uint8_t id](TOS_MsgPtr pMsg, result_t success) {
//dbg(DBG_ROUTE, "MHop: senddone 0x%x 0x%x\n", pMsg, success);
int8_t buf;
#ifdef PLATFORM_PC
pMsg->ack = 1;
#endif
call Leds.yellowOff();
if(pMsg->ack == 0 &&
pMsg->addr != TOS_BCAST_ADDR &&
pMsg->addr != TOS_UART_ADDR &&
fail_count < 5){
call RouteSelect.selectRoute(pMsg,id, 1);
if (call SendMsg.send[id](pMsg->addr,pMsg->length,pMsg) == SUCCESS) {
fail_count ++;
return SUCCESS;
} else {
sendFailures++;
}
}
fail_count = 0;
buf = is_ours(pMsg);
if (buf != -1) { // Msg was from forwarding queue
FwdBufBusy[(uint8_t)buf] = 0;
} else {
signal Send.sendDone[id](pMsg, success);
}
return SUCCESS;
}
command uint16_t RouteControl.getParent() {
return call RouteSelectCntl.getParent();
}
command uint8_t RouteControl.getQuality() {
return call RouteSelectCntl.getQuality();
}
command uint8_t RouteControl.getDepth() {
return call RouteSelectCntl.getDepth();
}
command uint8_t RouteControl.getOccupancy() {
uint16_t uiOutstanding = (uint16_t)iFwdBufTail - (uint16_t)iFwdBufHead;
uiOutstanding %= FWD_QUEUE_SIZE;
return (uint8_t)uiOutstanding;
}
command uint16_t RouteControl.getSender(TOS_MsgPtr msg) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)msg->data;
return pMHMsg->sourceaddr;
}
command result_t RouteControl.setUpdateInterval(uint16_t Interval) {
return call RouteSelectCntl.setUpdateInterval(Interval);
}
command result_t RouteControl.manualUpdate() {
return call RouteSelectCntl.manualUpdate();
}
command uint16_t RouteStats.getSendFailures() {
return sendFailures;
}
default event result_t Send.sendDone[uint8_t id](TOS_MsgPtr pMsg, result_t success) {
return SUCCESS;
}
default event result_t Intercept.intercept[uint8_t id](TOS_MsgPtr pMsg, void* payload,
uint16_t payloadLen) {
return SUCCESS;
}
default event result_t Snoop.intercept[uint8_t id](TOS_MsgPtr pMsg, void* payload,
uint16_t payloadLen) {
return SUCCESS;
}
}
--- NEW FILE: MultiHopLQI.nc ---
/* tab:4
* "Copyright (c) 2000-2003 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."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* Authors: Gilman Tolle
*/
includes MultiHop;
module MultiHopLQI {
provides {
interface StdControl;
interface RouteSelect;
interface RouteControl;
}
uses {
interface Timer;
interface SendMsg;
interface ReceiveMsg;
interface Random;
interface RouteStats;
#ifdef TIMESYNC
interface Time;
interface TimeUtil;
interface TimeSet;
interface RadioCoordinator;
#endif
}
}
implementation {
enum {
BASE_STATION_ADDRESS = 0,
BEACON_PERIOD = 32,
BEACON_TIMEOUT = 8,
};
enum {
ROUTE_INVALID = 0xff
};
TOS_Msg msgBuf;
bool msgBufBusy;
uint16_t gbCurrentParent;
uint16_t gbCurrentParentCost;
uint16_t gbCurrentLinkEst;
uint8_t gbCurrentHopCount;
uint16_t gbCurrentCost;
uint8_t gLastHeard;
int16_t gCurrentSeqNo;
uint16_t gUpdateInterval;
uint8_t gRecentIndex;
uint16_t gRecentPacketSender[MHOP_HISTORY_SIZE];
int16_t gRecentPacketSeqNo[MHOP_HISTORY_SIZE];
uint8_t gRecentOriginIndex;
uint16_t gRecentOriginPacketSender[MHOP_HISTORY_SIZE];
int16_t gRecentOriginPacketSeqNo[MHOP_HISTORY_SIZE];
uint16_t adjustLQI(uint8_t val) {
uint16_t result = (80 - (val - 50));
result = (((result * result) >> 3) * result) >> 3;
return result;
}
task void SendRouteTask() {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *) &msgBuf.data[0];
BeaconMsg *pRP = (BeaconMsg *)&pMHMsg->data[0];
uint8_t length = offsetof(TOS_MHopMsg,data) + sizeof(BeaconMsg);
dbg(DBG_ROUTE,"MultiHopRSSI Sending route update msg.\n");
if (gbCurrentParent != TOS_BCAST_ADDR) {
dbg(DBG_ROUTE,"MultiHopRSSI: Parent = %d\n", gbCurrentParent);
}
if (msgBufBusy) {
#ifndef PLATFORM_PC
post SendRouteTask();
#endif
return;
}
dbg(DBG_ROUTE,"MultiHopRSSI: Current cost: %d.\n",
gbCurrentParentCost + gbCurrentLinkEst);
pRP->parent = gbCurrentParent;
pRP->cost = gbCurrentParentCost + gbCurrentLinkEst;
pMHMsg->sourceaddr = pMHMsg->originaddr = TOS_LOCAL_ADDRESS;
pRP->hopcount = gbCurrentHopCount;
pMHMsg->hopcount = gbCurrentHopCount;
pMHMsg->originseqno = gCurrentSeqNo;
pMHMsg->seqno = gCurrentSeqNo++;
if (call SendMsg.send(TOS_BCAST_ADDR, length, &msgBuf) == SUCCESS) {
atomic msgBufBusy = TRUE;
}
}
task void TimerTask() {
uint8_t val;
atomic val = ++gLastHeard;
if ((TOS_LOCAL_ADDRESS != 0) && (val > BEACON_TIMEOUT)) {
gbCurrentParent = TOS_BCAST_ADDR;
gbCurrentParentCost = 0x7fff;
gbCurrentLinkEst = 0x7fff;
gbCurrentHopCount = ROUTE_INVALID;
gbCurrentCost = 0xfffe;
}
post SendRouteTask();
}
command result_t StdControl.init() {
int n;
gRecentIndex = 0;
for (n = 0; n < MHOP_HISTORY_SIZE; n++) {
gRecentPacketSender[n] = TOS_BCAST_ADDR;
gRecentPacketSeqNo[n] = 0;
}
gRecentOriginIndex = 0;
for (n = 0; n < MHOP_HISTORY_SIZE; n++) {
gRecentOriginPacketSender[n] = TOS_BCAST_ADDR;
gRecentOriginPacketSeqNo[n] = 0;
}
gbCurrentParent = TOS_BCAST_ADDR;
gbCurrentParentCost = 0x7fff;
gbCurrentLinkEst = 0x7fff;
gbCurrentHopCount = ROUTE_INVALID;
gbCurrentCost = 0xfffe;
gCurrentSeqNo = 0;
gUpdateInterval = BEACON_PERIOD;
atomic msgBufBusy = FALSE;
if (TOS_LOCAL_ADDRESS == BASE_STATION_ADDRESS) {
gbCurrentParent = TOS_UART_ADDR;
gbCurrentParentCost = 0;
gbCurrentLinkEst = 0;
gbCurrentHopCount = 0;
gbCurrentCost = 0;
}
return SUCCESS;
}
command result_t StdControl.start() {
gLastHeard = 0;
call Timer.start(TIMER_ONE_SHOT,
call Random.rand() % (1024 * gUpdateInterval));
return SUCCESS;
}
command result_t StdControl.stop() {
call Timer.stop();
return SUCCESS;
}
command bool RouteSelect.isActive() {
return TRUE;
}
command result_t RouteSelect.selectRoute(TOS_MsgPtr Msg, uint8_t id,
uint8_t resend) {
int i;
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)&Msg->data[0];
// if (gbCurrentParent != TOS_UART_ADDR && resend == 0) {
if (pMHMsg->originaddr != TOS_LOCAL_ADDRESS && resend == 0) {
// supress duplicate packets
for (i = 0; i < MHOP_HISTORY_SIZE; i++) {
if ((gRecentPacketSender[i] == pMHMsg->sourceaddr) &&
(gRecentPacketSeqNo[i] == pMHMsg->seqno)) {
return FAIL;
}
}
gRecentPacketSender[gRecentIndex] = pMHMsg->sourceaddr;
gRecentPacketSeqNo[gRecentIndex] = pMHMsg->seqno;
gRecentIndex = (gRecentIndex + 1) % MHOP_HISTORY_SIZE;
// supress multihop cycles and try to break out of it
for (i = 0; i < MHOP_HISTORY_SIZE; i++) {
if ((gRecentOriginPacketSender[i] == pMHMsg->originaddr) &&
(gRecentOriginPacketSeqNo[i] == pMHMsg->originseqno)) {
gbCurrentParentCost = 0x7fff;
gbCurrentLinkEst = 0x7fff;
gbCurrentParent = TOS_BCAST_ADDR;
gbCurrentHopCount = ROUTE_INVALID;
return FAIL;
}
}
gRecentOriginPacketSender[gRecentOriginIndex] = pMHMsg->originaddr;
gRecentOriginPacketSeqNo[gRecentOriginIndex] = pMHMsg->originseqno;
gRecentOriginIndex = (gRecentOriginIndex + 1) % MHOP_HISTORY_SIZE;
}
if (gbCurrentParent != TOS_UART_ADDR && resend == 0) {
pMHMsg->seqno = gCurrentSeqNo++;
}
pMHMsg->sourceaddr = TOS_LOCAL_ADDRESS;
Msg->addr = gbCurrentParent;
return SUCCESS;
}
command result_t RouteSelect.initializeFields(TOS_MsgPtr Msg, uint8_t id) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)&Msg->data[0];
pMHMsg->sourceaddr = pMHMsg->originaddr = TOS_LOCAL_ADDRESS;
pMHMsg->originseqno = gCurrentSeqNo;
pMHMsg->hopcount = gbCurrentHopCount;
return SUCCESS;
}
command uint8_t* RouteSelect.getBuffer(TOS_MsgPtr Msg, uint16_t* Len) {
}
command uint16_t RouteControl.getParent() {
return gbCurrentParent;
}
command uint8_t RouteControl.getQuality() {
return gbCurrentLinkEst;
}
command uint8_t RouteControl.getDepth() {
return gbCurrentHopCount;
}
command uint8_t RouteControl.getOccupancy() {
return 0;
}
command uint16_t RouteControl.getSender(TOS_MsgPtr msg) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)msg->data;
return pMHMsg->sourceaddr;
}
command result_t RouteControl.setUpdateInterval(uint16_t Interval) {
gUpdateInterval = Interval;
return SUCCESS;
}
command result_t RouteControl.manualUpdate() {
post SendRouteTask();
return SUCCESS;
}
event result_t Timer.fired() {
post TimerTask();
call Timer.start(TIMER_ONE_SHOT, 1024 * gUpdateInterval + 1);
return SUCCESS;
}
event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr Msg) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)&Msg->data[0];
BeaconMsg *pRP = (BeaconMsg *)&pMHMsg->data[0];
// dbg(DBG_ROUTE, "Received Beacon(source=%d, cost=%d, strength=%d)\n",
// pMHMsg->sourceaddr, pRP->cost, Msg->strength);
/* if the message is from my parent
store the new link estimation */
if (pMHMsg->sourceaddr == gbCurrentParent) {
// try to prevent cycles
if (pRP->parent != TOS_LOCAL_ADDRESS) {
gLastHeard = 0;
gbCurrentParentCost = pRP->cost;
gbCurrentLinkEst = adjustLQI(Msg->lqi);
gbCurrentHopCount = pRP->hopcount + 1;
}
else {
gLastHeard = 0;
gbCurrentParentCost = 0x7fff;
gbCurrentLinkEst = 0x7fff;
gbCurrentParent = TOS_BCAST_ADDR;
gbCurrentHopCount = ROUTE_INVALID;
}
#ifdef TIMESYNC
call TimeSet.set(call TimeUtil.create(0, pRP->timestamp));
dbg(DBG_ROUTE,"TimeSync: Setting Time To: %d\n", pRP->timestamp);
#endif
} else {
/* if the message is not from my parent,
compare the message's cost + link estimate to my current cost,
switch if necessary */
// make sure you don't pick a parent that creates a cycle
if (((uint32_t) pRP->cost + (uint32_t) adjustLQI(Msg->lqi)
<
((uint32_t) gbCurrentParentCost + (uint32_t) gbCurrentLinkEst) -
(((uint32_t) gbCurrentParentCost + (uint32_t) gbCurrentLinkEst) >> 2)
) &&
(pRP->parent != TOS_LOCAL_ADDRESS)) {
gLastHeard = 0;
gbCurrentParent = pMHMsg->sourceaddr;
gbCurrentParentCost = pRP->cost;
gbCurrentLinkEst = adjustLQI(Msg->lqi);
gbCurrentHopCount = pRP->hopcount + 1;
}
}
return Msg;
}
event result_t SendMsg.sendDone(TOS_MsgPtr pMsg, result_t success) {
atomic msgBufBusy = FALSE;
return SUCCESS;
}
#ifdef TIMESYNC
async event void RadioCoordinator.startSymbol(uint8_t bitsPerBlock,
uint8_t offset,
TOS_MsgPtr msgBuff) {
tos_time_t endTime;
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *) &msgBuff->data[0];
BeaconMsg *pRP = (BeaconMsg *) &pMHMsg->data[0];
atomic {
if (msgBufBusy == TRUE) {
endTime = call Time.get();
pRP->timestamp = endTime.low32;
dbg(DBG_ROUTE,"TimeSync: End Send RoutePacket Time %d\n", endTime.low32);
}
}
}
async event void RadioCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) {
/* XXX: do nothing */
}
async event void RadioCoordinator.blockTimer() {
/* XXX: do nothing */
}
#endif
}
--- NEW FILE: RouteSelect.nc ---
// $Id: RouteSelect.nc,v 1.1 2008/01/16 21:50:23 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 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."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* Authors: Philip Levis
* Date last modified: 8/12/02
*
* The RouteSelect interface is part of the TinyOS ad-hoc routing
* system architecture. The component that keeps track of routing
* information and makes route selection decisions provides this
* interface. When a Send component wants to send a packet, it passes
* it to RouteSelect for its routing information to be filled in. This
* way, the Send component is entirely unaware of the routing
* header/footer structure.
*/
/**
* Interface to a route selection component in the TinyOS ad-hoc
* system architecture.
* @author Philip Levis
*/
includes AM;
interface RouteSelect {
/**
* Whether there is currently a valid route.
*
* @return Whether there is a valid route.
*/
command bool isActive();
/**
* Select a route and fill in all of the necessary routing
* information to a packet.
*
* @param msg Message to select route for and fill in routing information.
*
* @return Whether a route was selected succesfully. On FAIL the
* packet should not be sent.
*
*/
command result_t selectRoute(TOS_MsgPtr msg, uint8_t id, uint8_t resend);
/**
* Given a TOS_MstPtr, initialize its routing fields to a known
* state, specifying that the message is originating from this node.
* This known state can then be used by selectRoute() to fill in
* the necessary data.
*
* @param msg Message to select route for and fill in init data.
*
* @return Should always return SUCCESS.
*
*/
command result_t initializeFields(TOS_MsgPtr msg, uint8_t id);
/**
* Given a TinyOS message buffer, provide a pointer to the data
* buffer within it that an application can use as well as its
* length. Unlike the getBuffer of the Send interface, this can
* be called freely and does not modify the buffer.
*
* @param msg The message to get the data region of.
*
* @param length Pointer to a field to store the length of the data region.
*
* @return A pointer to the data region.
*/
command uint8_t* getBuffer(TOS_MsgPtr msg, uint16_t* len);
}
--- NEW FILE: RouteStats.nc ---
interface RouteStats {
command uint16_t getSendFailures();
}
More information about the Tinyos-contrib-commits
mailing list