[Tinyos-commits] CVS: tinyos-1.x/tos/lib/Drip Drip.h, NONE, 1.1 Drip.nc, NONE, 1.1 DripC.nc, NONE, 1.1 DripM.nc, NONE, 1.1 DripSend.h, NONE, 1.1 DripSendC.nc, NONE, 1.1 DripSendM.nc, NONE, 1.1 DripState.nc, NONE, 1.1 DripStateC.nc, NONE, 1.1 DripStateM.nc, NONE, 1.1 DripStateMgr.nc, NONE, 1.1

Gilman Tolle gtolle at users.sourceforge.net
Thu Oct 27 14:29:48 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/tos/lib/Drip
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14367

Added Files:
	Drip.h Drip.nc DripC.nc DripM.nc DripSend.h DripSendC.nc 
	DripSendM.nc DripState.nc DripStateC.nc DripStateM.nc 
	DripStateMgr.nc 
Log Message:
Moved Drip from beta to core.

--- NEW FILE: Drip.h ---
//$Id: Drip.h,v 1.1 2005/10/27 21:29:43 gtolle 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."
 *
 */

/**
 * @author Gilman Tolle
 */

#ifndef __DRIP_H__
#define __DRIP_H__

enum {
  AM_DRIPMSG = 3,
};

typedef struct DripMetadata {
  uint8_t id;
  uint8_t dummyAlignmentByte; //this byte can go away if you maintain alignment
  uint16_t seqno;
} DripMetadata;

typedef struct DripMsg {
  DripMetadata metadata;
  uint8_t      data[0];
} DripMsg;

enum {
  DRIP_INVALID_KEY = 0,
  DRIP_CACHE_ENTRIES = uniqueCount("DripState"),
  DRIP_SEQNO_OLDEST = 0xfffe, // not ffff, because both oldest and newest should have the least significant bit unset.

  DRIP_SEQNO_NEWEST = 0,
  DRIP_SEQNO_UNKNOWN = 2,
  DRIP_SEQNO_FIRST = DRIP_SEQNO_UNKNOWN, //DRIP_SEQNO_OLDEST, //2,
  DRIP_TIMER_PERIOD = 100,
  DRIP_MIN_SEND_INTERVAL = 0,
  DRIP_MAX_SEND_INTERVAL = 15,
  DRIP_PRE_SEND = 0,
  DRIP_POST_SEND = 1,
  DRIP_WAKEUP_BIT = 0x1,
};

typedef struct DripCacheEntry {
  DripMetadata     metadata;
  uint16_t         trickleAnnounce;
  uint16_t         trickleCountdown;
  uint8_t          trickleStage;
  uint8_t          trickleSuppress:1;
  uint8_t          trickleState:6;
} DripCacheEntry;

#endif



--- NEW FILE: Drip.nc ---
//$Id: Drip.nc,v 1.1 2005/10/27 21:29:43 gtolle 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."
 *
 */

includes Drip;

/**
 * The Drip interface is used to initialize a Drip channel and send
 * messages into it.
 *
 * @author Gilman Tolle <get at cs.berkeley.edu>
 *
 */

interface Drip {
  
  /** 
   * You must call this in StdControl.init(). It sets up local state. 
   */
  command result_t init();

  /**
   * If you have saved a copy of the sequence number to persistent
   * storage, call this in StdControl.init() after retrieving your
   * copy.
   */
  command result_t setSeqno(uint16_t seqno);

  /** 
   * This event is signalled when the Trickle algorithm must rebroadcast
   * the value. Fill in the given buffer pointer, then call rebroadcast. 
   */
  event result_t rebroadcastRequest(TOS_MsgPtr msg, void *pData);

  /**
   * Call this from rebroadcastRequest() once you have filled the
   * buffer pointer.
   */
  command result_t rebroadcast(TOS_MsgPtr msg, void *pData, uint8_t len);

  /** 
   * Call this when you have changed the value locally, and would like
   * to disseminate new data with an incremented sequence number.
   * Once this is called, you will be receiving a rebroadcastRequest
   * event shortly.
   */
  command result_t change();
}

--- NEW FILE: DripC.nc ---
//$Id: DripC.nc,v 1.1 2005/10/27 21:29:43 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 Drip;

/**
 *
 * Drip provides an epidemic dissemination service for single messages.
 * <p>
 * Drip messages are identified using a standard Active Message ID.
 * <p>
 * Incoming messages are received on the Receive interface.
 * <p>
 * Each client of Drip is responsible for caching the message received
 * on the Receive interface, and providing it to the Drip interface
 * when retransmission is necessary.
 * <p>
 * Here is an example wiring you can use with Drip:
 * <p>
 * <tt>
 * TestDripM.ReceiveDrip -> DripC.Receive[AM_TESTDRIPMSG];<br>
 * TestDripM.Drip -> DripC.Drip[AM_TESTDRIPMSG];<br>
 * DripC.DripState[AM_TESTDRIPMSG] -> DripStateC.DripState[unique("DripState")];<br>
 * </tt>
 * <p>
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

configuration DripC {
  provides {
    interface StdControl;
    interface Receive[uint8_t id];
    interface Drip[uint8_t id];
  }
  uses {
    interface DripState[uint8_t id];
  }
}

implementation {
  components 
    DripM, 
    DripStateC,
    GenericComm as Comm, 
    TimerC, 
    RandomLFSR, 
    LedsC as Leds;

  StdControl = DripM;
  Receive = DripM.Receive;
  Drip = DripM;
  DripState = DripM;
  
  DripM.SubControl -> Comm;
  DripM.SubControl -> TimerC;
  DripM.SubControl -> DripStateC;

  DripM.DripStateMgr -> DripStateC.DripStateMgr;

  DripM.ReceiveMsg -> Comm.ReceiveMsg[AM_DRIPMSG];
  DripM.SendMsg -> Comm.SendMsg[AM_DRIPMSG];

  DripM.SendTimer -> TimerC.Timer[unique("Timer")];

  DripM.Leds -> Leds;
  
  DripM.Random -> RandomLFSR;
}


--- NEW FILE: DripM.nc ---
//$Id: DripM.nc,v 1.1 2005/10/27 21:29:43 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 Drip;

/**
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

module DripM {
  provides {
    interface StdControl;
    interface Receive[uint8_t id];
    interface Drip[uint8_t id];
  }
  uses {
    interface StdControl as SubControl;

    interface DripState[uint8_t id];
    interface DripStateMgr;

    interface ReceiveMsg;
    interface SendMsg;

    interface Timer as SendTimer;
    interface Random;
    interface Leds;
  }
}

implementation {

  TOS_Msg msgBuf;
  bool msgBufBusy;

  command result_t StdControl.init() {
    msgBufBusy = FALSE;
    return call SubControl.init();
  }
  
  command result_t StdControl.start() {
    call SendTimer.start(TIMER_ONE_SHOT, 
			 call Random.rand() % DRIP_TIMER_PERIOD);
    return call SubControl.start();
  }
  
  command result_t StdControl.stop() {
    call SendTimer.stop();
    return SUCCESS;
  }

  command result_t Drip.init[uint8_t id]() {
    call DripState.init[id](id);
    return SUCCESS;
  }

  command result_t Drip.change[uint8_t id]() {
    return call DripState.incrementSeqno[id]();    
  }
  
  command result_t Drip.setSeqno[uint8_t id](uint16_t seqno) {
    return call DripState.setSeqno[id](seqno);
  }

  event result_t SendTimer.fired() {

    TOS_MsgPtr pMsgBuf = &msgBuf;
    DripMsg *dripMsg = (DripMsg*) pMsgBuf->data;
    uint8_t readyKey;

    call DripStateMgr.updateCounters();

    readyKey = call DripStateMgr.findReadyEntry(); 

    if (readyKey != DRIP_INVALID_KEY) {

      if (!msgBufBusy) {

	msgBufBusy = TRUE;

	if (!signal Drip.rebroadcastRequest[readyKey](pMsgBuf, dripMsg->data)) {
	  msgBufBusy = FALSE;
	  call DripState.entrySent[readyKey]();
	} else {
	  dbg(DBG_USR1, "Sending id: %d\n", readyKey);
	}
      }
    }
    
    call SendTimer.start(TIMER_ONE_SHOT, DRIP_TIMER_PERIOD);
    
    return SUCCESS;
  }

  command result_t Drip.rebroadcast[uint8_t id](TOS_MsgPtr msg,
						void *pData,
						uint8_t len) {
    
    /* msg does not matter right now, because there's only one buf
       they might have been filling. It will matter if we 
       acquire the buf from a lower layer, or if we have a pool. */

    TOS_MsgPtr pMsgBuf = &msgBuf;
    DripMsg *dripMsg = (DripMsg*) pMsgBuf->data;
    result_t result;
    
    if (!msgBufBusy)
      return FAIL;

    call DripState.fillMetadata[id](&dripMsg->metadata);

    result = call SendMsg.send(TOS_BCAST_ADDR, 
			       offsetof(DripMsg,data) + len,
			       pMsgBuf);

    if (result == SUCCESS) {
      call DripState.entrySent[id]();
    } else {
      dbg(DBG_USR1, "DripM: radio busy\n");
      msgBufBusy = FALSE;
    }
    
    return result;
  }

  event result_t SendMsg.sendDone(TOS_MsgPtr pMsg, 
				  result_t success) {

    if (msgBufBusy == TRUE) {
      msgBufBusy = FALSE;      
    }

    return SUCCESS;
  }

  event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr pMsg) {
    
    TOS_MsgPtr retMsg = pMsg;
    DripMsg *dripMsg = (DripMsg*) pMsg->data;

    dbg(DBG_USR1, "Received msg(id=%d, seqno=%d)\n",
	dripMsg->metadata.id, dripMsg->metadata.seqno);

    if (call DripState.newMsg[dripMsg->metadata.id](dripMsg->metadata)) {

      dripMsg->metadata.seqno = 
	call DripState.getSeqno[dripMsg->metadata.id]();

      retMsg = signal Receive.receive[dripMsg->metadata.id]
	(pMsg, dripMsg->data, pMsg->length - offsetof(DripMsg,data));
    }
    
    return retMsg;
  }

  default event TOS_MsgPtr Receive.receive[uint8_t id](TOS_MsgPtr msg, 
						       void* payload, 
						       uint16_t payloadLen) {
    return msg;
  }

  default event result_t Drip.rebroadcastRequest[uint8_t id](TOS_MsgPtr msg, 
							     void *payload) {
    return FAIL;
  }
  
  default command result_t DripState.init[uint8_t localKey](uint8_t globalKey) {
    return FAIL;
  }

  default command uint16_t DripState.getSeqno[uint8_t localKey]() {
    return DRIP_SEQNO_OLDEST;
  }

  default command result_t DripState.incrementSeqno[uint8_t localKey]() {
    return FAIL;
  }

  default command result_t DripState.entrySent[uint8_t localKey]() {
    return FAIL;
  }

  default command bool DripState.newMsg[uint8_t localKey](DripMetadata incomingMetadata) {
    return FALSE;
  }

  default command result_t DripState.fillMetadata[uint8_t localKey](DripMetadata *metadata) {
    return FAIL;
  }

}










--- NEW FILE: DripSend.h ---
//$Id: DripSend.h,v 1.1 2005/10/27 21:29:43 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."
 */

/**
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

enum {
  AM_DRIPSEND = 75,
};

typedef struct AddressMsg {
  uint16_t source;
  uint16_t dest;
  uint8_t  data[0];
} AddressMsg;


--- NEW FILE: DripSendC.nc ---
//$Id: DripSendC.nc,v 1.1 2005/10/27 21:29:43 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."
 */

/**
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

includes DripSend;

generic configuration DripSendC(uint8_t channel) {
  provides interface StdControl;
  provides interface Send;
  provides interface SendMsg;
  provides interface Receive;
}
implementation {

  components new DripSendM();

  components DripC;
  components DripStateC;
  components GroupManagerC;
  components LedsC;

  StdControl = DripSendM;
  StdControl = DripC;

  Send = DripSendM;
  SendMsg = DripSendM;
  Receive = DripSendM;
  
  DripSendM.DripReceive -> DripC.Receive[channel];
  DripSendM.Drip -> DripC.Drip[channel];
  DripC.DripState[channel] -> DripStateC.DripState[unique("DripState")];

  DripSendM.GroupManager -> GroupManagerC;
  DripSendM.Leds -> LedsC;
}

--- NEW FILE: DripSendM.nc ---
//$Id: DripSendM.nc,v 1.1 2005/10/27 21:29:43 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."
 */

/**
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

generic module DripSendM() {
  provides interface StdControl;
  provides interface Send;
  provides interface SendMsg;
  provides interface Receive;

  uses interface Receive as DripReceive;
  uses interface Drip;
  uses interface GroupManager;
  uses interface Leds;
}
implementation {
  
  enum {
    DRIPSEND_OUTBUF_SIZE = TOSH_DATA_LENGTH - offsetof(DripMsg,data),
  };

  TOS_MsgPtr msgHolder;
  uint8_t outBuf[DRIPSEND_OUTBUF_SIZE];
  uint8_t outLength;
  bool outBufBusy;

  uint16_t receivedMsgs;
  uint16_t forwardedMsgs;

  task void sendDoneTask();
  task void sendMsgDoneTask();

  command result_t StdControl.init() {
    call Drip.init();
    return SUCCESS;
  }

  command result_t StdControl.start() { return SUCCESS; }
  command result_t StdControl.stop() { return SUCCESS; }

  command void* Send.getBuffer(TOS_MsgPtr pMsg, uint16_t* length) {
    DripMsg* dripMsg = (DripMsg*) &pMsg->data[0];
    AddressMsg* addressMsg = (AddressMsg*) &dripMsg->data[0];

    *length = TOSH_DATA_LENGTH - 
      offsetof(DripMsg,data) - offsetof(AddressMsg, data);
    
    return &addressMsg->data[0];
  }

  command result_t Send.send(TOS_MsgPtr msg, uint16_t length) {

    DripMsg* dripMsgIn = (DripMsg*) &msg->data[0];
    AddressMsg* addressMsgIn = (AddressMsg*) &dripMsgIn->data[0];
    AddressMsg* addressMsgOut = (AddressMsg*) &outBuf[0];
    
    if (outBufBusy) {
      return FAIL;
    }

    memcpy(addressMsgOut, addressMsgIn, length);

    outLength = length;
    msgHolder = msg;

    dbg(DBG_USR1, "Addrmsg = %x, addrIn->dest=%d\n", &dripMsgIn->data[0],
	addressMsgIn->dest);

    dbg(DBG_USR1, "DripSendM: Bridge-sending a message to group %d, length=%d\n", 
	addressMsgOut->dest, length);

    call Drip.change();

    post sendDoneTask();
    return SUCCESS;
  }

  command result_t SendMsg.send(uint16_t dest, uint8_t length, TOS_MsgPtr msg) {

    DripMsg* dripMsgIn = (DripMsg*) &msg->data[0];
    AddressMsg* addressMsgIn = (AddressMsg*) &dripMsgIn->data[0];
    AddressMsg* addressMsgOut = (AddressMsg*) &outBuf[0];

    if (outBufBusy) {
      return FAIL;
    }

    addressMsgOut->source = TOS_LOCAL_ADDRESS;
    addressMsgOut->dest = dest;
    
    memcpy(&addressMsgOut->data[0], &addressMsgIn->data[0], length);

    dbg(DBG_USR1, "Addrmsg = %x, addrIn->dest=%d\n", &dripMsgIn->data[0],
	addressMsgIn->dest);

    outLength = offsetof(AddressMsg,data) + length;
    msgHolder = msg;

    dbg(DBG_USR1, "DripSendM: Sending a message to group %d\n", 
	addressMsgOut->dest);

    call Drip.change();

    post sendMsgDoneTask();
    return SUCCESS;
  }

  task void sendDoneTask() {
    signal Send.sendDone(msgHolder, SUCCESS);
    outBufBusy = FALSE;
  }

  task void sendMsgDoneTask() {
    signal SendMsg.sendDone(msgHolder, SUCCESS);
    outBufBusy = FALSE;
  }

  event result_t Drip.rebroadcastRequest(TOS_MsgPtr msg, void *pData) {

    AddressMsg* addressMsgOut = (AddressMsg*) &outBuf[0];

    if (call GroupManager.isForwarder(addressMsgOut->dest)) {
      dbg(DBG_USR1, "DripSendM: Forwarding a message for group %d\n", 
	  addressMsgOut->dest);

      call Leds.greenToggle();
      
      memcpy(pData, &outBuf[0], outLength);

      forwardedMsgs++;

      call Drip.rebroadcast(msg, pData, outLength);
      return SUCCESS;
      
    } else {
      return FAIL;
    }
  }

  event TOS_MsgPtr DripReceive.receive(TOS_MsgPtr msg, void* payload, 
				       uint16_t payloadLen) {

    AddressMsg* addressMsgIn = (AddressMsg*) payload;
    TOS_MsgPtr pMsg = msg;
    
//    dbg(DBG_USR1, "DripSendM: Storing a message for group %d\n", addressMsgIn->dest);
    memcpy(&outBuf[0], payload, payloadLen);
    outLength = payloadLen;

    if (call GroupManager.isMember(addressMsgIn->dest)) {
      dbg(DBG_USR1, "DripSendM: Receiving a message dest=%d source=%d\n", 
	  addressMsgIn->dest, addressMsgIn->source);

      call Leds.yellowToggle();

      receivedMsgs++;
    
      pMsg = signal Receive.receive(msg, &addressMsgIn->data[0], 
				    payloadLen - offsetof(AddressMsg, data));
    } else {
//      dbg(DBG_USR1, "DripSendM: NOT receiving a message for group %d\n", addressMsgIn->dest);
    }

    return pMsg;
  }
}



--- NEW FILE: DripState.nc ---
//$Id: DripState.nc,v 1.1 2005/10/27 21:29:43 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."
 *
 */

/**
 * DripState is the per-client interface between the Drip component and the
 * DripStateC component, which stores the timing parameters needed for
 * the retransmission algorithm.
 * <p>
 * You do not need to call any functions in this interface, but you
 * must wire DripC to DripStateC once for each channel your component is
 * using, like this:
 * <p>
 * <tt>
 * TestDripM.Drip -> DripC.Drip[AM_TESTDRIPMSG];<br>
 * DripC.DripState[AM_TESTDRIPMSG] -> DripStateC.DripState[unique("DripState")];<br>
 * </tt>
 * <p>
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

interface DripState {

  command result_t init(uint8_t globalKey);
  command uint16_t getSeqno();
  command result_t setSeqno(uint16_t seqno);
  command result_t incrementSeqno();

  command result_t entrySent();
  command bool newMsg(DripMetadata incomingMetadata);
  command result_t fillMetadata(DripMetadata *metadata);
}

--- NEW FILE: DripStateC.nc ---
//$Id: DripStateC.nc,v 1.1 2005/10/27 21:29:43 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."
 */

/**
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

configuration DripStateC {
  provides {
    interface StdControl;
    interface DripState[uint8_t local];
    interface DripStateMgr;
  } 
}

implementation {
  components DripStateM, RandomLFSR;

  StdControl = DripStateM;
  DripState = DripStateM;
  DripStateMgr = DripStateM;

  DripStateM.Random -> RandomLFSR;
}

--- NEW FILE: DripStateM.nc ---
//$Id: DripStateM.nc,v 1.1 2005/10/27 21:29:43 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 Drip;

/**
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

module DripStateM {
  provides {
    interface StdControl;
    interface DripState[uint8_t local];
    interface DripStateMgr;
  }
  uses {
    interface Random;
  }
}

implementation {

  DripCacheEntry dripCache[DRIP_CACHE_ENTRIES];

  void printCacheEntry(DripCacheEntry *entry);
  void printCache();
  void trickleReset(DripCacheEntry *dripEntry);
  void trickleSet(DripCacheEntry *dripEntry);
  void incrementSeqno(DripCacheEntry *dripEntry);

  command result_t StdControl.init() {
    return SUCCESS;
  }

  command result_t StdControl.start() {
    return SUCCESS;
  }

  command result_t StdControl.stop() {
    return SUCCESS;
  }

  command result_t DripState.init[uint8_t localKey](uint8_t globalKey) {
    DripCacheEntry *dripEntry = &dripCache[localKey];
    
    dripEntry->metadata.id = globalKey;
    dripEntry->metadata.seqno = DRIP_SEQNO_FIRST;

    trickleReset(dripEntry);
    dbg(DBG_USR1, "INIT: ");
    printCacheEntry(dripEntry);

    return SUCCESS;
  }

  command uint16_t DripState.getSeqno[uint8_t localKey]() {
    DripCacheEntry *dripEntry = &dripCache[localKey];
    
    return dripEntry->metadata.seqno;
  }

  command result_t DripState.setSeqno[uint8_t localKey](uint16_t seqno) {
    DripCacheEntry *dripEntry = &dripCache[localKey];

    uint16_t trueSeqno = seqno & ~DRIP_WAKEUP_BIT;

    if (trueSeqno != DRIP_SEQNO_OLDEST && trueSeqno != DRIP_SEQNO_NEWEST) {
      dripEntry->metadata.seqno = seqno;
      return SUCCESS;
    }

    return FAIL;
  }

  command result_t DripState.incrementSeqno[uint8_t localKey]() {
    DripCacheEntry *dripEntry = &dripCache[localKey];

    incrementSeqno(dripEntry);

    trickleReset(dripEntry);

    return SUCCESS;
  }

  void incrementSeqno(DripCacheEntry *dripEntry) {
    dripEntry->metadata.seqno++;
    dripEntry->metadata.seqno++;
    
    // Seqno 0 means that the seqno is unknown, and should only be seen
    // in a message coming in from the UART.
    while (((dripEntry->metadata.seqno & ~DRIP_WAKEUP_BIT) == 
	    DRIP_SEQNO_OLDEST)
	   ||
	   ((dripEntry->metadata.seqno & ~DRIP_WAKEUP_BIT) == 
	    DRIP_SEQNO_NEWEST) 
	   ||
	   ((dripEntry->metadata.seqno & ~DRIP_WAKEUP_BIT) == 
	    DRIP_SEQNO_UNKNOWN))
    {
      dripEntry->metadata.seqno++;
      dripEntry->metadata.seqno++;
    }
  }

  command result_t DripState.entrySent[uint8_t localKey]() {
    DripCacheEntry *dripEntry = &dripCache[localKey];
    dripEntry->trickleState = DRIP_POST_SEND;

    return SUCCESS;
  }

  command bool DripState.newMsg[uint8_t localKey](DripMetadata incomingMetadata) {
    DripCacheEntry *dripEntry = &dripCache[localKey];

    uint16_t incomingSeqno = incomingMetadata.seqno & ~DRIP_WAKEUP_BIT;
    uint16_t currentSeqno = dripEntry->metadata.seqno & ~DRIP_WAKEUP_BIT;
 
    dbg(DBG_USR1,"DripState received: currentSeqNo=%d, incomingSeqNo=%d\n",currentSeqno, incomingSeqno);

    if ((currentSeqno == DRIP_SEQNO_UNKNOWN &&
	 incomingSeqno != DRIP_SEQNO_UNKNOWN &&
	 incomingSeqno != DRIP_SEQNO_OLDEST) ||
	(currentSeqno != DRIP_SEQNO_UNKNOWN &&
	 incomingSeqno != DRIP_SEQNO_UNKNOWN &&
	 incomingSeqno != DRIP_SEQNO_OLDEST &&
	 ((int16_t)(incomingSeqno - currentSeqno) > 0 ||
	  incomingSeqno == DRIP_SEQNO_NEWEST))) {

      /* my entry is older. save new data. */

      if (incomingSeqno == DRIP_SEQNO_NEWEST) {
	/* It's coming in from outside, and does not know the seqno. 
	   Give it an incremented seqno. */

	incrementSeqno(dripEntry);

	// if the new seqno and the current seqno are different in
	// their wakeup status, increment the current seqno once more
	// to make them match.

	if ((dripEntry->metadata.seqno & DRIP_WAKEUP_BIT) != 
	    (incomingMetadata.seqno & DRIP_WAKEUP_BIT)) {
	  dripEntry->metadata.seqno++;
	}
	
      } else {
	
	dripEntry->metadata.seqno = incomingMetadata.seqno;
      }

      trickleReset(dripEntry);

      return TRUE;
      
    } else if (((int16_t)(incomingSeqno - currentSeqno) == 0) && 
	       incomingSeqno != DRIP_SEQNO_OLDEST) {
      
      /* my entry is equal. suppress. */
      
      dripEntry->trickleSuppress = TRUE;

    } else {
      
      /* my entry is newer. rebroadcast. */

      trickleReset(dripEntry);
    }

    return FALSE;
  }

  command result_t DripState.fillMetadata[uint8_t localKey](DripMetadata* metadata) {
    DripCacheEntry *dripEntry = &dripCache[localKey];
    
    *metadata = dripEntry->metadata;
    return SUCCESS;
  }

  command result_t DripStateMgr.updateCounters() {

    /*
      For each entry in the cache:
        Decrement the countdown timer.
	If the countdown timer goes below the send time and we haven't
	sent yet:
	  If we have been suppressed, prevent sending.
  	If the countdown timer goes to 0, double the trickle timer.
    */
	
    uint8_t i;

    for(i = 0; i < DRIP_CACHE_ENTRIES; i++) {

      /*      
	      dbg(DBG_USR1, "COUNT:");
	      printCacheEntry(&dripCache[i]);
      */

      if (dripCache[i].trickleCountdown > 0)
	dripCache[i].trickleCountdown--;
      
      if (dripCache[i].trickleCountdown <= dripCache[i].trickleAnnounce &&
	  dripCache[i].trickleState == DRIP_PRE_SEND) {
	
	if (dripCache[i].trickleSuppress) {
	  dripCache[i].trickleState = DRIP_POST_SEND;
	}

      } else if (dripCache[i].trickleCountdown == 0) {
	
	if (dripCache[i].trickleStage < DRIP_MAX_SEND_INTERVAL)
	  dripCache[i].trickleStage++;
	
	trickleSet(&dripCache[i]);
      }
    }

    return SUCCESS;
  }

  command uint8_t DripStateMgr.findReadyEntry() {
    uint8_t i;

    for(i = 0; i < DRIP_CACHE_ENTRIES; i++) {
      if (dripCache[i].trickleCountdown <= dripCache[i].trickleAnnounce &&
	  dripCache[i].trickleState == DRIP_PRE_SEND) {      
//	dbg(DBG_USR1, "READY: ");
//	printCacheEntry(&dripCache[i]);
	return dripCache[i].metadata.id;
      }
    }
    
    return DRIP_INVALID_KEY;
  }

  void trickleReset(DripCacheEntry *dripEntry) {

    dripEntry->trickleStage = DRIP_MIN_SEND_INTERVAL;
    trickleSet(dripEntry);
  }

  void trickleSet(DripCacheEntry *dripEntry) {

    dripEntry->trickleCountdown = 1 << dripEntry->trickleStage;
    
    if (dripEntry->trickleCountdown < 4) {
      dripEntry->trickleAnnounce = 0;
    } else {
      dripEntry->trickleAnnounce = 
	call Random.rand() % (dripEntry->trickleCountdown / 2);
    }

    dripEntry->trickleSuppress = FALSE;    
    dripEntry->trickleState = DRIP_PRE_SEND;
  }
    
  void printCacheEntry(DripCacheEntry *entry) {
#ifdef PLATFORM_PC
    dbg(DBG_USR1, "@%lld (key=0x%x, seqno=%d), tstage=%d, tcount=%d, tannounce=%d, ts=%d\n", tos_state.tos_time, entry->metadata.id, entry->metadata.seqno, entry->trickleStage, entry->trickleCountdown, entry->trickleAnnounce, entry->trickleState);
#endif
  }

  void printCache() {
    uint8_t i;
    for (i = 0; i < DRIP_CACHE_ENTRIES; i++) {
      printCacheEntry(&dripCache[i]);
    }
  }

  
}

--- NEW FILE: DripStateMgr.nc ---
//$Id: DripStateMgr.nc,v 1.1 2005/10/27 21:29:43 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."
 */

/**
 * DripStateMgr is the all-clients interface between the Drip component and the
 * DripStateC component, which stores the timing parameters needed for
 * the retransmission algorithm.
 * <p>
 * @author Gilman Tolle <get at cs.berkeley.edu>
 */

interface DripStateMgr {
  command result_t updateCounters();
  command uint8_t findReadyEntry();
}



More information about the Tinyos-commits mailing list