[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