? tcheck-latest.patch
? tinyos_adc.patch
? apps/MultihopOscilloscope/LiveViolating1.txt
? apps/MultihopOscilloscope/StatisticData.txt
? apps/MultihopOscilloscope/TOSSIM.py
? apps/MultihopOscilloscope/TOSSIM.pyc
? apps/MultihopOscilloscope/app.xml
? apps/MultihopOscilloscope/build
? apps/MultihopOscilloscope/meyer-heavy.txt
? apps/MultihopOscilloscope/out
? apps/MultihopOscilloscope/preprocessing
? apps/MultihopOscilloscope/propertyWiring.txt
? apps/MultihopOscilloscope/sample
? apps/MultihopOscilloscope/sample.tar.gz
? apps/MultihopOscilloscope/simbuild
? apps/MultihopOscilloscope/test.py
? apps/MultihopOscilloscope/topo.txt
? apps/Oscilloscope/build
? apps/RadioCountToLeds/TOSSIM.py
? apps/RadioCountToLeds/app.xml
? apps/RadioCountToLeds/simbuild
? apps/tests/TestDhv/DhvData.class
? apps/tests/TestDhv/DhvData.java
? apps/tests/TestDhv/DhvDataMsg.class
? apps/tests/TestDhv/DhvDataMsg.java
? apps/tests/TestDhv/DhvDataMsg.py
? apps/tests/TestDhv/DhvInject.class
? apps/tests/TestDhv/DhvMsg.class
? apps/tests/TestDhv/DhvMsg.java
? apps/tests/TestDhv/DhvMsg.py
? apps/tests/TestDhv/DhvTestMsg.class
? apps/tests/TestDhv/DhvTestMsg.java
? apps/tests/TestDhv/TOSSIM.py
? apps/tests/TestDhv/app.xml
? apps/tests/TestDhv/property
? apps/tests/TestDhv/simbuild
? apps/tests/TestDip/DipData.class
? apps/tests/TestDip/DipData.java
? apps/tests/TestDip/DipDataMsg.class
? apps/tests/TestDip/DipDataMsg.java
? apps/tests/TestDip/DipDataMsg.py
? apps/tests/TestDip/DipInject.class
? apps/tests/TestDip/DipMsg.class
? apps/tests/TestDip/DipMsg.java
? apps/tests/TestDip/DipMsg.py
? apps/tests/TestDip/TOSSIM.py
? apps/tests/TestDip/TestDipC.nc
? apps/tests/TestDip/TestDipP.nc
? apps/tests/TestDip/app.xml
? apps/tests/TestDip/property
? apps/tests/TestDip/simbuild
? apps/tests/TestDissemination/LivenessFulfill.txt
? apps/tests/TestDissemination/StatisticData.txt
? apps/tests/TestDissemination/TOSSIM.py
? apps/tests/TestDissemination/TOSSIM.pyc
? apps/tests/TestDissemination/app.xml
? apps/tests/TestDissemination/meyer-heavy.txt
? apps/tests/TestDissemination/out
? apps/tests/TestDissemination/preprocessing
? apps/tests/TestDissemination/property
? apps/tests/TestDissemination/propertyWiring.txt
? apps/tests/TestDissemination/simbuild
? apps/tests/TestSerial/BugFile.txt
? apps/tests/TestSerial/LiveViolating1.txt
? apps/tests/TestSerial/LiveViolating5.txt
? apps/tests/TestSerial/LivenessFulfill.txt
? apps/tests/TestSerial/StatisticData.txt
? apps/tests/TestSerial/TOSSIM.py
? apps/tests/TestSerial/TOSSIM.pyc
? apps/tests/TestSerial/app.xml
? apps/tests/TestSerial/simbuild
? apps/tests/TestSerial/test.py
? support/sdk/python/tinyos/__init__.pyc
? support/sdk/python/tinyos/tossim/TossimApp.pyc
? support/sdk/python/tinyos/tossim/TossimNescDecls.pyc
? support/sdk/python/tinyos/tossim/__init__.pyc
? tos/ :q
? tos/chips/atm128/adc/sim
? tos/chips/cc2420/sim
? tos/chips/cc2420/control/sim
? tos/chips/cc2420/interfaces/sim
? tos/chips/cc2420/lowpan/sim
? tos/chips/cc2420/packet/sim
? tos/chips/cc2420/receive/sim
? tos/chips/cc2420/spi/sim
? tos/chips/cc2420/transmit/sim
? tos/lib/ftsp/property
? tos/lib/net/6lowpan/tmp
? tos/lib/serial/property
? tos/lib/tossim/tmp
Index: apps/MultihopOscilloscope/Makefile
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/MultihopOscilloscope/Makefile,v
retrieving revision 1.6
diff -u -b -p -r1.6 Makefile
--- apps/MultihopOscilloscope/Makefile	24 Sep 2007 14:02:28 -0000	1.6
+++ apps/MultihopOscilloscope/Makefile	9 Jul 2010 19:45:12 -0000
@@ -1,4 +1,6 @@
 COMPONENT=MultihopOscilloscopeAppC
 CFLAGS += -I$(TOSDIR)/lib/net/ -I$(TOSDIR)/lib/net/ctp  -I$(TOSDIR)/lib/net/4bitle
 
+PFLAGS += -fnesc-mc-state
+
 include $(MAKERULES)
Index: apps/MultihopOscilloscope/MultihopOscilloscopeC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/MultihopOscilloscope/MultihopOscilloscopeC.nc,v
retrieving revision 1.6
diff -u -b -p -r1.6 MultihopOscilloscopeC.nc
--- apps/MultihopOscilloscope/MultihopOscilloscopeC.nc	8 Apr 2010 04:23:39 -0000	1.6
+++ apps/MultihopOscilloscope/MultihopOscilloscopeC.nc	9 Jul 2010 19:45:12 -0000
@@ -225,6 +225,7 @@ implementation {
      - read next sample
   */
   event void Timer.fired() {
+    dbg("Multihop", "Currently, the timer fired... the reading is %d\n", reading);
     if (reading == NREADINGS) {
       if (!sendbusy) {
 	oscilloscope_t *o = (oscilloscope_t *)call Send.getPayload(&sendbuf, sizeof(oscilloscope_t));
@@ -261,6 +262,7 @@ implementation {
   }
 
   event void Read.readDone(error_t result, uint16_t data) {
+    dbg("Multihop", "Interrupt triggers readDone happen, the reading is %d\n", reading);
     if (result != SUCCESS) {
       data = 0xffff;
       report_problem();
Index: apps/Oscilloscope/OscilloscopeC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/Oscilloscope/OscilloscopeC.nc,v
retrieving revision 1.6
diff -u -b -p -r1.6 OscilloscopeC.nc
Index: apps/tests/TestDhv/TestDhvP-Master.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/tests/TestDhv/TestDhvP-Master.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 TestDhvP-Master.nc
--- apps/tests/TestDhv/TestDhvP-Master.nc	26 May 2010 22:00:33 -0000	1.2
+++ apps/tests/TestDhv/TestDhvP-Master.nc	9 Jul 2010 19:45:12 -0000
@@ -32,6 +32,7 @@ implementation {
   uint8_t newCount = N;
   */
   // ... NEWCOUNT
+  bool dissemComplete = FALSE; // This variable is added to help check user-specified properties.
 
   void bookkeep();
 
@@ -96,6 +97,7 @@ implementation {
 
     if(newCount == count) {
       dbg("TestDhvP","Dissemination COMPLETE!\n");
+      dissemComplete = TRUE;
       call Leds.set(7);
     }
     
Index: apps/tests/TestDip/TestDipP-Master.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/tests/TestDip/TestDipP-Master.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 TestDipP-Master.nc
--- apps/tests/TestDip/TestDipP-Master.nc	15 Dec 2009 01:12:47 -0000	1.3
+++ apps/tests/TestDip/TestDipP-Master.nc	9 Jul 2010 19:45:12 -0000
@@ -32,6 +32,7 @@ implementation {
   uint8_t newCount = N;
   */
   // ... NEWCOUNT
+  bool dissemComplete = FALSE; // This variable is added to help check user-specified properties.
 
   void bookkeep();
 
@@ -95,6 +96,7 @@ implementation {
 
     if(newCount == count) {
       dbg("TestDipP","Dissemination COMPLETE!\n");
+      dissemComplete = TRUE;
       call Leds.set(7);
     }
     
Index: apps/tests/TestDissemination/TestDisseminationC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/tests/TestDissemination/TestDisseminationC.nc,v
retrieving revision 1.6
diff -u -b -p -r1.6 TestDisseminationC.nc
--- apps/tests/TestDissemination/TestDisseminationC.nc	18 Apr 2007 04:02:06 -0000	1.6
+++ apps/tests/TestDissemination/TestDisseminationC.nc	9 Jul 2010 19:45:12 -0000
@@ -65,6 +65,9 @@ module TestDisseminationC {
   uses interface Timer<TMilli>;
 }
 implementation {
+  bool dissemComplete32 = FALSE;
+  bool dissemComplete16 = FALSE;
+
   event void Boot.booted() {
     uint32_t initialVal32 = 123456;
     uint16_t initialVal16 = 1234;
@@ -118,6 +121,7 @@ implementation {
     if ( *newVal == 0xDEADBEEF ) {
       call Leds.led0Toggle();
       dbg("TestDisseminationC", "Received new correct 32-bit value @ %s.\n", sim_time_string());
+      dissemComplete32 = TRUE;
     }
     else {
       dbg("TestDisseminationC", "Received new incorrect 32-bit value.\n");
@@ -129,6 +133,7 @@ implementation {
     if ( *newVal == 0xABCD ) {
       call Leds.led1Toggle();
       dbg("TestDisseminationC", "Received new correct 16-bit value @ %s.\n", sim_time_string());
+      dissemComplete16 = TRUE;
     }
     else {
       dbg("TestDisseminationC", "Received new incorrect 16-bit value: 0x%hx\n", *newVal);
Index: apps/tests/TestMultihopLqi/MultihopOscilloscopeC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/apps/tests/TestMultihopLqi/MultihopOscilloscopeC.nc,v
retrieving revision 1.4
diff -u -b -p -r1.4 MultihopOscilloscopeC.nc
--- apps/tests/TestMultihopLqi/MultihopOscilloscopeC.nc	19 Feb 2008 19:49:31 -0000	1.4
+++ apps/tests/TestMultihopLqi/MultihopOscilloscopeC.nc	9 Jul 2010 19:45:12 -0000
@@ -296,6 +296,7 @@ implementation {
       data = 0xffff;
       report_problem();
     }
+    if(reading < NREADINGS)
     local.readings[reading++] = data;
   }
 
Index: support/make/sim-fast.extra
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/support/make/sim-fast.extra,v
retrieving revision 1.8
diff -u -b -p -r1.8 sim-fast.extra
--- support/make/sim-fast.extra	8 Apr 2010 04:27:24 -0000	1.8
+++ support/make/sim-fast.extra	9 Jul 2010 19:45:14 -0000
@@ -5,7 +5,12 @@ GCC=gcc
 GPP=g++
 OPTFLAGS = -g -O3
 LIBS = -lm -lstdc++ 
-PFLAGS += -tossim -fnesc-nido-tosnodes=1000 -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\) -DTOSSIM_NO_DEBUG
+PFLAGS += -tossim -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\) -DTOSSIM_NO_DEBUG
+ifdef MAKE_DEPUTY_FLAG
+	PFLAGS += -fnesc-nido-tosnodes=100  
+else
+	PFLAGS += -fnesc-nido-tosnodes=1000  
+endif
 WFLAGS = -Wno-nesc-data-race
 PYTHON_VERSION=2.5
 
@@ -59,7 +64,7 @@ sim-exe: builddir $(BUILD_EXTRA_DEPS) FO
 	@echo "  placing object files in $(BUILDDIR)"
 	@echo "  writing XML schema to $(XML)"
 	@echo "  compiling $(COMPONENT) to object file sim.o"
-	$(NCC) -c $(PLATFORM_FLAGS) -o $(OBJFILE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS) $(WFLAGS) $(COMPONENT).nc $(LDFLAGS)  $(DUMPTYPES) -fnesc-dumpfile=$(XML)
+	$(NCC) -c $(PLATFORM_FLAGS) $(NCC_SAFE_SIM_TINYOS_FLAGS) -o $(OBJFILE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS) $(WFLAGS) $(COMPONENT).nc $(LDFLAGS)  $(DUMPTYPES) -fnesc-dumpfile=$(XML)
 
 	@echo "  compiling Python support and C libraries into pytossim.o, tossim.o, and c-support.o"
 	$(GPP) -c $(PLATFORM_CC_FLAGS) $(PLATFORM_FLAGS) -o $(PYOBJFILE) $(OPTFLAGS) $(CFLAGS) $(PYFILE) -I$(PYDIR) -I$(SIMDIR) -DHAVE_CONFIG_H 
Index: support/make/sim-sf.extra
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/support/make/sim-sf.extra,v
retrieving revision 1.1
diff -u -b -p -r1.1 sim-sf.extra
--- support/make/sim-sf.extra	3 Oct 2007 02:09:59 -0000	1.1
+++ support/make/sim-sf.extra	9 Jul 2010 19:45:14 -0000
@@ -39,9 +39,14 @@ GCC=gcc
 GPP=g++
 OPTFLAGS = -g -O0
 LIBS = -lm -lstdc++ 
-PFLAGS += -tossim -fnesc-nido-tosnodes=1000 -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\) $(SF_FLAGS)
+PFLAGS += -tossim -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\) $(SF_FLAGS)
+ifdef MAKE_DEPUTY_FLAG
+	PFLAGS += -fnesc-nido-tosnodes=100
+else
+	PFLAGS += -fnesc-nido-tosnodes=1000 
+endif
 WFLAGS = -Wno-nesc-data-race
-PYTHON_VERSION=2.5
+PYTHON_VERSION=2.6
 
 BUILDDIR = simbuild/$(PLATFORM)
 
@@ -105,7 +110,7 @@ sim-exe: builddir $(BUILD_EXTRA_DEPS) FO
 	@echo "  placing object files in $(BUILDDIR)"
 	@echo "  writing XML schema to $(XML)"
 	@echo "  compiling $(COMPONENT) to object file sim.o"
-	$(NCC) -c $(PLATFORM_FLAGS) -o $(OBJFILE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS) $(WFLAGS) $(COMPONENT).nc $(LDFLAGS)  $(DUMPTYPES) -fnesc-dumpfile=$(XML)
+	$(NCC) -c $(PLATFORM_FLAGS) $(NCC_SAFE_SIM_TINYOS_FLAGS) -o $(OBJFILE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS) $(WFLAGS) $(COMPONENT).nc $(LDFLAGS)  $(DUMPTYPES) -fnesc-dumpfile=$(XML)
 
 	@echo "  compiling Python support and C libraries into pytossim.o, tossim.o, and c-support.o"
 	$(GPP) -c $(PLATFORM_CC_FLAGS) $(PLATFORM_FLAGS) -o $(PYOBJFILE) $(OPTFLAGS) $(CFLAGS) $(SIM_CFLAGS) $(SF_FLAGS) $(PYFILE) -I$(PYDIR) -I$(SIMDIR) -DHAVE_CONFIG_H 
Index: support/make/sim.extra
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/support/make/sim.extra,v
retrieving revision 1.14
diff -u -b -p -r1.14 sim.extra
--- support/make/sim.extra	14 Nov 2009 02:14:18 -0000	1.14
+++ support/make/sim.extra	9 Jul 2010 19:45:14 -0000
@@ -5,9 +5,14 @@ export GCC=gcc
 GPP=g++
 OPTFLAGS = -g -O0
 LIBS = -lm -lstdc++ 
-PFLAGS += -tossim -fnesc-nido-tosnodes=1000 -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\) -fnesc-gcc=$(GCC)
+PFLAGS += -tossim -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\)  
+ifdef MAKE_DEPUTY_FLAG
+	PFLAGS += -fnesc-nido-tosnodes=100 
+else
+	PFLAGS += -fnesc-nido-tosnodes=1000  
+endif
 WFLAGS = -Wno-nesc-data-race
-PYTHON_VERSION=2.5
+PYTHON_VERSION=2.6
 
 BUILDDIR   = simbuild/$(PLATFORM)
 CFILE    = $(BUILDDIR)/sim.c
@@ -66,7 +71,7 @@ sim-exe: builddir $(BUILD_EXTRA_DEPS) FO
 	@echo "  placing object files in $(BUILDDIR)"
 	@echo "  writing XML schema to $(XML)"
 	@echo "  compiling $(COMPONENT) to object file sim.o"
-	$(NCC) -c $(PLATFORM_FLAGS) -o $(OBJFILE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS) $(WFLAGS) $(COMPONENT).nc $(LDFLAGS)  $(DUMPTYPES) -fnesc-dumpfile=$(XML)
+	$(NCC) -c $(PLATFORM_FLAGS) $(NCC_SAFE_SIM_TINYOS_FLAGS) -o $(OBJFILE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS) $(WFLAGS) $(COMPONENT).nc $(LDFLAGS)  $(DUMPTYPES) -fnesc-dumpfile=$(XML)
 
 	@echo "  compiling Python support and C libraries into pytossim.o, tossim.o, and c-support.o"
 	$(GPP) -c $(PLATFORM_CC_FLAGS) $(PLATFORM_FLAGS) -o $(PYOBJFILE) $(OPTFLAGS) $(CFLAGS) $(PYFILE) -I$(PYDIR) -I$(SIMDIR) -DHAVE_CONFIG_H 
Index: support/make/avr/avr.rules
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/support/make/avr/avr.rules,v
retrieving revision 1.29
diff -u -b -p -r1.29 avr.rules
--- support/make/avr/avr.rules	17 Mar 2010 00:38:04 -0000	1.29
+++ support/make/avr/avr.rules	9 Jul 2010 19:45:14 -0000
@@ -24,8 +24,10 @@ HELP += $(AVR_HELP)
 
 ifdef MAKE_DEPUTY_FLAG
         NCC_SAFE_TINYOS_FLAGS = -DSAFE_TINYOS -I$(TOSDIR)/lib/safe -fnesc-deputy -fnesc-deputy-args='-I$(TOSDIR)/lib/safe/include --FLIDs=build/$(PLATFORM)/flids.txt --envmachine -DSAFE_TINYOS --nolib '
+	NCC_SAFE_SIM_TINYOS_FLAGS = -DSAFE_TINYOS -I$(TOSDIR)/lib/tossim -fnesc-deputy -fnesc-deputy-args=' -DSAFE_TINYOS --nolib ' 
 else
         NCC_SAFE_TINYOS_FLAGS =
+        NCC_SAFE_SIM_TINYOS_FLAGS =
 endif
 
 OBJCOPY = avr-objcopy
Index: tos/chips/atm128/pins/sim/Atm128GpioInterruptC.nc
===================================================================
RCS file: tos/chips/atm128/pins/sim/Atm128GpioInterruptC.nc
diff -N tos/chips/atm128/pins/sim/Atm128GpioInterruptC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/pins/sim/Atm128GpioInterruptC.nc	9 Jul 2010 19:45:14 -0000
@@ -0,0 +1,53 @@
+/// $Id: Atm128GpioInterruptC.nc,v 1.5 2008/06/26 04:39:03 regehr Exp $
+
+/**
+ * @author Phil Levis
+ */
+generic module Atm128GpioInterruptC() @safe() {
+
+  provides interface GpioInterrupt as Interrupt;
+  provides interface TriggerInterrupt as TriggerIntr;
+  uses interface HplAtm128Interrupt as Atm128Interrupt;
+
+}
+
+implementation {
+
+  error_t enable( bool rising ) {
+    atomic {
+      call Atm128Interrupt.disable();
+      call Atm128Interrupt.clear();
+      call Atm128Interrupt.edge( rising );
+      call Atm128Interrupt.enable();
+    }
+    return SUCCESS;
+  }
+
+  error_t enableIntr() {
+     call Atm128Interrupt.enableIntr();
+     return SUCCESS; 
+  }
+
+  async command error_t TriggerIntr.enableIntr() {
+     return enableIntr(); 
+  }
+
+  async command error_t Interrupt.enableRisingEdge() {
+    return enable( TRUE );
+  }
+
+
+  async command error_t Interrupt.enableFallingEdge() {
+    return enable( FALSE );
+  }
+
+  async command error_t Interrupt.disable() {
+    call Atm128Interrupt.disable();
+    return SUCCESS;
+  }
+
+  async event void Atm128Interrupt.fired() {
+    signal Interrupt.fired();
+  }
+
+}
Index: tos/chips/atm128/pins/sim/HplAtm128Interrupt.nc
===================================================================
RCS file: tos/chips/atm128/pins/sim/HplAtm128Interrupt.nc
diff -N tos/chips/atm128/pins/sim/HplAtm128Interrupt.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/pins/sim/HplAtm128Interrupt.nc	9 Jul 2010 19:45:14 -0000
@@ -0,0 +1,66 @@
+/// $Id: HplAtm128Interrupt.nc,v 1.4 2006/12/12 18:23:03 vlahan Exp $
+
+/* "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."
+ */
+
+/**
+ * Interface to an Atmega128 external interrupt pin
+ *
+ * @author Joe Polastre
+ * @author Martin Turon
+ */
+
+interface HplAtm128Interrupt
+{
+  /** 
+   * Enables ATmega128 hardware interrupt on a particular port
+   */
+  async command void enable();
+
+  /** 
+   * Disables ATmega128 hardware interrupt on a particular port
+   */
+  async command void disable();
+
+  /** 
+   * Clears the ATmega128 Interrupt Pending Flag for a particular port
+   */
+  async command void clear();
+
+  /** 
+   * Gets the current value of the input voltage of a port
+   *
+   * @return TRUE if the pin is set high, FALSE if it is set low
+   */
+  async command bool getValue();
+
+  /** 
+   * Sets whether the edge should be high to low or low to high.
+   * @param TRUE if the interrupt should be triggered on a low to high
+   *        edge transition, false for interrupts on a high to low transition
+   */
+  async command void edge(bool low_to_high);
+
+  async command void enableIntr();
+  /**
+   * Signalled when an interrupt occurs on a port
+   */
+  async event void fired();
+}
Index: tos/chips/atm128/pins/sim/HplAtm128InterruptC.nc
===================================================================
RCS file: tos/chips/atm128/pins/sim/HplAtm128InterruptC.nc
diff -N tos/chips/atm128/pins/sim/HplAtm128InterruptC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/pins/sim/HplAtm128InterruptC.nc	9 Jul 2010 19:45:14 -0000
@@ -0,0 +1,81 @@
+/// $Id: HplAtm128InterruptC.nc,v 1.4 2006/12/12 18:23:03 vlahan Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+#include <atm128hardware.h>
+
+/**
+ * Component providing access to all external interrupt pins on ATmega128.
+ * @author Martin Turon <mturon@xbow.com>
+ */
+
+configuration HplAtm128InterruptC
+{
+  // provides all the ports as raw ports
+  provides {
+    interface HplAtm128Interrupt as Int0;
+    interface HplAtm128Interrupt as Int1;
+    interface HplAtm128Interrupt as Int2;
+    interface HplAtm128Interrupt as Int3;
+    interface HplAtm128Interrupt as Int4;
+    interface HplAtm128Interrupt as Int5;
+    interface HplAtm128Interrupt as Int6;
+    interface HplAtm128Interrupt as Int7;
+  }
+}
+implementation
+{
+#define IRQ_PORT_D_PIN(bit) bit
+#define IRQ_PORT_E_PIN(bit) bit
+
+  components 
+    HplAtm128InterruptSigP as IrqVector,
+    new HplAtm128InterruptPinP(IRQ_PORT_D_PIN(0)) as IntPin0,
+    new HplAtm128InterruptPinP(IRQ_PORT_D_PIN(1)) as IntPin1,
+    new HplAtm128InterruptPinP(IRQ_PORT_D_PIN(2)) as IntPin2,
+    new HplAtm128InterruptPinP(IRQ_PORT_D_PIN(3)) as IntPin3,
+    new HplAtm128InterruptPinP(IRQ_PORT_E_PIN(4)) as IntPin4,
+    new HplAtm128InterruptPinP(IRQ_PORT_E_PIN(5)) as IntPin5,
+    new HplAtm128InterruptPinP(IRQ_PORT_E_PIN(6)) as IntPin6,
+    new HplAtm128InterruptPinP(IRQ_PORT_E_PIN(7)) as IntPin7;
+  
+  Int0 = IntPin0;
+  Int1 = IntPin1;
+  Int2 = IntPin2;
+  Int3 = IntPin3;
+  Int4 = IntPin4;
+  Int5 = IntPin5;
+  Int6 = IntPin6;
+  Int7 = IntPin7;
+
+  IntPin0.IrqSignal -> IrqVector.IntSig0;
+  IntPin1.IrqSignal -> IrqVector.IntSig1;
+  IntPin2.IrqSignal -> IrqVector.IntSig2;
+  IntPin3.IrqSignal -> IrqVector.IntSig3;
+  IntPin4.IrqSignal -> IrqVector.IntSig4;
+  IntPin5.IrqSignal -> IrqVector.IntSig5;
+  IntPin6.IrqSignal -> IrqVector.IntSig6;
+  IntPin7.IrqSignal -> IrqVector.IntSig7;
+
+}
+
Index: tos/chips/atm128/pins/sim/HplAtm128InterruptPinP.nc
===================================================================
RCS file: tos/chips/atm128/pins/sim/HplAtm128InterruptPinP.nc
diff -N tos/chips/atm128/pins/sim/HplAtm128InterruptPinP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/pins/sim/HplAtm128InterruptPinP.nc	9 Jul 2010 19:45:14 -0000
@@ -0,0 +1,62 @@
+/// $Id: HplAtm128InterruptPinP.nc,v 1.6 2008/06/23 20:25:15 regehr Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Interrupt interface access for interrupt capable GPIO pins.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ */
+generic module HplAtm128InterruptPinP (uint8_t bit) @safe()
+{
+  provides interface HplAtm128Interrupt as Irq;
+  uses interface HplAtm128InterruptSig as IrqSignal;
+}
+implementation
+{
+  inline async command bool Irq.getValue() { return (EIFR & (1 << bit)) != 0; }
+  inline async command void Irq.clear()    { EIFR = 1 << bit; }
+  inline async command void Irq.enable()   { EIMSK |= 1 << bit; }
+  inline async command void Irq.disable()  { EIMSK &= ~(1 << bit); }
+  inline async command void Irq.enableIntr()  { call IrqSignal.enableIntr(); }
+
+#define ctrl  (*TCAST(volatile uint8_t * ONE, ctrl_addr))
+
+  inline async command void Irq.edge(bool low_to_high) {
+    //ctrl |= 1 << edge1bit; // use edge mode
+    // and select rising vs falling
+    //if (low_to_high)
+    //  ctrl |= 1 << edge0bit;
+    //else
+    //  ctrl &= ~(1 << edge0bit);
+  }
+
+  /** 
+   * Forward the external interrupt event.  This ties the statically
+   * allocated interrupt vector SIG_INTERRUPT##bit to a particular
+   * pin passed in via the generic component instantiation.
+   */
+  async event void IrqSignal.fired() { signal Irq.fired(); }
+
+  default async event void Irq.fired() { }
+}
Index: tos/chips/atm128/pins/sim/HplAtm128InterruptSig.nc
===================================================================
RCS file: tos/chips/atm128/pins/sim/HplAtm128InterruptSig.nc
diff -N tos/chips/atm128/pins/sim/HplAtm128InterruptSig.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/pins/sim/HplAtm128InterruptSig.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,44 @@
+/// $Id: HplAtm128InterruptSig.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+
+/*
+ *  Copyright (c) 2004-2005 Crossbow Technology, Inc.
+ *  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 (updated) modification history and the author appear in
+ *  all copies of this source code.
+ *
+ *  Permission is also granted to distribute this software under the
+ *  standard BSD license as contained in the TinyOS distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS 
+ *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, 
+ *  OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+ *  THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Interface to an Atmega128 external interrupt pin that exposes just the
+ * interrupt vector routine for easy linking to generic components (see
+ * HplAtm128Interrupt for the full interface).
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @see HplAtm128Interrupt
+ */
+interface HplAtm128InterruptSig
+{
+  async command void enableIntr();
+  /**
+   * Signalled when an interrupt occurs on a pin
+   */
+  async event void fired();
+}
+
Index: tos/chips/atm128/pins/sim/HplAtm128InterruptSigP.nc
===================================================================
RCS file: tos/chips/atm128/pins/sim/HplAtm128InterruptSigP.nc
diff -N tos/chips/atm128/pins/sim/HplAtm128InterruptSigP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/pins/sim/HplAtm128InterruptSigP.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,153 @@
+/// $Id: HplAtm128InterruptSigP.nc,v 1.5 2008/06/26 04:39:03 regehr Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Interrupt interface access for interrupt capable GPIO pins.
+ * Exposes just the interrupt vector routine for 
+ * easy linking to generic components.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ */
+#include <sim_gain.h>
+
+module HplAtm128InterruptSigP @safe()
+{
+  provides interface HplAtm128InterruptSig as IntSig0;
+  provides interface HplAtm128InterruptSig as IntSig1;
+  provides interface HplAtm128InterruptSig as IntSig2;
+  provides interface HplAtm128InterruptSig as IntSig3;
+  provides interface HplAtm128InterruptSig as IntSig4;
+  provides interface HplAtm128InterruptSig as IntSig5;
+  provides interface HplAtm128InterruptSig as IntSig6;
+  provides interface HplAtm128InterruptSig as IntSig7;
+}
+implementation
+{
+  sim_event_t sim_sig6_intr;
+
+  default async event void IntSig0.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT0 ) {
+    signal IntSig0.fired();
+  }
+
+  async command void IntSig0.enableIntr() {
+  }
+
+  default async event void IntSig1.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT1 ) {
+    signal IntSig1.fired();
+  }
+
+  async command void IntSig1.enableIntr() {
+  }
+
+  default async event void IntSig2.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT2 ) {
+    signal IntSig2.fired();
+  }
+
+  async command void IntSig2.enableIntr() {
+  }
+
+  default async event void IntSig3.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT3 ) {
+    signal IntSig3.fired();
+  }
+
+  async command void IntSig3.enableIntr() {
+  }
+
+  default async event void IntSig4.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT4 ) {
+    signal IntSig4.fired();
+  }
+
+  async command void IntSig4.enableIntr() {
+  }
+
+  default async event void IntSig5.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT5 ) {
+    signal IntSig5.fired();
+  }
+
+  async command void IntSig5.enableIntr() {
+  }
+
+  default async event void IntSig6.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT6 ) {
+    signal IntSig6.fired();
+    sim_sig6_intr.mark = FALSE;
+  }
+
+  void sig6_interrupt_handle(sim_event_t* evt) {
+     /* Here just emulate the occurrence of sig6 interrupt*/ 
+     if(evt->cancelled) {
+        return;
+     }
+     dbg("HplAtm128Sig6P", "The sig6 interrupt happens here!\n");
+     SIG_INTERRUPT6(); 
+  }
+
+  void allocate_sig6_interrupt() {
+    dbg("HplAtm128Sig6P", "Allocated sig6 interrupt at 0x%p\n", &sim_sig6_intr);
+
+    sim_sig6_intr.mote = sim_node();
+    sim_sig6_intr.force = 0;
+    sim_sig6_intr.cancelled = 0;
+    sim_sig6_intr.time = sim_time() + 10000;   
+
+    sim_sig6_intr.handle = sig6_interrupt_handle;
+    sim_sig6_intr.type = INTERRUPT;
+    sim_sig6_intr.source = INT_INTERRUPT6;
+    sim_sig6_intr.cleanup = sim_queue_cleanup_none;
+    sim_sig6_intr.mark = TRUE;
+  }
+
+  void sim_gain_enable_intr(int dest) {
+    int prevNode = sim_node();
+    sim_set_node(dest);
+    allocate_sig6_interrupt();
+    sim_queue_insert(&sim_sig6_intr);
+    sim_set_node(prevNode);
+  }
+
+  async command void IntSig6.enableIntr() {
+    gain_entry_t* neighborEntry = sim_gain_first(sim_node());
+    dbg("HplAtm128Sig6P", "node %lu makes the neighboring nodes' receive events enable.\n", sim_node());
+
+    while (neighborEntry != NULL) {
+      int other = neighborEntry->mote;
+      sim_gain_enable_intr(other);
+      neighborEntry = sim_gain_next(neighborEntry);
+    }
+  }
+
+  default async event void IntSig7.fired() { }
+  AVR_ATOMIC_HANDLER( SIG_INTERRUPT7 ) {
+    signal IntSig7.fired();
+  }
+
+  async command void IntSig7.enableIntr() {
+  }
+}
Index: tos/chips/atm128/sim/Atm128Uart0C.nc
===================================================================
RCS file: tos/chips/atm128/sim/Atm128Uart0C.nc
diff -N tos/chips/atm128/sim/Atm128Uart0C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/sim/Atm128Uart0C.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCH ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Alec Woo <awoo@archrock.com>
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2006/12/12 18:23:02 $
+ */
+
+configuration Atm128Uart0C {
+  
+  provides interface StdControl;
+  provides interface UartByte;
+  provides interface UartStream;
+  uses interface Counter<TMicro, uint32_t>;
+  
+}
+
+implementation{
+  
+  components new Atm128UartP() as UartP;
+  StdControl = UartP;
+  UartByte = UartP;
+  UartStream = UartP;
+  UartP.Counter = Counter;
+  
+  components HplAtm128UartC as HplUartC;
+  UartP.HplUartTxControl -> HplUartC.Uart0TxControl;
+  UartP.HplUartRxControl -> HplUartC.Uart0RxControl;
+  UartP.HplUart -> HplUartC.HplUart0;
+  
+  components MainC;
+  MainC.SoftwareInit -> UartP;
+  
+}
Index: tos/chips/atm128/sim/Atm128UartP.nc
===================================================================
RCS file: tos/chips/atm128/sim/Atm128UartP.nc
diff -N tos/chips/atm128/sim/Atm128UartP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/sim/Atm128UartP.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCH ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Alec Woo <awoo@archrock.com>
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author Philip Levis <pal@cs.stanford.edu> (maintainer)
+ * @version $Revision: 1.7 $ $Date: 2008/06/23 20:25:15 $
+ *
+ * Modification @ 11/27 (pal): Folded in Alec's reimplementation
+ * from the -devel branch. Fixed bug in RX interrupts, where
+ * they were not enabled on start. Possibly due to alternative
+ * ARC TEP113 implementation that uses UartStream?
+ */
+
+#include <Timer.h>
+
+generic module Atm128UartP() @safe(){
+  
+  provides interface Init;
+  provides interface StdControl;
+  provides interface UartByte;
+  provides interface UartStream;
+  
+  uses interface StdControl as HplUartTxControl;
+  uses interface StdControl as HplUartRxControl;
+  uses interface HplAtm128Uart as HplUart;
+  uses interface Counter<TMicro, uint32_t>;
+  
+}
+
+implementation{
+  
+  norace uint16_t m_tx_len, m_rx_len;
+  norace uint8_t * m_tx_buf, * m_rx_buf;
+  norace uint16_t m_tx_pos, m_rx_pos;
+  norace uint16_t m_byte_time;
+  norace uint8_t m_rx_intr;
+  norace uint8_t m_tx_intr;
+  
+  command error_t Init.init() {
+    if (PLATFORM_BAUDRATE == 19200UL)
+      m_byte_time = 200; // 1 TMicor ~= 2.12 us, one byte = 417us ~= 200
+    else if (PLATFORM_BAUDRATE == 57600UL)
+      m_byte_time = 68;  // 1 TMicor ~= 2.12 us, one byte = 138us ~= 65
+    return SUCCESS;
+  }
+  
+  command error_t StdControl.start(){
+    /* make sure interupts are off and set flags */
+    call HplUart.disableTxIntr();
+    call HplUart.disableRxIntr();
+    m_rx_intr = 0;
+    m_tx_intr = 0;
+
+    /* enable tx/rx */
+    call HplUartTxControl.start();
+    call HplUartRxControl.start();
+
+    // Bug fix: pal 11/26/07: RX interrupts should be enabled on start
+    call HplUart.enableRxIntr();
+    return SUCCESS;
+  }
+
+  command error_t StdControl.stop(){
+    call HplUartTxControl.stop();
+    call HplUartRxControl.stop();
+    return SUCCESS;
+  }
+
+  async command error_t UartStream.enableReceiveInterrupt(){
+    atomic{
+      m_rx_intr = 3;
+      call HplUart.enableRxIntr();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t UartStream.disableReceiveInterrupt(){
+    atomic{
+      call HplUart.disableRxIntr();
+      m_rx_intr = 0;
+    }
+    return SUCCESS;
+  }
+
+  async command error_t UartStream.receive( uint8_t* buf, uint16_t len ){
+    
+    if ( len == 0 )
+      return FAIL;
+    atomic {
+      if ( m_rx_buf )
+	return EBUSY;
+      m_rx_buf = buf;
+      m_rx_len = len;
+      m_rx_pos = 0;
+      m_rx_intr |= 1;
+      call HplUart.enableRxIntr();
+    }
+    
+    return SUCCESS;
+    
+  }
+
+  async event void HplUart.rxDone( uint8_t data ) {
+
+    if ( m_rx_buf ) {
+      if(m_rx_buf + m_rx_pos >= m_rx_buf + m_rx_len) {
+        dbg("Atm128UartP", "%s: The out-of-bound error happens here!\n", __FUNCTION__);
+        exit(0);
+      }
+      dbg("Atm128UartP", "%s, the m_rx_len: %d\n", __FUNCTION__, m_rx_len);
+
+      m_rx_buf[ m_rx_pos++ ] = data;
+      if ( m_rx_pos >= m_rx_len ) {
+	uint8_t* buf = m_rx_buf;
+	atomic{
+	  m_rx_buf = NULL;
+	  if(m_rx_intr != 3){
+	    call HplUart.disableRxIntr();
+	    m_rx_intr = 0;
+	  }
+	}
+	signal UartStream.receiveDone( buf, m_rx_len, SUCCESS );
+      }
+    }
+    else {
+      signal UartStream.receivedByte( data );
+    }
+  }
+
+  async command error_t UartStream.send( uint8_t *buf, uint16_t len){
+    
+    if ( len == 0 )
+      return FAIL;
+    else if ( m_tx_buf )
+      return EBUSY;
+    
+    m_tx_len = len;
+    m_tx_buf = buf;
+    m_tx_pos = 0;
+    m_tx_intr = 1;
+    call HplUart.enableTxIntr();
+
+    if(m_tx_buf + m_tx_pos >= m_tx_buf + m_tx_len) {
+      dbg("Atm128UartP", "%s: The out-of-bound error happens here!\n", __FUNCTION__);
+      exit(0);
+    }
+    call HplUart.tx( buf[ m_tx_pos++ ] );
+    
+    return SUCCESS;
+    
+  }
+
+  async event void HplUart.txDone() {
+    
+    if ( m_tx_pos < m_tx_len ) {
+      call HplUart.tx( m_tx_buf[ m_tx_pos++ ] );
+    }
+    else {
+      uint8_t* buf = m_tx_buf;
+      m_tx_buf = NULL;
+      m_tx_intr = 0;
+      call HplUart.disableTxIntr();
+      signal UartStream.sendDone( buf, m_tx_len, SUCCESS );
+    }
+    
+  }
+
+  async command error_t UartByte.send( uint8_t byte ){
+    if(m_tx_intr)
+      return FAIL;
+
+    call HplUart.tx( byte );
+    while ( !call HplUart.isTxEmpty() );
+    return SUCCESS;
+  }
+  
+  async command error_t UartByte.receive( uint8_t * byte, uint8_t timeout){
+
+    uint16_t timeout_micro = m_byte_time * timeout + 1;
+    uint16_t start;
+    
+    if(m_rx_intr)
+      return FAIL;
+
+    start = call Counter.get();
+    while ( call HplUart.isRxEmpty() ) {
+      if ( ( (uint16_t)call Counter.get() - start ) >= timeout_micro )
+	return FAIL;
+    }
+    *byte = call HplUart.rx();
+    
+    return SUCCESS;
+    
+  }
+  
+  async event void Counter.overflow() {}
+
+  default async event void UartStream.sendDone( uint8_t* buf, uint16_t len, error_t error ){}
+  default async event void UartStream.receivedByte( uint8_t byte ){}
+  default  async event void UartStream.receiveDone( uint8_t* buf, uint16_t len, error_t error ){}
+
+}
Index: tos/chips/atm128/sim/HplAtm128UartC.nc
===================================================================
RCS file: tos/chips/atm128/sim/HplAtm128UartC.nc
diff -N tos/chips/atm128/sim/HplAtm128UartC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/sim/HplAtm128UartC.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,66 @@
+/// $Id: HplAtm128UartC.nc,v 1.5 2006/12/12 18:23:03 vlahan Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/// 
+
+#include <Atm128Uart.h>
+
+/**
+ * HPL for the Atmega 128 serial ports.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author David Gay
+ */
+configuration HplAtm128UartC
+{
+  provides {
+    interface StdControl as Uart0TxControl;
+    interface StdControl as Uart0RxControl;
+    interface HplAtm128Uart as HplUart0;
+    
+    interface StdControl as Uart1TxControl;
+    interface StdControl as Uart1RxControl;
+    interface HplAtm128Uart as HplUart1;
+  }
+}
+implementation
+{
+  components HplAtm128UartP, PlatformC, McuSleepC;
+  
+  Uart0TxControl = HplAtm128UartP.Uart0TxControl;
+  Uart0RxControl = HplAtm128UartP.Uart0RxControl;
+  HplUart0 = HplAtm128UartP.HplUart0;
+  
+  Uart1TxControl = HplAtm128UartP.Uart1TxControl;
+  Uart1RxControl = HplAtm128UartP.Uart1RxControl;
+  HplUart1 = HplAtm128UartP.HplUart1;
+  
+  HplAtm128UartP.Atm128Calibrate -> PlatformC;
+  HplAtm128UartP.McuPowerState -> McuSleepC;
+  
+  components MainC;
+  MainC.SoftwareInit -> HplAtm128UartP.Uart0Init;
+  MainC.SoftwareInit -> HplAtm128UartP.Uart1Init;
+  
+}
Index: tos/chips/atm128/sim/HplAtm128UartP.nc
===================================================================
RCS file: tos/chips/atm128/sim/HplAtm128UartP.nc
diff -N tos/chips/atm128/sim/HplAtm128UartP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/sim/HplAtm128UartP.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCH ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Alec Woo <awoo@archrock.com>
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.6 $ $Date: 2007/11/28 19:17:08 $
+ */
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/** 
+ * Private component of the Atmega128 serial port HPL.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author David Gay
+ */
+
+#include <stdlib.h>
+#include <Atm128Uart.h>
+
+#include <randomlib.h>
+
+module HplAtm128UartP @safe(){
+  
+  provides interface Init as Uart0Init;
+  provides interface StdControl as Uart0TxControl;
+  provides interface StdControl as Uart0RxControl;
+  provides interface HplAtm128Uart as HplUart0;
+    
+  provides interface Init as Uart1Init;
+  provides interface StdControl as Uart1TxControl;
+  provides interface StdControl as Uart1RxControl;
+  provides interface HplAtm128Uart as HplUart1;
+  
+  uses interface Atm128Calibrate;
+  uses interface McuPowerState;
+}
+implementation {
+  sim_event_t sim_uart0_tx_intr;
+  sim_event_t sim_uart0_rx_intr;
+
+  uint8_t num;
+   
+  uint8_t rx_msg[20] = {
+    HDLC_FLAG_BYTE, SERIAL_PROTO_PACKET_ACK, 0x09, 0x00, 0xbe, 0xef, 0x05, 0x7d, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, HDLC_FLAG_BYTE 
+  };
+
+  enum {
+    RX_STATE_NOSYNC,
+    RX_STATE_PROTO,
+    RX_STATE_TOKEN,
+  };
+  
+  //=== Uart Init Commands. ====================================
+  command error_t Uart0Init.init() {
+    Atm128UartMode_t    mode;
+    Atm128UartStatus_t  stts;
+    Atm128UartControl_t ctrl;
+    uint16_t ubrr0;
+
+    ctrl.bits = (struct Atm128_UCSRB_t) {rxcie:0, txcie:0, rxen:0, txen:0};
+    stts.bits = (struct Atm128_UCSRA_t) {u2x:1};
+    mode.bits = (struct Atm128_UCSRC_t) {ucsz:ATM128_UART_DATA_SIZE_8_BITS};
+
+    ubrr0 = call Atm128Calibrate.baudrateRegister(PLATFORM_BAUDRATE);
+    UBRR0L = ubrr0;
+    UBRR0H = ubrr0 >> 8;
+    UCSR0A = stts.flat;
+    UCSR0C = mode.flat;
+    UCSR0B = ctrl.flat;
+
+    return SUCCESS;
+  }
+
+  command error_t Uart0TxControl.start() {
+    SET_BIT(ATM128_UCSR0B, TXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+
+  command error_t Uart0TxControl.stop() {
+    CLR_BIT(ATM128_UCSR0B, TXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+
+  command error_t Uart0RxControl.start() {
+    SET_BIT(ATM128_UCSR0B, RXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+
+  command error_t Uart0RxControl.stop() {
+    CLR_BIT(ATM128_UCSR0B, RXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+  
+  AVR_NONATOMIC_HANDLER(SIG_UART0_TRANS) {
+    sim_uart0_tx_intr.mark = FALSE;
+    signal HplUart0.txDone();
+  }
+  
+  void uart0_tx_interrupt_handle(sim_event_t* evt) {
+     /* Here just emulate the occurrence of uart tx interrupt*/ 
+     if(evt->cancelled) {
+        return;
+     }
+     if(READ_BIT(ATM128_UCSR0B, TXCIE)) {
+        SIG_UART0_TRANS(); 
+     }
+  }
+
+  void allocate_uart0_tx_interrupt() {
+    dbg("HplAtm128UartP", "Allocated uart transmit interrupt at 0x%p\n", &sim_uart0_tx_intr);
+
+    sim_uart0_tx_intr.mote = sim_node();
+    sim_uart0_tx_intr.force = 0;
+    sim_uart0_tx_intr.cancelled = 0;
+    sim_uart0_tx_intr.time = sim_time() + 10000;   
+
+    sim_uart0_tx_intr.handle = uart0_tx_interrupt_handle;
+    sim_uart0_tx_intr.type = INTERRUPT;
+    sim_uart0_tx_intr.source = INT_USART0_TRANS;
+    sim_uart0_tx_intr.cleanup = sim_queue_cleanup_none;
+  }
+
+  void isUart0TxEnabled() {
+    allocate_uart0_tx_interrupt();  
+    sim_queue_insert(&sim_uart0_tx_intr);
+  }
+  
+  async command error_t HplUart0.enableTxIntr() {
+    SET_BIT(ATM128_UCSR0A, TXC);
+    SET_BIT(ATM128_UCSR0B, TXCIE);
+    isUart0TxEnabled();
+    return SUCCESS;
+  }
+
+  async command error_t HplUart0.disableTxIntr(){
+    CLR_BIT(ATM128_UCSR0B, TXCIE);
+    sim_uart0_tx_intr.mark = FALSE;
+    return SUCCESS;
+  }
+
+  uint8_t index = 0;
+
+  // TODO: actually, the serial forwarder can realize the similar functionality
+  // in the future, I will integrate the SF part of Tossim with the receipt part of serial stack...
+
+  uint8_t fetch_fit_data() {
+     uint8_t m_data = 0;
+
+     if(index < 20) {
+       m_data = rx_msg[index++];
+     }
+     else {
+       index = 0;
+       num++; 
+     }
+
+     return m_data;
+  }
+
+  AVR_ATOMIC_HANDLER(SIG_UART0_RECV) {
+    uint8_t data = fetch_fit_data();
+
+    if (READ_BIT(ATM128_UCSR0A, RXC)) {
+       dbg("HplAtm128UartP", "avr_atomic_handler: 0x%x\n", data);
+       signal HplUart0.rxDone(data);
+    }
+  }
+  
+  void uart0_rx_interrupt_handle(sim_event_t* evt) {
+     /* Here emulate the occurrence of uart rx interrupt */ 
+     if(evt->cancelled) {
+        return;
+     }
+     if(READ_BIT(ATM128_UCSR0B, RXCIE)) {
+	SET_BIT(ATM128_UCSR0A, RXC); // Originally, in real mote, there is no such instruction 
+	                             // to signal the completion of receiving, thus, add this 
+	                             // instruction to emulate reception completion, the data
+	                             // is in pertinent register. 
+        SIG_UART0_RECV();
+     }
+  }
+
+  void allocate_uart0_rx_interrupt() {
+    dbg("HplAtm128UartP", "Allocated uart receive interrupt at 0x%p\n", &sim_uart0_rx_intr);
+
+    sim_uart0_rx_intr.mote = sim_node();
+    sim_uart0_rx_intr.force = 0;
+    sim_uart0_rx_intr.cancelled = 0;
+    sim_uart0_rx_intr.time = sim_time() + 10000;   
+
+    sim_uart0_rx_intr.handle = uart0_rx_interrupt_handle;
+    sim_uart0_rx_intr.type = INTERRUPT;
+    sim_uart0_rx_intr.source = INT_USART0_RECV;
+    sim_uart0_rx_intr.cleanup = sim_queue_cleanup_none;
+    sim_uart0_rx_intr.mark = TRUE;  
+    /*
+    if(num < 5) {
+      sim_uart0_rx_intr.mark = TRUE;    
+    }
+    else {
+      sim_uart0_rx_intr.mark = FALSE;  
+    }*/
+  }
+
+  void isUart0RxEnabled() {
+    allocate_uart0_rx_interrupt();  
+    sim_queue_insert(&sim_uart0_rx_intr);
+  }
+
+  async command error_t HplUart0.enableRxIntr() {
+    SET_BIT(ATM128_UCSR0B, RXCIE);
+    isUart0RxEnabled();
+    return SUCCESS;
+  }
+
+  async command error_t HplUart0.disableRxIntr() {
+    CLR_BIT(ATM128_UCSR0B, RXCIE);
+    sim_uart0_rx_intr.mark = FALSE;
+    return SUCCESS;
+  }
+  
+  async command bool HplUart0.isTxEmpty(){
+    return READ_BIT(ATM128_UCSR0A, TXC);
+  }
+
+  async command bool HplUart0.isRxEmpty(){
+    return !READ_BIT(ATM128_UCSR0A, RXC);
+  }
+  
+  async command uint8_t HplUart0.rx(){
+    return UDR0;
+  }
+
+  async command void HplUart0.tx(uint8_t data) {
+    atomic {
+      UDR0 = data; 
+      SET_BIT(ATM128_UCSR0A, TXC);
+    }
+    sim_uart0_tx_intr.mark = TRUE; //Currently, the tx interrupt is in the enable state 
+                                     //and the trigger condition has been fulfilled.
+  }
+
+  command error_t Uart1Init.init() {
+    Atm128UartMode_t    mode;
+    Atm128UartStatus_t  stts;
+    Atm128UartControl_t ctrl;
+    uint16_t ubrr1;
+    
+    ctrl.bits = (struct Atm128_UCSRB_t) {rxcie:0, txcie:0, rxen:0, txen:0};
+    stts.bits = (struct Atm128_UCSRA_t) {u2x:1};
+    mode.bits = (struct Atm128_UCSRC_t) {ucsz:ATM128_UART_DATA_SIZE_8_BITS};
+
+    ubrr1 = call Atm128Calibrate.baudrateRegister(PLATFORM_BAUDRATE);
+    UBRR1L = ubrr1;
+    UBRR1H = ubrr1 >> 8;
+    UCSR1A = stts.flat;
+    UCSR1C = mode.flat;
+    UCSR1B = ctrl.flat;
+
+    return SUCCESS;
+  }
+
+  command error_t Uart1TxControl.start() {
+    SET_BIT(ATM128_UCSR1B, TXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+
+  command error_t Uart1TxControl.stop() {
+    CLR_BIT(ATM128_UCSR1B, TXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+
+  command error_t Uart1RxControl.start() {
+    SET_BIT(ATM128_UCSR1B, RXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+
+  command error_t Uart1RxControl.stop() {
+    CLR_BIT(ATM128_UCSR1B, RXEN);
+    call McuPowerState.update();
+    return SUCCESS;
+  }
+  
+  async command error_t HplUart1.enableTxIntr() {
+    SET_BIT(ATM128_UCSR1A, TXC);
+    SET_BIT(ATM128_UCSR1B, TXCIE);
+    return SUCCESS;
+  }
+  
+  async command error_t HplUart1.disableTxIntr(){
+    CLR_BIT(ATM128_UCSR1B, TXCIE);
+    return SUCCESS;
+  }
+  
+  async command error_t HplUart1.enableRxIntr(){
+    SET_BIT(ATM128_UCSR1B, RXCIE);
+    return SUCCESS;
+  }
+
+  async command error_t HplUart1.disableRxIntr(){
+    CLR_BIT(ATM128_UCSR1B, RXCIE);
+    return SUCCESS;
+  }
+  
+  async command bool HplUart1.isTxEmpty() {
+    return READ_BIT(ATM128_UCSR1A, TXC);
+  }
+
+  async command bool HplUart1.isRxEmpty() {
+    return !READ_BIT(ATM128_UCSR1A, RXC);
+  }
+  
+  async command uint8_t HplUart1.rx(){
+    return UDR1;
+  }
+
+  async command void HplUart1.tx(uint8_t data) {
+    atomic{
+      UDR1 = data; 
+      SET_BIT(ATM128_UCSR1A, TXC);
+    }
+  }
+  
+  AVR_ATOMIC_HANDLER(SIG_UART1_RECV) {
+    if (READ_BIT(ATM128_UCSR1A, RXC))
+      signal HplUart1.rxDone(UDR1);
+  }
+  
+  AVR_NONATOMIC_HANDLER(SIG_UART1_TRANS) {
+    signal HplUart1.txDone();
+  }
+  
+  default async event void HplUart0.txDone() {} 
+  default async event void HplUart0.rxDone(uint8_t data) {}
+  default async event void HplUart1.txDone() {}
+  default async event void HplUart1.rxDone(uint8_t data) {}
+  
+}
Index: tos/chips/atm128/spi/sim/Atm128Spi.nc
===================================================================
RCS file: tos/chips/atm128/spi/sim/Atm128Spi.nc
diff -N tos/chips/atm128/spi/sim/Atm128Spi.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/spi/sim/Atm128Spi.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,126 @@
+/// $Id: Atm128Spi.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $ 
+
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * HPL-level access to the Atmega128 SPI bus. Refer to pages 162-9
+ * of the Atmega128 datasheet (rev. 2467M-AVR-11/04) for details.
+ *
+ * <pre>
+ *  $Id: Atm128Spi.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+ * </pre>
+ *
+ * @author Philip Levis
+ * @author Martin Turon <mturon@xbow.com>
+ * @date   September 8 2005
+ */
+
+#include "Atm128Spi.h"
+
+interface Atm128Spi {
+
+  /* Modal functions */
+
+  /** Initialize the ATmega128 SPI bus into master mode. */
+  async command void initMaster();
+
+  /** Initialize the ATmega128 SPI bus into slave mode. */
+  async command void initSlave();
+
+  /** Disable and sleep the ATmega128 SPI bus. */
+  async command void sleep();
+  
+  /* SPDR: SPI Data Register */
+
+  /** 
+   * Read the SPI data register 
+   * @return last data byte
+   */
+  async command uint8_t read();
+
+  /** 
+   * Write the SPI data register 
+   * @param data   next data byte
+   */
+  async command void write(uint8_t data, bool isTX);
+
+  /**
+   * Interrupt signalling SPI data cycle is complete. 
+   * @param data   data byte from data register
+   */
+  async event   void dataReady(uint8_t data);
+  
+  /* SPCR: SPI Control Register */
+  /* SPIE bit */
+  async command void enableInterrupt(bool enabled);
+  async command bool isInterruptEnabled();
+  /* SPI bit */
+  async command void enableSpi(bool busOn);
+  async command bool isSpiEnabled();
+  /* DORD bit */
+  async command void setDataOrder(bool lsbFirst);
+  async command bool isOrderLsbFirst();
+  /* MSTR bit */
+  async command void setMasterBit(bool isMaster);
+  async command bool isMasterBitSet();
+  /* CPOL bit */
+  async command void setClockPolarity(bool highWhenIdle);
+  async command bool getClockPolarity();
+  /* CPHA bit */
+  async command void setClockPhase(bool sampleOnTrailing);
+  async command bool getClockPhase();
+  /* SPR1 and SPR0 bits */
+  async command void  setClock(uint8_t speed);
+  async command uint8_t getClock();
+  
+  /* SPSR: SPI Status Register */
+  
+  /* SPIF bit */
+  async command bool isInterruptPending();
+  /* WCOL bit */
+  async command bool hasWriteCollided();
+  /* SPI2X bit */
+  async command bool isMasterDoubleSpeed();
+  async command void setMasterDoubleSpeed(bool on);
+}
Index: tos/chips/atm128/spi/sim/Atm128SpiC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/spi/sim/Atm128SpiC.nc,v
retrieving revision 1.5
diff -u -b -p -r1.5 Atm128SpiC.nc
--- tos/chips/atm128/spi/sim/Atm128SpiC.nc	29 Jun 2010 22:07:43 -0000	1.5
+++ tos/chips/atm128/spi/sim/Atm128SpiC.nc	9 Jul 2010 19:45:15 -0000
@@ -1,3 +1,5 @@
+/// $Id: Atm128SpiC.nc,v 1.6 2009/03/09 18:12:58 mmaroti Exp $
+
 /*
  * Copyright (c) 2005 Stanford University. All rights reserved.
  *
@@ -30,8 +32,7 @@
  */
 
 /**
- * The simulated HAL of the SPI bus on the atm128, which just maps to
- * the platform-specific implementation of the device end point.
+ * The HAL of the SPI bus on the atm128.
  *
  * <pre>
  *  $Id: Atm128SpiC.nc,v 1.5 2010/06/29 22:07:43 scipio Exp $
@@ -39,25 +40,32 @@
  *
  *
  * @author Philip Levis
- * @date   November 22 2005
+ * @author Martin Turon
+ * @author Joe Polastre
+ * @date   September 7 2005
  */
 
 configuration Atm128SpiC {
   provides interface Init;
-  provides interface SPIByte;
-  provides interface SPIPacket;
+  provides interface SpiByte;
+  provides interface FastSpiByte;
+  provides interface SpiPacket;
   provides interface Resource[uint8_t id];
 }
 implementation {
-  components SimAtm128SpiDeviceC as Device;
+  components Atm128SpiP as SpiMaster, HplAtm128SpiC as HplSpi;
   components new SimpleFcfsArbiterC("Atm128SpiC.Resource") as Arbiter;
   components McuSleepC;
   
-  Init         = Device;
+  Init         = SpiMaster;
   
-  SPIByte      = Device;
-  SPIPacket    = Device;
-  Resource     = Arbiter;
+  SpiByte      = SpiMaster;
+  FastSpiByte  = SpiMaster;
+  SpiPacket    = SpiMaster;
+  Resource     = SpiMaster;
 
-  Device.McuPowerState   -> McuSleepC;
+  SpiMaster.ResourceArbiter -> Arbiter;
+  SpiMaster.ArbiterInfo     -> Arbiter;
+  SpiMaster.Spi             -> HplSpi;
+  SpiMaster.McuPowerState   -> McuSleepC;
 }
Index: tos/chips/atm128/spi/sim/Atm128SpiP.nc
===================================================================
RCS file: tos/chips/atm128/spi/sim/Atm128SpiP.nc
diff -N tos/chips/atm128/spi/sim/Atm128SpiP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/spi/sim/Atm128SpiP.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,387 @@
+// $Id: Atm128SpiP.nc,v 1.10 2009/03/09 18:12:59 mmaroti Exp $
+
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ *  Copyright (c) 2004-2005 Crossbow Technology, Inc.
+ *  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 (updated) modification history and the author appear in
+ *  all copies of this source code.
+ *
+ *  Permission is also granted to distribute this software under the
+ *  standard BSD license as contained in the TinyOS distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ *  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE INTEL OR ITS
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+/**
+ * Primitives for accessing the SPI module on ATmega128
+ * microcontroller.  This module assumes the bus has been reserved and
+ * checks that the bus owner is in fact the person using the bus.
+ * SpiPacket provides an asynchronous send interface where the
+ * transmit data length is equal to the receive data length, while
+ * SpiByte provides an interface for sending a single byte
+ * synchronously. SpiByte allows a component to send a few bytes
+ * in a simple fashion: if more than a handful need to be sent,
+ * SpiPacket should be used.
+ *
+ *
+ * <pre>
+ *  $Id: Atm128SpiP.nc,v 1.10 2009/03/09 18:12:59 mmaroti Exp $
+ * </pre>
+ *
+ * @author Philip Levis
+ * @author Joe Polastre
+ * @author Martin Turon <mturon@xbow.com>
+ *
+ */
+
+module Atm128SpiP @safe() {
+  provides {
+    interface Init;
+    interface SpiByte;
+    interface FastSpiByte;
+    interface SpiPacket;
+    interface Resource[uint8_t id];
+  }
+  uses {
+    interface Atm128Spi as Spi;
+    interface Resource as ResourceArbiter[uint8_t id];
+    interface ArbiterInfo;
+    interface McuPowerState;
+  }
+}
+implementation {
+  uint16_t len;
+  uint8_t* ONE_NOK txBuffer;
+  uint8_t* ONE_NOK rxBuffer;
+  uint16_t pos;
+  
+  enum {
+    SPI_IDLE,
+    SPI_BUSY,
+    SPI_ATOMIC_SIZE = 10,
+  };
+
+  command error_t Init.init() {
+    return SUCCESS;
+  }
+  
+  void startSpi() {
+    call Spi.enableSpi(FALSE);
+    atomic {
+      call Spi.initMaster();
+      call Spi.enableInterrupt(FALSE);
+      call Spi.setMasterDoubleSpeed(TRUE);
+      call Spi.setClockPolarity(FALSE);
+      call Spi.setClockPhase(FALSE);
+      call Spi.setClock(0);
+      call Spi.enableSpi(TRUE);
+    }
+    call McuPowerState.update();
+  }
+
+  void stopSpi() {
+    call Spi.enableSpi(FALSE);
+    atomic {
+      call Spi.sleep();
+    } 
+    call McuPowerState.update();
+  }
+
+  async command uint8_t SpiByte.write( uint8_t tx ) {
+    /* There is no need to enable the SPI bus and update the power state
+       here since that must have been done when the resource was granted. 
+       However there seems to be a bug somewhere in the radio driver for 
+       the MicaZ platform so we cannot remove the following two lines 
+       before that problem is resolved. (Miklos Maroti) */
+    call Spi.enableSpi(TRUE);
+    call McuPowerState.update();
+
+    if(txBuffer != NULL){ 
+      call Spi.write( tx, TRUE );
+      dbg("Atm128SpiP", "txBuffer is not NULL, and tx: %x\n", tx);
+    }
+    else {
+      call Spi.write( tx, FALSE );
+      dbg("Atm128SpiP", "txBuffer is NULL, and tx: %x\n", tx);
+    }
+
+    // SPSR means the status register of SPI, when 
+    // the SPIF bit is set when the data is completely
+    // transfered.
+    while ( !( SPSR & 0x80 ) );
+    return call Spi.read();
+  }
+
+  inline async command void FastSpiByte.splitWrite(uint8_t data) {
+    call Spi.write(data, TRUE);
+  }
+
+  inline async command uint8_t FastSpiByte.splitRead() {
+    while( !( SPSR & 0x80 ) )
+      ;
+    return call Spi.read();
+  }
+
+  inline async command uint8_t FastSpiByte.splitReadWrite(uint8_t data) {
+    uint8_t b;
+
+    while( !( SPSR & 0x80 ) )
+	;
+    b = call Spi.read();
+    call Spi.write(data, TRUE);
+
+    return b;
+  }
+
+  inline async command uint8_t FastSpiByte.write(uint8_t data) {
+    call Spi.write(data, TRUE);
+    while( !( SPSR & 0x80 ) )
+      ;
+    return call Spi.read();
+  }
+
+  /**
+   * This component sends SPI packets in chunks of size SPI_ATOMIC_SIZE
+   * (which is normally 5). The tradeoff is between SPI performance
+   * (throughput) and how much the component limits concurrency in the
+   * rest of the system. Handling an interrupt on each byte is
+   * very expensive: the context saving/register spilling constrains
+   * the rate at which one can write out bytes. A more efficient
+   * approach is to write out a byte and wait for a few cycles until
+   * the byte is written (a tiny spin loop). This leads to greater
+   * throughput, but blocks the system and prevents it from doing
+   * useful work.
+   *
+   * This component takes a middle ground. When asked to transmit X
+   * bytes in a packet, it transmits those X bytes in 10-byte parts.
+   * <tt>sendNextPart()</tt> is responsible for sending one such
+   * part. It transmits bytes with the SpiByte interface, which
+   * disables interrupts and spins on the SPI control register for
+   * completion. On the last byte, however, <tt>sendNextPart</tt>
+   * re-enables SPI interrupts and sends the byte through the
+   * underlying split-phase SPI interface. When this component handles
+   * the SPI transmit completion event (handles the SPI interrupt),
+   * it calls sendNextPart() again. As the SPI interrupt does
+   * not disable interrupts, this allows processing in the rest of the
+   * system to continue.
+   */
+   
+  error_t sendNextPart() {
+    uint16_t end;
+    uint16_t tmpPos;
+    uint16_t myLen;
+    uint8_t* COUNT_NOK(myLen) tx;
+    uint8_t* COUNT_NOK(myLen) rx;
+    
+    atomic {
+      myLen = len;
+      tx = TCAST(uint8_t* COUNT_NOK(myLen), txBuffer);
+      rx = TCAST(uint8_t* COUNT_NOK(myLen), rxBuffer);
+      tmpPos = pos;
+      end = pos + SPI_ATOMIC_SIZE;
+      end = (end > len)? len:end;
+    }
+
+    for (;tmpPos < (end - 1) ; tmpPos++) {
+      uint8_t val;
+      if (tx != NULL) 
+	val = call SpiByte.write( tx[tmpPos] );
+      else
+	val = call SpiByte.write( 0 );
+    
+      if (rx != NULL) {
+	rx[tmpPos] = val;
+      }
+    }
+
+    // For the last byte, we re-enable interrupts.
+
+   call Spi.enableInterrupt(TRUE);
+   atomic {
+     if (tx != NULL)
+       call Spi.write(tx[tmpPos], TRUE);
+     else
+       call Spi.write(0, FALSE);
+     
+     pos = tmpPos;
+      // The final increment will be in the interrupt
+      // handler.
+    }
+    return SUCCESS;
+  }
+
+
+  task void zeroTask() {
+     uint16_t  myLen;
+     uint8_t* COUNT_NOK(myLen) rx;
+     uint8_t* COUNT_NOK(myLen) tx;
+
+     atomic {
+       myLen = len;
+       rx = rxBuffer;
+       tx = txBuffer;
+       rxBuffer = NULL;
+       txBuffer = NULL;
+       len = 0;
+       pos = 0;
+       signal SpiPacket.sendDone(tx, rx, myLen, SUCCESS);
+     }
+  }
+
+  /**
+   * Send bufLen bytes in <tt>writeBuf</tt> and receive bufLen bytes
+   * into <tt>readBuf</tt>. If <tt>readBuf</tt> is NULL, bytes will be
+   * read out of the SPI, but they will be discarded. A byte is read
+   * from the SPI before writing and discarded (to clear any buffered
+   * bytes that might have been left around).
+   *
+   * This command only sets up the state variables and clears the SPI:
+   * <tt>sendNextPart()</tt> does the real work.
+   * 
+   * If there's a send of zero bytes, short-circuit and just post
+   * a task to signal the sendDone. This generally occurs due to an
+   * error in the caler, but signaling an event will hopefully let
+   * it recover better than returning FAIL.
+   */
+
+  
+  async command error_t SpiPacket.send(uint8_t* writeBuf, 
+				       uint8_t* readBuf, 
+				       uint16_t  bufLen) {
+    uint8_t discard;
+    atomic {
+      len = bufLen;
+      txBuffer = writeBuf;
+      rxBuffer = readBuf;
+      pos = 0;
+    }
+    if (bufLen > 0) {
+      discard = call Spi.read();
+      return sendNextPart();
+    }
+    else {
+      post zeroTask();
+      return SUCCESS;
+    }
+  }
+
+ default async event void SpiPacket.sendDone
+      (uint8_t* _txbuffer, uint8_t* _rxbuffer, 
+       uint16_t _length, error_t _success) { }
+
+ async event void Spi.dataReady(uint8_t data) {
+   bool again;
+   
+   atomic {
+     if (rxBuffer != NULL) {
+       rxBuffer[pos] = data;
+       // Increment position
+     }
+     pos++;
+   }
+   call Spi.enableInterrupt(FALSE);
+   
+   atomic {
+     again = (pos < len);
+   }
+   
+   if (again) {
+     sendNextPart();
+   }
+   else {
+     uint8_t discard;
+     uint16_t  myLen;
+     uint8_t* COUNT_NOK(myLen) rx;
+     uint8_t* COUNT_NOK(myLen) tx;
+     
+     atomic {
+       myLen = len;
+       rx = TCAST(uint8_t* COUNT_NOK(myLen), rxBuffer);
+       tx = TCAST(uint8_t* COUNT_NOK(myLen), txBuffer);
+       rxBuffer = NULL;
+       txBuffer = NULL;
+       len = 0;
+       pos = 0;
+     }
+     discard = call Spi.read();
+
+     signal SpiPacket.sendDone(tx, rx, myLen, SUCCESS);
+   }
+ }
+
+ async command error_t Resource.immediateRequest[ uint8_t id ]() {
+   error_t result = call ResourceArbiter.immediateRequest[ id ]();
+   if ( result == SUCCESS ) {
+     startSpi();
+   }
+   return result;
+ }
+ 
+ async command error_t Resource.request[ uint8_t id ]() {
+   atomic {
+     if (!call ArbiterInfo.inUse()) {
+       startSpi();
+     }
+   }
+   return call ResourceArbiter.request[ id ]();
+ }
+
+ async command error_t Resource.release[ uint8_t id ]() {
+   error_t error = call ResourceArbiter.release[ id ]();
+   atomic {
+     if (!call ArbiterInfo.inUse()) {
+       stopSpi();
+     }
+   }
+   return error;
+ }
+
+ async command uint8_t Resource.isOwner[uint8_t id]() {
+   return call ResourceArbiter.isOwner[id]();
+ }
+ 
+ event void ResourceArbiter.granted[ uint8_t id ]() {
+   signal Resource.granted[ id ]();
+ }
+ 
+ default event void Resource.granted[ uint8_t id ]() {}
+ 
+}
Index: tos/chips/atm128/spi/sim/HplAtm128SpiC.nc
===================================================================
RCS file: tos/chips/atm128/spi/sim/HplAtm128SpiC.nc
diff -N tos/chips/atm128/spi/sim/HplAtm128SpiC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/spi/sim/HplAtm128SpiC.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,73 @@
+/// $Id: HplAtm128SpiC.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Configuration encapsulating the basic SPI HPL for the atm128.
+ *
+ * <pre>
+ * $Id: HplAtm128SpiC.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+ * </pre>
+ *
+ * @author Philip Levis
+ * @author Martin Turon <mturon@xbow.com>
+ */
+
+
+configuration HplAtm128SpiC {
+    provides interface Atm128Spi as SpiBus;
+}
+implementation
+{
+  components HplAtm128GeneralIOC as IO, HplAtm128SpiP as HplSpi;
+  components McuSleepC;
+  
+  SpiBus = HplSpi;
+
+  HplSpi.Mcu -> McuSleepC;
+  HplSpi.SS   -> IO.PortB0;  // Slave set line
+  HplSpi.SCK  -> IO.PortB1;  // SPI clock line
+  HplSpi.MOSI -> IO.PortB2;  // Master out, slave in
+  HplSpi.MISO -> IO.PortB3;  // Master in, slave out
+}
Index: tos/chips/atm128/spi/sim/HplAtm128SpiP.nc
===================================================================
RCS file: tos/chips/atm128/spi/sim/HplAtm128SpiP.nc
diff -N tos/chips/atm128/spi/sim/HplAtm128SpiP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/spi/sim/HplAtm128SpiP.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,351 @@
+/// $Id: HplAtm128SpiP.nc,v 1.6 2008/06/26 04:39:03 regehr Exp $
+
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Implementation of the SPI bus abstraction for the atm128
+ * microcontroller.
+ *
+ * @author Philip Levis
+ * @author Martin Turon
+ */
+
+#include "Atm128Spi.h"
+
+module HplAtm128SpiP @safe() {
+  provides interface Atm128Spi as SPI;
+  provides interface AsyncStdControl;
+  
+  uses {
+    interface GeneralIO as SS;   // Slave set line
+    interface GeneralIO as SCK;  // SPI clock line
+    interface GeneralIO as MOSI; // Master out, slave in
+    interface GeneralIO as MISO; // Master in, slave out
+    interface McuPowerState as Mcu;
+  }
+}
+implementation {
+
+  sim_event_t sim_spi_intr;
+
+  struct spdr_byte;
+  typedef struct spdr_byte spdr_byte_t;
+
+  struct spdr_byte {
+    uint8_t data;
+    int source;
+    spdr_byte_t* next;
+  };
+
+  spdr_byte_t* outstandingSpdrHead = NULL;
+  spdr_byte_t* allocate_spdr_byte();
+
+  void enqueue_spdr_byte(int source, uint8_t data) {
+    spdr_byte_t* sbt = allocate_spdr_byte(); 
+    spdr_byte_t* list = NULL;
+    sbt->source = source;
+    sbt->data = data;
+    list = outstandingSpdrHead;
+
+    if(outstandingSpdrHead == NULL) {
+       sbt->next = NULL;
+       outstandingSpdrHead = sbt;
+    }
+    else {
+       while(list->next != NULL) {
+         list = list->next;
+       }
+       sbt->next = NULL;
+       list->next = sbt;
+    }
+  }
+
+  spdr_byte_t* allocate_spdr_byte() {
+    return TCAST(spdr_byte_t* ONE, malloc(sizeof(spdr_byte_t)));
+  }
+
+  async command error_t AsyncStdControl.start() {
+    call SPI.enableSpi(TRUE);
+  }
+
+  async command error_t AsyncStdControl.stop() {
+    call SPI.enableInterrupt(FALSE);
+    call SPI.enableSpi(FALSE);
+  }
+  
+  async command void SPI.initMaster() {
+    call MOSI.makeOutput();
+    call MISO.makeInput();
+    call SCK.makeOutput();
+    call SPI.setMasterBit(TRUE);
+  }
+
+  async command void SPI.initSlave() {
+    call MISO.makeOutput();
+    call MOSI.makeInput();
+    call SCK.makeInput();
+    call SS.makeInput();
+    call SPI.setMasterBit(FALSE);
+  }
+  
+  async command void SPI.sleep() {
+//    call SS.set();	// why was this needed?
+  }
+  
+  spdr_byte_t* dequeue_spdr_byte() {
+     if(outstandingSpdrHead == NULL)
+	return NULL;
+     else {
+        spdr_byte_t* spdr = outstandingSpdrHead;
+	outstandingSpdrHead = spdr->next;
+	spdr->next = NULL;
+	return spdr;
+     }
+  }
+
+  async command TRUSTEDBLOCK uint8_t SPI.read() { 
+     // Here, the execution is inside dest node's domain...
+     // i.e., if node A sends byte stream to node B, then
+     // Here, the execution domain is B's...
+     spdr_byte_t* sbt = dequeue_spdr_byte();
+
+     if(sbt == NULL) {
+        return SPDR;
+     }
+     else {
+	uint8_t data = sbt->data;
+	dbg("Atm128SpiP", "The SPI read data: 0x%x, with node: %d\n", data, sbt->source);
+	free(sbt);
+        return data;
+     }
+  }
+ 
+  // enqueue the byte node into the dest's waiting queue...
+  void sim_gain_send(int dest, uint8_t data) {
+    int srcNode = sim_node();
+    sim_set_node(dest);
+    enqueue_spdr_byte(srcNode, data);
+    sim_set_node(srcNode);
+  }
+
+  void sim_send_byte(uint8_t data) {
+    gain_entry_t* neighborEntry = sim_gain_first(sim_node());
+    dbg("Atm128SpiP", "node %lu starts sending the byte data: 0x%x to its neighboring notes.\n", sim_node(), data);
+    while (neighborEntry != NULL) {
+      int dest = neighborEntry->mote;
+      sim_gain_send(dest, data);
+      neighborEntry = sim_gain_next(neighborEntry);
+    }
+  }
+
+  async command void SPI.write(uint8_t d, bool isTX) { 
+     SPDR = d;
+     /* Here, based on the higher-layer meaning, for 
+        transmission, the byte d is one to be transmited; 
+	for receive, the byte d is always 0 */
+     if(isTX == TRUE) {
+       sim_send_byte(d);
+     }
+     else {
+       dbg("Atm128SpiP", "Byte 0x%x is for reception\n", d);
+     }
+     // The SPSR should be set by hardware when data
+     // transmission is complete.
+     SET_BIT(ATM128_SPSR, SPIF);
+  }
+    
+  default async event void SPI.dataReady(uint8_t d) {}
+  AVR_ATOMIC_HANDLER(SIG_SPI) {
+     signal SPI.dataReady(call SPI.read());
+  }
+
+  void spi_interrupt_handle(sim_event_t* evt) {
+     /* Here just emulate the occurrence of adc interrupt, omitting the analysis of value
+	of register*/ 
+     if(evt->cancelled) {
+        return;
+     }
+     if(call SPI.isInterruptEnabled()) {
+        SIG_SPI(); 
+     }
+  }
+
+  void allocate_spi_interrupt() {
+    dbg("Atm128SpiP", "Allocated spi completion interrupt at 0x%p\n", &sim_spi_intr);
+    sim_spi_intr.mote = sim_node();
+    sim_spi_intr.force = 0;
+    sim_spi_intr.cancelled = 0;
+    sim_spi_intr.time = sim_time() + 10000;   
+
+    sim_spi_intr.handle = spi_interrupt_handle;
+    sim_spi_intr.type = INTERRUPT;
+    sim_spi_intr.source = INT_SPI;
+    sim_spi_intr.cleanup = sim_queue_cleanup_none;
+    sim_spi_intr.mark = TRUE;     
+  }
+
+  void isSpiEnabled() {
+    allocate_spi_interrupt();  
+    sim_queue_insert(&sim_spi_intr);
+  }
+
+  //=== SPI Bus utility routines. ====================================
+  async command bool SPI.isInterruptPending() {
+    return READ_BIT(ATM128_SPSR, SPIF);
+  }
+
+  async command bool SPI.isInterruptEnabled () {
+    return READ_BIT(ATM128_SPCR, SPIE);
+  }
+
+  async command void SPI.enableInterrupt(bool enabled) {
+    if (enabled) {
+      SET_BIT(ATM128_SPCR, SPIE);
+      isSpiEnabled();
+      call Mcu.update();
+    }
+    else {
+      CLR_BIT(ATM128_SPCR, SPIE);
+      sim_spi_intr.mark = FALSE;     
+      call Mcu.update();
+    }
+  }
+
+  async command bool SPI.isSpiEnabled() {
+    return READ_BIT(ATM128_SPCR, SPE);
+  }
+  
+  async command void SPI.enableSpi(bool enabled) {
+    if (enabled) {
+      SET_BIT(ATM128_SPCR, SPE);
+      call Mcu.update();
+    }
+    else {
+      CLR_BIT(ATM128_SPCR, SPE);
+      call Mcu.update();
+    }
+  }
+
+  /* DORD bit */
+  async command void SPI.setDataOrder(bool lsbFirst) {
+    if (lsbFirst) {
+      SET_BIT(ATM128_SPCR, DORD);
+    }
+    else {
+      CLR_BIT(ATM128_SPCR, DORD);
+    }
+  }
+  
+  async command bool SPI.isOrderLsbFirst() {
+    return READ_BIT(ATM128_SPCR, DORD);
+  }
+  
+  /* MSTR bit */
+  async command void SPI.setMasterBit(bool isMaster) {
+    if (isMaster) {
+      SET_BIT(ATM128_SPCR, MSTR);
+    }
+    else {
+      CLR_BIT(ATM128_SPCR, MSTR);
+    }
+  }
+
+  async command bool SPI.isMasterBitSet() {
+    return READ_BIT(ATM128_SPCR, MSTR);
+  }
+  
+  /* CPOL bit */
+  async command void SPI.setClockPolarity(bool highWhenIdle) {
+    if (highWhenIdle) {
+      SET_BIT(ATM128_SPCR, CPOL);
+    }
+    else {
+      CLR_BIT(ATM128_SPCR, CPOL);
+    }
+  }
+  
+  async command bool SPI.getClockPolarity() {
+    return READ_BIT(ATM128_SPCR, CPOL);
+  }
+  
+  /* CPHA bit */
+  async command void SPI.setClockPhase(bool sampleOnTrailing) {
+    if (sampleOnTrailing) {
+      SET_BIT(ATM128_SPCR, CPHA);
+    }
+    else {
+      CLR_BIT(ATM128_SPCR, CPHA);
+    }
+  }
+  async command bool SPI.getClockPhase() {
+    return READ_BIT(ATM128_SPCR, CPHA);
+  }
+
+  
+  async command uint8_t SPI.getClock () {                
+    return READ_FLAG(ATM128_SPCR, ((1 << SPR1) | (1 <<SPR0)));
+  }
+  
+  async command void SPI.setClock (uint8_t v) {
+    v &= (SPR1) | (SPR0);
+    SPCR = (SPCR & ~(SPR1 | SPR0)) | v;
+  }
+
+  async command bool SPI.hasWriteCollided() {
+    return READ_BIT(ATM128_SPSR, WCOL);
+  }
+
+  async command bool SPI.isMasterDoubleSpeed() {
+    return READ_BIT(ATM128_SPSR, SPI2X);
+  }
+
+  async command void SPI.setMasterDoubleSpeed(bool on) {
+    if (on) {
+      SET_BIT(ATM128_SPSR, SPI2X);
+    }
+    else {
+      CLR_BIT(ATM128_SPSR, SPI2X);
+    }
+  }
+}
Index: tos/chips/atm128/timer/sim/Atm128AlarmC.nc
===================================================================
RCS file: tos/chips/atm128/timer/sim/Atm128AlarmC.nc
diff -N tos/chips/atm128/timer/sim/Atm128AlarmC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/timer/sim/Atm128AlarmC.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,95 @@
+/// $Id: Atm128AlarmC.nc,v 1.8 2008/06/26 04:39:05 regehr Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Build a TEP102 Alarm from an Atmega128 hardware timer and one of its
+ * compare registers.
+ * @param frequency_tag The frequency tag for this Alarm
+ * @param timer_size The width of this Alarm
+ * @param mindt The shortest time in the future this Alarm can be set
+ *   (in its own time units). Has to be at least 2, as setting a compare
+ *   register one above the current counter value is unreliable. Has to be
+ *   large enough that the Alarm time does not pass between the computation
+ *   of <code>expires</code> and actually setting the compare register.
+ *   Check this (for high-frequency timers) by inspecting the generated
+ *   assembly code...
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author David Gay <david.e.gay@intel.com>
+ */
+
+generic module Atm128AlarmC(typedef frequency_tag, 
+			    typedef timer_size @integer(),
+			    int mindt) @safe()
+{
+  provides interface Alarm<frequency_tag, timer_size> as Alarm @atmostonce();
+
+  //uses interface HplAtm128Timer<timer_size>; 
+  uses interface HplAtm128Compare<timer_size>;
+}
+implementation
+{
+  async command timer_size Alarm.getNow() {
+    // Since the value returned by this command is always set by hardware
+    // Instead, return 1000;
+    //return call HplAtm128Timer.get();
+    return 1000;
+  }
+
+  async command timer_size Alarm.getAlarm() {
+    //return call HplAtm128Compare.get();
+    return 1000;
+  }
+
+  async command bool Alarm.isRunning() {
+    return TRUE;
+  }
+
+  async command void Alarm.stop() {
+    return;
+  }
+
+  async command void Alarm.start( timer_size dt ) 
+  {
+    //call Alarm.startAt( call HplAtm128Timer.get(), dt);
+    call Alarm.startAt( 1000, dt);
+  }
+
+  async command void Alarm.startAt( timer_size t0, timer_size dt ) {
+	/* Note: all HplAtm128Compare.set values have one subtracted,
+	   because the comparisons are continuous, but the actual
+	   interrupt is signalled at the next timer clock cycle. */
+     call HplAtm128Compare.start();
+  }
+
+  async event void HplAtm128Compare.fired() {
+    call HplAtm128Compare.stop();
+    dbg("Atm128AlarmC", " Compare fired, signal alarm above.\n");
+    __nesc_enable_interrupt();
+    signal Alarm.fired();
+  }
+
+  //async event void HplAtm128Timer.overflow() {
+  //}
+}
Index: tos/chips/atm128/timer/sim/Atm128GpioCaptureC.nc
===================================================================
RCS file: tos/chips/atm128/timer/sim/Atm128GpioCaptureC.nc
diff -N tos/chips/atm128/timer/sim/Atm128GpioCaptureC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/timer/sim/Atm128GpioCaptureC.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (c) 2004-2005 Crossbow Technology, Inc.
+ *  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 (updated) modification history and the author appear in
+ *  all copies of this source code.
+ *
+ *  Permission is also granted to distribute this software under the
+ *  standard BSD license as contained in the TinyOS distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS 
+ *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, 
+ *  OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+ *  THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  $Id: Atm128GpioCaptureC.nc,v 1.5 2008/06/26 04:39:06 regehr Exp $
+ */
+
+/**
+ * Expose capture capability as a GpioCapture interface from TEP117.
+ *
+ * @author Martin Turon, Crossbow <mturon@xbow.com>
+ */
+generic module Atm128GpioCaptureC() @safe() {
+
+  provides interface GpioCapture as Capture;
+  uses interface HplAtm128Capture<uint16_t> as Atm128Capture;
+
+}
+
+implementation {
+
+  error_t enableCapture( uint8_t mode ) {
+    atomic {
+      call Atm128Capture.stop();
+      call Atm128Capture.reset();
+      call Atm128Capture.setEdge( mode );
+      call Atm128Capture.start();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t Capture.captureRisingEdge() {
+    return enableCapture( TRUE );
+  }
+
+  async command error_t Capture.captureFallingEdge() {
+    return enableCapture( FALSE );
+  }
+
+  async command void Capture.disable() {
+    call Atm128Capture.stop();
+  }
+
+  async event void Atm128Capture.captured( uint16_t timet ) {
+    call Atm128Capture.reset();
+    signal Capture.captured( timet );
+  }
+
+}
Index: tos/chips/atm128/timer/sim/HplAtm128CompareC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/timer/sim/HplAtm128CompareC.nc,v
retrieving revision 1.7
diff -u -b -p -r1.7 HplAtm128CompareC.nc
--- tos/chips/atm128/timer/sim/HplAtm128CompareC.nc	29 Jun 2010 22:07:43 -0000	1.7
+++ tos/chips/atm128/timer/sim/HplAtm128CompareC.nc	9 Jul 2010 19:45:15 -0000
@@ -268,6 +268,9 @@ implementation {
       sim_event_t* newEvent = allocate_compare();
       configure_compare(newEvent);
 
+      newEvent->type = TIMER;
+      newEvent->source = RADIO;
+      newEvent->mark = TRUE;
       compare = newEvent;
       sim_queue_insert(newEvent);
     }
@@ -277,6 +280,7 @@ implementation {
     dbg("HplAtm128CompareC", "Cancelling compare at 0x%p\n", compare);
     if (compare != NULL) {
       compare->cancelled = 1;
+      compare->mark = FALSE;
       compare->cleanup = sim_queue_cleanup_total;
     }
   }
Index: tos/chips/atm128/timer/sim/HplAtm128Counter0C.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/timer/sim/HplAtm128Counter0C.nc,v
retrieving revision 1.5
diff -u -b -p -r1.5 HplAtm128Counter0C.nc
--- tos/chips/atm128/timer/sim/HplAtm128Counter0C.nc	29 Jun 2010 22:07:43 -0000	1.5
+++ tos/chips/atm128/timer/sim/HplAtm128Counter0C.nc	9 Jul 2010 19:45:15 -0000
@@ -373,12 +373,16 @@ implementation
       cancel_overflow();
     }
     overflow = newEvent;
+    newEvent->type = TIMER;
+    newEvent->source = SERIAL;
+    newEvent->mark = TRUE;
     sim_queue_insert(newEvent);
   }
   
   void cancel_overflow() {
     if (overflow != NULL) {
       overflow->cancelled = 1;
+      overflow->mark = FALSE;
       dbg("HplAtm128Counter0C", "Cancelling overflow %p.\n", overflow);
       overflow->cleanup = sim_queue_cleanup_total;
     }
Index: tos/chips/atm128/timer/sim/HplAtm128Timer0AsyncP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/timer/sim/HplAtm128Timer0AsyncP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 HplAtm128Timer0AsyncP.nc
--- tos/chips/atm128/timer/sim/HplAtm128Timer0AsyncP.nc	29 Jun 2010 22:07:43 -0000	1.2
+++ tos/chips/atm128/timer/sim/HplAtm128Timer0AsyncP.nc	9 Jul 2010 19:45:15 -0000
@@ -94,6 +94,7 @@ implementation {
   AVR_ATOMIC_HANDLER(SIG_OUTPUT_COMPARE0) {
     //stabiliseTimer0();
     signal Compare.fired();
+    sim_timer0_compare_signal();
   }
  
   default async event void Timer0.overflow() { }
@@ -225,6 +226,7 @@ implementation {
     dbg("HplAtm128Timer0AsyncP", "Allocated compare at 0x%p\n", newEvent);
     newEvent->handle = timer0_compare_handle;
     newEvent->cleanup = sim_queue_cleanup_none;
+    newEvent->source = RADIO;
     return newEvent;
   }
   
@@ -273,6 +275,8 @@ implementation {
       configure_compare(newEvent);
 
       compare = newEvent;
+      newEvent->type = TIMER;
+      newEvent->mark = TRUE;
       sim_queue_insert(newEvent);
     }
   }
@@ -502,6 +506,7 @@ implementation {
 
     newEvent->handle = timer0_overflow_handle;
     newEvent->cleanup = sim_queue_cleanup_none;
+    newEvent->source = SERIAL;
     return newEvent;
   }
   
@@ -539,12 +544,15 @@ implementation {
       cancel_overflow();
     }
     overflow = newEvent;
+    newEvent->type = TIMER;
+    newEvent->mark = TRUE;
     sim_queue_insert(newEvent);
   }
   
   void cancel_overflow() {
     if (overflow != NULL) {
       overflow->cancelled = 1;
+      overflow->mark = FALSE;
       dbg("HplAtm128Timer0AsyncP", "Cancelling overflow %p.\n", overflow);
       overflow->cleanup = sim_queue_cleanup_total;
     }
@@ -578,7 +586,34 @@ implementation {
     dbg("HplAtm128CompareC", "Cancelling compare at 0x%p\n", compare);
     if (compare != NULL) {
       compare->cancelled = 1;
+      compare->mark = FALSE;
       compare->cleanup = sim_queue_cleanup_total;
     }
   }
+
+  /****************  The following two functions are constructed for preserving and restoring state *************/
+  void sim_reset_compare_overflow(sim_event_t* timer) @C() @spontaneous() {
+    int tmp = sim_node();
+    sim_set_node(timer->mote);
+
+    if(timer->source == RADIO) {
+       if(timer->mark == TRUE) {
+          compare = timer;
+       }
+    }
+    else {
+       if(timer->mark == TRUE) {
+          overflow = timer;
+       }
+    }
+    sim_set_node(tmp);
+  }
+
+  void sim_clear_compare_overflow(int node) @C() @spontaneous() {
+    int tmp = sim_node();
+    sim_set_node(node);
+    compare = NULL;
+    overflow = NULL;
+    sim_set_node(tmp);
+  }
 }
Index: tos/chips/atm128/timer/sim/HplAtm128Timer1C.nc
===================================================================
RCS file: tos/chips/atm128/timer/sim/HplAtm128Timer1C.nc
diff -N tos/chips/atm128/timer/sim/HplAtm128Timer1C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/timer/sim/HplAtm128Timer1C.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,55 @@
+/// $Id: HplAtm128Timer1C.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * HPL interface to Atmega128 timer 1.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author David Gay <dgay@intel-research.net>
+ */
+
+configuration HplAtm128Timer1C
+{
+  provides {
+    // 16-bit Timers
+    interface HplAtm128Timer<uint16_t>   as Timer;
+    interface HplAtm128TimerCtrl16       as TimerCtrl;
+    interface HplAtm128Capture<uint16_t> as Capture;
+    interface HplAtm128Compare<uint16_t> as Compare[uint8_t id];
+  }
+}
+implementation
+{
+  components HplAtm128Timer0AsyncC, HplAtm128Timer1P;
+
+  Timer = HplAtm128Timer1P;
+  TimerCtrl = HplAtm128Timer1P;
+  Capture = HplAtm128Timer1P;
+
+  Compare[0] = HplAtm128Timer1P.CompareA; 
+  Compare[1] = HplAtm128Timer1P.CompareB;
+  Compare[2] = HplAtm128Timer1P.CompareC;
+
+  HplAtm128Timer1P.Timer0Ctrl -> HplAtm128Timer0AsyncC;
+}
Index: tos/chips/atm128/timer/sim/HplAtm128Timer1P.nc
===================================================================
RCS file: tos/chips/atm128/timer/sim/HplAtm128Timer1P.nc
diff -N tos/chips/atm128/timer/sim/HplAtm128Timer1P.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/timer/sim/HplAtm128Timer1P.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,324 @@
+/// $Id: HplAtm128Timer1P.nc,v 1.6 2008/06/23 20:25:15 regehr Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Internal component of the HPL interface to Atmega128 timer 1.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ */
+
+#include <Atm128Timer.h>
+
+module HplAtm128Timer1P @safe()
+{
+  provides {
+    // 16-bit Timers
+    interface HplAtm128Timer<uint16_t>   as Timer;
+    interface HplAtm128TimerCtrl16       as TimerCtrl;
+    interface HplAtm128Capture<uint16_t> as Capture;
+    interface HplAtm128Compare<uint16_t> as CompareA;
+    interface HplAtm128Compare<uint16_t> as CompareB;
+    interface HplAtm128Compare<uint16_t> as CompareC;
+  }
+  uses interface HplAtm128TimerCtrl8     as Timer0Ctrl;
+}
+implementation
+{
+  sim_event_t sim_compare1A_intr;
+  sim_event_t sim_compare1B_intr;
+  sim_event_t sim_compare1C_intr;
+
+  //=== Read the current timer value. ===================================
+  async command uint16_t Timer.get() { return TCNT1; }
+
+  //=== Set/clear the current timer value. ==============================
+  async command void Timer.set(uint16_t t) { TCNT1 = t; }
+
+  //=== Read the current timer scale. ===================================
+  async command uint8_t Timer.getScale() { return TCCR1B & 0x7; }
+
+  //=== Turn off the timers. ============================================
+  async command void Timer.off() { call Timer.setScale(AVR_CLOCK_OFF); }
+
+  //=== Write a new timer scale. ========================================
+  async command void Timer.setScale(uint8_t s)  { 
+    Atm128TimerCtrlCapture_t x = call TimerCtrl.getCtrlCapture();
+    x.bits.cs = s;
+    call TimerCtrl.setCtrlCapture(x);  
+  }
+
+  //=== Read the control registers. =====================================
+  async command Atm128TimerCtrlCompare_t TimerCtrl.getCtrlCompare() { 
+    return *(Atm128TimerCtrlCompare_t*ONE)&TCCR1A; 
+  }
+  async command Atm128TimerCtrlCapture_t TimerCtrl.getCtrlCapture() { 
+    return *(Atm128TimerCtrlCapture_t*ONE)&TCCR1B; 
+  }
+  async command Atm128TimerCtrlClock_t TimerCtrl.getCtrlClock() { 
+    return *(Atm128TimerCtrlClock_t*ONE)&TCCR1C; 
+  }
+
+
+  //=== Control registers utilities. ==================================
+  DEFINE_UNION_CAST(TimerCtrlCompare2int, Atm128TimerCtrlCompare_t, uint16_t);
+  DEFINE_UNION_CAST(TimerCtrlCapture2int, Atm128TimerCtrlCapture_t, uint16_t);
+  DEFINE_UNION_CAST(TimerCtrlClock2int, Atm128TimerCtrlClock_t, uint16_t);
+
+  //=== Write the control registers. ====================================
+  async command void TimerCtrl.setCtrlCompare( Atm128_TCCR1A_t x ) { 
+    TCCR1A = TimerCtrlCompare2int(x); 
+  }
+  async command void TimerCtrl.setCtrlCapture( Atm128_TCCR1B_t x ) { 
+    TCCR1B = TimerCtrlCapture2int(x); 
+  }
+  async command void TimerCtrl.setCtrlClock( Atm128_TCCR1C_t x ) { 
+    TCCR1C = TimerCtrlClock2int(x); 
+  }
+
+  //=== Read the interrupt mask. =====================================
+  async command Atm128_ETIMSK_t TimerCtrl.getInterruptMask() { 
+    return *(Atm128_ETIMSK_t*)&ETIMSK; 
+  }
+
+  //=== Write the interrupt mask. ====================================
+  DEFINE_UNION_CAST(TimerMask8_2int, Atm128_TIMSK_t, uint8_t);
+  DEFINE_UNION_CAST(TimerMask16_2int, Atm128_ETIMSK_t, uint8_t);
+
+  async command void TimerCtrl.setInterruptMask( Atm128_ETIMSK_t x ) { 
+    ETIMSK = TimerMask16_2int(x); 
+  }
+
+  //=== Read the interrupt flags. =====================================
+  async command Atm128_ETIFR_t TimerCtrl.getInterruptFlag() { 
+    return *(Atm128_ETIFR_t*ONE)&ETIFR; 
+  }
+
+  //=== Write the interrupt flags. ====================================
+  DEFINE_UNION_CAST(TimerFlags8_2int, Atm128_TIFR_t, uint8_t);
+  DEFINE_UNION_CAST(TimerFlags16_2int, Atm128_ETIFR_t, uint8_t);
+
+  async command void TimerCtrl.setInterruptFlag( Atm128_ETIFR_t x ) { 
+    ETIFR = TimerFlags16_2int(x); 
+  }
+
+  //=== Capture 16-bit implementation. ===================================
+  async command void Capture.setEdge(bool up) { WRITE_BIT(TCCR1B,ICES1, up); }
+
+  //=== Timer 16-bit implementation. ===================================
+  async command void Timer.reset()    { TIFR = 1 << TOV1; }
+  async command void Capture.reset()  { TIFR = 1 << ICF1; }
+  async command void CompareA.reset() { TIFR = 1 << OCF1A; }
+  async command void CompareB.reset() { TIFR = 1 << OCF1B; }
+  async command void CompareC.reset() { ETIFR = 1 << OCF1C; }
+
+  async command void Timer.start()    { SET_BIT(TIMSK,TOIE1); }
+  async command void Capture.start()  { SET_BIT(TIMSK,TICIE1); }
+
+  //=== Timer interrupts signals ========================================
+  default async event void CompareA.fired() { }
+  AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE1A) {
+    signal CompareA.fired();
+  }
+  default async event void CompareB.fired() { }
+  AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE1B) {
+    signal CompareB.fired();
+  }
+  default async event void CompareC.fired() { }
+  AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE1C) {
+    signal CompareC.fired();
+  }
+
+  /* Here we just emulate the occurrence of compare A interrupt, 
+     omitting the analysis of value of register*/
+  void compareA_interrupt_handle(sim_event_t* evt) {
+    if(evt->cancelled) {
+       return;
+    }
+    SIG_OUTPUT_COMPARE1A();
+  }
+
+  void compareB_interrupt_handle(sim_event_t* evt) {
+    if(evt->cancelled) {
+       return;
+    }
+    SIG_OUTPUT_COMPARE1B();
+  }
+
+  void compareC_interrupt_handle(sim_event_t* evt) {
+    if(evt->cancelled) {
+       return;
+    }
+    SIG_OUTPUT_COMPARE1C();
+  }
+
+  void allocate_compareA_interrupt() {
+    dbg("HplAtm128Timer1P", "Allocated compare A interrupt at 0x%p\n", &sim_compare1A_intr);
+    sim_compare1A_intr.mote = sim_node();
+    sim_compare1A_intr.force = 0;
+    sim_compare1A_intr.cancelled = 0;
+    sim_compare1A_intr.time = sim_time() + 10000;
+
+    sim_compare1A_intr.handle = compareA_interrupt_handle;
+    sim_compare1A_intr.type = INTERRUPT;
+    sim_compare1A_intr.source = INT_OUTPUT_COMPARE1A;
+    sim_compare1A_intr.cleanup = sim_queue_cleanup_none;
+    sim_compare1A_intr.mark = TRUE;
+  }
+
+  void allocate_compareB_interrupt() {
+    dbg("HplAtm128Timer1P", "Allocated compare B interrupt at 0x%p\n", &sim_compare1B_intr);
+    sim_compare1B_intr.mote = sim_node();
+    sim_compare1B_intr.force = 0;
+    sim_compare1B_intr.cancelled = 0;
+    sim_compare1B_intr.time = sim_time() + 10000;   
+
+    sim_compare1B_intr.handle = compareB_interrupt_handle;
+    sim_compare1B_intr.type = INTERRUPT;
+    sim_compare1B_intr.source = INT_OUTPUT_COMPARE1B;
+    sim_compare1B_intr.cleanup = sim_queue_cleanup_none;
+    sim_compare1B_intr.mark = TRUE;     
+  }
+
+  void allocate_compareC_interrupt() {
+    dbg("HplAtm128Timer1P", "Allocated compare C interrupt at 0x%p\n", &sim_compare1C_intr);
+    sim_compare1C_intr.mote = sim_node();
+    sim_compare1C_intr.force = 0;
+    sim_compare1C_intr.cancelled = 0;
+    sim_compare1C_intr.time = sim_time() + 10000;   
+
+    sim_compare1C_intr.handle = compareC_interrupt_handle;
+    sim_compare1C_intr.type = INTERRUPT;
+    sim_compare1C_intr.source = INT_OUTPUT_COMPARE1C;
+    sim_compare1C_intr.cleanup = sim_queue_cleanup_none;
+    sim_compare1C_intr.mark = TRUE;     
+  }
+
+  async command void CompareA.start() { 
+     SET_BIT(ATM128_TIMSK,OCIE1A);
+     allocate_compareA_interrupt();
+     sim_queue_insert(&sim_compare1A_intr);
+  }
+
+  async command void CompareB.start() { 
+     SET_BIT(ATM128_TIMSK,OCIE1B);
+     allocate_compareB_interrupt();
+     sim_queue_insert(&sim_compare1B_intr);
+  }
+
+  async command void CompareC.start() { 
+     SET_BIT(ATM128_TIMSK,OCIE1C);
+     allocate_compareC_interrupt();
+     sim_queue_insert(&sim_compare1C_intr);
+  }
+
+  async command void Timer.stop()    { CLR_BIT(TIMSK,TOIE1); }
+  async command void Capture.stop()  { CLR_BIT(TIMSK,TICIE1); }
+
+  async command void CompareA.stop() { 
+     CLR_BIT(ATM128_TIMSK,OCIE1A);
+     sim_compare1A_intr.mark = FALSE;
+     return; 
+  }
+
+  async command void CompareB.stop() { 
+     CLR_BIT(ATM128_TIMSK,OCIE1B);
+     sim_compare1B_intr.mark = FALSE;
+     return; 
+  }
+
+  async command void CompareC.stop() { 
+     CLR_BIT(ATM128_TIMSK,OCIE1C);
+     sim_compare1C_intr.mark = FALSE;
+     return; 
+  }
+
+  // Note: Many Timer interrupt flags are on Timer0 register
+  async command bool Timer.test() { 
+    //return (call Timer0Ctrl.getInterruptFlag()).bits.tov1; 
+    return TRUE;
+  }
+  async command bool Capture.test()  { 
+    //return (call Timer0Ctrl.getInterruptFlag()).bits.icf1; 
+    return TRUE;
+  }
+  async command bool CompareA.test() { 
+    //return (call Timer0Ctrl.getInterruptFlag()).bits.ocf1a; 
+    return TRUE;
+  }
+  async command bool CompareB.test() { 
+    //return (call Timer0Ctrl.getInterruptFlag()).bits.ocf1b; 
+    return TRUE;
+  }
+  async command bool CompareC.test() { 
+    //return (call TimerCtrl.getInterruptFlag()).bits.ocf1c; 
+    return TRUE;
+  }
+
+  // Note: Many Timer interrupt mask bits are on Timer0 register
+  async command bool Timer.isOn() {
+    //return (call Timer0Ctrl.getInterruptMask()).bits.toie1;
+    return TRUE;
+  }
+  async command bool Capture.isOn()  {
+    //return (call Timer0Ctrl.getInterruptMask()).bits.ticie1;
+    return TRUE;
+  }
+  async command bool CompareA.isOn() {
+    //return (call Timer0Ctrl.getInterruptMask()).bits.ocie1a;
+    return TRUE;
+  }
+  async command bool CompareB.isOn() {
+    //return (call Timer0Ctrl.getInterruptMask()).bits.ocie1b;
+    return TRUE;
+  }
+  async command bool CompareC.isOn() {
+    //return (call TimerCtrl.getInterruptMask()).bits.ocie1c;
+    return TRUE;
+  }
+
+  //=== Read the compare registers. =====================================
+  async command uint16_t CompareA.get() { return OCR1A; }
+  async command uint16_t CompareB.get() { return OCR1B; }
+  async command uint16_t CompareC.get() { return OCR1C; }
+
+  //=== Write the compare registers. ====================================
+  async command void CompareA.set(uint16_t t) { OCR1A = t; }
+  async command void CompareB.set(uint16_t t) { OCR1B = t; }
+  async command void CompareC.set(uint16_t t) { OCR1C = t; }
+
+  //=== Read the capture registers. =====================================
+  async command uint16_t Capture.get() { return ICR1; }
+
+  //=== Write the capture registers. ====================================
+  async command void Capture.set(uint16_t t)  { ICR1 = t; }
+
+  default async event void Capture.captured(uint16_t timet) { }
+  AVR_NONATOMIC_HANDLER(SIG_INPUT_CAPTURE1) {
+    signal Capture.captured(call Timer.get());
+  }
+  default async event void Timer.overflow() { }
+  AVR_NONATOMIC_HANDLER(SIG_OVERFLOW1) {
+    signal Timer.overflow();
+  }
+}
Index: tos/chips/atm128/timer/sim/HplAtm128Timer3C.nc
===================================================================
RCS file: tos/chips/atm128/timer/sim/HplAtm128Timer3C.nc
diff -N tos/chips/atm128/timer/sim/HplAtm128Timer3C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/timer/sim/HplAtm128Timer3C.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,53 @@
+/// $Id: HplAtm128Timer3C.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * HPL interface to Atmega128 timer 2.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author David Gay <david.e.gay@intel.com>
+ */
+
+configuration HplAtm128Timer3C
+{
+  provides {
+    // 16-bit Timers
+    interface HplAtm128Timer<uint16_t>   as Timer;
+    interface HplAtm128TimerCtrl16       as TimerCtrl;
+    interface HplAtm128Capture<uint16_t> as Capture;
+    interface HplAtm128Compare<uint16_t> as Compare[uint8_t id];
+  }
+}
+implementation
+{
+  components HplAtm128Timer3P;
+
+  Timer = HplAtm128Timer3P;
+  TimerCtrl = HplAtm128Timer3P;
+  Capture = HplAtm128Timer3P;
+
+  Compare[0] = HplAtm128Timer3P.CompareA; 
+  Compare[1] = HplAtm128Timer3P.CompareB;
+  Compare[2] = HplAtm128Timer3P.CompareC;
+}
Index: tos/chips/atm128/timer/sim/HplAtm128Timer3P.nc
===================================================================
RCS file: tos/chips/atm128/timer/sim/HplAtm128Timer3P.nc
diff -N tos/chips/atm128/timer/sim/HplAtm128Timer3P.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/chips/atm128/timer/sim/HplAtm128Timer3P.nc	9 Jul 2010 19:45:15 -0000
@@ -0,0 +1,310 @@
+/// $Id: HplAtm128Timer3P.nc,v 1.4 2006/12/12 18:23:04 vlahan Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Internal componentr of the HPL interface to Atmega128 timer 3.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ */
+
+#include <Atm128Timer.h>
+
+module HplAtm128Timer3P
+{
+  provides {
+    interface HplAtm128Timer<uint16_t>   as Timer;
+    interface HplAtm128TimerCtrl16       as TimerCtrl;
+    interface HplAtm128Capture<uint16_t> as Capture;
+    interface HplAtm128Compare<uint16_t> as CompareA;
+    interface HplAtm128Compare<uint16_t> as CompareB;
+    interface HplAtm128Compare<uint16_t> as CompareC;
+  }
+}
+implementation
+{
+  sim_event_t sim_compare3A_intr;
+  sim_event_t sim_compare3B_intr;
+  sim_event_t sim_compare3C_intr;
+
+  //=== Read the current timer value. ===================================
+  async command uint16_t Timer.get() { return TCNT3; }
+
+  //=== Set/clear the current timer value. ==============================
+  async command void Timer.set(uint16_t t) { TCNT3 = t; }
+
+  //=== Read the current timer scale. ===================================
+  async command uint8_t Timer.getScale() { return TCCR3B & 0x7; }
+
+  //=== Turn off the timers. ============================================
+  async command void Timer.off() { call Timer.setScale(AVR_CLOCK_OFF); }
+
+  //=== Write a new timer scale. ========================================
+  async command void Timer.setScale(uint8_t s)  { 
+    Atm128TimerCtrlCapture_t x = call TimerCtrl.getCtrlCapture();
+    x.bits.cs = s;
+    call TimerCtrl.setCtrlCapture(x);  
+  }
+  //=== Read the control registers. =====================================
+
+  async command Atm128TimerCtrlCompare_t TimerCtrl.getCtrlCompare() { 
+    return *(Atm128TimerCtrlCompare_t*)&TCCR3A; 
+  }
+  async command Atm128TimerCtrlCapture_t TimerCtrl.getCtrlCapture() { 
+    return *(Atm128TimerCtrlCapture_t*)&TCCR3B; 
+  }
+  async command Atm128TimerCtrlClock_t TimerCtrl.getCtrlClock() { 
+    return *(Atm128TimerCtrlClock_t*)&TCCR3C; 
+  }
+
+
+  //=== Control registers utilities. ==================================
+  DEFINE_UNION_CAST(TimerCtrlCompare2int, Atm128TimerCtrlCompare_t, uint16_t);
+  DEFINE_UNION_CAST(TimerCtrlCapture2int, Atm128TimerCtrlCapture_t, uint16_t);
+  DEFINE_UNION_CAST(TimerCtrlClock2int, Atm128TimerCtrlClock_t, uint16_t);
+
+  //=== Write the control registers. ====================================
+  async command void TimerCtrl.setCtrlCompare( Atm128_TCCR3A_t x ) { 
+    TCCR3A = TimerCtrlCompare2int(x); 
+  }
+  async command void TimerCtrl.setCtrlCapture( Atm128_TCCR3B_t x ) { 
+    TCCR3B = TimerCtrlCapture2int(x); 
+  }
+  async command void TimerCtrl.setCtrlClock( Atm128_TCCR3C_t x ) { 
+    TCCR3C = TimerCtrlClock2int(x); 
+  }
+
+  //=== Read the interrupt mask. =====================================
+  async command Atm128_ETIMSK_t TimerCtrl.getInterruptMask() { 
+    return *(Atm128_ETIMSK_t*)&ETIMSK; 
+  }
+
+  //=== Write the interrupt mask. ====================================
+  DEFINE_UNION_CAST(TimerMask16_2int, Atm128_ETIMSK_t, uint8_t);
+
+  async command void TimerCtrl.setInterruptMask( Atm128_ETIMSK_t x ) { 
+    ETIMSK = TimerMask16_2int(x); 
+  }
+
+  //=== Read the interrupt flags. =====================================
+  async command Atm128_ETIFR_t TimerCtrl.getInterruptFlag() { 
+    return *(Atm128_ETIFR_t*)&ETIFR; 
+  }
+
+  //=== Write the interrupt flags. ====================================
+  DEFINE_UNION_CAST(TimerFlags16_2int, Atm128_ETIFR_t, uint8_t);
+
+  async command void TimerCtrl.setInterruptFlag( Atm128_ETIFR_t x ) { 
+    ETIFR = TimerFlags16_2int(x); 
+  }
+
+  //=== Capture 16-bit implementation. ===================================
+  async command void Capture.setEdge(bool up) { WRITE_BIT(TCCR3B,ICES3, up); }
+
+  //=== Timer 16-bit implementation. ===================================
+  async command void Timer.reset()    { ETIFR = 1 << TOV3; }
+  async command void Capture.reset()  { ETIFR = 1 << ICF3; }
+
+  async command void Timer.start()    { SET_BIT(ETIMSK,TOIE3); }
+  async command void Capture.start()  { SET_BIT(ETIMSK,TICIE3); }
+
+  async command void Timer.stop()    { CLR_BIT(ETIMSK,TOIE3); }
+  async command void Capture.stop()  { CLR_BIT(ETIMSK,TICIE3); }
+
+  async command bool Timer.test() { 
+    //return (call TimerCtrl.getInterruptFlag()).bits.tov3; 
+    return TRUE; 
+  }
+  async command bool Capture.test()  { 
+    //return (call TimerCtrl.getInterruptFlag()).bits.icf3; 
+    return TRUE; 
+  }
+
+  async command bool Timer.isOn() {
+    //return (call TimerCtrl.getInterruptMask()).bits.toie3;
+    return TRUE;
+  }
+  async command bool Capture.isOn()  {
+    //return (call TimerCtrl.getInterruptMask()).bits.ticie3;
+    return TRUE;
+  }
+
+  default async event void Timer.overflow() { }
+  AVR_NONATOMIC_HANDLER(SIG_OVERFLOW3) {
+    signal Timer.overflow();
+  }
+
+  //=== Read the capture registers. =====================================
+  async command uint16_t Capture.get() { return ICR3; }
+
+  //=== Write the capture registers. ====================================
+  async command void Capture.set(uint16_t t)  { ICR3 = t; }
+
+  default async event void Capture.captured(uint16_t timet) { }
+  AVR_NONATOMIC_HANDLER(SIG_INPUT_CAPTURE3) {
+    signal Capture.captured(call Timer.get());
+  }
+
+  //=== Timer 16-bit implementation. ===================================
+  async command void CompareA.reset() { return; }
+  async command void CompareB.reset() { return; }
+  async command void CompareC.reset() { return; }
+
+  //=== Timer interrupts signals ========================================
+  default async event void CompareA.fired() { }
+  AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE3A) {
+    signal CompareA.fired();
+  }
+  default async event void CompareB.fired() { }
+  AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE3B) {
+    signal CompareB.fired();
+  }
+  default async event void CompareC.fired() { }
+  AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE3C) {
+    signal CompareC.fired();
+  }
+
+  /* Here we just emulate the occurrence of compare A interrupt, 
+     omitting the analysis of value of register*/
+  void compareA_interrupt_handle(sim_event_t* evt) {
+    if(evt->cancelled) {
+       return;
+    }
+    SIG_OUTPUT_COMPARE3A();
+  }
+
+  void compareB_interrupt_handle(sim_event_t* evt) {
+    if(evt->cancelled) {
+       return;
+    }
+    SIG_OUTPUT_COMPARE3B();
+  }
+
+  void compareC_interrupt_handle(sim_event_t* evt) {
+    if(evt->cancelled) {
+       return;
+    }
+    SIG_OUTPUT_COMPARE3C();
+  }
+
+  void allocate_compareA_interrupt() {
+    dbg("SimHplAtm128Timer3P", "Allocated compare A interrupt at 0x%p\n", &sim_compare3A_intr);
+    sim_compare3A_intr.mote = sim_node();
+    sim_compare3A_intr.force = 0;
+    sim_compare3A_intr.cancelled = 0;
+    sim_compare3A_intr.time = sim_time() + 10000;
+
+    sim_compare3A_intr.handle = compareA_interrupt_handle;
+    sim_compare3A_intr.type = INTERRUPT;
+    sim_compare3A_intr.source = INT_OUTPUT_COMPARE3A;
+    sim_compare3A_intr.cleanup = sim_queue_cleanup_none;
+    sim_compare3A_intr.mark = TRUE;
+  }
+
+  void allocate_compareB_interrupt() {
+    dbg("SimHplAtm128Timer3P", "Allocated compare B interrupt at 0x%p\n", &sim_compare3B_intr);
+    sim_compare3B_intr.mote = sim_node();
+    sim_compare3B_intr.force = 0;
+    sim_compare3B_intr.cancelled = 0;
+    sim_compare3B_intr.time = sim_time() + 10000;   
+
+    sim_compare3B_intr.handle = compareB_interrupt_handle;
+    sim_compare3B_intr.type = INTERRUPT;
+    sim_compare3B_intr.source = INT_OUTPUT_COMPARE3B;
+    sim_compare3B_intr.cleanup = sim_queue_cleanup_none;
+    sim_compare3B_intr.mark = TRUE;     
+  }
+
+  void allocate_compareC_interrupt() {
+    dbg("SimHplAtm128Timer3P", "Allocated compare C interrupt at 0x%p\n", &sim_compare3C_intr);
+    sim_compare3C_intr.mote = sim_node();
+    sim_compare3C_intr.force = 0;
+    sim_compare3C_intr.cancelled = 0;
+    sim_compare3C_intr.time = sim_time() + 10000;   
+
+    sim_compare3C_intr.handle = compareC_interrupt_handle;
+    sim_compare3C_intr.type = INTERRUPT;
+    sim_compare3C_intr.source = INT_OUTPUT_COMPARE3C;
+    sim_compare3C_intr.cleanup = sim_queue_cleanup_none;
+    sim_compare3C_intr.mark = TRUE;     
+  }
+
+  async command void CompareA.start() { 
+     allocate_compareA_interrupt();
+     sim_queue_insert(&sim_compare3A_intr);
+  }
+
+  async command void CompareB.start() { 
+     allocate_compareB_interrupt();
+     sim_queue_insert(&sim_compare3B_intr);
+  }
+
+  async command void CompareC.start() { 
+     allocate_compareC_interrupt();
+     sim_queue_insert(&sim_compare3C_intr);
+  }
+
+  async command void CompareA.stop() { 
+     sim_compare3A_intr.mark = FALSE;
+     return; 
+  }
+  async command void CompareB.stop() { 
+     sim_compare3B_intr.mark = FALSE;
+     return; 
+  }
+  async command void CompareC.stop() { 
+     sim_compare3C_intr.mark = FALSE;
+     return; 
+  }
+
+  async command bool CompareA.test() { 
+    return TRUE;
+  }
+  async command bool CompareB.test() { 
+    return TRUE;
+  }
+  async command bool CompareC.test() { 
+    return TRUE;
+  }
+
+  async command bool CompareA.isOn() {
+    return TRUE;
+  }
+  async command bool CompareB.isOn() {
+    return TRUE;
+  }
+  async command bool CompareC.isOn() {
+    return TRUE;
+  }
+
+  //=== Read the compare registers. =====================================
+  async command uint16_t CompareA.get() { return OCR3A; }
+  async command uint16_t CompareB.get() { return OCR3B; }
+  async command uint16_t CompareC.get() { return OCR3C; }
+
+  //=== Write the compare registers. ====================================
+  async command void CompareA.set(uint16_t t) { OCR3A = t; }
+  async command void CompareB.set(uint16_t t) { OCR3B = t; }
+  async command void CompareC.set(uint16_t t) { OCR3C = t; }
+
+}
Index: tos/lib/ftsp/TimeSyncP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/ftsp/TimeSyncP.nc,v
retrieving revision 1.13
diff -u -b -p -r1.13 TimeSyncP.nc
--- tos/lib/ftsp/TimeSyncP.nc	29 Jun 2010 22:07:47 -0000	1.13
+++ tos/lib/ftsp/TimeSyncP.nc	9 Jul 2010 19:45:15 -0000
@@ -34,7 +34,7 @@
  */
 #include "TimeSyncMsg.h"
 
-generic module TimeSyncP(typedef precision_tag)
+generic module TimeSyncP(typedef precision_tag) @safe()
 {
     provides
     {
@@ -122,10 +122,10 @@ implementation
     uint8_t     numEntries; // the number of full entries in the table
 
     message_t processedMsgBuffer;
-    message_t* processedMsg;
+    message_t* ONE_NOK processedMsg;
 
     message_t outgoingMsgBuffer;
-    TimeSyncMsg* outgoingMsg;
+    TimeSyncMsg* ONE_NOK outgoingMsg;
 
     uint8_t heartBeats; // the number of sucessfully sent messages
                         // since adding a new entry with lower beacon id than ours
@@ -135,31 +135,34 @@ implementation
         return call LocalTime.get();
     }
 
-    async command error_t GlobalTime.getGlobalTime(uint32_t *time)
+    async command error_t GlobalTime.getGlobalTime(uint32_t *timet)
     {
-        *time = call GlobalTime.getLocalTime();
-        return call GlobalTime.local2Global(time);
+        *timet = call GlobalTime.getLocalTime();
+        return call GlobalTime.local2Global(timet);
     }
 
     error_t is_synced()
     {
+      // These two lines are added for checking user-specified properties.
+      if(outgoingMsg == NULL)
+        return FAIL;
+
       if (numEntries>=ENTRY_VALID_LIMIT || outgoingMsg->rootID==TOS_NODE_ID)
         return SUCCESS;
       else
         return FAIL;
     }
 
-
-    async command error_t GlobalTime.local2Global(uint32_t *time)
+    async command error_t GlobalTime.local2Global(uint32_t *timet)
     {
-        *time += offsetAverage + (int32_t)(skew * (int32_t)(*time - localAverage));
+        *timet += offsetAverage + (int32_t)(skew * (int32_t)(*timet - localAverage));
         return is_synced();
     }
 
-    async command error_t GlobalTime.global2Local(uint32_t *time)
+    async command error_t GlobalTime.global2Local(uint32_t *timet)
     {
-        uint32_t approxLocalTime = *time - offsetAverage;
-        *time = approxLocalTime - (int32_t)(skew * (int32_t)(approxLocalTime - localAverage));
+        uint32_t approxLocalTime = *timet - offsetAverage;
+        *timet = approxLocalTime - (int32_t)(skew * (int32_t)(approxLocalTime - localAverage));
         return is_synced();
     }
 
@@ -291,7 +294,7 @@ implementation
 
     void task processMsg()
     {
-        TimeSyncMsg* msg = (TimeSyncMsg*)(call Send.getPayload(processedMsg, sizeof(TimeSyncMsg)));
+	TimeSyncMsg* msg = TCAST(TimeSyncMsg* ONE, call Send.getPayload(processedMsg, sizeof(TimeSyncMsg)));
 
         if( msg->rootID < outgoingMsg->rootID &&
             //after becoming the root, a node ignores messages that advertise the old root (it may take
@@ -335,7 +338,7 @@ implementation
             message_t* old = processedMsg;
 
             processedMsg = msg;
-            ((TimeSyncMsg*)(payload))->localTime = call TimeSyncPacket.eventTime(msg);
+            (TCAST(TimeSyncMsg* ONE, payload))->localTime = call TimeSyncPacket.eventTime(msg);
 
             state |= STATE_PROCESSING;
             post processMsg();
@@ -459,7 +462,7 @@ implementation
 
         clearTable();
 
-        atomic outgoingMsg = (TimeSyncMsg*)call Send.getPayload(&outgoingMsgBuffer, sizeof(TimeSyncMsg));
+        atomic outgoingMsg = TCAST(TimeSyncMsg* ONE, call Send.getPayload(&outgoingMsgBuffer, sizeof(TimeSyncMsg)));
         outgoingMsg->rootID = 0xFFFF;
 
         processedMsg = &processedMsgBuffer;
Index: tos/lib/net/4bitle/LinkEstimatorP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/4bitle/LinkEstimatorP.nc,v
retrieving revision 1.19
diff -u -b -p -r1.19 LinkEstimatorP.nc
--- tos/lib/net/4bitle/LinkEstimatorP.nc	29 Jun 2010 22:07:47 -0000	1.19
+++ tos/lib/net/4bitle/LinkEstimatorP.nc	9 Jul 2010 19:45:15 -0000
@@ -39,7 +39,7 @@
 
 #include "./LinkEstimator.h"
 
-module LinkEstimatorP {
+module LinkEstimatorP @safe(){
   provides {
     interface StdControl;
     interface AMSend as Send;
Index: tos/lib/net/6lowpan/IP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/6lowpan/IP.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 IP.nc
--- tos/lib/net/6lowpan/IP.nc	5 Dec 2007 22:58:41 -0000	1.1
+++ tos/lib/net/6lowpan/IP.nc	9 Jul 2010 19:45:15 -0000
@@ -74,5 +74,5 @@
 interface IP {
     command void getAddress(ip6_addr_t *addr);
     command void setAddress(const ip6_addr_t *addr);
-    command void setAddressAutoconf(const ip6_addr_t *addr);
+    command void setAddressAutoconf(const ip6_addr_t * ONE addr);
 }
Index: tos/lib/net/6lowpan/IPC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/6lowpan/IPC.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 IPC.nc
--- tos/lib/net/6lowpan/IPC.nc	5 Dec 2007 22:58:41 -0000	1.1
+++ tos/lib/net/6lowpan/IPC.nc	9 Jul 2010 19:45:15 -0000
@@ -34,7 +34,9 @@
 #include "message.h"
 
 #ifdef ENABLE_PRINTF_DEBUG
-#include "printf.h"
+#ifndef TOSSIM
+  #include "printf.h"
+#endif
 #endif /* ENABLE_PRINTF_DEBUG */
 
 configuration IPC {
Index: tos/lib/net/6lowpan/IPP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/6lowpan/IPP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 IPP.nc
--- tos/lib/net/6lowpan/IPP.nc	4 Jun 2008 04:33:45 -0000	1.2
+++ tos/lib/net/6lowpan/IPP.nc	9 Jul 2010 19:45:15 -0000
@@ -102,7 +102,7 @@
 #include "printf.h"
 #endif /* ENABLE_PRINTF_DEBUG */
 
-module IPP {
+module IPP @safe() {
     provides {
 	interface SplitControl as IPControl;
 	interface IP;
@@ -159,18 +159,18 @@ implementation { 
 
     // Pre-declare
     // clear all fields, set app_data = NULL
-    void lowpan_pkt_clear(lowpan_pkt_t *pkt);
+    void lowpan_pkt_clear(lowpan_pkt_t * ONE pkt);
     int ip6_addr_cmp(const ip6_addr_t *a, const ip6_addr_t *b);
 
     static void dump_serial_packet(const unsigned char *packet, const int len);
 /*---------------------------------------------------------------------------*/
 /* from http://www.nabble.com/memcpy-assumes-16-bit-alignment--t712619.html */
 void * 
-my_memcpy(void *dst0, const void *src0, size_t len) 
+my_memcpy(void * COUNT(len) dst0, const void * COUNT(len) src0, size_t len) 
 { 
         char *dst = (char *)dst0; 
         const char *src = (const char *)src0; 
-        void *ret = dst0; 
+        void * COUNT(len) ret = dst0; 
 
         for (; len > 0; len--) 
                 *dst++ = *src++; 
@@ -189,7 +189,7 @@ my_memcpy(void *dst0, const void *src0, 
  * and page 25 in http://www.eecs.harvard.edu/~konrad/projects/motetrack/mspgcc-manual-20031127.pdf for details.
  */
 /* use when DST may be UNALIGNED */
-inline void set_16t(void *dst, uint16_t val)
+inline void set_16t(void * COUNT(2) dst, uint16_t val)
 {
     *((uint8_t*)dst) = *((uint8_t*)&val);
     *(((uint8_t*)dst)+1) = *(((uint8_t*)&val)+1);
@@ -198,7 +198,7 @@ inline void set_16t(void *dst, uint16_t 
 }
 
 /* use when SRC may be UNALIGNED */
-inline uint16_t get_16t(void *val)
+inline uint16_t get_16t(void * COUNT(2) val)
 {
     uint16_t tmp;
     *((uint8_t*)&tmp) = *((uint8_t*)val);
@@ -249,21 +249,25 @@ inline uint16_t get_16t(void *val)
 /*---------------------------------------------------------------------------*/
     
     /* This should be optimized for aligned and unaligned case */
-    static uint16_t ip_chksum(const uint8_t *buf, uint16_t len,
+    static uint16_t ip_chksum(const uint8_t * COUNT(len) buf, uint16_t len,
 			      uint16_t acc)
     {
 	uint16_t v;
+	uint16_t tmpLen = len;
+	const uint8_t* BND(buf, buf+tmpLen) tmpBuf = buf;
 	
 	for (; len > 1; len -= 2) {
-	    v = (((uint16_t) buf[1]) << 8) | ((uint16_t) buf[0]);
+	    //v = (((uint16_t) buf[1]) << 8) | ((uint16_t) buf[0]);
+	    v = (((uint16_t) tmpBuf[1]) << 8) | ((uint16_t) tmpBuf[0]);
 	    
 	    if ( (acc += v) < v ) acc++;
-	    buf += 2;
+	    tmpBuf += 2;
     }
 	
 	// add an odd byte (note we pad with 0)
 	if (len) {
-	    v = (uint16_t) buf[0];
+	    //v = (uint16_t) buf[0];
+	    v = (uint16_t) tmpBuf[0];
 	    if ( (acc += v) < v ) acc++;
 	}
 	
@@ -275,8 +279,8 @@ inline uint16_t get_16t(void *val)
      * src_addr and dst_addr are in nerwork byte order
      * len is in host byte order (will internally be converted)
      */
-    static uint16_t ipv6_chksum(const ip6_addr_t* src_addr,
-				const ip6_addr_t* dst_addr,
+    static uint16_t ipv6_chksum(const ip6_addr_t* ONE_NOK src_addr,
+				const ip6_addr_t* ONE_NOK dst_addr,
 				const uint8_t next_header,
 				const uint16_t upper_layer_len,
 				uint16_t acc)
@@ -301,10 +305,10 @@ inline uint16_t get_16t(void *val)
     }
 
     /* same as above, but including the uppel-layer buffer */
-    static uint16_t ipv6_chksum_data(const ip6_addr_t* src_addr,
-				     const ip6_addr_t* dst_addr, 
+    static uint16_t ipv6_chksum_data(const ip6_addr_t* ONE_NOK src_addr,
+				     const ip6_addr_t* ONE_NOK dst_addr, 
 				     const uint8_t next_header,
-				     const uint8_t *data, uint16_t data_len,
+				     const uint8_t * COUNT(data_len) data, uint16_t data_len,
 				     uint16_t acc)
     {
 	/* upper-layer payload */
@@ -341,13 +345,15 @@ inline uint16_t get_16t(void *val)
     }
     
 //TODO: prepend pan_id once we have a proper 802.15.4 stack
-void ipv6_iface_id_from_am_addr(am_addr_t am_addr, uint8_t *host_part)
+void ipv6_iface_id_from_am_addr(am_addr_t am_addr, uint8_t * COUNT(8) host_part)
 {
+    uint8_t* BND(host_part, host_part + 8) tmp_host_part = host_part;
     memset(host_part, 0, 6);
     host_part[4] = 0xFF;
     host_part[5] = 0xFE;
-    host_part += 6;
-    set_16t(host_part, htons(am_addr));
+    //host_part += 6;
+    tmp_host_part += 6;
+    set_16t(tmp_host_part, htons(am_addr));
 }
 
 void ipv6_iface_id_from_hw_addr(hw_addr_t *hw_addr, uint8_t *host_part)
@@ -470,7 +476,7 @@ uint8_t ipv6_addr_is_for_me(const ip6_ad
 }
 
 /* determine the right src_addr given a dst_addr */
-ip6_addr_t * determine_src_ipv6_addr(const ip6_addr_t *dst_addr)
+ip6_addr_t * ONE determine_src_ipv6_addr(const ip6_addr_t *dst_addr)
 {
     if (ipv6_addr_is_linklocal(dst_addr)) {
 	return &linklocal_addr;
@@ -479,7 +485,7 @@ ip6_addr_t * determine_src_ipv6_addr(con
     }
 }
 
-uint8_t cmp_hw_addr(const hw_addr_t *addr1, const hw_addr_t *addr2)
+uint8_t TRUSTEDBLOCK cmp_hw_addr(const hw_addr_t *addr1, const hw_addr_t *addr2)
 {
     // for short addresses compare only the first two bytes
     if (addr1->type == HW_ADDR_SHORT && addr2->type == HW_ADDR_SHORT) {
@@ -522,7 +528,7 @@ void increment_g_dgram_tag()
     g_dgram_tag = htons(tmp);
 }
 
-void lowpan_pkt_clear(lowpan_pkt_t *pkt)
+void TRUSTEDBLOCK lowpan_pkt_clear(lowpan_pkt_t * pkt)
 {
     memset(pkt, 0, sizeof(*pkt));
     pkt->header_begin = pkt->header + sizeof(pkt->header);
@@ -574,7 +580,7 @@ void free_frag_list(frag_info_t *p)
 }
 /*---------------------------------------------------------------------------*/
   
-    void ip_init()
+    void TRUSTEDBLOCK ip_init()
     {
 	//int i;
 	lastport = 1024;
@@ -611,7 +617,7 @@ void free_frag_list(frag_info_t *p)
     }    
 
 /* ========================= IPv6 - output ================================= */
-task void sendTask()
+TRUSTEDBLOCK task void sendTask()
 {
     lowpan_pkt_t *pkt = send_queue;
     struct lowpan_frag_hdr *frag_hdr;
@@ -886,6 +892,7 @@ void ipv6_compressed_output(lowpan_pkt_t
 {
     lowpan_pkt_t *p;
     uint8_t hc1_enc = 0;
+    uint8_t* COUNT(pkt->header_len) tmp_header_begin;
 
     /* HC2 compression */
     if (hc2_present) {
@@ -908,7 +915,9 @@ void ipv6_compressed_output(lowpan_pkt_t
     default:
 	hc1_enc |= HC1_NEXTHDR_INLINE;
 
+        //tmp_header_begin = pkt->header_begin - sizeof(next_header); 
 	pkt->header_begin -= sizeof(next_header);
+	//pkt->header_begin = tmp_header_begin;
 	pkt->header_len += sizeof(next_header);
 	*(pkt->header_begin) = next_header;
 	break;
@@ -922,7 +931,7 @@ void ipv6_compressed_output(lowpan_pkt_t
     
     pkt->header_begin -= 8;
     pkt->header_len += 8;
-    memcpy(pkt->header_begin, ((void*)&(pkt->ip_dst_addr)) + 8, 8);
+    memcpy(pkt->header_begin, (TCAST(void* COUNT(16), &(pkt->ip_dst_addr))) + 8, 8);
 
     /* destination address prefix */
     if (ipv6_addr_is_linklocal_unicast(&pkt->ip_dst_addr)) {
@@ -940,7 +949,7 @@ void ipv6_compressed_output(lowpan_pkt_t
     
     pkt->header_begin -= 8;
     pkt->header_len += 8;
-    memcpy(pkt->header_begin, ((void*)&(pkt->ip_src_addr)) + 8, 8);
+    memcpy(pkt->header_begin, (TCAST(void* COUNT(16), &(pkt->ip_src_addr))) + 8, 8);
 
     /* source address prefix */
     if (ipv6_addr_is_linklocal_unicast(&pkt->ip_src_addr)) {
@@ -1012,7 +1021,7 @@ void icmpv6_output(lowpan_pkt_t *pkt,
     cksum = ipv6_chksum(&pkt->ip_src_addr, &pkt->ip_dst_addr,
 			NEXT_HEADER_ICMP6,
 			pkt->header_len + pkt->app_data_len, cksum);
-    cksum = ip_chksum((void*)hdr, sizeof(struct icmp6_hdr), cksum);
+    cksum = ip_chksum(TCAST(void* COUNT(sizeof(struct icmp6_hdr)), hdr), sizeof(struct icmp6_hdr), cksum);
     cksum = ip_chksum(pkt->app_data_begin, pkt->app_data_len,
 			   cksum);
     cksum = ~cksum;
@@ -1085,9 +1094,9 @@ error_t udp_uncompressed_output(void* bu
     return SUCCESS;
 }
 
-error_t udp_compressed_output(void* buf, uint16_t len,
-			      const ip6_addr_t *src_addr,
-			      const ip6_addr_t *dst_addr,
+error_t udp_compressed_output(const void* COUNT(len) buf, uint16_t len,
+			      const ip6_addr_t * ONE_NOK src_addr,
+			      const ip6_addr_t * ONE_NOK dst_addr,
 			      uint16_t src_port,
 			      uint16_t dst_port,
 			      uint8_t udp_client_num)
@@ -1166,10 +1175,12 @@ error_t udp_compressed_output(void* buf,
     return SUCCESS;
 }
 /* ========================== IPv6 - input ================================= */
-void icmpv6_input(uint8_t* buf, uint16_t len)
+void icmpv6_input(uint8_t* COUNT(len) buf, uint16_t len)
 {
     lowpan_pkt_t *pkt;
     struct icmp6_hdr *hdr = (struct icmp6_hdr *)buf;
+    uint16_t tmpLen = len;
+    uint8_t* BND(buf, buf + tmpLen) tmpBuf = buf;
 
     /* Compute and check the IP header checksum. */
     if (ipv6_chksum_data(&rx_pkt.ip_src_addr, &rx_pkt.ip_dst_addr,
@@ -1183,7 +1194,8 @@ void icmpv6_input(uint8_t* buf, uint16_t
 	return;
     }
 
-    buf += sizeof(struct icmp6_hdr);
+    //buf += sizeof(struct icmp6_hdr);
+    tmpBuf += sizeof(struct icmp6_hdr);
     len -= sizeof(struct icmp6_hdr);
     
     switch (hdr->type) {
@@ -1211,7 +1223,8 @@ void icmpv6_input(uint8_t* buf, uint16_t
 	if (rx_pkt.app_data) {
 	    /* fragment reassembly took place - ICMP data is in app_data buf */
 	    pkt->app_data = rx_pkt.app_data;
-	    pkt->app_data_begin = buf;
+	    //pkt->app_data_begin = buf;
+	    pkt->app_data_begin = tmpBuf;
 	    pkt->app_data_len = len;
 	    pkt->app_data_dealloc = rx_pkt.app_data_dealloc;
 
@@ -1220,7 +1233,7 @@ void icmpv6_input(uint8_t* buf, uint16_t
 	} else {
 	    /* there is no app_data buf, everything fits into the header buf */
 	    pkt->header_begin -= len;
-	    my_memcpy(pkt->header_begin, buf, len);
+	    my_memcpy(pkt->header_begin, tmpBuf, len);
 	    pkt->app_data_begin = pkt->header_begin;
 	    pkt->app_data_len = len;
 	}
@@ -1239,11 +1252,13 @@ void icmpv6_input(uint8_t* buf, uint16_t
 }
 
 /* UDP input processing. */
-void udp_input(uint8_t* buf, uint16_t len)
+void udp_input(uint8_t* COUNT(len) buf, uint16_t len)
 {
     struct udp_conn *conn;
     int c;
     struct udp_hdr *hdr = (struct udp_hdr *)buf;
+    uint16_t tmpLen = len;
+    uint8_t* BND(buf, buf+tmpLen) tmpBuf = buf;
     
     /* Compute and check the IP header checksum. */
     if (ipv6_chksum_data(&rx_pkt.ip_src_addr, &rx_pkt.ip_dst_addr,
@@ -1293,12 +1308,12 @@ void udp_input(uint8_t* buf, uint16_t le
  udp_match_found:
     len -= sizeof(struct udp_hdr);
     if (len > 0) {
-	signal UDPClient.receive[c](&rx_pkt.ip_src_addr, ntohs(hdr->srcport),
-				    buf+sizeof(struct udp_hdr), len);
+	tmpBuf = buf + sizeof(struct udp_hdr);
+	signal UDPClient.receive[c](&rx_pkt.ip_src_addr, ntohs(hdr->srcport), tmpBuf, len);
     }
 }
 
-void udp_input_compressed(uint8_t* buf, uint16_t len, uint8_t hc2_enc)
+void udp_input_compressed(uint8_t* COUNT(len) buf, uint16_t len, uint8_t hc2_enc)
 {
     struct udp_conn *conn;
     int c;
@@ -1307,11 +1322,14 @@ void udp_input_compressed(uint8_t* buf, 
     uint16_t chksum;
     uint16_t tmp_chksum;
     uint16_t tmp_len;
+    uint16_t tmpLen = len;	
+    uint8_t* BND(buf, buf+tmpLen) tmpBuf = buf;
     
     /* UDP Source Port */
     if ((hc2_enc & HC2_UDP_SRC_PORT_MASK) == HC2_UDP_SRC_PORT_INLINE) {
 	src_port = get_16t(buf);
-	buf += sizeof(src_port);
+	//buf += sizeof(src_port);
+	tmpBuf += sizeof(src_port);
 	len -= sizeof(src_port);
     } else {
 	//TODO
@@ -1321,7 +1339,8 @@ void udp_input_compressed(uint8_t* buf, 
     /* UDP Destination Port */
     if ((hc2_enc & HC2_UDP_DST_PORT_MASK) == HC2_UDP_DST_PORT_INLINE) {
 	dst_port = get_16t(buf);
-	buf += sizeof(dst_port);
+	//buf += sizeof(dst_port);
+	tmpBuf += sizeof(dst_port);
 	len -= sizeof(dst_port);
     } else {
 	//TODO
@@ -1340,13 +1359,16 @@ void udp_input_compressed(uint8_t* buf, 
 #endif /* ENABLE_PRINTF_DEBUG */
 	    return;
 	}
-	buf += sizeof(uint16_t);
+	//buf += sizeof(uint16_t);
+	tmpBuf += sizeof(uint16_t);
 	len -= sizeof(uint16_t);
     }
 	
     /* Checksum */
-    chksum = get_16t(buf);
-    buf += sizeof(chksum);
+    //chksum = get_16t(buf);
+    chksum = get_16t(tmpBuf);
+    //buf += sizeof(chksum);
+    tmpBuf += sizeof(chksum);
     len -= sizeof(chksum);
 
     /* --- end of decompression --- */
@@ -1417,7 +1439,7 @@ void udp_input_compressed(uint8_t* buf, 
 }
 
 /* processed the IPv6 header (uncompressed) */
-void ipv6_input_uncompressed(uint8_t* buf, uint16_t len)
+void ipv6_input_uncompressed(uint8_t* COUNT(len) buf, uint16_t len)
 {
     struct ip6_hdr *hdr = (struct ip6_hdr *) buf;
 
@@ -1490,13 +1512,15 @@ void ipv6_input_uncompressed(uint8_t* bu
 }
 
 /* processed the IPv6 header (uncompressed) */
-void ipv6_input_compressed(uint8_t* buf, uint16_t len)
+void ipv6_input_compressed(uint8_t* COUNT(len) buf, uint16_t len)
 {
     struct ip6_hdr *ip_hdr = (struct ip6_hdr *) buf;
 
     uint8_t hc1_enc;
     uint8_t hc2_enc = 0;
     uint8_t next_header;
+    uint16_t tmpLen = len;	
+    uint8_t* BND(buf, buf+tmpLen) tmpBuf = buf;
 
     /*
     printf("nxt_hdr: 0x%X\n", hdr->nxt_hdr);
@@ -1505,19 +1529,22 @@ void ipv6_input_compressed(uint8_t* buf,
     */
 
     hc1_enc = *buf;
-    buf += sizeof(hc1_enc);
+    //buf += sizeof(hc1_enc);
+    tmpBuf += sizeof(hc1_enc);
     len -= sizeof(hc1_enc);
 
     /* HC2 encoding follows HC1 encoding */
     if ((hc1_enc & HC1_HC2_MASK) == HC1_HC2_PRESENT) {
 	hc2_enc = *buf;
-	buf += sizeof(hc2_enc);
+	//buf += sizeof(hc2_enc);
+	tmpBuf += sizeof(hc2_enc);
 	len -= sizeof(hc2_enc);
     }
 
     /* Hop Limit */
     if (*buf) {
-	buf += sizeof(ip_hdr->hlim);
+	//buf += sizeof(ip_hdr->hlim);
+	tmpBuf += sizeof(ip_hdr->hlim);
 	len -= sizeof(ip_hdr->hlim);
     } else {
 	/* Hop Limit reached zero */
@@ -1527,7 +1554,8 @@ void ipv6_input_compressed(uint8_t* buf,
     /* source IP address */
     if ((hc1_enc & HC1_SRC_PREFIX_MASK) == HC1_SRC_PREFIX_INLINE) {
 	memcpy(&rx_pkt.ip_src_addr, buf, sizeof(rx_pkt.ip_src_addr)/2);
-	buf += sizeof(rx_pkt.ip_src_addr)/2;
+	//buf += sizeof(rx_pkt.ip_src_addr)/2;
+	tmpBuf += sizeof(rx_pkt.ip_src_addr)/2;
 	len -= sizeof(rx_pkt.ip_src_addr)/2;
     } else {
 	/* linl-local prefix */
@@ -1537,16 +1565,18 @@ void ipv6_input_compressed(uint8_t* buf,
     }
      
     if ((hc1_enc & HC1_SRC_IFACEID_MASK) == HC1_SRC_IFACEID_INLINE) {
-	memcpy(((void*)&rx_pkt.ip_src_addr) + sizeof(rx_pkt.ip_src_addr)/2,
+	memcpy((TCAST(void* COUNT(16), &rx_pkt.ip_src_addr)) + sizeof(rx_pkt.ip_src_addr)/2,
 	       buf, sizeof(rx_pkt.ip_src_addr)/2);
-	buf += sizeof(rx_pkt.ip_src_addr)/2;
+	//buf += sizeof(rx_pkt.ip_src_addr)/2;
+	tmpBuf += sizeof(rx_pkt.ip_src_addr)/2;
 	len -= sizeof(rx_pkt.ip_src_addr)/2;
     }
 
     /* destination IP address */
     if ((hc1_enc & HC1_DST_PREFIX_MASK) == HC1_DST_PREFIX_INLINE) {
 	memcpy(&rx_pkt.ip_dst_addr, buf, sizeof(rx_pkt.ip_dst_addr)/2);
-	buf += sizeof(rx_pkt.ip_dst_addr)/2;
+	//buf += sizeof(rx_pkt.ip_dst_addr)/2;
+	tmpBuf += sizeof(rx_pkt.ip_dst_addr)/2;
 	len -= sizeof(rx_pkt.ip_dst_addr)/2;
     } else {
 	/* linl-local prefix */
@@ -1556,9 +1586,10 @@ void ipv6_input_compressed(uint8_t* buf,
     }
      
     if ((hc1_enc & HC1_DST_IFACEID_MASK) == HC1_DST_IFACEID_INLINE) {
-	memcpy(((void*)&rx_pkt.ip_dst_addr) + sizeof(rx_pkt.ip_dst_addr)/2,
+	memcpy((TCAST(void* COUNT(16), &rx_pkt.ip_dst_addr)) + sizeof(rx_pkt.ip_dst_addr)/2,
 	       buf, sizeof(rx_pkt.ip_dst_addr)/2);
-	buf += sizeof(rx_pkt.ip_dst_addr)/2;
+	//buf += sizeof(rx_pkt.ip_dst_addr)/2;
+	tmpBuf += sizeof(rx_pkt.ip_dst_addr)/2;
 	len -= sizeof(rx_pkt.ip_dst_addr)/2;
     }
 
@@ -1582,7 +1613,8 @@ void ipv6_input_compressed(uint8_t* buf,
     switch (hc1_enc & HC1_NEXTHDR_MASK) {
     case HC1_NEXTHDR_INLINE:
 	next_header = *buf;
-	buf += sizeof(uint8_t);
+	//buf += sizeof(uint8_t);
+	tmpBuf += sizeof(uint8_t);
 	len -= sizeof(uint8_t);
 	break;
     case HC1_NEXTHDR_UDP:
@@ -1631,10 +1663,13 @@ void ipv6_input_compressed(uint8_t* buf,
 }
 
 /* call the right fct for processing the IPv6 header */
-void layer3_input(uint8_t *buf, uint16_t len)
+void layer3_input(uint8_t * COUNT(len) buf, uint16_t len)
 {
     uint8_t *dispatch = buf;
-    buf++;
+    uint16_t tmpLen = len;	
+    uint8_t* BND(buf, buf+tmpLen) tmpBuf = buf;
+    //buf++;
+    tmpBuf++;
     len--;
 
     /* uncompressed IPv6 */
@@ -2080,7 +2115,7 @@ UDPClient.connect[uint8_t num](const ip6
 
 command error_t
 UDPClient.sendTo[uint8_t num](const ip6_addr_t *addr, uint16_t port,
-			      const uint8_t *buf, uint16_t len)
+			      const uint8_t * COUNT(len) buf, uint16_t len)
 {
     if (udp_conns[num].lport == 0) {
 	set_16t(&udp_conns[num].lport, htons(udp_assign_port()));
Index: tos/lib/net/6lowpan/IP_internal.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/6lowpan/IP_internal.h,v
retrieving revision 1.1
diff -u -b -p -r1.1 IP_internal.h
--- tos/lib/net/6lowpan/IP_internal.h	5 Dec 2007 22:58:42 -0000	1.1
+++ tos/lib/net/6lowpan/IP_internal.h	9 Jul 2010 19:45:15 -0000
@@ -225,7 +225,7 @@ typedef struct _app_data_t {
 
 /* used for fragment reassembly */
 typedef struct _frag_buf_t {
-    uint8_t *buf;          /* usually a pointer to app_data_t */
+    uint8_t * COUNT_NOK(sizeof(app_data_t)) buf;          /* usually a pointer to app_data_t */
     hw_addr_t hw_src_addr;
     hw_addr_t hw_dst_addr;
     uint16_t dgram_tag;    /* network byte order */
@@ -249,16 +249,16 @@ typedef struct _frag_buf_t {
  */
 typedef struct _lowpan_pkt_t {
     /* buffers */
-    uint8_t  *app_data;         /* buffer for application data */
     uint16_t  app_data_len;     /* how much data is in the buffer */
-    uint8_t  *app_data_begin;   /* start of the data in the buffer */
+    uint8_t  * COUNT_NOK(app_data_len) app_data;         /* buffer for application data */
+    uint8_t  * COUNT_NOK(app_data_len) app_data_begin;   /* start of the data in the buffer */
     uint8_t   app_data_dealloc; /* shall IPC deallocate the app_data buffer?
-                           /* APP_DATA_DEALLOC_FALSE | APP_DATA_DEALLOC_TRUE */
+                            APP_DATA_DEALLOC_FALSE | APP_DATA_DEALLOC_TRUE */
 
     uint8_t header[LINK_DATA_MTU]; /* buffer for the header (tx)
-                                    * or unfragmented 802.15.4 frame (rx) */
+                                    or unfragmented 802.15.4 frame (rx) */
     uint16_t  header_len;          /* how much data is in the buffer */
-    uint8_t *header_begin;         /* start of the data in the buffer */
+    uint8_t * BND_NOK(header, header + LINK_DATA_MTU) header_begin;         /* start of the data in the buffer */
 
     /* fragmentation */
     uint16_t dgram_tag;     /* network byte order */
@@ -278,7 +278,7 @@ typedef struct _lowpan_pkt_t {
     /* to notify app with sendDone */
     uint8_t notify_num;     /* num of UDPClient + 1, 0 means o not notify */
 
-    struct _lowpan_pkt_t *next;
+    struct _lowpan_pkt_t * ONE_NOK next;
 } lowpan_pkt_t;
 
 enum {
Index: tos/lib/net/6lowpan/UDPClient.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/6lowpan/UDPClient.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 UDPClient.nc
--- tos/lib/net/6lowpan/UDPClient.nc	5 Dec 2007 22:58:42 -0000	1.1
+++ tos/lib/net/6lowpan/UDPClient.nc	9 Jul 2010 19:45:15 -0000
@@ -92,9 +92,13 @@ interface UDPClient {
    *  calling 'send'.  If a local port has not yet been assigned, a dynamic
    *  one will be assigned by these commands.  Both commands are asynchronous
    *  and will generate the 'sendDone' event once the datagram has been sent.
+   *
+   * @param 'const ip6_addr_t* ONE addr'    the address 
+   * @param 'const uint8_t* COUNT(len) buf'   the buffer
+   *
    */  
 
-  command  error_t sendTo(const ip6_addr_t *addr, uint16_t port,
+  command  error_t sendTo(const ip6_addr_t * addr, uint16_t port,
 			  const uint8_t *buf, uint16_t len );
   command  error_t send(const uint8_t *buf, uint16_t len );
 
@@ -108,6 +112,9 @@ interface UDPClient {
    *  A datagram has been received.  Datagrams are only received on sockets
    *  that have had 'listen' called to assign a local port, or have used
    *  the 'send' or 'sendTo' command.
+   *
+   * @param 'const ip6_addr_t* ONE addr'    the address 
+   * @param 'uint8_t* COUNT(len) buf'   the buffer
    */
 
   event    void     receive(const ip6_addr_t *addr, uint16_t port,
Index: tos/lib/net/ctp/CtpForwardingEngineP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/ctp/CtpForwardingEngineP.nc,v
retrieving revision 1.24
diff -u -b -p -r1.24 CtpForwardingEngineP.nc
--- tos/lib/net/ctp/CtpForwardingEngineP.nc	11 Apr 2010 23:27:30 -0000	1.24
+++ tos/lib/net/ctp/CtpForwardingEngineP.nc	9 Jul 2010 19:45:16 -0000
@@ -104,7 +104,7 @@
 #include <CtpForwardingEngine.h>
 #include <CtpDebugMsg.h>
    
-generic module CtpForwardingEngineP() {
+generic module CtpForwardingEngineP() @safe(){
   provides {
     interface Init;
     interface StdControl;
Index: tos/lib/net/ctp/CtpRoutingEngineP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/ctp/CtpRoutingEngineP.nc,v
retrieving revision 1.25
diff -u -b -p -r1.25 CtpRoutingEngineP.nc
--- tos/lib/net/ctp/CtpRoutingEngineP.nc	29 Jun 2010 22:07:49 -0000	1.25
+++ tos/lib/net/ctp/CtpRoutingEngineP.nc	9 Jul 2010 19:45:16 -0000
@@ -104,7 +104,7 @@
  *  @see Net2-WG
  */
 
-generic module CtpRoutingEngineP(uint8_t routingTableSize, uint32_t minInterval, uint32_t maxInterval) {
+generic module CtpRoutingEngineP(uint8_t routingTableSize, uint32_t minInterval, uint32_t maxInterval) @safe(){
     provides {
         interface UnicastNameFreeRouting as Routing;
         interface RootControl;
Index: tos/lib/net/dhv/AMDhvP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/AMDhvP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 AMDhvP.nc
--- tos/lib/net/dhv/AMDhvP.nc	26 May 2010 22:01:22 -0000	1.2
+++ tos/lib/net/dhv/AMDhvP.nc	9 Jul 2010 19:45:16 -0000
@@ -11,7 +11,7 @@
  * @modified 8/28/2008  Took the source code from DIP.
  **/
 
-module AMDhvP {
+module AMDhvP @safe(){
   provides interface Init;
   provides interface DhvSend;
   provides interface DhvReceive as DhvDataReceive;
@@ -84,7 +84,7 @@ implementation {
     return err;
   }
 
-  command void* DhvSend.getPayloadPtr() {
+  command TRUSTEDBLOCK void* DhvSend.getPayloadPtr() {
     // returns NULL if message is busy
     if(busy) {
       return NULL;
@@ -103,7 +103,7 @@ implementation {
     }
   }
 
-  event message_t* NetReceive.receive(message_t* msg, void* payload,
+  event TRUSTEDBLOCK message_t* NetReceive.receive(message_t* msg, void* payload,
       uint8_t len) {
     dhv_msg_t* dmsg;
     uint8_t type;
Index: tos/lib/net/dhv/Dhv.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/Dhv.h,v
retrieving revision 1.3
diff -u -b -p -r1.3 Dhv.h
--- tos/lib/net/dhv/Dhv.h	11 Mar 2010 22:34:58 -0000	1.3
+++ tos/lib/net/dhv/Dhv.h	9 Jul 2010 19:45:16 -0000
@@ -27,6 +27,13 @@
 
 #define VBIT_LENGTH 8
 #define INFO_THRESHOLD 1
+
+#define DHV_SUMMARY_VALUES_PER_PACKET 2
+#define DHV_VECTOR_VALUES_PER_PACKET 2
+
+#define DHV_SUMMARY_ENTRIES_PER_PACKET (DHV_SUMMARY_VALUES_PER_PACKET * 3)
+#define DHV_VECTOR_ENTRIES_PER_PACKET (DHV_VECTOR_VALUES_PER_PACKET * 2)
+
 enum {
   AM_DHV_TEST_MSG = 0xAB
 };
@@ -66,19 +73,19 @@ typedef dhv_index_t dhv_hashlen_t;
 
 typedef nx_struct dhv_msg {
   nx_uint8_t type; 
-  nx_uint8_t content[0];
+  nx_uint8_t (COUNT(0)content)[0];
 } dhv_msg_t;
 
 typedef nx_struct dhv_data_msg {
   nx_dhv_key_t key;
   nx_dhv_version_t version;
   nx_uint8_t size;
-  nx_uint8_t data[0];
+  nx_uint8_t (COUNT(16) data)[0];
 } dhv_data_msg_t;
 
 typedef nx_struct dhv_vector_msg {
   nx_uint8_t unitLen;
-  nx_uint32_t vector[0];
+  nx_uint32_t (COUNT(DHV_VECTOR_ENTRIES_PER_PACKET) vector)[0];
 } dhv_vector_msg_t;
 
 typedef nx_struct dhv_summary_msg {
@@ -87,7 +94,7 @@ typedef nx_struct dhv_summary_msg {
   nx_uint32_t info;
 } dhv_summary_msg_t;
 
-typedef nx_struct dhv_hsum_msg{
+typedef nx_struct dhv_hsum_msg {
   nx_uint32_t salt;
   nx_uint32_t info;
   nx_uint32_t checksum;
@@ -99,7 +106,7 @@ typedef nx_struct dhv_vbit_msg{
   nx_uint8_t vindex;
   nx_uint32_t salt;
   nx_uint32_t info; //include hash into vbit message
-  nx_uint8_t vbit[0];
+  nx_uint8_t (COUNT(TOSH_DATA_LENGTH - sizeof(dhv_msg_t) - 11) vbit)[0];
 }dhv_vbit_msg_t;
 
 typedef nx_struct dhv_data {
@@ -115,9 +122,4 @@ typedef nx_struct dhv_test_msg {
 
 
 /* TUNABLE PARAMETERS */
-#define DHV_SUMMARY_VALUES_PER_PACKET 2
-#define DHV_VECTOR_VALUES_PER_PACKET 2
-
-#define DHV_SUMMARY_ENTRIES_PER_PACKET (DHV_SUMMARY_VALUES_PER_PACKET * 3)
-#define DHV_VECTOR_ENTRIES_PER_PACKET (DHV_VECTOR_VALUES_PER_PACKET * 2)
 #endif
Index: tos/lib/net/dhv/DhvDataP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvDataP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DhvDataP.nc
--- tos/lib/net/dhv/DhvDataP.nc	11 Mar 2010 22:34:58 -0000	1.2
+++ tos/lib/net/dhv/DhvDataP.nc	9 Jul 2010 19:45:16 -0000
@@ -13,7 +13,7 @@
 
 #include <Dhv.h>
 
-module DhvDataP {
+module DhvDataP @safe(){
   provides interface DhvDecision;
 
   uses interface DhvSend as DataSend;
@@ -43,7 +43,7 @@ implementation {
     dhv_key_t key;
     uint8_t i;
     dhv_version_t ver;
-    dhv_msg_t* dmsg;
+    dhv_msg_t* ONE_NOK dmsg;
     dhv_data_msg_t* ddmsg;
     const dhv_data_t* data;
     error_t status;
@@ -61,7 +61,7 @@ implementation {
     if(dmsg == NULL) {
       return FAIL;
     }
-    ddmsg = (dhv_data_msg_t*) dmsg->content;
+    ddmsg = TCAST(dhv_data_msg_t* ONE,  dmsg->content);
     dmsg->type = ID_DHV_DATA;
     ddmsg->key = key;
     ddmsg->version = ver;
@@ -83,7 +83,7 @@ implementation {
     dhv_version_t msgVer;
     dhv_data_msg_t* ddmsg;
 
-    ddmsg = (dhv_data_msg_t*) payload;
+    ddmsg = TCAST(dhv_data_msg_t* ONE, payload);
     key = ddmsg->key;
     msgVer = ddmsg->version;
     myVer = call DhvHelp.keyToVersion(key);
Index: tos/lib/net/dhv/DhvHSumP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvHSumP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DhvHSumP.nc
--- tos/lib/net/dhv/DhvHSumP.nc	11 Mar 2010 22:34:58 -0000	1.3
+++ tos/lib/net/dhv/DhvHSumP.nc	9 Jul 2010 19:45:16 -0000
@@ -11,7 +11,7 @@
 
 #include<Dhv.h>
 
-module DhvHSumP{
+module DhvHSumP @safe(){
   provides interface DhvDecision;
 
   uses interface DhvSend as HSumSend;
@@ -31,8 +31,8 @@ implementation{
     commRate = 0;
   }
   command error_t DhvDecision.send(){
-    dhv_hsum_msg_t* dhsmsg;
-    dhv_msg_t* 			dmsg;
+    dhv_hsum_msg_t* ONE dhsmsg;
+    dhv_msg_t* ONE_NOK dmsg;
     uint32_t  salt;
     error_t sendResult;
 
@@ -41,7 +41,7 @@ implementation{
         return FAIL;
 
     dmsg->type = ID_DHV_HSUM;
-    dhsmsg = (dhv_hsum_msg_t*) dmsg->content;
+    dhsmsg = TCAST(dhv_hsum_msg_t* ONE,  dmsg->content);
 
     //add the hash value
     salt = call Random.rand32();
@@ -57,7 +57,7 @@ implementation{
   }	
 
   event void HSumReceive.receive(void* payload, uint8_t len){
-    dhv_hsum_msg_t * rcv_dhmsg;
+    dhv_hsum_msg_t * ONE rcv_dhmsg;
     int32_t local_checksum;
     int32_t rcv_checksum;
     int32_t xor_checksum;
@@ -65,7 +65,7 @@ implementation{
     int32_t rcv_hash;
     int32_t local_hash;
 
-    rcv_dhmsg = (dhv_hsum_msg_t*) payload;
+    rcv_dhmsg = TCAST(dhv_hsum_msg_t* ONE, payload);
 
     rcv_checksum = rcv_dhmsg->checksum;
     local_checksum = call DhvHelp.getHSum();
Index: tos/lib/net/dhv/DhvLogicP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvLogicP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DhvLogicP.nc
--- tos/lib/net/dhv/DhvLogicP.nc	11 Mar 2010 22:34:58 -0000	1.2
+++ tos/lib/net/dhv/DhvLogicP.nc	9 Jul 2010 19:45:16 -0000
@@ -13,7 +13,7 @@
 
 #include <Dhv.h>
 
-module DhvLogicP {
+module DhvLogicP @safe(){
   provides interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
 
   provides interface Init;
Index: tos/lib/net/dhv/DhvSummaryP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvSummaryP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DhvSummaryP.nc
--- tos/lib/net/dhv/DhvSummaryP.nc	11 Mar 2010 22:34:58 -0000	1.3
+++ tos/lib/net/dhv/DhvSummaryP.nc	9 Jul 2010 19:45:16 -0000
@@ -13,7 +13,7 @@
 
 #include <Dhv.h>
 
-module DhvSummaryP {
+module DhvSummaryP @safe(){
   provides interface DhvDecision;
 
   uses interface DhvSend as SummarySend;
@@ -38,15 +38,15 @@ implementation {
 
   command error_t DhvDecision.send() {
     uint32_t salt;
-    dhv_msg_t* dmsg;
-    dhv_summary_msg_t* dsmsg;
+    dhv_msg_t* ONE_NOK dmsg;
+    dhv_summary_msg_t* ONE dsmsg;
 
     dmsg = (dhv_msg_t*) call SummarySend.getPayloadPtr();
     if(dmsg == NULL)
         return FAIL;
 
     dmsg->type = ID_DHV_SUMMARY;
-    dsmsg = (dhv_summary_msg_t*) dmsg->content;
+    dsmsg = TCAST(dhv_summary_msg_t* ONE, dmsg->content);
 
     salt = call Random.rand32();
     dsmsg->info = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
@@ -57,11 +57,11 @@ implementation {
   }
 
   event void SummaryReceive.receive(void* payload, uint8_t len) {
-    dhv_summary_msg_t* dsmsg;
+    dhv_summary_msg_t* ONE dsmsg;
     uint32_t salt, myHash;
 
 
-    dsmsg = (dhv_summary_msg_t*) payload;
+    dsmsg = TCAST(dhv_summary_msg_t* ONE, payload);
     salt = dsmsg->salt;
     
     myHash = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
Index: tos/lib/net/dhv/DhvVBitP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvVBitP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DhvVBitP.nc
--- tos/lib/net/dhv/DhvVBitP.nc	11 Mar 2010 22:34:58 -0000	1.3
+++ tos/lib/net/dhv/DhvVBitP.nc	9 Jul 2010 19:45:16 -0000
@@ -12,7 +12,7 @@
 
 #include<Dhv.h>
 
-module DhvVBitP{
+module DhvVBitP @safe(){
   provides interface DhvDecision;
 
   uses interface DhvSend as VBitSend;
@@ -44,8 +44,8 @@ implementation{
     uint8_t numMsg;
     uint8_t maxDataLength;
     uint8_t i, j;
-    dhv_msg_t* dmsg;
-    dhv_vbit_msg_t* dvbmsg;
+    dhv_msg_t* ONE_NOK dmsg;
+    dhv_vbit_msg_t* ONE dvbmsg;
     uint8_t *versionPtr;
     error_t sendResult;
     uint32_t salt;
@@ -76,7 +76,7 @@ implementation{
       return FAIL;
 
     dmsg->type = ID_DHV_VBIT;
-    dvbmsg = (dhv_vbit_msg_t*) dmsg->content;
+    dvbmsg = TCAST(dhv_vbit_msg_t* ONE, dmsg->content);
     dvbmsg->bindex = bindex;
 
     //put the hash into the message
@@ -123,7 +123,7 @@ implementation{
 
 
   event void VBitReceive.receive(void* payload, uint8_t len){
-    dhv_vbit_msg_t * rcv_dvbmsg;
+    dhv_vbit_msg_t * ONE rcv_dvbmsg;
     uint8_t bindex, vindex;
     int i,j;
     dhv_version_t version;
@@ -153,7 +153,7 @@ implementation{
       numMsg    = 0;	
     }
 
-    rcv_dvbmsg = (dhv_vbit_msg_t*) payload;
+    rcv_dvbmsg = TCAST(dhv_vbit_msg_t* ONE, payload);
     bindex = rcv_dvbmsg->bindex;
     vindex = rcv_dvbmsg->vindex;
 
Index: tos/lib/net/dhv/DhvVectorP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvVectorP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DhvVectorP.nc
--- tos/lib/net/dhv/DhvVectorP.nc	26 May 2010 22:01:22 -0000	1.3
+++ tos/lib/net/dhv/DhvVectorP.nc	9 Jul 2010 19:45:16 -0000
@@ -13,7 +13,7 @@
 
 #include <Dhv.h>
 
-module DhvVectorP {
+module DhvVectorP @safe(){
   provides interface DhvDecision;
 
   uses interface DhvSend as VectorSend;
@@ -41,8 +41,8 @@ implementation {
     dhv_index_t i, j;
     dhv_key_t sendkey;
     bool* keyvector;
-    dhv_msg_t* dmsg;
-    dhv_vector_msg_t* dvmsg;
+    dhv_msg_t* ONE_NOK dmsg;
+    dhv_vector_msg_t* ONE dvmsg;
     error_t status;
 
     dbg("DhvVectorP", "prepare to send vector out \n");
@@ -54,7 +54,7 @@ implementation {
 
     keyvector = call VectorLogic.allItem();
     dmsg->type = ID_DHV_VECTOR;
-    dvmsg = (dhv_vector_msg_t*) dmsg->content;
+    dvmsg = TCAST(dhv_vector_msg_t* ONE, dmsg->content);
 
     //dvmsg->unitLen = DHV_VECTOR_ENTRIES_PER_PACKET;
 
@@ -114,8 +114,8 @@ implementation {
 
   /*TODO: a callback event to remove the sent vectors*/
   event void VectorReceive.receive(void* payload, uint8_t len) {
-    dhv_vector_msg_t* dvmsg;
-    dhv_msg_t* dmsg;
+    dhv_vector_msg_t* ONE dvmsg;
+    dhv_msg_t* ONE dmsg;
 
     uint8_t unitlen;
     uint8_t i;
@@ -125,10 +125,10 @@ implementation {
     uint32_t myver;
 
     commRate  = commRate + 1;        	
-    dmsg  = (dhv_msg_t*) payload; 
+    dmsg  = TCAST(dhv_msg_t* ONE, payload); 
     type = dmsg->type;
 
-    dvmsg = (dhv_vector_msg_t*) dmsg->content;
+    dvmsg = TCAST(dhv_vector_msg_t* ONE, dmsg->content);
     unitlen = dvmsg->unitLen;
 
     dbg("DhvVectorP", "Receive vector msg len %u  unitlen 0x%02x  0x%02x \n", len, unitlen, dvmsg->unitLen);			
Index: tos/lib/net/dhv/DhvVersionP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DhvVersionP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DhvVersionP.nc
--- tos/lib/net/dhv/DhvVersionP.nc	11 Mar 2010 22:34:58 -0000	1.2
+++ tos/lib/net/dhv/DhvVersionP.nc	9 Jul 2010 19:45:16 -0000
@@ -14,7 +14,7 @@
  * @modified 8/28/2008  Took the source code from DIP.
  **/
 
-module DhvVersionP {
+module DhvVersionP @safe(){
   provides interface DhvHelp;
   provides interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
 	provides interface DhvCache as DhvDataCache;
@@ -253,7 +253,10 @@ implementation {
 	command uint32_t DhvHelp.computeHash(uint8_t left, uint8_t right, uint32_t salt) {
      dhv_index_t i;
      uint32_t hashValue = salt;
-     uint8_t *sequence;
+     //uint8_t *sequence;
+     uint8_t upperIdx = (right < UQCOUNT_DHV) ? right : UQCOUNT_DHV;
+     uint8_t * COUNT((upperIdx-left)*sizeof(dhv_version_t)) sequence;
+
      if(right <= left) return 0;
      sequence = ((uint8_t*) (versions + left)); 
      for(i = 0; i <= (right-left-1)*sizeof(dhv_version_t); i++) {
Index: tos/lib/net/dhv/DisseminatorP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/DisseminatorP.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DisseminatorP.nc
--- tos/lib/net/dhv/DisseminatorP.nc	22 Aug 2009 08:24:06 -0000	1.1
+++ tos/lib/net/dhv/DisseminatorP.nc	9 Jul 2010 19:45:16 -0000
@@ -80,7 +80,7 @@ implementation {
     signal AppDisseminationValue.changed();
   }
 
-  command void AppDisseminationUpdate.change( t* newVal ) {
+  command TRUSTEDBLOCK void AppDisseminationUpdate.change( t* newVal ) {
     memcpy( &valueCache, newVal, sizeof(t) );
     /* Increment the counter and append the local node ID later. */
     /* DhvLogicC doesn't care what the data actually is,
Index: tos/lib/net/dhv/interfaces/DhvCache.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/interfaces/DhvCache.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DhvCache.nc
--- tos/lib/net/dhv/interfaces/DhvCache.nc	22 Aug 2009 08:26:01 -0000	1.1
+++ tos/lib/net/dhv/interfaces/DhvCache.nc	9 Jul 2010 19:45:16 -0000
@@ -5,6 +5,10 @@ interface DhvCache{
 	command void addReqItem(dhv_key_t key);
 	command void removeItem(dhv_key_t key);
 	command bool hasItemToSend();
+
+        /**
+          * @return  'uint8_t* COUNT(128)'      
+        */
 	command uint8_t* allItem();
 	command uint8_t nextItem();
 	command void removeAll();
Index: tos/lib/net/dhv/interfaces/DhvHelp.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/interfaces/DhvHelp.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DhvHelp.nc
--- tos/lib/net/dhv/interfaces/DhvHelp.nc	22 Aug 2009 08:26:01 -0000	1.1
+++ tos/lib/net/dhv/interfaces/DhvHelp.nc	9 Jul 2010 19:45:16 -0000
@@ -8,8 +8,16 @@ interface DhvHelp {
   command dhv_key_t indexToKey(dhv_index_t ind);
   command dhv_version_t keyToVersion(dhv_key_t key);
   command void setVersion(dhv_key_t key, dhv_version_t ver);
+  /**
+     * @return  'dhv_version_t* COUNT(128)'      
+  */
   command dhv_version_t* getAllVersions();
 	command dhv_version_t getHSum();
+
+  /**
+     * @return  'uint8_t* COUNT((128-1)/VBIT_LENGTH +1)'      
+  */
 	command uint8_t* getVBits(uint32_t bindex);
+
 	command uint32_t computeHash(uint8_t left, uint8_t right,uint32_t salt);	 
 }
Index: tos/lib/net/dhv/interfaces/DhvLogic.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/interfaces/DhvLogic.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DhvLogic.nc
--- tos/lib/net/dhv/interfaces/DhvLogic.nc	22 Aug 2009 08:26:01 -0000	1.1
+++ tos/lib/net/dhv/interfaces/DhvLogic.nc	9 Jul 2010 19:45:16 -0000
@@ -5,5 +5,8 @@ interface DhvLogic{
 	command error_t setReqItem(dhv_key_t key);
 	command error_t unsetItem(dhv_key_t key);
 	command uint8_t nextItem();
+        /**
+          * @return  'uint8_t* COUNT(128)'      
+        */
   command uint8_t * allItem();
 } 
Index: tos/lib/net/dhv/interfaces/DhvReceive.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dhv/interfaces/DhvReceive.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DhvReceive.nc
--- tos/lib/net/dhv/interfaces/DhvReceive.nc	22 Aug 2009 08:26:01 -0000	1.1
+++ tos/lib/net/dhv/interfaces/DhvReceive.nc	9 Jul 2010 19:45:16 -0000
@@ -1,4 +1,6 @@
 
 interface DhvReceive {
+  /* @param  'void* COUNT(len) payload'  a pointer to the packet's payload
+  */
   event void receive(void* payload, uint8_t len);
 }
Index: tos/lib/net/dip/AMDipP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/AMDipP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 AMDipP.nc
--- tos/lib/net/dip/AMDipP.nc	15 Dec 2009 01:13:00 -0000	1.2
+++ tos/lib/net/dip/AMDipP.nc	9 Jul 2010 19:45:16 -0000
@@ -1,5 +1,5 @@
 
-module AMDipP {
+module AMDipP @safe(){
   provides interface Init;
 
   provides interface DipSend;
@@ -31,7 +31,7 @@ implementation {
     return err;
   }
 
-  command void* DipSend.getPayloadPtr() {
+  command TRUSTEDBLOCK void* DipSend.getPayloadPtr() {
     // returns NULL if message is busy
     if(busy) {
       return NULL;
@@ -43,19 +43,19 @@ implementation {
     return call NetAMSend.maxPayloadLength();
   }
 
-  event void NetAMSend.sendDone(message_t* msg, error_t err) {
+  event void NetAMSend.sendDone(message_t* ONE msg, error_t err) {
     dbg("AMDipP", "Data send successfully in the air\n");
     if(msg == &am_msg) {
       busy = FALSE;
     }
   }
 
-  event message_t* NetReceive.receive(message_t* msg, void* payload,
+  event TRUSTEDBLOCK message_t* NetReceive.receive(message_t* msg, void* payload,
 				      uint8_t len) {
     dip_msg_t* dmsg;
     uint8_t type;
 
-    dmsg = (dip_msg_t*) payload;
+    dmsg = TCAST(dip_msg_t* ONE, payload);
     type = dmsg->type;
     switch(type) {
     case ID_DIP_DATA:
Index: tos/lib/net/dip/Dip.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/Dip.h,v
retrieving revision 1.6
diff -u -b -p -r1.6 Dip.h
--- tos/lib/net/dip/Dip.h	1 Jun 2010 03:18:58 -0000	1.6
+++ tos/lib/net/dip/Dip.h	9 Jul 2010 19:45:16 -0000
@@ -15,6 +15,14 @@ enum {
   DIP_ADV_SUPPRESSION = 1
 };
 
+enum {
+  DIP_SUMMARY_VALUES_PER_PACKET = 2,
+  DIP_VECTOR_VALUES_PER_PACKET = 2
+};
+
+#define DIP_SUMMARY_ENTRIES_PER_PACKET (DIP_SUMMARY_VALUES_PER_PACKET * 3)
+#define DIP_VECTOR_ENTRIES_PER_PACKET (DIP_VECTOR_VALUES_PER_PACKET * 2)
+
 typedef enum {
   ID_DIP_INVALID = 0x0,
   ID_DIP_SUMMARY = 0x1,
@@ -39,33 +47,31 @@ typedef dip_index_t dip_hashlen_t;
 
 typedef nx_struct dip_msg {
   nx_uint8_t type; // dip_msgid_t
-  nx_uint8_t content[0];
+  nx_uint8_t (COUNT(0) content)[0];
 } dip_msg_t;
 
 typedef nx_struct dip_data_msg {
   nx_dip_key_t key;
   nx_dip_version_t version;
   nx_uint8_t size;
-  nx_uint8_t data[0];
+  nx_uint8_t (COUNT(16) data)[0];
 } dip_data_msg_t;
 
 typedef nx_struct dip_vector_msg {
   nx_uint8_t unitLen;
-  nx_uint32_t vector[0];
+  nx_uint32_t (COUNT(DIP_VECTOR_ENTRIES_PER_PACKET) vector)[0];
 } dip_vector_msg_t;
 
 typedef nx_struct dip_summary_msg {
   nx_uint8_t unitLen;
   nx_uint32_t salt;
-  nx_uint32_t info[0];
+  nx_uint32_t (COUNT(DIP_SUMMARY_ENTRIES_PER_PACKET) info)[0];
 } dip_summary_msg_t;
 
 dip_estimate_t DIP_DATA_ESTIMATE;
 dip_estimate_t DIP_MAX_ESTIMATE;
 dip_estimate_t DIP_VECTOR_ESTIMATE;
 
-#define DIP_SUMMARY_ENTRIES_PER_PACKET (DIP_SUMMARY_VALUES_PER_PACKET * 3)
-#define DIP_VECTOR_ENTRIES_PER_PACKET (DIP_VECTOR_VALUES_PER_PACKET * 2)
 
 #include "qsort.c"
 
@@ -75,9 +81,5 @@ typedef nx_struct dip_data {
   nx_uint8_t data[16];
 } dip_data_t;
 
-enum {
-  DIP_SUMMARY_VALUES_PER_PACKET = 2,
-  DIP_VECTOR_VALUES_PER_PACKET = 2
-};
 
 #endif
Index: tos/lib/net/dip/DipDataP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/DipDataP.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DipDataP.nc
--- tos/lib/net/dip/DipDataP.nc	3 Jan 2008 21:30:35 -0000	1.1
+++ tos/lib/net/dip/DipDataP.nc	9 Jul 2010 19:45:16 -0000
@@ -1,7 +1,7 @@
 
 #include <Dip.h>
 
-module DipDataP {
+module DipDataP @safe(){
   provides interface DipDecision;
 
   uses interface DipSend as DataSend;
@@ -34,9 +34,9 @@ implementation {
     dip_index_t high_est;
     dip_key_t key;
     dip_version_t ver;
-    dip_estimate_t* ests;
-    dip_msg_t* dmsg;
-    dip_data_msg_t* ddmsg;
+    dip_estimate_t* COUNT_NOK(UQCOUNT_DIP) ests;
+    dip_msg_t* ONE_NOK dmsg;
+    dip_data_msg_t* ONE ddmsg;
     const dip_data_t* data;
 
     ests = call DipEstimates.getEstimates();
@@ -55,7 +55,7 @@ implementation {
     if(dmsg == NULL) {
       return FAIL;
     }
-    ddmsg = (dip_data_msg_t*) dmsg->content;
+    ddmsg = TCAST(dip_data_msg_t* ONE, dmsg->content);
     dmsg->type = ID_DIP_DATA;
 
     ddmsg->key = key;
@@ -72,11 +72,11 @@ implementation {
     dip_key_t key;
     dip_version_t myVer;
     dip_version_t msgVer;
-    dip_data_msg_t* ddmsg;
+    dip_data_msg_t* ONE ddmsg;
 
     commRate = commRate + 1;
 
-    ddmsg = (dip_data_msg_t*) payload;
+    ddmsg = TCAST(dip_data_msg_t* ONE, payload);
     key = ddmsg->key;
     msgVer = ddmsg->version;
     myVer = call DipHelp.keyToVersion(key);
Index: tos/lib/net/dip/DipLogicP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/DipLogicP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DipLogicP.nc
--- tos/lib/net/dip/DipLogicP.nc	1 Jun 2010 03:18:58 -0000	1.3
+++ tos/lib/net/dip/DipLogicP.nc	9 Jul 2010 19:45:16 -0000
@@ -1,7 +1,7 @@
 
 #include <Dip.h>
 
-module DipLogicP {
+module DipLogicP @safe(){
   provides interface DisseminationUpdate<dip_data_t>[dip_key_t key];
   provides interface DipEstimates;
 
@@ -247,7 +247,7 @@ implementation {
     uint8_t dataCommRate;
     uint8_t vectorCommRate;
     uint8_t summaryCommRate;
-    dip_estimate_t* allEsts;
+    dip_estimate_t* COUNT(UQCOUNT_DIP) allEsts;
     dip_index_t i;
 
     uint16_t E, D, L, V, C;
Index: tos/lib/net/dip/DipSummaryP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/DipSummaryP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DipSummaryP.nc
--- tos/lib/net/dip/DipSummaryP.nc	14 Jul 2009 17:14:54 -0000	1.2
+++ tos/lib/net/dip/DipSummaryP.nc	9 Jul 2010 19:45:16 -0000
@@ -3,7 +3,7 @@
 
 #include <Dip.h>
 
-module DipSummaryP {
+module DipSummaryP @safe(){
   provides interface DipDecision;
 
   uses interface DipSend as SummarySend;
@@ -42,19 +42,20 @@ implementation {
 
   command error_t DipDecision.send() {
     dip_index_t i, j, left, right;
-    dip_version_t* allVers;
-    dip_estimate_t* allEsts;
+    dip_version_t* COUNT(UQCOUNT_DIP) allVers;
+    dip_estimate_t* COUNT(UQCOUNT_DIP) allEsts;
     uint32_t salt;
 
-    dip_msg_t* dmsg;
-    dip_summary_msg_t* dsmsg;
+    dip_msg_t* ONE_NOK dmsg;
+    dip_summary_msg_t* ONE dsmsg;
 
     dmsg = (dip_msg_t*) call SummarySend.getPayloadPtr();
     if(dmsg == NULL) {
       return FAIL;
     }
+
     dmsg->type = ID_DIP_SUMMARY;
-    dsmsg = (dip_summary_msg_t*) dmsg->content;
+    dsmsg = TCAST(dip_summary_msg_t* ONE, dmsg->content);
 
     allVers = call DipHelp.getAllVersions();
     allEsts = call DipEstimates.getEstimates();
@@ -91,16 +92,16 @@ implementation {
   }
 
   event void SummaryReceive.receive(void* payload, uint8_t len) {
-    dip_summary_msg_t* dsmsg;
+    dip_summary_msg_t* ONE dsmsg;
     uint8_t unitlen;
     uint32_t salt, myHash;
     uint8_t i;
     dip_index_t left, right;
-    dip_version_t* allVers;
+    dip_version_t* COUNT(UQCOUNT_DIP) allVers;
 
     commRate = commRate + 1;
 
-    dsmsg = (dip_summary_msg_t*) payload;
+    dsmsg = TCAST(dip_summary_msg_t* ONE, payload);
     unitlen = dsmsg->unitLen;
     salt = dsmsg->salt;
     allVers = call DipHelp.getAllVersions();
@@ -203,11 +204,12 @@ implementation {
   }
 
   uint32_t computeHash(dip_index_t left, dip_index_t right,
-		       dip_version_t* basedata, uint32_t salt) {
+		       dip_version_t* COUNT(right) basedata, uint32_t salt) {
     dip_index_t i;
     uint32_t hashValue = salt;
     //uint8_t *sequence;
-    dip_version_t* sequence;
+    uint16_t upperIdx = (right < UQCOUNT_DIP) ? right : UQCOUNT_DIP;
+    dip_version_t* COUNT(upperIdx - left) sequence;
     uint32_t iterations;
 
     if(right <= left) return 0;
@@ -230,7 +232,7 @@ implementation {
   }
 
   uint32_t computeBloomHash(dip_index_t left, dip_index_t right,
-			    dip_version_t* basedata, uint32_t salt) {
+			    dip_version_t* COUNT(right) basedata, uint32_t salt) {
     dip_index_t i;
     uint32_t bit;
     uint32_t returnHash;
@@ -261,7 +263,7 @@ implementation {
   }
 
   void adjustEstimatesDiff(dip_index_t left, dip_index_t right,
-			   dip_version_t* data, uint32_t salt,
+			   dip_version_t* COUNT(right) data, uint32_t salt,
 			   uint32_t bHash) {
     dip_index_t i;
     dip_estimate_t est;
Index: tos/lib/net/dip/DipTrickleMilliP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/DipTrickleMilliP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DipTrickleMilliP.nc
--- tos/lib/net/dip/DipTrickleMilliP.nc	29 Jun 2010 22:07:49 -0000	1.2
+++ tos/lib/net/dip/DipTrickleMilliP.nc	9 Jul 2010 19:45:16 -0000
@@ -49,7 +49,7 @@
 #include <Timer.h>
 #include <Dip.h>
 
-module DipTrickleMilliP {
+module DipTrickleMilliP @safe() {
   provides {
     interface Init;
     interface DipTrickleTimer as TrickleTimer;
Index: tos/lib/net/dip/DipVectorP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/DipVectorP.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DipVectorP.nc
--- tos/lib/net/dip/DipVectorP.nc	3 Jan 2008 21:30:35 -0000	1.1
+++ tos/lib/net/dip/DipVectorP.nc	9 Jul 2010 19:45:16 -0000
@@ -1,7 +1,7 @@
 
 #include <Dip.h>
 
-module DipVectorP {
+module DipVectorP @safe(){
   provides interface DipDecision;
 
   uses interface DipSend as VectorSend;
@@ -22,7 +22,7 @@ implementation {
   pairs_t pairs[UQCOUNT_DIP]; // This is large memory footprint
 
   int myComparator(const void* a, const void* b);
-  void randomizeRun(pairs_t* localPairs, dip_index_t length);
+  void randomizeRun(pairs_t* COUNT(length) localPairs, dip_index_t length);
 
   command uint8_t DipDecision.getCommRate() {
     return commRate;
@@ -35,10 +35,10 @@ implementation {
   command error_t DipDecision.send() {
     dip_index_t i, j, r;
     dip_key_t sendkey;
-    dip_estimate_t* ests;
+    dip_estimate_t* COUNT(UQCOUNT_DIP) ests;
 
-    dip_msg_t* dmsg;
-    dip_vector_msg_t* dvmsg;
+    dip_msg_t* ONE_NOK dmsg;
+    dip_vector_msg_t* ONE dvmsg;
 
     dmsg = call VectorSend.getPayloadPtr();
     if(dmsg == NULL) {
@@ -66,7 +66,7 @@ implementation {
 
     // fill up the packet
     dmsg->type = ID_DIP_VECTOR;
-    dvmsg = (dip_vector_msg_t*) dmsg->content;
+    dvmsg = TCAST(dip_vector_msg_t* ONE, dmsg->content);
     dvmsg->unitLen = DIP_VECTOR_ENTRIES_PER_PACKET;
     for(i = 0, j = 0;
 	i < DIP_VECTOR_ENTRIES_PER_PACKET;
@@ -115,14 +115,14 @@ implementation {
   }
 
   int myComparator(const void* a, const void* b) {
-    const pairs_t *x = (const pairs_t *) a;
-    const pairs_t *y = (const pairs_t *) b;
+    const pairs_t *x = TCAST(const pairs_t * ONE, a);
+    const pairs_t *y = TCAST(const pairs_t * ONE, b);
     if( x->estimate < y->estimate ) { return 1; }
     if( x->estimate > y->estimate ) { return -1; }
     return 0;
   }
 
-  void randomizeRun(pairs_t* localPairs, dip_index_t length) {
+  void randomizeRun(pairs_t* COUNT(length) localPairs, dip_index_t length) {
     dip_index_t i,j;
     dip_index_t rLength = length;
     pairs_t temp;
Index: tos/lib/net/dip/DipVersionP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/DipVersionP.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DipVersionP.nc
--- tos/lib/net/dip/DipVersionP.nc	1 Aug 2009 06:35:37 -0000	1.2
+++ tos/lib/net/dip/DipVersionP.nc	9 Jul 2010 19:45:16 -0000
@@ -1,5 +1,5 @@
 
-module DipVersionP {
+module DipVersionP @safe(){
   provides interface DipHelp;
 
   provides interface DisseminationUpdate<dip_data_t>[dip_key_t key];
@@ -86,7 +86,7 @@ implementation {
     return versions;
   }
 
-  int lessThan(const void* a, const void* b) {
+  int TRUSTEDBLOCK lessThan(const void* a, const void* b) {
     if ((*(dip_key_t*) a) < (*(dip_key_t*) b)) {
       return -1;
     }
Index: tos/lib/net/dip/interfaces/DipEstimates.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/interfaces/DipEstimates.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DipEstimates.nc
--- tos/lib/net/dip/interfaces/DipEstimates.nc	3 Jan 2008 21:30:35 -0000	1.1
+++ tos/lib/net/dip/interfaces/DipEstimates.nc	9 Jul 2010 19:45:16 -0000
@@ -2,6 +2,9 @@
 #include <Dip.h>
 
 interface DipEstimates {
+  /**
+    * @return  'dip_estimate_t* COUNT(128)'      
+    */
   command dip_estimate_t* getEstimates();
   command void decEstimateByIndex(dip_index_t i);
   command void decEstimateByKey(dip_key_t key);
Index: tos/lib/net/dip/interfaces/DipHelp.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/dip/interfaces/DipHelp.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DipHelp.nc
--- tos/lib/net/dip/interfaces/DipHelp.nc	3 Jan 2008 21:30:35 -0000	1.1
+++ tos/lib/net/dip/interfaces/DipHelp.nc	9 Jul 2010 19:45:16 -0000
@@ -8,5 +8,8 @@ interface DipHelp {
   command dip_key_t indexToKey(dip_index_t ind);
   command dip_version_t keyToVersion(dip_key_t key);
   command void setVersion(dip_key_t key, dip_version_t ver);
+  /**
+    * @return  'dip_version_t* COUNT(128)'      
+    */
   command dip_version_t* getAllVersions(); 
 }
Index: tos/lib/net/drip/DisseminationEngineImplP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/drip/DisseminationEngineImplP.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DisseminationEngineImplP.nc
--- tos/lib/net/drip/DisseminationEngineImplP.nc	14 Sep 2007 00:22:18 -0000	1.1
+++ tos/lib/net/drip/DisseminationEngineImplP.nc	9 Jul 2010 19:45:16 -0000
@@ -42,7 +42,7 @@
  * @version $Revision: 1.1 $ $Date: 2007/09/14 00:22:18 $
  */
 
-module DisseminationEngineImplP {
+module DisseminationEngineImplP @safe() {
   provides interface StdControl;
 
   uses {
@@ -127,7 +127,7 @@ implementation {
     }
   }
 
-  void sendObject( uint16_t key ) {
+  TRUSTEDBLOCK void sendObject( uint16_t key ) {
     void* object;
     uint8_t objectSize = 0;
     
@@ -160,7 +160,7 @@ implementation {
     m_bufBusy = FALSE;
   }
 
-  event message_t* Receive.receive( message_t* msg, 
+  event TRUSTEDBLOCK message_t* Receive.receive( message_t* msg, 
 				    void* payload, 
 				    uint8_t len ) {
 
Index: tos/lib/net/drip/DisseminatorP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/drip/DisseminatorP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DisseminatorP.nc
--- tos/lib/net/drip/DisseminatorP.nc	16 Feb 2008 01:31:50 -0000	1.3
+++ tos/lib/net/drip/DisseminatorP.nc	9 Jul 2010 19:45:16 -0000
@@ -103,7 +103,7 @@ implementation {
     return &valueCache;
   }
 
-  command void DisseminationCache.storeData( void* data, uint8_t size,
+  command void DisseminationCache.storeData( void* COUNT(size) data, uint8_t size,
 					     uint32_t newSeqno ) {
     memcpy( &valueCache, data, size < sizeof(t) ? size : sizeof(t) );
     seqno = newSeqno;
Index: tos/lib/net/tymo/ForwardingEngineM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/ForwardingEngineM.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 ForwardingEngineM.nc
--- tos/lib/net/tymo/ForwardingEngineM.nc	3 Nov 2008 21:30:21 -0000	1.3
+++ tos/lib/net/tymo/ForwardingEngineM.nc	9 Jul 2010 19:45:16 -0000
@@ -16,7 +16,7 @@
  */
 
 //TODO probably need a lot of cleaning, and to be moved elsewhere
-generic module ForwardingEngineM () {
+generic module ForwardingEngineM () @safe(){
   provides { //For the upper layer
     interface AMSend[uint8_t id];
     interface Receive[uint8_t id];
@@ -39,8 +39,8 @@ generic module ForwardingEngineM () {
 
 implementation {
   message_t buf; //first available, do NOT use it
-  message_t * avail = &buf;
-  message_t * waiting;
+  message_t * ONE_NOK avail = &buf;
+  message_t * ONE_NOK waiting;
   uint8_t typebuf;
   uint8_t lenWaiting;
   uint8_t amWaiting = 0;
@@ -105,8 +105,8 @@ implementation {
 
     case FW_RECEIVE:
       dbg("fwe", "FE: Received a message, signaling to upper layer.\n");
-      payload = call PPacket.getPayload(msg, call PPacket.payloadLength(msg));
-      return signal Receive.receive[typebuf](msg, payload, call PPacket.payloadLength(msg));
+      //payload = TCAST(void* COUNT(ppLen), call PPacket.getPayload(msg, call PPacket.payloadLength(msg)));
+      return signal Receive.receive[typebuf](msg, call PPacket.getPayload(msg, call PPacket.payloadLength(msg)), call PPacket.payloadLength(msg));
 
     case FW_WAIT:
       atomic {
Index: tos/lib/net/tymo/LoopBackM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/LoopBackM.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 LoopBackM.nc
--- tos/lib/net/tymo/LoopBackM.nc	18 Feb 2008 20:24:56 -0000	1.1
+++ tos/lib/net/tymo/LoopBackM.nc	9 Jul 2010 19:45:16 -0000
@@ -1,4 +1,4 @@
-module LoopBackM {
+module LoopBackM @safe(){
   provides {
     interface AMSend[uint8_t id];
     interface Receive[uint8_t id];
@@ -13,9 +13,9 @@ module LoopBackM {
 implementation {
 
   message_t first_avail;
-  message_t * avail = &first_avail;
+  message_t * ONE avail = &first_avail;
 
-  message_t * buf_msg;
+  message_t * ONE_NOK buf_msg;
   uint8_t buf_am;
 
   task void sendDoneTask(){
Index: tos/lib/net/tymo/dymo/DymoEngineM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/dymo/DymoEngineM.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DymoEngineM.nc
--- tos/lib/net/tymo/dymo/DymoEngineM.nc	18 Feb 2008 20:24:57 -0000	1.1
+++ tos/lib/net/tymo/dymo/DymoEngineM.nc	9 Jul 2010 19:45:16 -0000
@@ -13,7 +13,7 @@
  * @author Romain Thouvenin
  */
 
-module DymoEngineM {
+module DymoEngineM @safe(){
   provides {
     interface SplitControl;
   }
@@ -337,7 +337,7 @@ implementation {
     } //end info!=target
   }//end event
 
-  proc_action_t process_err_info(message_t * msg, rt_info_t * info){
+  proc_action_t process_err_info(message_t * ONE msg, rt_info_t * ONE info){
     info->nexthop = call AMPacket.source(msg);
     if(call DymoTable.update(info, call DymoPacket.getType(msg)) == EINVAL){
       return ACTION_DISCARD;       
@@ -347,7 +347,7 @@ implementation {
     }
   }
 
-  event proc_action_t DymoPacket.infoProcessed(message_t * msg, rt_info_t * info){
+  event proc_action_t DymoPacket.infoProcessed(message_t * ONE msg, rt_info_t * ONE info){
     if(call DymoPacket.getType(msg) == DYMO_RERR)
       return process_err_info(msg, info);
     else
Index: tos/lib/net/tymo/dymo/DymoPacket.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/dymo/DymoPacket.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DymoPacket.nc
--- tos/lib/net/tymo/dymo/DymoPacket.nc	18 Feb 2008 20:24:58 -0000	1.1
+++ tos/lib/net/tymo/dymo/DymoPacket.nc	9 Jul 2010 19:45:16 -0000
@@ -19,12 +19,14 @@ interface DymoPacket {
 
   /**
    * Type of the packet.
+   * @param 'message_t* ONE msg'
    * @return DYMO_RREQ, DYMO_RREP or DYMO_RERR
    */
   command dymo_msg_t getType(message_t * msg);
 
   /**
    * Size of the packet (all fields included).
+   * @param 'message_t* ONE msg'
    */
   command uint16_t getSize(message_t * msg);
 
@@ -37,7 +39,7 @@ interface DymoPacket {
    * Create a routing message.  This is not strictly a Routing Message
    * as defined by DYMO specs: this is also the command to create a
    * RERR.
-   * @param msg the buffer to fill
+   * @param 'message_t* ONE msg' msg the buffer to fill
    * @param msg_type The type of message (RREQ, RREP or RERR)
    * @param origin The originator of the routing message, should be NULL for a RERR
    * @param target The target of the routing message, or first unreachable node for a RERR
@@ -50,7 +52,7 @@ interface DymoPacket {
    * implementation to choose where in the message the information
    * should be added. In anycase, it must not be added before the
    * target and originator.
-   * @param msg the existing message 
+   * @param 'message_t* ONE msg' msg the existing message 
    * @param info The piece of information to append @return
    * @return ESIZE if the payload has reached its maximum size<br/>
    *         SUCCESS otherwise
@@ -67,15 +69,15 @@ interface DymoPacket {
    * way to access the content of a message is to read it entirely
    * with this command. It will report all information found thanks to
    * events above.
-   * @param msg The message to process
-   * @param newmsg The message that will contain the processed message
+   * @param 'message_t* ONE msg' msg The message to process
+   * @param 'message_t* ONE newmsg' newmsg The message that will contain the processed message
    * to be forwarded. May be NULL if such a message is not wanted.
    */
   command void startProcessing(message_t * msg, message_t * newmsg);
 
   /**
    * Hop values have been extracted from the processed packet.
-   * @param msg the message being processed
+   * @param 'message_t* ONE msg' msg the message being processed
    * @param hop_limit the (decremented) hop limit value of the message
    * @param hop_count the (incremented) hop count value of the message
    * @return ACTION_DISCARD_MSG if a building a message to be forwarded
@@ -86,7 +88,7 @@ interface DymoPacket {
 
   /**
    * A piece of routing information has been extracted from the processed packet.
-   * @param msg the message being processed
+   * @param 'message_t* ONE msg' msg the message being processed
    * @param info the extracted piece of information. If present, hopcnt has been decremented.
    * @return ACTION_KEEP to keep this information in the forwarded message<br/>
    *         ACTION_DISCARD to remove this information in the forwardedmessage<br/>
@@ -97,6 +99,7 @@ interface DymoPacket {
   /**
    * Processing task finished.
    * No further processing event will be signaled for this message.
+   * @param 'message_t* ONE msg'
    */
   event void messageProcessed(message_t * msg);
 }
Index: tos/lib/net/tymo/dymo/DymoPacketM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/dymo/DymoPacketM.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DymoPacketM.nc
--- tos/lib/net/tymo/dymo/DymoPacketM.nc	18 Feb 2008 20:24:58 -0000	1.1
+++ tos/lib/net/tymo/dymo/DymoPacketM.nc	9 Jul 2010 19:45:16 -0000
@@ -59,8 +59,11 @@ implementation {
 			const rt_info_t * origin, const rt_info_t * target){
     nx_uint8_t * payload = call Packet.getPayload(msg, call Packet.maxPayloadLength());
     nx_uint16_t * size_p;
+
+    dbg("DymoPacketM", "Currently, the function is %s\n", __FUNCTION__);
+
     *(payload++) = msg_type;
-    size_p = (nx_uint16_t *) payload;
+    size_p = TCAST(nx_uint16_t * ONE, payload);
     payload += 2;
     *(payload++) = DYMO_HOPLIMIT;
     *(payload++) = 0;
@@ -86,7 +89,7 @@ implementation {
     *size_p += 5; 
   }
 
-  command error_t DymoPacket.addInfo(message_t * msg, const rt_info_t * info){
+  command error_t DymoPacket.addInfo(message_t * msg, const rt_info_t * ONE info){
     nx_uint8_t * payload = call Packet.getPayload(msg, call Packet.maxPayloadLength());
     nx_uint16_t * size_p = (nx_uint16_t *)(payload + 1);
     nx_uint8_t * block = payload + 5;
Index: tos/lib/net/tymo/dymo/DymoTableM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/dymo/DymoTableM.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 DymoTableM.nc
--- tos/lib/net/tymo/dymo/DymoTableM.nc	3 Nov 2008 21:30:22 -0000	1.2
+++ tos/lib/net/tymo/dymo/DymoTableM.nc	9 Jul 2010 19:45:16 -0000
@@ -12,7 +12,7 @@
  * @author Romain Thouvenin
  */
 
-generic module DymoTableM(uint8_t maxsize) {
+generic module DymoTableM(uint8_t maxsize) @safe(){
   provides {
     interface StdControl;
     interface RoutingTable;
Index: tos/lib/net/tymo/dymo/NetControlM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/dymo/NetControlM.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 NetControlM.nc
--- tos/lib/net/tymo/dymo/NetControlM.nc	18 Feb 2008 20:25:03 -0000	1.1
+++ tos/lib/net/tymo/dymo/NetControlM.nc	9 Jul 2010 19:45:16 -0000
@@ -11,7 +11,7 @@
  */
 
 // TODO generalize to a multiControl
-module NetControlM {
+module NetControlM @safe(){
   provides interface SplitControl;
   uses {
     interface SplitControl as AMControl;
Index: tos/lib/net/tymo/dymo/sim/DymoEngineM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/dymo/sim/DymoEngineM.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 DymoEngineM.nc
--- tos/lib/net/tymo/dymo/sim/DymoEngineM.nc	18 Feb 2008 20:25:05 -0000	1.1
+++ tos/lib/net/tymo/dymo/sim/DymoEngineM.nc	9 Jul 2010 19:45:16 -0000
@@ -14,7 +14,7 @@
  * @author Romain Thouvenin
  */
 
-module DymoEngineM {
+module DymoEngineM @safe(){
   provides {
     interface SplitControl;
   }
Index: tos/lib/net/tymo/dymo/sim/DymoPacketM.nc
===================================================================
RCS file: tos/lib/net/tymo/dymo/sim/DymoPacketM.nc
diff -N tos/lib/net/tymo/dymo/sim/DymoPacketM.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/net/tymo/dymo/sim/DymoPacketM.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2007 Romain Thouvenin <romain.thouvenin@gmail.com>
+ * Published under the terms of the GNU General Public License (GPLv2).
+ */
+
+#include "dymo_packet.h"
+
+/**
+ * DymoPacketM - Implementation of the DYMO packets format.
+ *
+ * @author Romain Thouvenin
+ */
+
+module DymoPacketM @safe() {
+  provides {
+    interface DymoPacket;
+    interface PacketMaker; //For tests and debugging
+  }
+  uses interface Packet;
+}
+//TODO generalize size values
+implementation {
+  message_t * currentMsg;
+  message_t * processedMsg;
+
+#ifdef TOSSIM
+  #define MAXLEN call Packet.maxPayloadLength()
+#endif
+
+  /* Local functions */
+  void create_block(nx_uint8_t * payload, const rt_info_t * info, uint8_t len);
+  uint8_t block_size(nx_uint8_t * block);
+  uint8_t block_info_size(nx_uint8_t * block);
+  uint8_t block_header_size(nx_uint8_t * block);
+  uint8_t block_num_addr(nx_uint8_t * block);
+  void    block_get_info(nx_uint8_t * block, uint8_t pos, rt_info_t * info, bool update, uint8_t len);
+  nx_uint8_t * block_get_pointer(nx_uint8_t * block, uint8_t pos, uint8_t * size, uint8_t len);
+  bool block_can_contain(nx_uint8_t * COUNT(len) block, const rt_info_t * info, uint8_t len);
+  void block_add_info(nx_uint8_t * block, const rt_info_t * info, uint8_t len);
+  void move_data(nx_uint8_t * data, uint8_t amount, uint8_t offset, uint8_t len);
+
+
+  /*****************
+   * Packet header *
+   *****************/
+
+  command dymo_msg_t DymoPacket.getType(message_t * msg){
+    nx_uint8_t * p = call Packet.getPayload(msg, 1);
+    return *p;
+  }
+
+  command uint16_t DymoPacket.getSize(message_t * msg){
+    nx_uint8_t * p = call Packet.getPayload(msg, 3);
+    return *(nx_uint16_t *)(p + 1);
+  }
+
+
+  /*********************
+   * Creating a packet *
+   *********************/
+
+  command void DymoPacket.createRM(message_t * msg, dymo_msg_t msg_type, 
+			const rt_info_t * origin, const rt_info_t * target) {
+    uint8_t len = call Packet.maxPayloadLength();
+    uint8_t llen = 0;
+    nx_uint8_t * payload = call Packet.getPayload(msg, len);
+    nx_uint16_t * size_p;
+
+    *(payload++) = msg_type;
+    size_p = TCAST(nx_uint16_t * ONE, payload);
+    payload += 2;
+    *(payload++) = DYMO_HOPLIMIT;
+    *(payload++) = 0;
+
+    llen = len - 5;
+    create_block(payload, target, llen);
+   
+    if(origin){
+      if(block_can_contain(payload, origin, llen)){
+	block_add_info(payload, origin, llen);
+	*size_p = block_size(payload);
+      } else {
+	*size_p = block_size(payload);
+	payload += *size_p;
+	llen = llen - *size_p;
+	create_block(payload, origin, llen);
+	*size_p += block_size(payload);
+      }
+    } else {
+      *size_p = block_size(payload);
+    }
+
+    //size of msg header
+    //it is here to save a few instructions or a byte
+    *size_p += 5; 
+  }
+
+  command error_t DymoPacket.addInfo(message_t * msg, const rt_info_t * info){
+    uint8_t len = call Packet.maxPayloadLength();
+    uint8_t llen = 0;
+    nx_uint8_t * payload = call Packet.getPayload(msg, len);
+    nx_uint16_t * size_p = (nx_uint16_t *)(payload + 1);
+    nx_uint8_t * BND(payload + 5, payload + len) block = payload + 5;
+    uint8_t bsize;
+
+    llen = len - 5;
+
+    while(block < payload + *size_p){
+      //We don't want to add something before the origin
+      if ( ((block > payload + 5) && block_can_contain(block, info, llen))
+	   || ((block == payload + 5) && (block_num_addr(block) > 1)) ) {
+
+	uint8_t isize = block_info_size(block);
+	if(*size_p + isize > call Packet.maxPayloadLength()){
+	  return ESIZE;
+	} else {
+	  bsize = block_size(block);
+	  move_data(block + bsize, payload + *size_p - (block + bsize), isize, llen - bsize);
+	  block_add_info(block, info, llen);
+	  *size_p += isize;
+	  return SUCCESS;
+	}
+      } else {
+	block += block_size(block);
+	llen -= block_size(block);
+      }
+    }
+
+    create_block(block, info, llen);
+    bsize = block_size(block);
+    if(*size_p +  bsize > call Packet.maxPayloadLength()){
+      return ESIZE;
+    } else {
+      *size_p += bsize;
+      return SUCCESS;
+    }
+  }
+
+
+  /***********************
+   * Processing a packet *
+   ***********************/
+
+  task void processMessage(){
+    uint8_t len = call Packet.maxPayloadLength();
+    uint8_t llen = 0;
+
+    nx_uint8_t * payload = call Packet.getPayload(currentMsg, len);
+    nx_uint8_t * end = payload + *(nx_uint16_t *)(payload+1);
+    nx_uint8_t * fw_payload = NULL;
+    nx_uint16_t * fw_size = NULL;
+    nx_uint8_t *fw_block, * info_p;
+    rt_info_t info;
+    uint8_t i,n,s;
+    bool first_block = 1;
+    proc_action_t action;
+
+    payload += 3;
+    *(payload++) -= 1; //decr hopL
+    *(payload++) += 1; //incr hopC
+
+    llen = len - 5;
+    action = signal DymoPacket.hopsProcessed(currentMsg, *(payload-2), *(payload-1));
+
+    if(processedMsg){
+      if(action != ACTION_DISCARD_MSG){
+	fw_payload = call Packet.getPayload(processedMsg, call Packet.maxPayloadLength());
+	memcpy(fw_payload, payload - 5, 5);
+	fw_size = (nx_uint16_t *)(fw_payload + 1);
+	*fw_size = 5;
+	fw_payload += 5;
+      } else {
+	processedMsg = NULL;
+      }
+    }
+
+    dbg("DymoPacket", "%s: payload: %p\n", __FUNCTION__, payload);
+
+    while(payload < end){
+      fw_block = NULL;
+      n = block_num_addr(payload);
+
+      for(i=0;i<n;i++){
+	block_get_info(payload, i, &info, !first_block || i, llen);
+	action = signal DymoPacket.infoProcessed(currentMsg, &info);
+
+	if(processedMsg){
+	  switch(action){
+	  case ACTION_KEEP:
+	    if(!fw_block){
+	      s = block_header_size(payload);
+	      memcpy(fw_payload, payload, s);
+	      fw_block = fw_payload;
+	      *(fw_block+1) = 0;
+	      fw_payload += s;
+	    }
+            dbg("DymoPacket", "before get pointer, %s: payload: %p, s: %u\n", __FUNCTION__, payload, s);
+	    info_p = block_get_pointer(payload, i, &s, llen);
+	    memcpy(fw_payload, info_p, s);
+            dbg("DymoPacket", "after get pointer, %s: payload: %p, info_p: %p, s: %u\n", __FUNCTION__, payload, info_p, s);
+	    fw_payload += s;
+	    *(fw_block+1) += 1; //increments NumAddr
+	    break;
+
+	  case ACTION_DISCARD_MSG:
+	    processedMsg = NULL;
+	  default:
+	  }
+	}//if
+
+      }//for
+      payload += block_size(payload);
+      llen -= block_size(payload);
+      first_block = 0;
+      if(fw_block)
+	*fw_size += block_size(fw_block);
+    }
+    
+    signal DymoPacket.messageProcessed(currentMsg);
+  }
+
+  command void DymoPacket.startProcessing(message_t * msg, message_t * newmsg){
+    currentMsg = msg;
+    processedMsg = newmsg;
+    post processMessage();
+  }
+
+
+
+  //TODO return block_size, it is always needed after a block creation
+  void create_block(nx_uint8_t * COUNT(len) payload, const rt_info_t * info, uint8_t len){
+    uint8_t semantics;
+    nx_uint8_t * BND(payload, payload + len) tmp_payload = payload;
+
+    semantics = BLOCK_HEAD;
+    if(info->seqnum)
+      semantics |= BLOCK_SEQNUM;
+    if(info->has_hopcnt)
+      semantics |= BLOCK_HOPCNT;
+
+    *(tmp_payload++) = semantics;
+    *(tmp_payload++) = 1;
+    *(nx_addr_t *)tmp_payload = info->address;
+    tmp_payload += sizeof(addr_t);
+
+    if(info->seqnum){
+      *(nx_seqnum_t *)tmp_payload = info->seqnum;
+      tmp_payload += 2;
+    }
+    if(info->has_hopcnt){
+      *(tmp_payload++) = info->hopcnt;
+    }
+  }
+
+  void block_add_info(nx_uint8_t * COUNT(len) block, const rt_info_t * info, uint8_t len) {
+    nx_uint8_t* BND(block, block + len) tmp_block = block;
+
+    uint8_t semantics = *tmp_block;
+    nx_uint8_t * size_p = tmp_block + 1;
+    tmp_block += block_size(tmp_block);
+    *size_p += 1;
+
+    if(semantics & BLOCK_HEAD){
+      *tmp_block = info->address % 256;
+      tmp_block++;
+    } else {
+      *(nx_addr_t *)tmp_block = info->address;
+      tmp_block += sizeof(addr_t);
+    }
+
+    if(semantics & BLOCK_SEQNUM){
+      *(nx_seqnum_t *)tmp_block = info->seqnum;
+      tmp_block += sizeof(seqnum_t);
+    }
+
+    if(semantics & BLOCK_HOPCNT){
+      *tmp_block = info->hopcnt;
+    }
+  }
+
+  bool block_can_contain(nx_uint8_t * COUNT(len) block, const rt_info_t * info, uint8_t len){
+    if( (*block & BLOCK_SEQNUM) && !info->seqnum )
+      return 0;
+    if( !(*block & BLOCK_SEQNUM) && info->seqnum )
+      return 0;
+
+    if( (*block & BLOCK_HOPCNT) && !info->has_hopcnt )
+      return 0;
+    if( !(*block & BLOCK_HOPCNT) && info->has_hopcnt )
+      return 0;
+
+    if( (*block & BLOCK_HEAD) && (*(block + 2) != (info->address / 256)) )
+      return 0;
+
+    return 1;
+  }
+
+  uint8_t block_info_size(nx_uint8_t * block){
+    uint8_t result = 1;
+    if(!(*block & BLOCK_HEAD))
+      result++;
+    if(*block & BLOCK_SEQNUM)
+      result += 2;
+    if(*block & BLOCK_HOPCNT)
+      result++;
+    //TODO add max age
+    return result;
+  }
+
+  uint8_t block_header_size(nx_uint8_t * block){
+    if(*block & BLOCK_HEAD)
+      return 3;
+    else
+      return 2;
+  }
+
+  TRUSTEDBLOCK uint8_t block_num_addr(nx_uint8_t * block){
+    return *(block + 1);
+  }
+
+  uint8_t block_size(nx_uint8_t * block){
+    uint8_t result = 2;
+    if(*block & BLOCK_HEAD){
+      result++;
+    }
+    return result + block_num_addr(block) * block_info_size(block);
+  }
+
+  nx_uint8_t * BND(block, block + len) block_get_pointer(nx_uint8_t * COUNT(len) block, uint8_t pos, uint8_t * size, uint8_t len){
+    uint8_t idx = 0;
+    dbg("DymoPacket", "%s: block_get_pointer start!\n", __FUNCTION__);
+    if(size){
+      *size = block_info_size(block);
+      idx = block_header_size(block) + pos * (*size); 
+      dbg("DymoPacket", "%s: idx: %u!\n", __FUNCTION__, idx);
+      //return block + block_header_size(block) + pos * (*size);
+      return block + idx;
+    } else {
+      idx = block_header_size(block) + pos * block_info_size(block); 
+      dbg("DymoPacket", "%s: idx: %u!\n", __FUNCTION__, idx);
+      //return block + block_header_size(block) + pos * block_info_size(block);
+      return block + idx;
+    }
+  }
+
+  void block_get_info(nx_uint8_t * COUNT(len) block, uint8_t pos, rt_info_t * info, bool update, uint8_t len){
+    nx_uint8_t* BND(block, block + len) tmp_block = block;
+
+    nx_uint8_t * semantics = tmp_block;
+    dbg("DymoPacket", "%s: the tmp_block: %p\n", __FUNCTION__, tmp_block);
+    tmp_block = block_get_pointer(tmp_block, pos, NULL, len);
+    dbg("DymoPacket", "%s: the tmp_block: %p\n", __FUNCTION__, tmp_block);
+    
+    if(*semantics & BLOCK_HEAD){
+      info->address = *(semantics + 2) * 256 + *tmp_block;
+      tmp_block++;
+    } else {
+      info->address = *(nx_addr_t *)tmp_block;
+      tmp_block += sizeof(addr_t);
+    }
+
+    if(*semantics & BLOCK_SEQNUM){
+      info->seqnum = *(nx_seqnum_t *)tmp_block;
+      tmp_block += sizeof(seqnum_t);
+    } else {
+      info->seqnum = 0;
+    }
+
+    if(*semantics & BLOCK_HOPCNT) {
+      info->has_hopcnt = 1;
+      if(update)
+	*tmp_block += 1;
+      info->hopcnt = *tmp_block;
+      tmp_block++;
+    } else {
+      info->has_hopcnt = 0;
+    }
+  }
+
+  void move_data(nx_uint8_t * data, uint8_t amount, uint8_t offset, uint8_t len){
+    nx_uint8_t * BND(data + offset, data + len) newdata = data + amount + offset;
+    nx_uint8_t * BND(data, data + len) tmp_data = data;
+
+    tmp_data += amount;
+    for(; amount > 0; amount--)
+      *--newdata = *--tmp_data;
+  }
+
+
+  /**************
+   * PakerMaker *
+   **************/
+
+  command uint16_t PacketMaker.getSize(message_t * msg){
+    return call DymoPacket.getSize(msg);
+  }
+
+  command void PacketMaker.createRM(message_t * msg, dymo_msg_t msg_type, 
+				   const rt_info_t * origin, const rt_info_t * target){
+    call DymoPacket.createRM(msg, msg_type, origin, target);
+  }
+
+  command error_t PacketMaker.addInfo(message_t * msg, const rt_info_t * info){
+    return call DymoPacket.addInfo(msg, info);
+  }
+}
Index: tos/lib/net/tymo/mh/MHEngineM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/mh/MHEngineM.nc,v
retrieving revision 1.1
diff -u -b -p -r1.1 MHEngineM.nc
--- tos/lib/net/tymo/mh/MHEngineM.nc	18 Feb 2008 20:25:09 -0000	1.1
+++ tos/lib/net/tymo/mh/MHEngineM.nc	9 Jul 2010 19:45:16 -0000
@@ -11,7 +11,7 @@
  *
  * @author Romain Thouvenin
  */
-module MHEngineM {
+module MHEngineM @safe() {
   provides interface RouteSelect;
   uses {
     interface AMPacket as MHPacket;
Index: tos/lib/net/tymo/mh/MHPacketM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/net/tymo/mh/MHPacketM.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 MHPacketM.nc
--- tos/lib/net/tymo/mh/MHPacketM.nc	14 Sep 2009 21:21:56 -0000	1.3
+++ tos/lib/net/tymo/mh/MHPacketM.nc	9 Jul 2010 19:45:16 -0000
@@ -5,7 +5,7 @@
 
 #include "mhpacket.h"
 
-#define HEADER  ((mhpacket_header_t *)(call SubPacket.getPayload(amsg, call SubPacket.maxPayloadLength())))
+#define HEADER  ((mhpacket_header_t * ONE)(call SubPacket.getPayload(amsg, call SubPacket.maxPayloadLength())))
 
 /**
  * MHPacketM - Implements ActiveMessage on top of ActiveMessage,
@@ -14,7 +14,7 @@
  * @author Romain Thouvenin
  */
 
-module MHPacketM {
+module MHPacketM @safe(){
   provides {
     interface Packet;
     interface AMPacket as MHPacket;
Index: tos/lib/serial/SerialDispatcherP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/serial/SerialDispatcherP.nc,v
retrieving revision 1.10
diff -u -b -p -r1.10 SerialDispatcherP.nc
--- tos/lib/serial/SerialDispatcherP.nc	29 Jun 2010 22:07:50 -0000	1.10
+++ tos/lib/serial/SerialDispatcherP.nc	9 Jul 2010 19:45:16 -0000
@@ -45,7 +45,7 @@
 
 #include "Serial.h"
 
-generic module SerialDispatcherP() {
+generic module SerialDispatcherP() @safe() {
   provides {
     interface Receive[uart_id_t id];
     interface Send[uart_id_t id];
@@ -86,7 +86,7 @@ implementation {
 
   /* This component provides double buffering. */
   message_t messages[2];     // buffer allocation
-  message_t* ONE messagePtrs[2] = { &messages[0], &messages[1]};
+  message_t* ONE_NOK messagePtrs[2] = { &messages[0], &messages[1]};
   
   // We store a separate receiveBuffer variable because indexing
   // into a pointer array can be costly, and handling interrupts
@@ -108,6 +108,8 @@ implementation {
   message_t * ONE_NOK receiveTaskBuf = NULL;
   uint8_t receiveTaskSize = 0;
 
+  bool startPacket = FALSE; // This variable is added to help check user-specified properties.
+  
   command error_t Send.send[uint8_t id](message_t* msg, uint8_t len) {
     if (sendState != SEND_STATE_IDLE) {
       return EBUSY;
@@ -131,6 +133,7 @@ implementation {
       // sendLen is where in the buffer the packet stops.
       // This is the length of the packet, plus its start point
       sendLen = call PacketInfo.dataLinkLength[id](msg, len) + sendIndex;
+      dbg("SerialDispatch", "%s: sendIndex: %u, sendLen: %u, size of message: %u, payload len: %u\n", __FUNCTION__, sendIndex, sendLen, sizeof(message_t), len);
     }
     if (call SendBytePacket.startSend(id) == SUCCESS) {
       return SUCCESS;
@@ -220,11 +223,13 @@ implementation {
   
   void receiveBufferSwap() {
     receiveState.which = (receiveState.which)? 0: 1;
+    dbg("SerialDispatch", "%s: buffer changed to: %u\n", __FUNCTION__, receiveState.which);
     receiveBuffer = (uint8_t*)(messagePtrs[receiveState.which]);
   }
   
   async event error_t ReceiveBytePacket.startPacket() {
     error_t result = SUCCESS;
+    startPacket = TRUE;
     atomic {
       if (!isCurrentBufferLocked()) {
         // We are implicitly in RECV_STATE_IDLE, as it is the only
@@ -233,6 +238,7 @@ implementation {
         receiveState.state = RECV_STATE_BEGIN;
         recvIndex = 0;
         recvType = TOS_SERIAL_UNKNOWN_ID;
+	dbg("SerialDispatch", "%s: not locked, and start packet\n", __FUNCTION__);
       }
       else {
         result = EBUSY;
@@ -245,6 +251,7 @@ implementation {
     atomic {
       switch (receiveState.state) {
       case RECV_STATE_BEGIN:
+	dbg("SerialDispatch", "%s: receive state begin\n", __FUNCTION__);
         receiveState.state = RECV_STATE_DATA;
         recvIndex = call PacketInfo.offset[b]();
         recvType = b;
@@ -254,6 +261,7 @@ implementation {
         if (recvIndex < sizeof(message_t)) {
           receiveBuffer[recvIndex] = b;
           recvIndex++;
+	  dbg("SerialDispatch", "%s: receive state data, index: %d, size of message: %d\n", __FUNCTION__, recvIndex, sizeof(message_t));
         }
         else {
           // Drop extra bytes that do not fit in a message_t.
@@ -289,6 +297,7 @@ implementation {
     atomic {
       messagePtrs[myWhich] = myBuf;
       unlockBuffer(myWhich);
+      dbg("SerialDispatch", "%s: the unlock buffer: %u\n", __FUNCTION__, myWhich);
       receiveTaskPending = FALSE;
     }
   }
Index: tos/lib/serial/SerialP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/serial/SerialP.nc,v
retrieving revision 1.5
diff -u -b -p -r1.5 SerialP.nc
--- tos/lib/serial/SerialP.nc	24 Jan 2007 17:17:01 -0000	1.5
+++ tos/lib/serial/SerialP.nc	9 Jul 2010 19:45:16 -0000
@@ -56,8 +56,11 @@
 
 #include "AM.h"
 #include "crc.h"
+#ifdef TOSSIM
+  #include <randomlib.h>
+#endif
 
-module SerialP {
+module SerialP @safe() {
 
   provides {
     interface Init;
@@ -359,6 +362,7 @@ implementation {
     else {
       atomic offPending = TRUE;
     }
+    //dbg("SerialP","%s: testOff is executing! offPending: %u\n", __FUNCTION__, offPending);
   }
     
   command error_t SplitControl.stop() {
@@ -404,6 +408,7 @@ implementation {
     switch (rxState) {
       
     case RXSTATE_NOSYNC: 
+      //dbg("SerialP", "rx_state_machine: RXSTATE_NOSYNC, data: %x\n", data);
       if (isDelimeter) {
         rxInit();
         rxState = RXSTATE_PROTO;
@@ -411,6 +416,7 @@ implementation {
       break;
       
     case RXSTATE_PROTO:
+      //dbg("SerialP", "rx_state_machine: RXSTATE_PROTO, data: %x\n", data);
       if (!isDelimeter){
         rxCRC = crcByte(rxCRC,data);
         rxState = RXSTATE_TOKEN;
@@ -428,6 +434,7 @@ implementation {
       break;
       
     case RXSTATE_TOKEN:
+      //dbg("SerialP", "rx_state_machine: RXSTATE_TOKEN, data: %x\n", data);
       if (isDelimeter) {
         goto nosync;
       }
@@ -439,9 +446,37 @@ implementation {
       break;
       
     case RXSTATE_INFO:
-      if (rxByteCnt < SERIAL_MTU){ 
+      //dbg("SerialP", "rx_state_machine: RXSTATE_INFO, data: %x\n", data);
+      if (rxByteCnt < SERIAL_MTU) { 
         if (isDelimeter) { /* handle end of frame */
           if (rxByteCnt >= 2) {
+
+#ifndef TOSSIM
+              if (rx_current_crc() == rxCRC) {
+                signal ReceiveBytePacket.endPacket(SUCCESS);
+                ack_queue_push(rxSeqno);
+                goto nosync;
+              }
+              else {
+                goto nosync;
+              }
+#else
+            if(mc_state != TOSSIM_RUNNING) {
+	      uint8_t choose = 0;
+	      Toss_Internal_Choose(1, &choose);
+	      /************* Dynamic check added to make the execution fork **********/
+	      if(choose) {
+	        dbg("SerialP", "Pass the crc checking\n");
+                signal ReceiveBytePacket.endPacket(SUCCESS);
+                ack_queue_push(rxSeqno);
+                goto nosync;
+	      }
+	      else {
+	        dbg("SerialP", "Fail the crc checking\n");
+                goto nosync;
+	      }
+	    }
+	    else {
             if (rx_current_crc() == rxCRC) {
               signal ReceiveBytePacket.endPacket(SUCCESS);
               ack_queue_push(rxSeqno);
@@ -451,6 +486,8 @@ implementation {
               goto nosync;
             }
           }
+#endif
+          }
           else {
             goto nosync;
           }
@@ -479,6 +516,7 @@ implementation {
   nosync:
     /* reset all counters, etc */
     rxInit();
+    //dbg("SerialP", "rx_state_machine: goto no sync, offPending: %u, rxState: %u\n", offPending, rxState);
     call SerialFrameComm.resetReceive();
     signal ReceiveBytePacket.endPacket(FAIL);
     if (offPending) {
@@ -491,6 +529,7 @@ implementation {
     }
     
   done:
+    //dbg("SerialP", "rx_state_machine: goto done, offPending: %u, rxState: %u\n", offPending, rxState);
   }
 
   
Index: tos/lib/timer/AlarmToTimerC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/timer/AlarmToTimerC.nc,v
retrieving revision 1.7
diff -u -b -p -r1.7 AlarmToTimerC.nc
--- tos/lib/timer/AlarmToTimerC.nc	29 Jun 2010 22:07:50 -0000	1.7
+++ tos/lib/timer/AlarmToTimerC.nc	9 Jul 2010 19:45:16 -0000
@@ -60,6 +60,9 @@ implementation
     m_dt = dt;
     m_oneshot = oneshot;
     call Alarm.startAt(t0, dt);
+#ifdef TOSSIM
+    sim_alarm_set();
+#endif
   }
 
   command void Timer.startPeriodic(uint32_t dt)
@@ -79,7 +82,12 @@ implementation
   }
 
   async event void Alarm.fired()
-  { post fired(); }
+  { 
+     post fired(); 
+#ifdef TOSSIM
+     sim_alarm_timer_signal();
+#endif
+  }
 
   command bool Timer.isRunning()
   { return call Alarm.isRunning(); }
Index: tos/lib/tossim/ActiveMessageAddressC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/ActiveMessageAddressC.nc,v
retrieving revision 1.6
diff -u -b -p -r1.6 ActiveMessageAddressC.nc
--- tos/lib/tossim/ActiveMessageAddressC.nc	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/ActiveMessageAddressC.nc	9 Jul 2010 19:45:16 -0000
@@ -54,12 +54,49 @@
  */
 
 module ActiveMessageAddressC  {
+  provides interface ActiveMessageAddress;
   provides async command am_addr_t amAddress();
   provides async command void setAmAddress(am_addr_t a);
 }
 implementation {
   bool set = FALSE;
-  am_addr_t addr;
+  //am_addr_t addr;
+
+  /** Node address */
+  am_addr_t addr = TOS_AM_ADDRESS;
+
+  /** Group address */
+  am_group_t group = TOS_AM_GROUP;
+
+  /***************** ActiveMessageAddress Commands ****************/
+  /**
+   * @return the active message address of this node
+   */
+  async command am_addr_t ActiveMessageAddress.amAddress() {
+    return call amAddress();
+  }
+  
+  /**
+   * Set the active message address of this node
+   * @param group The node's group ID
+   * @param addr The node's active message address
+   */
+  async command void ActiveMessageAddress.setAddress(am_group_t myGroup, am_addr_t myAddr) {
+    atomic {
+      addr = myAddr;
+      group = myGroup;
+    }
+    signal ActiveMessageAddress.changed();
+  }
+  
+  /**
+   * @return the group address of this node
+   */
+  async command am_group_t ActiveMessageAddress.amGroup() {
+    am_group_t myGroup;
+    atomic myGroup = group;
+    return myGroup;
+  }
 
   async command am_addr_t amAddress() {
     if (!set) {
@@ -73,4 +110,11 @@ implementation {
     set = TRUE;
     addr = a;
   }
+
+  /***************** Defaults ****************/
+  /**
+   * Notification that the address of this node changed.
+   */
+  default async event void ActiveMessageAddress.changed() {
+  }
 }
Index: tos/lib/tossim/ActiveMessageC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/ActiveMessageC.nc,v
retrieving revision 1.7
diff -u -b -p -r1.7 ActiveMessageC.nc
--- tos/lib/tossim/ActiveMessageC.nc	29 Jun 2010 22:07:51 -0000	1.7
+++ tos/lib/tossim/ActiveMessageC.nc	9 Jul 2010 19:45:16 -0000
@@ -50,12 +50,24 @@ configuration ActiveMessageC {
     interface Packet;
     interface AMPacket;
     interface PacketAcknowledgements;
+
+#if defined(TIMESYNC) || defined(SIM_CC2420)
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+#ifdef SIM_CC2420
+    interface LowPowerListening;
+#endif
+#endif
   }
 }
 implementation {
+#ifdef SIM_CC2420
+  components CC2420ActiveMessageC as AM;
+  SplitControl = AM;
+#else
   components TossimActiveMessageC as AM;
-  components TossimPacketModelC as Network;
 
+  components TossimPacketModelC as Network;
   components CpmModelC as Model;
 
   components ActiveMessageAddressC as Address;
@@ -63,17 +75,28 @@ implementation {
   
   MainC.SoftwareInit -> Network;
   SplitControl = Network;
+#endif
   
   AMSend       = AM;
   Receive      = AM.Receive;
   Snoop        = AM.Snoop;
   Packet       = AM;
   AMPacket     = AM;
-  PacketAcknowledgements = Network;
 
+#ifdef SIM_CC2420
+  PacketAcknowledgements = AM;
+  LowPowerListening = AM;
+#else
+  PacketAcknowledgements = Network;
   AM.Model -> Network.Packet;
   AM.amAddress -> Address;
-  
   Network.GainRadioModel -> Model;
+#endif
+  
+#if defined(TIMESYNC) || defined(SIM_CC2420)
+  components CC2420PacketC;
+  PacketTimeStamp32khz = CC2420PacketC;
+  PacketTimeStampMilli = CC2420PacketC;
+#endif
 }
 
Index: tos/lib/tossim/CpmModelC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/CpmModelC.nc,v
retrieving revision 1.16
diff -u -b -p -r1.16 CpmModelC.nc
--- tos/lib/tossim/CpmModelC.nc	29 Jun 2010 22:07:51 -0000	1.16
+++ tos/lib/tossim/CpmModelC.nc	9 Jul 2010 19:45:16 -0000
@@ -87,6 +87,57 @@ implementation {
   double packetNoise(receive_message_t* msg);
   double checkPrr(receive_message_t* msg);
   
+  message_t* copy_message(message_t* msg) {
+    message_t* tmpMsg = (message_t*)malloc(sizeof(message_t));
+    memcpy(tmpMsg, msg, sizeof(message_t));
+    return tmpMsg;
+  }
+
+  void sim_copy_general_event(sim_event_t* gen, sim_event_t* _mc_gen) @C() @spontaneous() {     
+    _mc_gen->data = copy_message((message_t*)gen->data);
+  }
+
+  void sim_copy_receive_event(sim_event_t* rcv, sim_event_t* _mc_rcv) @C() @spontaneous() {
+    int tmp = sim_node();
+    receive_message_t* rmt = NULL;
+    receive_message_t* _mc_rmt = NULL;
+
+    sim_set_node(rcv->mote);
+    rmt = (receive_message_t*)rcv->data; 
+    _mc_rmt = allocate_receive_message();
+    memcpy(_mc_rmt, rmt, sizeof(receive_message_t));
+    _mc_rmt->next = NULL;
+    _mc_rmt->msg = copy_message(rmt->msg);
+    _mc_rcv->data = _mc_rmt;
+    
+    sim_set_node(tmp);
+  }
+
+  void sim_clear_outstandingReceptionHead(int node) @C() @spontaneous() {
+    int tmp = sim_node();
+    sim_set_node(node);
+    outstandingReceptionHead = NULL;
+    sim_set_node(tmp);
+  }
+
+  void sim_reset_outstandingReceptionHead(sim_event_t* evt) @C() @spontaneous() {
+    int tmp = sim_node();
+    receive_message_t* rmt = NULL;
+    sim_set_node(evt->mote);
+    rmt = (receive_message_t*)evt->data;
+    rmt->next = outstandingReceptionHead;
+    outstandingReceptionHead = rmt;  
+    sim_set_node(tmp);
+  }
+
+  void sim_cleanup_event_receive_message(sim_event_t* evt) @C() @spontaneous() {
+    receive_message_t* rcv = (receive_message_t*)evt->data;
+    if(rcv != NULL) {
+      free_receive_message(rcv);
+      evt->data = NULL;
+    }
+  }
+
   double timeInMs()   {
     sim_time_t ftime = sim_time();
     int hours, minutes, seconds;
@@ -175,6 +226,37 @@ implementation {
     return (int)prr;
   }
   
+  bool sim_ack_choose_mode(sim_event_t* evt, double snr) {
+    bool choose_mode = FALSE;
+
+    switch(mc_state) {
+       case TOSSIM_RUNNING:
+	  choose_mode = shouldAckReceive(snr);
+	  break;
+       case MC_RUNNING:
+          choose_mode = evt->mark;
+	  break;
+       case RANDOM_WALK: 
+	  // Considering the noise...
+	  if(sim_loss_mode == LOSS_WITH_NOISE) {
+	    choose_mode = shouldAckReceive(snr);
+	    sim_set_mc_element_num(choose_mode);
+	  } 
+	  else
+	    choose_mode = evt->mark;
+	  break;
+       case MC_RW_REPEAT:
+          choose_mode = evt->mark;
+	  break;
+       case TOSSIM_RE_RUNNING:
+	  choose_mode = shouldAckReceive(snr);
+	  break;
+    }
+
+    return choose_mode;
+  }
+
+
   void sim_gain_ack_handle(sim_event_t* evt)  {
     // Four conditions must hold for an ack to be issued:
     // 1) Transmitter is still sending a packet (i.e., not cancelled)
@@ -188,8 +270,12 @@ implementation {
       double power = rcv->reversePower;
       double noise = packetNoise(rcv);
       double snr = power - noise;
-      if (shouldAckReceive(snr)) {
-	signal Model.acked(outgoing);
+      message_t* ackMsg = rcv->msg;
+      bool choose_mode = sim_ack_choose_mode(evt, snr);
+      dbg("Acks", "%s: Here the ack should execute!\n", __FUNCTION__);
+
+      if (choose_mode) {
+	signal Model.acked(ackMsg);
       }
     }
     free_receive_message((receive_message_t*)evt->data);
@@ -216,6 +302,7 @@ implementation {
   void sim_gain_schedule_ack(int source, sim_time_t t, receive_message_t* r) {
     sim_event_t* ackEvent = (sim_event_t*)malloc(sizeof(sim_event_t));
     
+    int mote = sim_node(); 
     ackEvent->mote = source;
     ackEvent->force = 1;
     ackEvent->cancelled = 0;
@@ -224,9 +311,38 @@ implementation {
     ackEvent->cleanup = sim_queue_cleanup_event;
     ackEvent->data = r;
     
+    ackEvent->type = ACK;
+    ackEvent->source = mote;
+    ackEvent->mark = TRUE;
+    // Ack event's mote and source are equal to receive's source and mote...
     sim_queue_insert(ackEvent);
   }
 
+  sim_event_t* sim_apply_ack_event(element_t* ackElem) @C() @spontaneous() {
+    sim_event_t* ackEvent = (sim_event_t*)malloc(sizeof(sim_event_t)); 
+
+    ackEvent->mote = ackElem->MoteID;
+    ackEvent->force = 1;
+    ackEvent->cancelled = 0;
+    ackEvent->time = sim_time() + 1;
+    ackEvent->handle = sim_gain_ack_handle;
+    ackEvent->cleanup = sim_queue_cleanup_event;
+
+    printf("%s: ack rebuild, current mote is %lu\n", __FUNCTION__, sim_node());
+
+    // Actually, the tRcvEvt should not be NULL ...
+    if(tRcvEvt != NULL) {
+      ackEvent->data = tRcvEvt->data;
+      tRcvEvt->data = NULL;
+    }
+
+    ackEvent->type = ACK;
+    ackEvent->source = ackElem->source;
+    ackEvent->mark = ackElem->num;
+
+    return ackEvent;
+  }
+
   double prr_estimate_from_snr(double SNR) {
     // Based on CC2420 measurement by Kannan.
     // The updated function below fixes the problem of non-zero PRR
@@ -289,6 +405,35 @@ implementation {
     return prr_estimate_from_snr(msg->power / packetNoise(msg));
   }
   
+  bool sim_receive_choose_mode(sim_event_t* evt, receive_message_t* mine) {
+    bool choose_mode = FALSE; 
+
+    switch(mc_state) {
+       case TOSSIM_RUNNING:
+          choose_mode = !mine->lost;
+	  break;
+       case MC_RUNNING:
+          choose_mode = evt->mark;
+	  break;
+       case RANDOM_WALK: 
+	  // Considering the noise...
+	  if(sim_loss_mode == LOSS_WITH_NOISE) {
+            choose_mode = !mine->lost;
+	    sim_set_mc_element_num(choose_mode);
+	  }
+	  else 
+	    choose_mode = evt->mark;
+	  break;
+       case MC_RW_REPEAT:
+          choose_mode = evt->mark;
+	  break;
+       case TOSSIM_RE_RUNNING:
+          choose_mode = !mine->lost;
+	  break;
+    }
+
+    return choose_mode;
+  }
 
   /* Handle a packet reception. If the packet is being acked,
      pass the corresponding receive_message_t* to the ack handler,
@@ -297,7 +442,9 @@ implementation {
     receive_message_t* mine = (receive_message_t*)evt->data;
     receive_message_t* predecessor = NULL;
     receive_message_t* list = outstandingReceptionHead;
+    bool choose_mode = FALSE;
 
+    sim_set_neighbor_receive(evt->source, evt->mote);
     dbg("CpmModelC", "Handling reception event @ %s.\n", sim_time_string());
     while (list != NULL) {
       if (list->next == mine) {
@@ -319,11 +466,13 @@ implementation {
       dbg("CpmModelC,SNRLoss", " - lost packet from %i as SNR was too low.\n", (int)mine->source);
       mine->lost = 1;
     }
-    if (!mine->lost) {
+
+    choose_mode = sim_receive_choose_mode(evt, mine);
+    if (choose_mode) {
       // Copy this receiver's packet signal strength to the metadata region
       // of the packet. Note that this packet is actually shared across all
       // receivers: a higher layer performs the copy.
-      tossim_metadata_t* meta = (tossim_metadata_t*)(&mine->msg->metadata);
+      cc2420_metadata_t* meta = (cc2420_metadata_t*)(&mine->msg->metadata);
       meta->strength = mine->strength;
       
       dbg_clear("CpmModelC,SNRLoss", "  -signaling reception\n");
@@ -381,7 +530,7 @@ implementation {
     // the beginning of the packet. This is true for the CC2420, but is not true for all
     // radios. But generalizing seems like complexity for minimal gain at this point.
     rcv->strength = (int8_t)(floor(10.0 * log(pow(10.0, power/10.0) + pow(10.0, noiseStr/10.0)) / log(10.0)));
-    rcv->msg = msg;
+    rcv->msg = copy_message(msg);
     rcv->lost = 0;
     rcv->ack = receive;
     // If I'm off, I never receive the packet, but I need to keep track of
@@ -421,6 +570,7 @@ implementation {
     rcv->next = outstandingReceptionHead;
     outstandingReceptionHead = rcv;
     evt = allocate_receive_event(endTime, rcv);
+    evt->source = source;
     sim_queue_insert(evt);
 
   }
@@ -473,6 +623,11 @@ implementation {
    evt->cancelled = 0;
    evt->force = 1; // Need to keep track of air even when node is off
    evt->data = msg;
+   evt->type = RECEIVE;
+   if (!sim_mote_is_on(sim_node())) 
+       evt->mark = FALSE;
+   else 
+       evt->mark = TRUE;
    return evt;
  }
 
@@ -480,7 +635,11 @@ implementation {
    return (receive_message_t*)malloc(sizeof(receive_message_t));
  }
 
- void free_receive_message(receive_message_t* msg) {
-   free(msg);
+ void free_receive_message(receive_message_t* rmsg) { 
+   if(rmsg->msg != NULL) {
+     free(rmsg->msg);
+     rmsg->msg = NULL;
+   }
+   free(rmsg);
  }
 }
Index: tos/lib/tossim/DemoSensorC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/DemoSensorC.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 DemoSensorC.nc
--- tos/lib/tossim/DemoSensorC.nc	29 Jun 2010 22:07:51 -0000	1.3
+++ tos/lib/tossim/DemoSensorC.nc	9 Jul 2010 19:45:16 -0000
@@ -33,6 +33,11 @@ generic configuration DemoSensorC(){
   provides interface Read<uint16_t>;
 }
 implementation {
+#ifdef ADCON
+  components new VoltageC() as DemoChannel;
+  Read = DemoChannel;
+#else
   components new ConstantSensorC(uint16_t, 0xbeef);
   Read = ConstantSensorC;
+#endif
 }
Index: tos/lib/tossim/DemoSensorNowC.nc
===================================================================
RCS file: tos/lib/tossim/DemoSensorNowC.nc
diff -N tos/lib/tossim/DemoSensorNowC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/DemoSensorNowC.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,27 @@
+/* $Id: DemoSensorNowC.nc,v 1.5 2007/05/22 20:59:01 idgay Exp $
+ * Copyright (c) 2006 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.
+ */
+/**
+ * The micaZ doesn't have any built-in sensors - this DemoSensor just reads
+ * the ground value.
+ *
+ * @author David Gay
+ */
+
+generic configuration DemoSensorNowC()
+{
+  provides interface Resource;
+  provides interface ReadNow<uint16_t>;
+}
+implementation {
+  components new VoltageNowC() as Sensor;
+
+  Resource = Sensor;
+  ReadNow = Sensor;
+}
Index: tos/lib/tossim/DemoSensorStreamC.nc
===================================================================
RCS file: tos/lib/tossim/DemoSensorStreamC.nc
diff -N tos/lib/tossim/DemoSensorStreamC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/DemoSensorStreamC.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,28 @@
+/* $Id: DemoSensorStreamC.nc,v 1.5 2007/05/22 20:59:01 idgay Exp $
+ * Copyright (c) 2006 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.
+ */
+/**
+ * The micaZ doesn't have any built-in sensors - the DemoSensor returns
+ * a constant value of 0xbeef, or just reads the ground value for the
+ * stream sensor.
+ *
+ * @author Philip Levis
+ * @authod David Gay
+ */
+
+generic configuration DemoSensorStreamC()
+{
+  provides interface ReadStream<uint16_t>;
+}
+implementation
+{
+  components new VoltageStreamC() as Sensor;
+
+  ReadStream = Sensor;
+}
Index: tos/lib/tossim/HilTimerMilliC.nc
===================================================================
RCS file: tos/lib/tossim/HilTimerMilliC.nc
diff -N tos/lib/tossim/HilTimerMilliC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/HilTimerMilliC.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,173 @@
+// $Id: HilTimerMilliC.nc,v 1.4 2006/12/12 18:23:32 vlahan Exp $
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * This is a TOSSIM-specific implementation of TimerMilliC that
+ * directly emulates timers rather than their underlying hardware.  It
+ * is intended to be a basic fill-in for microcontrollers that do not
+ * have TOSSIM simulation support.
+ *
+ * @author Philip Levis
+ * @date   December 1 2005
+ */
+
+#include <Timer.h>
+
+module HilTimerMilliC {
+  provides interface Init;
+  provides interface Timer<TMilli> as TimerMilli[uint8_t num];
+}
+implementation {
+
+  enum {
+    TIMER_COUNT = uniqueCount(UQ_TIMER_MILLI)
+  };
+
+  typedef struct tossim_timer {
+    uint32_t t0;
+    uint32_t dt;
+    bool isPeriodic;
+    bool isActive;
+    sim_event_t* evt;
+  } tossim_timer_t;
+
+  tossim_timer_t timers[TIMER_COUNT];
+  sim_time_t initTime;
+
+  void initializeEvent(sim_event_t* evt, uint8_t timerID);
+  
+  sim_time_t clockToSim(sim_time_t clockVal) {
+    return (clockVal * sim_ticks_per_sec()) / 1024;
+  }
+
+  sim_time_t simToClock(sim_time_t sim) {
+    return (sim * 1024) / sim_ticks_per_sec();
+  }
+  
+  command error_t Init.init() {
+    memset(timers, 0, sizeof(timers));
+    initTime = sim_time();
+    return SUCCESS;
+  }
+  
+  command void TimerMilli.startPeriodic[uint8_t id]( uint32_t dt ) {
+    call TimerMilli.startPeriodicAt[id](call TimerMilli.getNow[id](), dt);
+  }
+  command void TimerMilli.startOneShot[uint8_t id]( uint32_t dt ) {
+    call TimerMilli.startOneShotAt[id](call TimerMilli.getNow[id](), dt);
+  }
+
+  command void TimerMilli.stop[uint8_t id]() {
+    timers[id].isActive = 0;
+    if (timers[0].evt != NULL) {
+      timers[0].evt->cancelled = 1;
+      timers[0].evt->cleanup = sim_queue_cleanup_total;
+      timers[0].evt = NULL;
+    }
+  }
+
+  // extended interface
+  command bool TimerMilli.isRunning[uint8_t id]() {return timers[id].isActive;}
+  command bool TimerMilli.isOneShot[uint8_t id]() {return !timers[id].isActive;}
+  
+  command void TimerMilli.startPeriodicAt[uint8_t id]( uint32_t t0, uint32_t dt ) {
+    call TimerMilli.startOneShotAt[id](t0, dt);
+    timers[id].isPeriodic = 1;
+  }
+  command void TimerMilli.startOneShotAt[uint8_t id]( uint32_t t0, uint32_t dt ) {
+    uint32_t currentTime = call TimerMilli.getNow[id]();
+    sim_time_t fireTime = sim_time();
+
+    call TimerMilli.stop[id]();
+    
+    timers[id].evt = sim_queue_allocate_event();
+    initializeEvent(timers[id].evt, id);
+
+    fireTime += clockToSim(dt);
+    
+    // Be careful about signing and casts, etc.
+    if (currentTime > t0) {
+      fireTime -= clockToSim(currentTime - t0);
+    }
+    else {
+      fireTime += clockToSim(t0 - currentTime);      
+    }
+
+    timers[id].evt->time = fireTime;
+    timers[id].isPeriodic = 0;
+    timers[id].isActive = 1;
+    timers[id].t0 = t0;
+    timers[id].dt = dt;
+
+    sim_queue_insert(timers[id].evt);
+  }
+    
+  command uint32_t TimerMilli.getNow[uint8_t id]() {
+    sim_time_t nowTime = sim_time();
+    nowTime -= initTime;
+    nowTime = simToClock(nowTime);
+    return nowTime & 0xffffffff;
+  }
+  
+  command uint32_t TimerMilli.gett0[uint8_t id]() {
+    return timers[id].t0;
+  }
+  command uint32_t TimerMilli.getdt[uint8_t id]() {
+    return timers[id].dt;
+  }
+
+  void tossim_timer_handle(sim_event_t* evt) {
+    uint8_t* datum = (uint8_t*)evt->data;
+    uint8_t id = *datum;
+    signal TimerMilli.fired[id]();
+
+    // We should only re-enqueue the event if it is a follow-up firing
+    // of the same timer.  If the timer is stopped, it's a one shot,
+    // or someone has started a new timer, don't re-enqueue it.
+    if (timers[id].isActive &&
+	timers[id].isPeriodic &&
+	timers[id].evt == evt) {
+      evt->time = evt->time += clockToSim(timers[id].dt);
+      sim_queue_insert(evt);
+    }
+    // If we aren't enqueueing it, and nobody has done something that
+    // would cause the event to have been garbage collected, then do
+    // so.
+    else if (timers[id].evt == evt) {
+      call TimerMilli.stop[id]();
+    }
+  }
+  
+  void initializeEvent(sim_event_t* evt, uint8_t timerID) {
+    uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t));
+    *data = timerID;
+
+    evt->handle = tossim_timer_handle;
+    evt->cleanup = sim_queue_cleanup_none;
+    evt->data = data;
+  }
+
+ default event void TimerMilli.fired[uint8_t id]() {}
+}
+
Index: tos/lib/tossim/MainC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/MainC.nc,v
retrieving revision 1.6
diff -u -b -p -r1.6 MainC.nc
--- tos/lib/tossim/MainC.nc	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/MainC.nc	9 Jul 2010 19:45:16 -0000
@@ -56,6 +56,10 @@ implementation {
   // includes functionality many other systems depend on.
   components SimMoteP;
   
+#ifdef SAFE_TINYOS
+  components SimSafeFailureHandlerP;
+#endif
+
   SimMainP.Scheduler -> TinySchedulerC;
   SimMainP.PlatformInit -> PlatformC;
 
@@ -71,5 +75,8 @@ implementation {
   // tries to deliver a packet to a node that has no radio stack.
   components TossimActiveMessageC;
   
+#if defined(SAFETY) || defined(LIVENESS) 
+  components SimPropertyCheckC;
+#endif
 }
 
Index: tos/lib/tossim/SimAuxiliaryOutput.nc
===================================================================
RCS file: tos/lib/tossim/SimAuxiliaryOutput.nc
diff -N tos/lib/tossim/SimAuxiliaryOutput.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimAuxiliaryOutput.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,5 @@
+//Just for the other property checking besides the safety or liveness ...
+
+interface SimAuxiliaryOutput {
+  command void auxiliaryOutput();
+}
Index: tos/lib/tossim/SimMoteP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/SimMoteP.nc,v
retrieving revision 1.6
diff -u -b -p -r1.6 SimMoteP.nc
--- tos/lib/tossim/SimMoteP.nc	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/SimMoteP.nc	9 Jul 2010 19:45:16 -0000
@@ -78,12 +78,14 @@ implementation {
       startTime = sim_time();
       dbg("SimMoteP", "Setting start time to %llu\n", startTime);
       isOn = TRUE;
+      sim_signal_turn_on_mote();
       sim_main_start_mote();
     }
   }
 
   async command void SimMote.turnOff() {
     isOn = FALSE;
+    sim_signal_turn_off_mote();
   }
 
   
@@ -154,6 +156,13 @@ implementation {
     sim_set_node(tmp);
   }
 
+  void sim_mote_reset(int mote) @C() @spontaneous() {
+    int tmp = sim_node();
+    sim_set_node(mote);
+    __nesc_nido_initialise(sim_node());
+    sim_set_node(tmp);
+  }
+
   void sim_mote_boot_handle(sim_event_t* e) {
     char buf[128];
     sim_print_now(buf, 128);
@@ -185,7 +194,7 @@ implementation {
     bootEvent->data = NULL;
     bootEvent->handle = sim_mote_boot_handle;
     bootEvent->cleanup = sim_queue_cleanup_event;
-    sim_queue_insert(bootEvent);
+    sim_queue_insert_boot_event(bootEvent);
     
     sim_set_node(tmp);
   }
Index: tos/lib/tossim/SimProperty.nc
===================================================================
RCS file: tos/lib/tossim/SimProperty.nc
diff -N tos/lib/tossim/SimProperty.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimProperty.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,6 @@
+//Just for the convenience of property checking...
+
+interface SimProperty {
+  command bool safetyPropertyCheck();
+  command bool livenessPropertyCheck(); 
+}
Index: tos/lib/tossim/SimPropertyCheckC.nc
===================================================================
RCS file: tos/lib/tossim/SimPropertyCheckC.nc
diff -N tos/lib/tossim/SimPropertyCheckC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimPropertyCheckC.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,4 @@
+//Here, this is the configuration just for the property check...
+configuration SimPropertyCheckC {}
+implementation {
+}
Index: tos/lib/tossim/SimPropertyCheckC.nc.bak
===================================================================
RCS file: tos/lib/tossim/SimPropertyCheckC.nc.bak
diff -N tos/lib/tossim/SimPropertyCheckC.nc.bak
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimPropertyCheckC.nc.bak	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,4 @@
+//Here, this is the configuration just for the property check...
+configuration SimPropertyCheckC {}
+implementation {
+}
Index: tos/lib/tossim/SimPropertyCheckP-Master.nc
===================================================================
RCS file: tos/lib/tossim/SimPropertyCheckP-Master.nc
diff -N tos/lib/tossim/SimPropertyCheckP-Master.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimPropertyCheckP-Master.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+module SimPropertyCheckP {
+   //... INTERFACE
+}
+implementation {
+
+   void sim_specified_safety_checking(bool safetySatisfied, uint8_t count) {
+      // User-specified safety property is not satisfied, then dump this 
+      // information...
+      if(!safetySatisfied) {
+         FILE * bugFile = fopen("BugFile.txt", "a+"); 
+	 if(bugFile) {
+            fprintf(bugFile, "This bug occurs at the %dth path\n", (path + 1));
+            fprintf(bugFile, "%d transitions explored before this memory safety bug\n", transition_explored);
+            fprintf(bugFile, "%d event explored before this safety error\n", event_explored);
+            fprintf(bugFile, "In model checking phase, %d depth explored before this safety bug occurs\n", steps);
+            fprintf(bugFile, "The error-occurring mote #: %lu\n", sim_node());
+            fputs("\n\n\n", bugFile);
+            fclose(bugFile);
+            bugFile = NULL;
+	 }
+	 sim_signal_user_safety_bug_occur(count);
+      }
+   }
+
+   // For safety properties, T-Check will check all user-specified properties in each state...
+   void sim_safety_property_check() @C() @spontaneous() {
+      // Whether the user-provided safety property is satisfied or not
+      bool safetySatisfied; 
+      uint8_t safetyCount = 0;
+       
+      //... SAFETY 
+   }
+
+   void sim_specified_liveness_checking(bool liveSatisfied, uint8_t count) {
+      sim_signal_liveness_fulfill(count, liveSatisfied);
+   }
+   
+   void sim_liveness_property_check() @C() @spontaneous() {
+      // Whether the user-provided liveness property is satisfied or not
+      bool liveSatisfied;
+      uint8_t liveCount = 0;	
+      
+      //... LIVENESS
+   }
+}
Index: tos/lib/tossim/SimPropertyCheckP.nc
===================================================================
RCS file: tos/lib/tossim/SimPropertyCheckP.nc
diff -N tos/lib/tossim/SimPropertyCheckP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimPropertyCheckP.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,73 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+module SimPropertyCheckP {
+   uses interface SimProperty as Property1;
+   uses interface SimProperty as Property2;
+   uses interface SimProperty as Property3;
+}
+implementation {
+
+   void sim_specified_safety_checking(bool safetySatisfied, uint8_t count) {
+      // User-specified safety property is not satisfied, then dump this 
+      // information...
+      if(!safetySatisfied) {
+         FILE * bugFile = fopen("BugFile.txt", "a+"); 
+	 if(bugFile) {
+            fprintf(bugFile, "This bug occurs at the %dth path\n", (path + 1));
+            fprintf(bugFile, "%d transitions explored before this memory safety bug\n", transition_explored);
+            fprintf(bugFile, "%d event explored before this safety error\n", event_explored);
+            fprintf(bugFile, "In model checking phase, %d depth explored before this safety bug occurs\n", steps);
+            fprintf(bugFile, "The error-occurring mote #: %lu\n", sim_node());
+            fputs("\n\n\n", bugFile);
+            fclose(bugFile);
+            bugFile = NULL;
+	 }
+	 sim_signal_user_safety_bug_occur(count);
+      }
+   }
+
+   // For safety properties, T-Check will check all user-specified properties in each state...
+   void sim_safety_property_check() @C() @spontaneous() {
+      // Whether the user-provided safety property is satisfied or not
+      bool safetySatisfied; 
+      uint8_t safetyCount = 0;
+       
+      safetySatisfied = call Property1.safetyPropertyCheck();
+      sim_specified_safety_checking(safetySatisfied, safetyCount++);
+
+      safetySatisfied = call Property2.safetyPropertyCheck();
+      sim_specified_safety_checking(safetySatisfied, safetyCount++);
+
+      safetySatisfied = call Property3.safetyPropertyCheck();
+      sim_specified_safety_checking(safetySatisfied, safetyCount++);
+
+   }
+
+   void sim_specified_liveness_checking(bool liveSatisfied, uint8_t count) {
+      if(liveSatisfied)
+	sim_signal_liveness_fulfill(count);
+   }
+   
+   void sim_liveness_property_check() @C() @spontaneous() {
+      // Whether the user-provided liveness property is satisfied or not
+      bool liveSatisfied;
+      uint8_t liveCount = 0;	
+      
+      if(sim_property_should_be_checked(liveCount)) {
+        liveSatisfied = call Property1.livenessPropertyCheck();
+        sim_specified_liveness_checking(liveSatisfied, liveCount++);
+      }
+
+      if(sim_property_should_be_checked(liveCount)) {
+        liveSatisfied = call Property2.livenessPropertyCheck();
+        sim_specified_liveness_checking(liveSatisfied, liveCount++);
+      }
+
+      if(sim_property_should_be_checked(liveCount)) {
+        liveSatisfied = call Property3.livenessPropertyCheck();
+        sim_specified_liveness_checking(liveSatisfied, liveCount++);
+      }
+
+   }
+}
Index: tos/lib/tossim/SimPropertyCheckP.nc.bak
===================================================================
RCS file: tos/lib/tossim/SimPropertyCheckP.nc.bak
diff -N tos/lib/tossim/SimPropertyCheckP.nc.bak
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimPropertyCheckP.nc.bak	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,73 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+module SimPropertyCheckP {
+   uses interface SimProperty as Property1;
+   uses interface SimProperty as Property2;
+   uses interface SimProperty as Property3;
+}
+implementation {
+
+   void sim_specified_safety_checking(bool safetySatisfied, uint8_t count) {
+      // User-specified safety property is not satisfied, then dump this 
+      // information...
+      if(!safetySatisfied) {
+         FILE * bugFile = fopen("BugFile.txt", "a+"); 
+	 if(bugFile) {
+            fprintf(bugFile, "This bug occurs at the %dth path\n", (path + 1));
+            fprintf(bugFile, "%d transitions explored before this memory safety bug\n", transition_explored);
+            fprintf(bugFile, "%d event explored before this safety error\n", event_explored);
+            fprintf(bugFile, "In model checking phase, %d depth explored before this safety bug occurs\n", steps);
+            fprintf(bugFile, "The error-occurring mote #: %lu\n", sim_node());
+            fputs("\n\n\n", bugFile);
+            fclose(bugFile);
+            bugFile = NULL;
+	 }
+	 sim_signal_user_safety_bug_occur(count);
+      }
+   }
+
+   // For safety properties, T-Check will check all user-specified properties in each state...
+   void sim_safety_property_check() @C() @spontaneous() {
+      // Whether the user-provided safety property is satisfied or not
+      bool safetySatisfied; 
+      uint8_t safetyCount = 0;
+       
+      safetySatisfied = call Property1.safetyPropertyCheck();
+      sim_specified_safety_checking(safetySatisfied, safetyCount++);
+
+      safetySatisfied = call Property2.safetyPropertyCheck();
+      sim_specified_safety_checking(safetySatisfied, safetyCount++);
+
+      safetySatisfied = call Property3.safetyPropertyCheck();
+      sim_specified_safety_checking(safetySatisfied, safetyCount++);
+
+   }
+
+   void sim_specified_liveness_checking(bool liveSatisfied, uint8_t count) {
+      if(liveSatisfied)
+	sim_signal_liveness_fulfill(count);
+   }
+   
+   void sim_liveness_property_check() @C() @spontaneous() {
+      // Whether the user-provided liveness property is satisfied or not
+      bool liveSatisfied;
+      uint8_t liveCount = 0;	
+      
+      if(sim_property_should_be_checked(liveCount)) {
+        liveSatisfied = call Property1.livenessPropertyCheck();
+        sim_specified_liveness_checking(liveSatisfied, liveCount++);
+      }
+
+      if(sim_property_should_be_checked(liveCount)) {
+        liveSatisfied = call Property2.livenessPropertyCheck();
+        sim_specified_liveness_checking(liveSatisfied, liveCount++);
+      }
+
+      if(sim_property_should_be_checked(liveCount)) {
+        liveSatisfied = call Property3.livenessPropertyCheck();
+        sim_specified_liveness_checking(liveSatisfied, liveCount++);
+      }
+
+   }
+}
Index: tos/lib/tossim/SimSafeFailureHandlerP.nc
===================================================================
RCS file: tos/lib/tossim/SimSafeFailureHandlerP.nc
diff -N tos/lib/tossim/SimSafeFailureHandlerP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/SimSafeFailureHandlerP.nc	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,68 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+module SimSafeFailureHandlerP {
+
+}
+implementation {
+
+  #ifndef asmlinkage
+  #define asmlinkage __attribute__((regparm(0)))
+  #endif
+
+  #ifndef noreturn
+  #define noreturn __attribute__((noreturn))
+  #endif
+
+  asmlinkage noreturn
+  void deputy_fail_noreturn_fast(void) @C() @spontaneous()
+  {
+      exit(0);
+  }
+
+  asmlinkage 
+  void deputy_fail_mayreturn(const char* check, const char *text,
+		           const char* file, int line, const char* func) @C() @spontaneous()
+  {
+      FILE * bugFile = fopen("BugFile.txt", "a+"); 
+      if(bugFile) {
+        fprintf(bugFile, "This bug occurs at the %dth statistic stage\n", stats_state);
+        fprintf(bugFile, "This bug occurs at the %dth running stage\n", mc_state);
+
+        fprintf(bugFile, "This bug occurs at the %dth path\n", (path + 1));
+        fprintf(bugFile, "%lu transitions explored before this safety bug occurs\n", transition_explored);
+        fprintf(bugFile, "%lu event explored before this safety bug occurs\n", event_explored);
+
+        fprintf(bugFile, "The error-occurring mote #: %lu\n", sim_node());
+        fprintf(bugFile, "The check type: %s\n", check);
+        fprintf(bugFile, "The detailed error message: %s\n", text); 
+        fprintf(bugFile, "The error-occurring file: %s\n", file); 
+        fprintf(bugFile, "The error function: %s, its corresponding line #: %d\n", func, line);
+        fputs("\n\n\n", bugFile);
+        sim_signal_mem_safety_bug_occur();
+        fclose(bugFile);
+      }
+  }
+
+  asmlinkage noreturn
+  void deputy_fail_noreturn(const char* check, const char *text, 
+		           const char* file, int line, const char* func) @C() @spontaneous()
+  {
+      FILE * bugFile = fopen("BugFile.txt", "a+"); 
+      fprintf(bugFile, "This bug occurs at the %dth statistic stage\n", stats_state);
+      fprintf(bugFile, "This bug occurs at the %dth stage\n", mc_state);
+
+      fprintf(bugFile, "This bug occurs at the %dth path\n", (path + 1));
+      fprintf(bugFile, "%lu transitions explored before this safety bug occurs\n", transition_explored);
+      fprintf(bugFile, "%lu event explored before this safety bug occurs\n", event_explored);
+
+      fprintf(bugFile, "The error-occurring mote #: %lu\n", sim_node());
+      fprintf(bugFile, "The check type: %s\n", check);
+      fprintf(bugFile, "The detailed error message: %s\n", text); 
+      fprintf(bugFile, "The error-occurring file: %s\n", file); 
+      fprintf(bugFile, "The error function: %s, its corresponding line #: %d\n", func, line);
+      fputs("\n\n\n", bugFile);
+      sim_signal_mem_safety_bug_occur();
+      fclose(bugFile);
+  }
+}
Index: tos/lib/tossim/SimSchedulerBasicP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/SimSchedulerBasicP.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 SimSchedulerBasicP.nc
--- tos/lib/tossim/SimSchedulerBasicP.nc	29 Jun 2010 22:07:51 -0000	1.3
+++ tos/lib/tossim/SimSchedulerBasicP.nc	9 Jul 2010 19:45:16 -0000
@@ -68,6 +68,7 @@ implementation
 
   int sim_config_task_latency() {return 100;}
   
+  uint8_t getPeakTask();
 
   /* Only enqueue the event for execution if it is
      not already enqueued. If there are more tasks in the
@@ -76,11 +77,30 @@ implementation
   
   void sim_scheduler_submit_event() {
     if (sim_scheduler_event_pending == FALSE) {
+      uint8_t TaskNum = getPeakTask();
+      printf("The peak task num is %d\n", TaskNum);
+      if(TaskNum != NO_TASK) {
       sim_scheduler_event.time = sim_time() + sim_config_task_latency();
+        sim_scheduler_event.source = TaskNum;
+        sim_scheduler_event.mark = TRUE;
       sim_queue_insert(&sim_scheduler_event);
       sim_scheduler_event_pending = TRUE;
     }
   }
+  }
+
+  void sim_apply_scheduler_event(sim_event_t* evt) @C() @spontaneous() {
+      int tmp = sim_node();
+      sim_set_node(evt->mote);
+      sim_scheduler_event.mote = sim_node();
+      sim_scheduler_event.type = SCHEDULER;
+      sim_scheduler_event.time = evt->time;
+      sim_scheduler_event.source = evt->source;
+      sim_scheduler_event.mark = TRUE;
+      sim_queue_insert(&sim_scheduler_event);
+      //sim_scheduler_event_pending = TRUE;
+      sim_set_node(tmp);
+  } 
 
   void sim_scheduler_event_handle(sim_event_t* e) {
     sim_scheduler_event_pending = FALSE;
@@ -104,6 +124,7 @@ implementation
     e->mote = sim_node();
     e->force = 0;
     e->data = NULL;
+    e->type = SCHEDULER;
     e->handle = sim_scheduler_event_handle;
     e->cleanup = sim_queue_cleanup_none;
   }
@@ -114,6 +135,10 @@ implementation
   // sections.  It is left as the duty of the exported interface functions to
   // manage atomicity to minimize chances for binary code bloat.
 
+  uint8_t getPeakTask() {
+    return m_head;
+  }
+
   // move the head forward
   // if the head is at the end, mark the tail at the end, too
   // mark the task as not in the queue
Index: tos/lib/tossim/TOSSIM.py
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/TOSSIM.py,v
retrieving revision 1.6
diff -u -b -p -r1.6 TOSSIM.py
--- tos/lib/tossim/TOSSIM.py	15 Aug 2008 18:34:36 -0000	1.6
+++ tos/lib/tossim/TOSSIM.py	9 Jul 2010 19:45:16 -0000
@@ -247,6 +247,12 @@ class Tossim(_object):
     __swig_destroy__ = _TOSSIM.delete_Tossim
     __del__ = lambda self : None;
     def init(*args): return _TOSSIM.Tossim_init(*args)
+    def initMoteNum(*args): return _TOSSIM.Tossim_initMoteNum(*args)
+    def setDeltaDebugging(*args): return _TOSSIM.Tossim_setDeltaDebugging(*args)
+    def setLossAndBiasingAndTossim(*args): return _TOSSIM.Tossim_setLossAndBiasingAndTossim(*args)
+    def mcMoteRevival(*args): return _TOSSIM.Tossim_mcMoteRevival(*args)
+    def mcMoteDeath(*args): return _TOSSIM.Tossim_mcMoteDeath(*args)
+    def mcMoteReboot(*args): return _TOSSIM.Tossim_mcMoteReboot(*args)
     def time(*args): return _TOSSIM.Tossim_time(*args)
     def ticksPerSecond(*args): return _TOSSIM.Tossim_ticksPerSecond(*args)
     def setTime(*args): return _TOSSIM.Tossim_setTime(*args)
@@ -258,6 +264,12 @@ class Tossim(_object):
     def removeChannel(*args): return _TOSSIM.Tossim_removeChannel(*args)
     def randomSeed(*args): return _TOSSIM.Tossim_randomSeed(*args)
     def runNextEvent(*args): return _TOSSIM.Tossim_runNextEvent(*args)
+    def startTossim(*args): return _TOSSIM.Tossim_startTossim(*args)
+    def startModelChecking(*args): return _TOSSIM.Tossim_startModelChecking(*args)
+    def startRandomWalk(*args): return _TOSSIM.Tossim_startRandomWalk(*args)
+    def setSendProb(*args): return _TOSSIM.Tossim_setSendProb(*args)
+    def setReceiveProb(*args): return _TOSSIM.Tossim_setReceiveProb(*args)
+    def setAckProb(*args): return _TOSSIM.Tossim_setAckProb(*args)
     def mac(*args): return _TOSSIM.Tossim_mac(*args)
     def radio(*args): return _TOSSIM.Tossim_radio(*args)
     def newPacket(*args): return _TOSSIM.Tossim_newPacket(*args)
Index: tos/lib/tossim/TossimActiveMessageC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/TossimActiveMessageC.nc,v
retrieving revision 1.7
diff -u -b -p -r1.7 TossimActiveMessageC.nc
--- tos/lib/tossim/TossimActiveMessageC.nc	29 Jun 2010 22:07:51 -0000	1.7
+++ tos/lib/tossim/TossimActiveMessageC.nc	9 Jul 2010 19:45:16 -0000
@@ -62,25 +62,31 @@ implementation {
   message_t buffer;
   message_t* bufferPointer = &buffer;
   
-  tossim_header_t* getHeader(message_t* amsg) {
-    return (tossim_header_t*)(amsg->data - sizeof(tossim_header_t));
+  cc2420_header_t* getHeader(message_t* amsg) {
+    return (cc2420_header_t*)(amsg->data - sizeof( cc2420_header_t ));
   }
 
-  tossim_metadata_t* getMetadata(message_t* amsg) {
-    return (tossim_metadata_t*)(&amsg->metadata);
+  cc2420_metadata_t* getMetadata(message_t* amsg) {
+    return (cc2420_metadata_t*)(&amsg->metadata);
   }
   
   command error_t AMSend.send[am_id_t id](am_addr_t addr,
 					  message_t* amsg,
 					  uint8_t len) {
     error_t err;
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
+
+    if (len > call Packet.maxPayloadLength()) {
+      return ESIZE;
+    }
+
     dbg("AM", "AM: Sending packet (id=%hhu, len=%hhu) to %hu\n", id, len, addr);
     header->type = id;
     header->dest = addr;
     header->src = call AMPacket.address();
     header->length = len;
-    err = call Model.send((int)addr, amsg, len + sizeof(tossim_header_t) + sizeof(tossim_footer_t));
+    dbg("AM", "AM: Sending packet (id=%hhu, len=%hhu) to %hu, src: %u\n", id, len, addr, header->src);
+    err = call Model.send((int)addr, amsg, len + sizeof(cc2420_header_t) + sizeof(cc2420_footer_t));
     return err;
   }
 
@@ -96,6 +102,7 @@ implementation {
     return call Packet.getPayload(m, len);
   }
 
+  /*******************AMPacket Commands***************/
   command int8_t TossimPacket.strength(message_t* msg) {
     return getMetadata(msg)->strength;
   }
@@ -125,7 +132,7 @@ implementation {
   }
 
   event bool Model.shouldAck(message_t* msg) {
-    tossim_header_t* header = getHeader(msg);
+    cc2420_header_t* header = getHeader(msg);
     if (header->dest == call amAddress()) {
       dbg("Acks", "Received packet addressed to me so ack it\n");
       return TRUE;
@@ -138,22 +145,22 @@ implementation {
   }
  
   command am_addr_t AMPacket.destination(message_t* amsg) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     return header->dest;
   }
 
   command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     header->dest = addr;
   }
 
   command am_addr_t AMPacket.source(message_t* amsg) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     return header->src;
   }
 
   command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     header->src = addr;
   }
   
@@ -163,12 +170,12 @@ implementation {
   }
 
   command am_id_t AMPacket.type(message_t* amsg) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     return header->type;
   }
 
   command void AMPacket.setType(message_t* amsg, am_id_t t) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     header->type = t;
   }
  
@@ -196,12 +203,12 @@ implementation {
   }
 
   command am_group_t AMPacket.group(message_t* amsg) {
-    tossim_header_t* header = getHeader(amsg);
+    cc2420_header_t* header = getHeader(amsg);
     return header->group;
   }
   
   command void AMPacket.setGroup(message_t* msg, am_group_t group) {
-    tossim_header_t* header = getHeader(msg);
+    cc2420_header_t* header = getHeader(msg);
     header->group = group;
   }
 
@@ -242,6 +249,7 @@ implementation {
  sim_event_t* allocate_deliver_event(int node, message_t* msg, sim_time_t t) {
    sim_event_t* evt = (sim_event_t*)malloc(sizeof(sim_event_t));
    evt->mote = node;
+   evt->type = GENERAL;
    evt->time = t;
    evt->handle = active_message_deliver_handle;
    evt->cleanup = sim_queue_cleanup_event;
@@ -251,9 +259,9 @@ implementation {
    return evt;
  }
  
- void active_message_deliver(int node, message_t* msg, sim_time_t t) @C() @spontaneous() {
+ void TRUSTEDBLOCK active_message_deliver(int node, message_t* msg, sim_time_t t) @C() @spontaneous() {
    sim_event_t* evt = allocate_deliver_event(node, msg, t);
-   sim_queue_insert(evt);
+   sim_queue_insert_general(evt, RADIO);
  }
  
 }
Index: tos/lib/tossim/TossimPacketModelC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/TossimPacketModelC.nc,v
retrieving revision 1.12
diff -u -b -p -r1.12 TossimPacketModelC.nc
--- tos/lib/tossim/TossimPacketModelC.nc	29 Jun 2010 22:07:51 -0000	1.12
+++ tos/lib/tossim/TossimPacketModelC.nc	9 Jul 2010 19:45:16 -0000
@@ -79,8 +79,8 @@ implementation {
   
   message_t receiveBuffer;
   
-  tossim_metadata_t* getMetadata(message_t* msg) {
-    return (tossim_metadata_t*)(&msg->metadata);
+  cc2420_metadata_t* getMetadata(message_t* msg) {
+    return (cc2420_metadata_t*)(&msg->metadata);
   }
   
   command error_t Init.init() {
@@ -103,6 +103,26 @@ implementation {
     signal Control.stopDone(SUCCESS);
   }
   
+  void sim_apply_send_event(sim_event_t* evt) @C() @spontaneous() {
+      int tmp = sim_node();
+      sim_set_node(evt->mote);
+      sendEvent.mote = sim_node();
+      sendEvent.time = evt->time;
+      sendEvent.type = SEND;
+      sendEvent.source = evt->source;
+      sendEvent.mark = evt->mark;
+      sendEvent.force = 0;
+      sendEvent.cancelled = 0;
+      sendEvent.handle = evt->handle;
+      sim_queue_insert(&sendEvent);
+      sim_set_node(tmp);
+  } 
+
+  bool sim_send_check_clear_channel() @C() @spontaneous() {
+    bool clear = call GainRadioModel.clearChannel();
+    return clear;
+  }
+
   command error_t Control.start() {
     if (!initialized) {
       dbgerror("TossimPacketModelC", "TossimPacketModelC: Control.start() called before initialization!\n");
@@ -126,28 +146,30 @@ implementation {
   
   
   async command error_t PacketAcknowledgements.requestAck(message_t* msg) {
-    tossim_metadata_t* meta = getMetadata(msg);
+    cc2420_metadata_t* meta = getMetadata(msg);
     meta->ack = TRUE;
+    dbg("Acks", "%s: request the ack!\n", __FUNCTION__);
     return SUCCESS;
   }
 
   async command error_t PacketAcknowledgements.noAck(message_t* ack) {
-    tossim_metadata_t* meta = getMetadata(ack);
+    cc2420_metadata_t* meta = getMetadata(ack);
     meta->ack = FALSE;
     return SUCCESS;
   }
 
   async command error_t PacketAcknowledgements.wasAcked(message_t* ack) {
-    tossim_metadata_t* meta = getMetadata(ack);
+    cc2420_metadata_t* meta = getMetadata(ack);
+    dbg("Acks", "%s: determine whether ack was accepted!\n", __FUNCTION__);
     return meta->ack;
   }
       
   task void sendDoneTask() {
     message_t* msg = sending;
-    tossim_metadata_t* meta = getMetadata(msg);
+    cc2420_metadata_t* meta = getMetadata(msg);
     meta->ack = 0;
     meta->strength = 0;
-    meta->time = 0;
+    //meta->time = 0;
     sending = FALSE;
     signal Packet.sendDone(msg, running? SUCCESS:EOFF);
   }
@@ -201,6 +223,9 @@ implementation {
     sendEvent.time = first_sample;
     sendEvent.force = 0;
     sendEvent.cancelled = 0;
+    sendEvent.type = SEND;
+    sendEvent.source = BACKOFF;
+    sendEvent.mark = TRUE;
 
     sendEvent.handle = send_backoff;
     sendEvent.cleanup = sim_queue_cleanup_none;
@@ -216,12 +241,34 @@ implementation {
     else {
       neededFreeSamples = sim_csma_min_free_samples();
     }
+
+    if(mc_state != TOSSIM_RUNNING && mc_state != TOSSIM_RE_RUNNING) {
+      if(evt->mark) {
+        sim_time_t delay;
+        delay = sim_csma_rxtx_delay();
+        delay *= (sim_ticks_per_sec() / sim_csma_symbols_per_sec());
+        evt->time += delay;
+        transmitting = TRUE;
+        evt->source = TRANSMIT;
+        call GainRadioModel.setPendingTransmission();
+        evt->handle = send_transmit;
+        sim_queue_insert(evt);
+      }
+      else {
+        message_t* rval = sending;
+        sending = NULL;
+        dbg("TossimPacketModelC", "PACKET: Failed to send packet due to busy channel.\n");
+        signal Packet.sendDone(rval, EBUSY);
+      }
+    }
+    else {
     if (neededFreeSamples == 0) {
       sim_time_t delay;
       delay = sim_csma_rxtx_delay();
       delay *= (sim_ticks_per_sec() / sim_csma_symbols_per_sec());
       evt->time += delay;
       transmitting = TRUE;
+        evt->source = TRANSMIT;
       call GainRadioModel.setPendingTransmission();
       evt->handle = send_transmit;
       sim_queue_insert(evt);
@@ -233,6 +280,7 @@ implementation {
       modulo *= pow(sim_csma_exponent_base(), backoffCount);
       backoff %= modulo;
 									
+        evt->source = TRANSMIT;
       backoff += sim_csma_init_low();
       backoff *= (sim_ticks_per_sec() / sim_csma_symbols_per_sec());
       evt->time += backoff;
@@ -245,6 +293,7 @@ implementation {
       signal Packet.sendDone(rval, EBUSY);
     }
   }
+  }
 
   int sim_packet_header_length() {
     return sizeof(tossim_header_t);
@@ -252,7 +301,7 @@ implementation {
   
   void send_transmit(sim_event_t* evt) {
     sim_time_t duration;
-    tossim_metadata_t* metadata = getMetadata(sending);
+    cc2420_metadata_t* metadata = getMetadata(sending);
 
     duration = 8 * sendingLength;
     duration /= sim_csma_bits_per_symbol();
@@ -263,6 +312,8 @@ implementation {
     }
     duration *= (sim_ticks_per_sec() / sim_csma_symbols_per_sec());
 
+    evt->source = TRANSMITDONE;
+    evt->mark = TRUE;
     evt->time += duration;
     evt->handle = send_transmit_done;
 
@@ -279,6 +330,9 @@ implementation {
 
   void send_transmit_done(sim_event_t* evt) {
     message_t* rval = sending;
+    if(sim_is_all_neighbor_transmit(evt->mote)) {
+      sim_reset_all_neighbor_status(evt->mote); 
+    }
     sending = NULL;
     transmitting = FALSE;
     dbg("TossimPacketModelC", "PACKET: Signaling send done at %llu.\n", sim_time());
@@ -295,11 +349,13 @@ implementation {
   
   event void GainRadioModel.acked(message_t* msg) {
     if (running) {
-      tossim_metadata_t* metadata = getMetadata(sending);
+      if(sending != NULL) {
+        cc2420_metadata_t* metadata = getMetadata(sending);
       metadata->ack = 1;
       if (msg != sending) {
 	error = 1;
-	dbg("TossimPacketModelC", "Requested ack for 0x%x, but outgoing packet is 0x%x.\n", msg, sending);
+	  dbg("Acks", "Requested ack for 0x%x, but outgoing packet is 0x%x.\n", msg, sending);
+        }
       }
     }
   }
Index: tos/lib/tossim/heap.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/heap.c,v
retrieving revision 1.6
diff -u -b -p -r1.6 heap.c
--- tos/lib/tossim/heap.c	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/heap.c	9 Jul 2010 19:45:16 -0000
@@ -57,28 +57,275 @@
 
 const int STARTING_SIZE = 511;
 
-#define HEAP_NODE(heap, index) (((node_t*)(heap->data))[index])
-
-typedef struct node {
-  void* data;
-  long long int key;
-} node_t;
+#define HEAP_NODE(heap, index) (((time_node_t*)(heap->data))[index])
 
 void down_heap(heap_t* heap, int findex);
 void up_heap(heap_t* heap, int findex);
-void swap(node_t* first, node_t* second);
+void swap(time_node_t* first,time_node_t* second);
 node_t* prev(node_t* node);
 node_t* next(node_t* next);
 
-void init_node(node_t* node) {
+node_t* init_node() {
+  node_t* node = (node_t*)malloc(sizeof(node_t));
+  node->data = NULL;
+  node->next = NULL;
+  return node;
+}
+
+queue_t* init_queue() {
+  queue_t* queue = (queue_t*)malloc(sizeof(queue_t));
+  queue->size = 0;
+  queue->head = queue->tail = NULL;
+  return queue;
+}
+
+int queue_size(queue_t* queue) {
+  if(queue == NULL) {
+     dbg("Event", "At present, the queue is NULL!\n");
+     return 0;
+  }
+  return queue->size;
+}
+
+bool queue_is_empty(queue_t* queue) {
+  return queue->size == 0;
+}
+
+void* queue_get_data(queue_t* queue, int num) {
+   if(queue == NULL){
+	queue = init_queue();
+	return NULL;
+   }
+   else if(queue->size == 0){
+	return NULL;
+   }
+   else{
+	int i=0;
+        void* data = NULL;	
+	node_t* temp = queue->head;
+	if(num <= queue_size(queue)) {
+	  while(i < num-1) {
+	    temp = temp->next;
+	    i++;
+	  }
+	  data = temp->data;
+	}
+	else {
+	  dbg("Event", "num is greater than queue size, tricky!!\n");
+	}
+	return data;
+   }
+}
+
+static void free_node(node_t* node) {
   node->data = NULL;
-  node->key = -1;
+   node->next = NULL;
+   free(node);
+}
+
+void free_data(void* data) {
+   if(data != NULL) {
+      free(data);
+   }
+}
+
+void* queue_pop_first_data(queue_t* queue)
+{
+   node_t* temp;
+   void* data;
+   if(queue == NULL || queue_is_empty(queue))
+      return NULL;
+   
+   temp = queue->head;
+   queue->head = temp->next;
+   if(queue->size == 1)
+      queue->tail = NULL;
+   queue->size--;
+   data = temp->data;
+   free_node(temp);
+   return data;
+}
+
+void* queue_pop_general_data(queue_t* queue, int type, int num) {
+   node_t* current = queue->head;
+   void* general = NULL;
+   sim_event_t* tmp_general = NULL;
+   
+   if(queue == NULL || queue_is_empty(queue)) 
+        return NULL;
+
+   tmp_general = (sim_event_t*)(current->data);
+   if(tmp_general->source == type && tmp_general->mark == num) {
+       queue->head = current->next;
+       if(queue->size == 1)
+	 queue->tail = NULL;
+       free_node(current);
+       general = tmp_general;
+       queue->size--;
+   }
+   else {
+       node_t* nextNode = current->next;
+       if(nextNode != NULL) {
+         while(nextNode != NULL) {
+            tmp_general = (sim_event_t*)(nextNode->data);
+	    if(tmp_general->source == type && tmp_general->mark == num)
+	        break;
+	    current = current->next;
+	    nextNode = current->next;
+	 }
+	 if(nextNode != NULL) {
+	    current->next = nextNode->next;
+	    if(current->next == NULL)
+	       queue->tail = current;
+	    free_node(nextNode);
+	    general = tmp_general;
+	    queue->size--;
+	 }
+	 else 
+            dbg("Event", "There is no matching general node!\n");
+       }
+       else {
+          dbg("Event", "There is no matching general node!\n");
+       }
+   }
+   return general;
+}
+
+void* queue_pop_receive_ack_data(queue_t* queue, int source) {
+   node_t* current = queue->head;
+   sim_event_t* receive_ack = NULL;
+   sim_event_t* tmp_ra = NULL;
+
+   if(queue == NULL || queue_is_empty(queue))
+       return NULL;
+
+   tmp_ra = (sim_event_t*)(current->data);
+
+   if(tmp_ra->source == source) {
+       queue->head = current->next;
+       if(queue->size == 1)
+	   queue->tail = NULL;
+       free_node(current);
+       receive_ack = tmp_ra;
+       queue->size--; 
+   }
+   else {
+       node_t* nextNode = current->next;
+       if(nextNode != NULL) {
+           while(nextNode != NULL) {
+              tmp_ra = (sim_event_t*)(nextNode->data);
+	      if(tmp_ra->source == source)
+	         break;
+	      current = current->next;
+	      nextNode = current->next;
+	   }
+	   if(nextNode != NULL) {
+	      current->next = nextNode->next;
+	      if(current->next == NULL)
+		 queue->tail = current;
+	      free_node(nextNode);
+	      receive_ack = tmp_ra;
+	      queue->size--;
+	   }
+           else 
+              dbg("Event", "There is no matching receive or ack node!\n");
+       }
+       else {
+          dbg("Event", "There is no matching receive or ack node!\n");
+       }
+   }
+   return receive_ack;
+}
+
+void* queue_pop_last_data(queue_t* queue) {
+    node_t* temp = queue->head;
+    void* data;
+    if(queue == NULL || queue_is_empty(queue))
+        return NULL;
+
+    if(queue->size == 1) {
+	queue->head = queue->tail = NULL;
+	data = temp->data;
+	free_node(temp);
+    }
+    else {
+	node_t* p = NULL;
+        while(temp->next != queue->tail)
+          temp = temp->next;
+        p = queue->tail;
+	temp->next = p->next;
+	queue->tail = temp;
+        data = p->data;
+	free_node(p);
+    }
+    queue->size--;
+    return data;
+}
+
+void queue_insert(queue_t* queue, void* data) {
+    node_t* newNode = (node_t*)malloc(sizeof(node_t));
+    newNode->data = data;
+    if(queue->size == 0) {
+       newNode->next = queue->tail;
+       queue->head = newNode;
+    }
+    else {
+       newNode->next = queue->tail->next; 
+       queue->tail->next = newNode;
+    }
+    queue->tail = newNode;
+    queue->size++;
+    return;
+}
+
+void queue_destroy(queue_t* queue, int type) {
+    node_t* temp = NULL;
+    sim_event_t* simEvent = NULL;
+	
+    if(queue == NULL || queue->size == 0) 
+       return;
+    while(queue->head != NULL)
+    {
+       temp = queue->head;
+       switch(type) {
+	  case SCHEDULER:
+	     simEvent = (sim_event_t*)(temp->data);
+	     simEvent->cleanup(simEvent);
+	     break;
+	  case GENERAL:
+	     simEvent = (sim_event_t*)(temp->data);
+	     simEvent->cleanup(simEvent);
+	     break;
+	  case SEND:
+	     simEvent = (sim_event_t*)(temp->data);
+	     simEvent->cleanup(simEvent);
+   	     break;
+	  case RECEIVE:
+	     simEvent = (sim_event_t*)(temp->data);
+             sim_cleanup_event_receive_message(simEvent); 
+	     simEvent->cleanup(simEvent);
+	     break;
+	  case ACK:
+	     simEvent = (sim_event_t*)(temp->data);
+             sim_cleanup_event_receive_message(simEvent); 
+	     simEvent->cleanup(simEvent);
+	     break;
+	  default:
+	     free(temp->data);
+	     break;
+        }
+        queue->head = temp->next;
+        queue->size--;
+        free_node(temp);
+     }
+     queue->tail = NULL;
+     return;
 }
 
 void init_heap(heap_t* heap) {
   heap->size = 0;
   heap->private_size = STARTING_SIZE;
-  heap->data = malloc(sizeof(node_t) * heap->private_size);
+  heap->data = malloc(sizeof(time_node_t) * heap->private_size);
 }
 
 int heap_size(heap_t* heap) {
@@ -129,11 +376,11 @@ void* heap_pop_min_data(heap_t* heap, lo
 
 void expand_heap(heap_t* heap) {
   int new_size = (heap->private_size * 2) + 1;
-  void* new_data = malloc(sizeof(node_t) * new_size);
+  void* new_data = malloc(sizeof(time_node_t) * new_size);
 
   //dbg(DBG_SIM, "Resized heap from %i to %i.\n", heap->private_size, new_size);
   
-  memcpy(new_data, heap->data, (sizeof(node_t) * heap->private_size));
+  memcpy(new_data, heap->data, (sizeof(time_node_t) * heap->private_size));
   free(heap->data);
 
   heap->data = new_data;
@@ -155,7 +402,34 @@ void heap_insert(heap_t* heap, void* dat
   heap->size++;
 }
 
-void swap(node_t* first, node_t* second) {
+void timer_heap_destroy(heap_t* heap) {
+  long long int key;
+  if(heap == NULL)
+     return;
+  while(!heap_is_empty(heap)) {
+     sim_event_t* event = (sim_event_t*)heap_pop_min_data(heap, &key);
+     event->data = NULL;
+     free(event);
+     event = NULL;
+  }
+  return;
+}
+
+void heap_destroy(heap_t* heap) {
+  long long int key;
+  if(heap == NULL)
+     return;
+  while(!heap_is_empty(heap)) {
+     sim_event_t* event = (sim_event_t*)heap_pop_min_data(heap, &key);
+     if(event->type == RECEIVE || event->type == ACK) 
+       sim_cleanup_event_receive_message(event); 
+     event->cleanup(event);
+     event = NULL;
+  }
+  return;
+}
+
+void swap(time_node_t* first, time_node_t* second) {
   long long int key;
   void* data;
 
Index: tos/lib/tossim/heap.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/heap.h,v
retrieving revision 1.6
diff -u -b -p -r1.6 heap.h
--- tos/lib/tossim/heap.h	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/heap.h	9 Jul 2010 19:45:16 -0000
@@ -58,6 +58,37 @@
 #ifndef HEAP_H_INCLUDED
 #define HEAP_H_INCLUDED
 
+typedef struct node node_t;
+
+struct node {
+   void* data;
+   node_t* next; 
+};
+
+typedef struct queue {
+  node_t* head;
+  node_t* tail;
+  int size;
+} queue_t;
+
+queue_t* init_queue();
+int queue_size(queue_t* queue);
+bool queue_is_empty(queue_t* queue);
+void* queue_get_data(queue_t* queue, int num);
+void* queue_pop_first_data(queue_t* queue);
+void* queue_pop_general_data(queue_t* queue, int type, int num);
+void* queue_pop_receive_ack_data(queue_t* queue, int source);
+void* queue_pop_last_data(queue_t* queue);
+
+void queue_insert(queue_t* queue, void* data);
+void queue_destroy(queue_t* queue, int type);
+void free_data(void* data);
+
+typedef struct time_node {
+     void* data;
+     long long int key;
+} time_node_t;
+
 typedef struct heap {
   int size;
   void* data;
@@ -72,6 +103,19 @@ long long int heap_get_min_key(heap_t* h
 void* heap_peek_min_data(heap_t* heap);
 void* heap_pop_min_data(heap_t* heap, long long int* key);
 void heap_insert(heap_t * heap, void* data, long long int key);
+void heap_destroy(heap_t* heap);
 
+typedef struct event_queue_set {
+    uint8_t Status;
+    long long int StartTime;
+    void* BootEvt;
+    queue_t* SchedulerQ;
+    queue_t* GeneralQ;
+    queue_t* SendQ;
+    queue_t* ReceiveQ;
+    queue_t* AckQ;
+    heap_t* TimerH;
+    void* InterruptSet[40];
+} event_queue_set_t;
 
 #endif // HEAP_H_INCLUDED
Index: tos/lib/tossim/platform_message.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/platform_message.h,v
retrieving revision 1.5
diff -u -b -p -r1.5 platform_message.h
--- tos/lib/tossim/platform_message.h	29 Jun 2010 22:07:51 -0000	1.5
+++ tos/lib/tossim/platform_message.h	9 Jul 2010 19:45:16 -0000
@@ -44,20 +44,24 @@
 #ifndef PLATFORM_MESSAGE_H
 #define PLATFORM_MESSAGE_H
 
-#include <TossimRadioMsg.h>
+//#include <TossimRadioMsg.h>
+#include <CC2420.h>
 #include <Serial.h>
 
 typedef union message_header {
-  tossim_header_t tossim;
+  //tossim_header_t tossim;
+  cc2420_header_t cc2420;
   serial_header_t serial;
 } message_header_t;
 
 typedef union message_footer {
-  tossim_footer_t tossim;
+  //tossim_footer_t tossim;
+  cc2420_footer_t cc2420;
 } message_footer_t;
 
 typedef union message_metadata {
-  tossim_metadata_t tossim;
+  //tossim_metadata_t tossim;
+  cc2420_metadata_t cc2420;
 } message_metadata_t;
 
 #endif
Index: tos/lib/tossim/sim_delta_debugging.c
===================================================================
RCS file: tos/lib/tossim/sim_delta_debugging.c
diff -N tos/lib/tossim/sim_delta_debugging.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_delta_debugging.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,59 @@
+#include <sim_delta_debugging.h>
+
+bool sim_find_shorter_random_path(queue_t** rwQueue, int d_curr, bool buggyNodeFlag) {
+   int qSize = queue_size(*rwQueue);
+   bool findShortCut = FALSE;
+   queue_t* deltaWalk = NULL;
+   sim_move_to_new_state(*rwQueue, d_curr);
+
+   deltaWalk = sim_transition_queue_init();
+   findShortCut = sim_random_walk_with_bound_for_delta(deltaWalk, (qSize-d_curr-1), buggyNodeFlag);
+
+   if(findShortCut) {
+     sim_intercept_transition_queue(rwQueue, d_curr);
+     sim_combine_transition_queues(*rwQueue, deltaWalk);
+     return TRUE;
+   }
+   // Here, we should clear the deltawalk...
+   sim_transition_queue_destroy(deltaWalk);
+   return FALSE;
+}
+
+void sim_reduce_random_path(queue_t** rwQueue) {
+   int i = 0, d_curr = 1;
+   int qSize = queue_size(*rwQueue);
+   bool shorter = FALSE;
+
+   // Phase 1. Exponential reduction...
+   while(d_curr <= qSize) {
+      printf("In delta debugging, the current common steps: %d, the qSize: %d\n", d_curr, qSize);
+      for(i = 0; i<50; i++) {
+         shorter = sim_find_shorter_random_path(rwQueue, d_curr, FALSE);
+	 if(shorter)
+           break; 
+      }
+      if(shorter) {
+	 qSize = queue_size(*rwQueue);
+	 shorter = FALSE;
+      }
+      else
+         d_curr *= 2;
+   }
+   
+   // Phase 2: ...
+   for(i = 0; i < 1000; i++) { 
+      d_curr = RandomInt(1, qSize);
+      printf("In delta debugging, the %dth try, the current common steps: %d, the qSize: %d\n", i+1, d_curr, qSize);
+      shorter = sim_find_shorter_random_path(rwQueue, d_curr, FALSE);
+      if(shorter)
+	 qSize = queue_size(*rwQueue);
+   }
+
+   // Phase 3. buggy-node-prone heuristic reducation...
+   for(i = 0; i < 100; i++) {
+      shorter = sim_find_shorter_random_path(rwQueue, 0, TRUE);
+   }
+
+   // Once finding the "shortest" path, we should log its execution.
+   sim_log_safety_violating_path(*rwQueue);
+}
Index: tos/lib/tossim/sim_delta_debugging.h
===================================================================
RCS file: tos/lib/tossim/sim_delta_debugging.h
diff -N tos/lib/tossim/sim_delta_debugging.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_delta_debugging.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,6 @@
+#ifndef SIM_DELTA_DEBUGGING_H_INCLUDED
+#define SIM_DELTA_DEBUGGING_H_INCLUDED
+
+void sim_reduce_random_path(queue_t** rwQueue);
+
+#endif
Index: tos/lib/tossim/sim_depth_first_search.c
===================================================================
RCS file: tos/lib/tossim/sim_depth_first_search.c
diff -N tos/lib/tossim/sim_depth_first_search.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_depth_first_search.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,121 @@
+#include <sim_depth_first_search.h>
+
+static element_t* sim_depth_first_search_prefix(queue_t* enableSet) {
+    bool keepOn = FALSE;
+    element_t* elem = sim_element_queue_get_first(enableSet);
+    element_t* _mc_elem = sim_copy_element(elem); 
+
+    keepOn = sim_mc_run_next_event(_mc_elem);
+    printf("moteid: %d, eventType: %d, source: %d, num: %d\n", _mc_elem->MoteID, _mc_elem->eventType, _mc_elem->source, _mc_elem->num);
+    // Exploring the transition...
+    sim_increase_transition_explored_number();
+    sim_build_transition(Transition_Stack, _mc_elem);
+    sim_element_gen_list_node_access_clearance(_mc_elem);
+
+#ifdef SAFETY
+    sim_safety_property_check(); 
+#endif
+
+    //Here, we should check whether the head is NULL or not
+    if((_mc_elem->glnHead).head != NULL) {
+       bool preserve = sim_handle_gen_list_node_set(elem, _mc_elem);  
+
+       if(!preserve) {
+          element_t* elem_t = sim_element_queue_pop(enableSet);
+	  sim_free_element(elem_t);
+       }
+    }
+    else {
+       element_t* elem_t = sim_element_queue_pop(enableSet); 
+       sim_free_element(elem_t);
+    }
+    steps++;
+    return _mc_elem;
+}
+
+static void sim_depth_first_search_postfix() {
+    if(steps == MC_BOUND) {
+       sim_output_transition_queue(Transition_Stack);
+       if(!sim_safety_bug_occur()) {
+	  if(RW_BOUND > 0)
+	     sim_random_walk(RW_BOUND);
+       }
+    }
+}
+
+/* Main function for stateless Depth-First search without POR reduction*/
+void DFS() {
+     if(sim_safety_bug_occur()) {
+	sim_safety_report_statistics_data();
+        sim_log_safety_violating_path(NULL);
+        transition_explored = 0;
+        event_explored = 0;
+	return;
+     }
+     else {
+        queue_t* enableSet = sim_element_queue_init();
+        sim_find_enabled_event_set(enableSet, FALSE);
+
+        if(queue_is_empty(enableSet)) {
+          sim_output_transition_queue(Transition_Stack);
+        }
+
+        while(!queue_is_empty(enableSet) && steps < MC_BOUND) {
+          sim_depth_first_search_prefix(enableSet);
+
+          DFS();
+          
+	  sim_depth_first_search_postfix();
+          sim_transition_queue_pop(Transition_Stack); 
+	  if(steps == MC_BOUND || sim_safety_bug_occur()) {
+             path++;
+             printf("This is the %dth path\n", path+1);
+	  }
+	  steps--;
+	  sim_reset_and_re_execute(TRUE);
+       }
+       sim_element_queue_destroy(enableSet);
+     }
+}
+
+/* Main function for stateless DFS with the help of POR reduction*/
+void DFS_POR(queue_t* sleepSet) {
+     if(sim_safety_bug_occur()) {
+	sim_safety_report_statistics_data();
+        sim_log_safety_violating_path(NULL);
+        transition_explored = 0;
+        event_explored = 0;
+	return;
+     }
+     else {
+        queue_t* enableSet = NULL;
+        queue_t* persistentSet = sim_element_queue_init();
+        sim_find_enabled_event_set(persistentSet, TRUE);
+        enableSet = sim_find_enabled_set(persistentSet, sleepSet);
+
+        if(queue_is_empty(enableSet)) {
+           sim_output_transition_queue(Transition_Stack);
+        }
+
+        while(!queue_is_empty(enableSet) && steps < MC_BOUND) {
+           element_t* pop_element = NULL;
+	   element_t* tmpElem = sim_depth_first_search_prefix(enableSet);
+           queue_t* new_sleepSet = sim_find_sleep_set(sleepSet, tmpElem);
+
+           DFS_POR(new_sleepSet);
+
+           sim_depth_first_search_postfix();
+           pop_element = sim_por_transition_queue_pop(Transition_Stack); 
+	   if(steps == MC_BOUND || sim_safety_bug_occur()) {
+             path++;
+             printf("This is the %dth path\n", path+1);
+	   }
+	   steps--;
+	   sim_reset_and_re_execute(TRUE);
+	   sim_sleep_set_insert(sleepSet, pop_element);
+        }
+        sim_element_queue_destroy(enableSet);
+        sim_element_queue_destroy(sleepSet);
+     }
+}
+
Index: tos/lib/tossim/sim_depth_first_search.h
===================================================================
RCS file: tos/lib/tossim/sim_depth_first_search.h
diff -N tos/lib/tossim/sim_depth_first_search.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_depth_first_search.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,7 @@
+#ifndef SIM_DEPTH_FIRST_SEARCH_H_INCLUDED
+#define SIM_DEPTH_FIRST_SEARCH_H_INCLUDED
+
+void DFS();
+void DFS_POR(queue_t* sleepSet);
+
+#endif
Index: tos/lib/tossim/sim_event_queue.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_event_queue.c,v
retrieving revision 1.6
diff -u -b -p -r1.6 sim_event_queue.c
--- tos/lib/tossim/sim_event_queue.c	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/sim_event_queue.c	9 Jul 2010 19:45:16 -0000
@@ -38,20 +38,224 @@
  */
 
 
-#include <heap.h>
 #include <sim_event_queue.h>
+#include <sim_random_walk_assist.h>
 
+static int radio_count;
+static int serial_count;
 static heap_t eventHeap;
+static heap_t _mc_eventHeap;
 
 void sim_queue_init() __attribute__ ((C, spontaneous)) {
+      radio_count = 0;
+      serial_count = 0;
   init_heap(&eventHeap);
+      return;
 }
 
-void sim_queue_insert(sim_event_t* event) __attribute__ ((C, spontaneous)) {
-  dbg("Queue", "Inserting 0x%p\n", event);
+/* Function for inserting tossim event into the event queue set */
+static void sim_insert_event_into_eqs(sim_event_t* event) {
+        queue_t* queue;
+	heap_t* heap;
+
+	switch(event->type) {
+	  case BOOT:
+	    nodeEqs[event->mote].BootEvt = event;
+            break;
+	  case SCHEDULER:
+	    if(nodeEqs[event->mote].SchedulerQ == NULL) {
+               nodeEqs[event->mote].SchedulerQ = init_queue();
+	    }
+            queue = nodeEqs[event->mote].SchedulerQ;
+	    queue_insert(queue, event);
+	    break;
+	  case GENERAL:
+	    if(nodeEqs[event->mote].GeneralQ == NULL) {
+               nodeEqs[event->mote].GeneralQ = init_queue();
+	    }
+	    queue = nodeEqs[event->mote].GeneralQ;
+	    queue_insert(queue, event);
+	    break;
+	  case SEND:
+	    if(nodeEqs[event->mote].SendQ == NULL) {
+               nodeEqs[event->mote].SendQ = init_queue();
+	    }
+	    queue = nodeEqs[event->mote].SendQ;
+	    queue_insert(queue, event);
+	    break;
+	  case RECEIVE:
+	    if(nodeEqs[event->mote].ReceiveQ == NULL) {
+               nodeEqs[event->mote].ReceiveQ = init_queue();
+	    }
+	    queue = nodeEqs[event->mote].ReceiveQ;
+	    queue_insert(queue, event);
+	    break;
+	  case ACK:
+	    if(nodeEqs[event->mote].AckQ == NULL) {
+               nodeEqs[event->mote].AckQ = init_queue();
+	    }
+	    queue = nodeEqs[event->mote].AckQ;
+	    queue_insert(queue, event);
+	    break;
+	  case TIMER:
+	    if(nodeEqs[event->mote].TimerH == NULL) {
+               nodeEqs[event->mote].TimerH = (heap_t*)malloc(sizeof(heap_t));
+	       init_heap(nodeEqs[event->mote].TimerH);
+	    }
+	    heap = nodeEqs[event->mote].TimerH;
+	    heap_insert(heap, event, event->time);
+	    break;
+	  case INTERRUPT:
+	    if(!nodeEqs[event->mote].InterruptSet[event->source]) {
+	       nodeEqs[event->mote].InterruptSet[event->source] = event;
+	    }
+	    break;
+       }
+}
+
+void sim_output_event(sim_event_t* evt) {
+     printf("(%lu:", evt->mote);
+     switch(evt->type) {
+         case BOOT:
+	      printf("Boot:%d:%d)->", evt->source, evt->mark);
+	      break;
+         case SCHEDULER:
+	      printf("Scheduler:%d:%d)->", evt->source, evt->mark);
+	      break;
+	 case GENERAL:
+	      printf("General:%d:%d)->", evt->source, evt->mark);
+	      break;
+	 case SEND:
+	      printf("Send:%d:%d)->", evt->source, evt->mark);
+	      break;
+	 case RECEIVE:
+	      printf("Receive:%d:%d)->", evt->source, evt->mark);
+	      break;
+	 case TIMER:
+	      printf("Timer:%d:%d)->", evt->source, evt->mark);
+	      break;
+	 case ACK:
+	      printf("Ack:%d:%d)->", evt->source, evt->mark);
+	      break;
+	 case INTERRUPT:
+	      printf("Interrupt:%d:%d)->", evt->source, evt->mark);
+	      break;
+     }
+     printf("end\n");
+}
+
+void sim_copy_event(sim_event_t* src_evt, sim_event_t* dst_evt) {
+      memcpy(dst_evt, src_evt, sizeof(sim_event_t));
+      if(src_evt->data) {
+         if(src_evt->type == GENERAL) {
+	    sim_copy_general_event(src_evt, dst_evt);
+	 }
+         if(src_evt->type == RECEIVE) {
+	    sim_copy_receive_event(src_evt, dst_evt);
+	 }
+      }
+}
+
+/* Function for outputing the event queue set (for debugging) */
+void sim_output_event_queue_set() {
+       int i;
+       for(i = 0; i<MAX_NODES; i++) {
+	  if(nodeEqs[i].Status != UNACTIVE) {
+	    int SchedulerSize = queue_size(nodeEqs[i].SchedulerQ);
+	    int GeneralSize = queue_size(nodeEqs[i].GeneralQ);
+	    int SendSize = queue_size(nodeEqs[i].SendQ);
+	    int ReceiveSize = queue_size(nodeEqs[i].ReceiveQ);
+            int TimerSize = heap_size(nodeEqs[i].TimerH);
+	    int AckSize = queue_size(nodeEqs[i].AckQ);
+            printf("mote %d:", i);
+	    printf("Scheduler:%d, General:%d, Send:%d, Receive:%d, Timer:%d, Ack:%d\n", SchedulerSize, GeneralSize, SendSize, ReceiveSize, TimerSize, AckSize);
+	  }
+       }
+}
+/******************************* insert part ****************************************/
+/* This is a function for model checker to choose where to store the event, original eventHeap
+ * or event queue set established by me. */
+static void sim_queue_heap_final_insert(sim_event_t* event) {
+      if(mc_state == TOSSIM_RUNNING || mc_state == TOSSIM_RE_RUNNING)
   heap_insert(&eventHeap, event, event->time);
+      else 
+         sim_insert_event_into_eqs(event);
+}
+
+/* insert the boot event as the bootNode in EQS*/
+void sim_queue_insert_boot_event(sim_event_t* event) __attribute__ ((C, spontaneous)) {
+      event->type = BOOT;
+      event->source = ON;
+      event->mark = TRUE;
+      sim_queue_heap_final_insert(event);
+
+      if(nodeEqs[event->mote].StartTime == -1) {
+        nodeEqs[event->mote].StartTime = event->time;
+        sim_allocate_specific_mote_eqs(event->mote);
+        sim_build_neighbor_set(event->mote);
+      }
+      return;
+}
+
+void sim_queue_insert_turn_off_event(sim_event_t* event) {
+      if(nodeEqs[event->mote].BootEvt != NULL) {
+         dbg("TOSMC", "At present, the boot event is not null!\n");
+	 return;
+      }
+      else {
+         sim_queue_heap_final_insert(event);
+      }
+}
+
+/* insert the scheduler, send and timer events into the EQS */ 
+void sim_queue_insert(sim_event_t* event) __attribute__ ((C, spontaneous)) {
+      sim_queue_heap_final_insert(event);
+      return;
+}
+
+/* insert the inject events into the EQS */
+void sim_queue_insert_general(sim_event_t* event, int type) __attribute__ ((C, spontaneous)) {
+      sim_event_t* tmpEvt = NULL;
+      event->type = GENERAL;
+      switch(type) {
+        case RADIO:
+           radio_count++;
+	   event->source = type;
+	   event->mark = radio_count;
+	   break;
+	case SERIAL:
+	   serial_count++;
+	   event->source = type;
+	   event->mark = serial_count;
+	   break;
+      }
+      tmpEvt = sim_queue_allocate_event();
+      sim_copy_event(event, tmpEvt);
+      queue_insert(InjectSet, tmpEvt);
+      sim_queue_heap_final_insert(event);
+      return;
+}
+
+/* restore the preserved inject events to be used in next round */
+void sim_copyback_from_inject_set() {
+     int i;
+     int size = queue_size(InjectSet);
+
+     for(i = 0; i < size; i++) {
+        sim_event_t* general = (sim_event_t*)sim_queue_get(InjectSet,i+1); 
+        sim_event_t* tmpGeneral = sim_queue_allocate_event();
+	sim_copy_event(general, tmpGeneral);
+	sim_queue_heap_final_insert(tmpGeneral);
+     }
+     return;
 }
 
+/******************************************assist part *********************************/
+void* sim_queue_get(queue_t* queue, int num) {
+     return queue_get_data(queue, num);   
+}
+
+/* pop the corresponding tossim event with lowest global time from the eventHeap */
 sim_event_t* sim_queue_pop() __attribute__ ((C, spontaneous)) {
   long long int key;
   return (sim_event_t*)(heap_pop_min_data(&eventHeap, &key));
@@ -70,6 +274,330 @@ long long int sim_queue_peek_time() __at
   }
 }
 
+/* pop the corresponding tossim event from the EQS according to the element description */
+sim_event_t* sim_mc_queue_pop(element_t* element) __attribute__ ((C, spontaneous)) {
+     queue_t* queue = NULL;
+     heap_t* heap = NULL;
+     sim_time_t time;
+     sim_event_t* event = NULL;
+
+     switch(element->eventType) {
+	case BOOT: 
+           if(nodeEqs[element->MoteID].BootEvt != NULL) {
+	     // This shows first bunch of boot events... 
+             event = (sim_event_t*)nodeEqs[element->MoteID].BootEvt;
+	     nodeEqs[element->MoteID].BootEvt = NULL;
+	   }
+	   else {
+	     dbg("Event", "Missing the boot event!\n");
+
+	     if(element->source == ON)
+	       sim_turn_on_specific_mote(element->MoteID);
+	     else if(element->source == OFF)
+	       sim_turn_off_specific_mote(element->MoteID);
+	     else
+	       sim_reboot_specific_mote(element->MoteID);
+
+             event = (sim_event_t*)nodeEqs[element->MoteID].BootEvt;
+	     nodeEqs[element->MoteID].BootEvt = NULL;
+	   }
+	   break;
+
+	case SCHEDULER:
+	   queue = nodeEqs[element->MoteID].SchedulerQ;
+           event = (sim_event_t*)queue_pop_first_data(queue);
+	   if(event != NULL) {
+	      if(event->source != element->source) {
+	         dbg("Event", "The current peak task is not matching with the original, element = %d, event = %d!\n", element->source, event->source);
+		 event = NULL;
+	      }
+	   }
+	   else {
+	      dbg("Event", "Missing the schedule event!\n");
+	   }
+       	   break;
+		
+	case GENERAL:
+	   queue = nodeEqs[element->MoteID].GeneralQ;
+	   event = (sim_event_t*)queue_pop_general_data(queue, element->source, element->num);
+           if(event == NULL) {
+	      dbg("Event", "Missing the general event!\n");
+	   }
+	   break;
+
+	case SEND:
+	   queue = nodeEqs[element->MoteID].SendQ;
+	   event = (sim_event_t*)queue_pop_first_data(queue);
+
+           if(event != NULL) {
+	     if(element->source == event->source) {
+	       if(event->source == BACKOFF) {
+	         if((mc_state == MC_RUNNING || mc_state == RANDOM_WALK) && sim_loss_mode == LOSS_WITH_PROB) { 
+		    //Based on the probability assigned by users, the element's mark can be changed.
+                    sim_handle_element_with_loss_probability(element); 
+	         }
+		 if(element->num == TRUE) 
+	            event->mark = TRUE;
+		 else
+	            event->mark = FALSE;
+	       } 
+	     }
+	     else {
+	       dbg("Event", "There happens the unmatching case for send events, tricky case!\n");
+	       event = NULL;
+	     }
+	  }
+	  else {
+	      dbg("Event", "Missing the send event!\n");
+	  }   
+	  break;
+
+        case RECEIVE:
+	   queue = nodeEqs[element->MoteID].ReceiveQ;
+	   event = (sim_event_t*)queue_pop_receive_ack_data(queue, element->source);
+	   if(event != NULL) {
+	      if((mc_state == MC_RUNNING || mc_state == RANDOM_WALK) && sim_loss_mode == LOSS_WITH_PROB) { 
+		 //Based on the probability assigned by users, the element's mark can be changed.
+                 sim_handle_element_with_loss_probability(element); 
+	      }
+	      if(element->num == TRUE) 
+	         event->mark = TRUE;
+	      else 
+	         event->mark = FALSE;
+	   }
+	   else {
+	      dbg("Event", "Missing the receive event!\n");
+	   }
+	   break;
+
+	case TIMER:
+	   heap = nodeEqs[element->MoteID].TimerH;
+	   event = (sim_event_t*)heap_pop_min_data(heap, &time);
+	   if(event == NULL) {
+	     dbg("Event", "Missing the timer event!\n");
+	   }
+	   break;
+
+	case ACK:
+	   queue = nodeEqs[element->MoteID].AckQ;
+	   event = (sim_event_t*)queue_pop_receive_ack_data(queue, element->source);
+	   if(event != NULL) {
+	      if((mc_state == MC_RUNNING || mc_state == RANDOM_WALK) && sim_loss_mode == LOSS_WITH_PROB) { 
+		 //Based on the probability assigned by users, the element's mark can be changed.
+                 sim_handle_element_with_loss_probability(element); 
+	      }
+	      if(element->num == TRUE) 
+	         event->mark = TRUE;
+	      else 
+	         event->mark = FALSE;
+	   }
+	   else {  
+	     dbg("Event", "Missing the ACK event!\n");
+	   }
+	   break;
+
+	case INTERRUPT:
+	   if(element->num == TRUE) {
+             event = (sim_event_t*)nodeEqs[element->MoteID].InterruptSet[element->source];
+	     if(event == NULL || event->mark == FALSE) {
+	       dbg("Event", "Missing the interrupt event: %d!\n", element->source);
+	     }
+	   }
+           break;
+        }
+	return event;
+}
+
+void sim_queue_destroy(queue_t* queue, int type) {
+     if(queue != NULL) {
+       queue_destroy(queue, type);
+       free(queue);
+       queue = NULL;
+     }
+}
+
+void sim_heap_destroy(heap_t* heap) {
+     heap_destroy(heap);
+}
+
+void sim_destroy_event_heap() {
+     if(eventHeap.data != NULL) {
+       sim_heap_destroy(&eventHeap);
+       free_data(eventHeap.data);
+       eventHeap.data = NULL;
+     }
+}
+
+void sim_destroy_mc_node_eqs() {
+     if(_mc_nodeEqs != NULL) {
+       while(queue_size(_mc_nodeEqs) != 0) {
+         sim_event_t* evt = (sim_event_t*)queue_pop_first_data(_mc_nodeEqs);
+         evt->cleanup(evt);
+       }
+       free(_mc_nodeEqs);
+     }
+}
+
+/****************************preserve and restore part ********************************/
+static void sim_insert_event_into_mc_eqs(sim_event_t* event) {
+     sim_event_t* _mc_event = sim_queue_allocate_event();
+     sim_copy_event(event, _mc_event);
+     queue_insert(_mc_nodeEqs, _mc_event);        
+}
+
+/* copy the events existing in eventHeap into the EQS */
+void sim_copy_from_tossim_to_eqs() {
+     long long int time;
+
+     while(!heap_is_empty(&eventHeap)) {
+        sim_event_t* event = (sim_event_t*)heap_pop_min_data(&eventHeap, &time); 
+
+	if(event->type == SEND && event->source == TRANSMIT) {
+	   sim_run_specific_event(event); 
+	}
+	else if(event->type == ACK) {
+	   sim_run_specific_event(event);
+	}
+	else {
+	   sim_insert_event_into_eqs(event);
+	   if(tossim_step > 0) {
+	      sim_insert_event_into_mc_eqs(event);
+	   }
+	}
+     }
+}
+
+static void sim_copy_RGT_event(sim_event_t* _mc_event) {
+     sim_event_t* event = sim_queue_allocate_event(); 
+     sim_copy_event(_mc_event, event);
+
+     if(_mc_event->type == RECEIVE) {
+	sim_reset_outstandingReceptionHead(event); 	
+     }
+     if(_mc_event->type == TIMER) {
+        sim_reset_compare_overflow(event);    
+     }
+     sim_queue_heap_final_insert(event);
+}
+
+static void sim_re_insert_event_into_eqs(sim_event_t* evt) {
+      sim_event_t* intr = NULL;
+      sim_event_t* boot = NULL;
+      int mote = evt->mote;
+
+      switch(evt->type) {
+	  case BOOT:
+	    boot = sim_queue_allocate_event();
+	    memcpy(boot, evt, sizeof(sim_event_t));
+	    sim_queue_heap_final_insert(boot);
+            break;
+	  case SCHEDULER:
+	    sim_apply_scheduler_event(evt);   
+	    break;
+	  case GENERAL:
+            sim_copy_RGT_event(evt);
+	    break;
+	  case SEND:
+	    sim_apply_send_event(evt);   
+	    break;
+	  case RECEIVE:
+            sim_copy_RGT_event(evt);
+	    break;
+	  case ACK:
+	    //There is no ACK actually
+	    break;
+	  case TIMER:
+            sim_copy_RGT_event(evt);
+	    break;
+	  case INTERRUPT:
+	    intr = nodeEqs[mote].InterruptSet[evt->source];
+	    // Here, the interrupt event should not be NULL...
+	    if(intr != NULL) {
+	      intr->mark = evt->mark;
+	      intr->time = evt->time;
+	    }
+	    if(mc_state == TOSSIM_RE_RUNNING) {
+	      sim_queue_heap_final_insert(intr);
+	    }
+	    break;
+       }
+}
+
+static void sim_clear_interrupt(int mote) {
+     int i;
+     for(i = 0; i<VECTOR_SIZE; i++) {
+	if(nodeEqs[mote].InterruptSet[i] != NULL) {
+	   sim_event_t* intr = nodeEqs[mote].InterruptSet[i];
+	   if(intr->mark == TRUE) 
+	       intr->mark = FALSE;
+	}
+     }
+}
+
+void sim_clear_specific_mote_eqs(int mote) {
+     sim_event_t* bootEvt = (sim_event_t*)nodeEqs[mote].BootEvt;
+
+     if(bootEvt != NULL) {
+        bootEvt->cleanup(bootEvt);
+        nodeEqs[mote].BootEvt = NULL;
+     }
+     queue_destroy(nodeEqs[mote].SchedulerQ, SCHEDULER);
+     queue_destroy(nodeEqs[mote].GeneralQ, GENERAL);
+     queue_destroy(nodeEqs[mote].SendQ, SEND);
+     queue_destroy(nodeEqs[mote].ReceiveQ, RECEIVE);
+     queue_destroy(nodeEqs[mote].AckQ, ACK);
+
+     timer_heap_destroy(nodeEqs[mote].TimerH);
+     //printf("After the clear, the heap size for TimerH is %d\n", heap_size(nodeEqs[mote].TimerH));
+}
+
+void sim_clear_specific_mote_eqs_and_interrupt(int mote) {
+     sim_clear_specific_mote_eqs(mote);
+     sim_clear_interrupt(mote);
+}
+
+void sim_clear_receive_and_timer(int mote) {
+     sim_clear_outstandingReceptionHead(mote);
+     sim_clear_compare_overflow(mote); 
+}
+
+void sim_copyback_from_mc_eqs_to_alternatives() {
+     int i;
+     int size = queue_size(_mc_nodeEqs); 
+     
+     for(i = 0; i < size; i++) {
+        sim_event_t* _mc_event = (sim_event_t*)sim_queue_get(_mc_nodeEqs, i+1); 
+        sim_re_insert_event_into_eqs(_mc_event); 
+     }
+}
+
+void sim_turn_off_clearance(int mote) {
+     sim_clear_specific_mote_eqs_and_interrupt(mote);
+     sim_clear_receive_and_timer(mote);
+}
+
+void sim_turn_off_remove_from_eventHeap(int mote) {
+     long long int key = 0;
+
+     init_heap(&_mc_eventHeap);
+     while(heap_is_empty(&eventHeap)) {
+        sim_event_t* evt = (sim_event_t*)(heap_pop_min_data(&eventHeap, &key));
+	if(evt->mote == mote) {
+           if(evt->type == RECEIVE || evt->type == ACK) 
+             sim_cleanup_event_receive_message(evt); 
+	   evt->cleanup(evt);
+	   evt = NULL;
+	}
+	else
+           heap_insert(&_mc_eventHeap, evt, evt->time);
+     }
+     free_data(eventHeap.data);
+     eventHeap.data = NULL;
+     eventHeap.data = _mc_eventHeap.data; 
+     eventHeap.size = _mc_eventHeap.size; 
+     eventHeap.private_size = _mc_eventHeap.private_size; 
+     _mc_eventHeap.data = NULL;
+}
 
 void sim_queue_cleanup_none(sim_event_t* event) __attribute__ ((C, spontaneous)) {
   dbg("Queue", "cleanup_none: 0x%p\n", event);
Index: tos/lib/tossim/sim_event_queue.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_event_queue.h,v
retrieving revision 1.6
diff -u -b -p -r1.6 sim_event_queue.h
--- tos/lib/tossim/sim_event_queue.h	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/sim_event_queue.h	9 Jul 2010 19:45:16 -0000
@@ -46,6 +46,7 @@
 #define SIM_EVENT_QUEUE_H_INCLUDED
 
 #include <sim_tossim.h>
+#include <sim_transition.h>
 
 struct sim_event;
 typedef struct sim_event sim_event_t;
@@ -60,20 +61,60 @@ struct sim_event {
   
   void (*handle)(sim_event_t* e);
   void (*cleanup)(sim_event_t* e);
+  int type;
+  int source;
+  int mark;
 };
 
 sim_event_t* sim_queue_allocate_event();
-
 void sim_queue_init();
-void sim_queue_insert(sim_event_t* event);
+
+void sim_output_event(sim_event_t*);
+void sim_output_send_event();
+void sim_copy_event();
+void sim_output_event_queue_set();
+/* insert part */
+void sim_queue_insert_boot_event(sim_event_t*);
+void sim_queue_insert(sim_event_t* e);
+void sim_queue_insert_general(sim_event_t*, int);
+void sim_queue_insert_turn_off_event(sim_event_t*);
+void sim_copyback_from_inject_set();
+
+/* assist part */
+void* sim_queue_get(queue_t*, int);
+sim_event_t* sim_queue_pop();
+sim_event_t* sim_mc_queue_pop(element_t*);
+void sim_destroy_event_heap();
 bool sim_queue_is_empty();
 long long int sim_queue_peek_time();
-sim_event_t* sim_queue_pop();
+void sim_destroy_mc_node_eqs();
+
+/* preserve and store part */
+void sim_copy_from_tossim_to_eqs();
+
+
+void sim_clear_specific_mote_eqs(int mote);
+void sim_clear_specific_mote_eqs_and_interrupt(int mote);
+void sim_clear_receive_and_timer(int mote);
+void sim_copyback_from_mc_eqs_to_alternatives();
+
+void sim_turn_off_clearance(int mote);
+void sim_turn_off_remove_from_eventHeap(int mote); 
 
 void sim_queue_cleanup_none(sim_event_t* e);
 void sim_queue_cleanup_event(sim_event_t* e);
 void sim_queue_cleanup_data(sim_event_t* e) ;
 void sim_queue_cleanup_total(sim_event_t* e);
 
+void sim_clear_outstandingReceptionHead(int node); 
+void sim_reset_outstandingReceptionHead(sim_event_t* evt); 
+void sim_clear_compare_overflow(int node); 
+void sim_reset_compare_overflow(sim_event_t* evt); 
+void sim_apply_send_event(sim_event_t* evt);
+void sim_apply_scheduler_event(sim_event_t* evt);
+void sim_copy_general_event(sim_event_t* gen, sim_event_t* _mc_gen);
+void sim_copy_receive_event(sim_event_t* rcv, sim_event_t* _mc_rcv);
+void sim_cleanup_event_receive_message(sim_event_t* evt);
+sim_event_t* sim_apply_ack_event(element_t* element);
 
 #endif // EVENT_QUEUE_H_INCLUDED
Index: tos/lib/tossim/sim_gen_list.c
===================================================================
RCS file: tos/lib/tossim/sim_gen_list.c
diff -N tos/lib/tossim/sim_gen_list.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_gen_list.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,120 @@
+#include <sim_gen_list.h>
+
+gen_list_node_t* sim_allocate_gen_list_node(uint8_t _t_Cand) {
+     gen_list_node_t* glnt = (gen_list_node_t*)malloc(sizeof(gen_list_node_t));
+     glnt->Cand = _t_Cand;
+     glnt->Chosen = glnt->Cand;
+     glnt->Access = FALSE;
+     glnt->tlink = NULL;
+     return glnt;
+}
+
+void sim_clear_gen_list_node(gen_list_node_t* head) {
+     if(head == NULL)
+	return;
+     while(head != NULL) {
+        gen_list_node_t* tmp = head;
+	head = head->tlink;
+	tmp->tlink = NULL;
+	free(tmp);
+     }
+     /*
+      * Perhaps we need this kind of free method later
+     sim_clear_gen_list_node(node->tlink);
+     free(node);
+     node = NULL;
+     */
+}
+
+static gen_list_node_t* sim_copy_single_gen_list_node(gen_list_node_t* gl_node) {
+     gen_list_node_t* glnt = (gen_list_node_t*)malloc(sizeof(gen_list_node_t));
+     glnt->Cand = gl_node->Cand;
+     glnt->Chosen = gl_node->Chosen;
+     glnt->Access = FALSE;
+     glnt->tlink = NULL;
+     return glnt;
+}
+
+//Construct a new list via the old list...
+gen_list_node_t* sim_copy_multi_gen_list_node(gen_list_node_t* gl_node) {
+     gen_list_node_t* head = NULL;
+     gen_list_node_t* glnt = NULL;
+
+     while(gl_node != NULL) {
+        if(head == NULL) {
+           glnt = sim_copy_single_gen_list_node(gl_node);
+	   head = glnt;
+	}
+	else {
+	  gen_list_node_t* glnt_t = sim_copy_single_gen_list_node(gl_node); 
+	  glnt->tlink = glnt_t;
+	  glnt = glnt_t;
+	}
+        gl_node = gl_node->tlink;
+     }
+     return head;
+}
+
+bool sim_decrease_gen_list_node_set(gen_list_node_t* head) {
+     gen_list_node_t* glnt = head;
+
+     do {
+       int Chosen_t = glnt->Chosen;
+       if(--Chosen_t < 0) {
+          glnt->Chosen = glnt->Cand;
+	  glnt = glnt->tlink;
+       }
+       else {
+          glnt->Chosen = (uint8_t)Chosen_t; 
+	  break;
+       }
+     } while(glnt != NULL);
+
+     if(glnt == NULL)
+        return FALSE; //All cases have been explored, no need to preserve the element
+     else
+	return TRUE; // Keep on preserving this element
+}
+
+bool sim_compare_two_glnt_set(gen_list_node_t* lHead, gen_list_node_t* rHead) {
+     while(lHead != NULL && rHead != NULL) {
+       if(lHead->Chosen != rHead->Chosen) 
+	  return FALSE;
+       lHead = lHead->tlink;
+       rHead = rHead->tlink;
+     }
+     if(lHead == NULL && rHead == NULL)
+	 return TRUE;
+     else
+	 return FALSE;
+}
+
+gen_list_node_t* sim_insert_gen_list_node_to_element(uint8_t Cand) {
+   gen_list_node_t* glnt = sim_allocate_gen_list_node(Cand);
+
+   if((_mc_element->glnHead).head == NULL) {
+     (_mc_element->glnHead).head = glnt;
+   }
+   else {
+     glnt->tlink = (_mc_element->glnHead).head;
+     (_mc_element->glnHead).head = glnt;
+   }
+
+   return glnt;
+}
+
+void sim_traverse_toss_internal_choose(uint8_t* Chosen) {
+   gen_list_node_t* glnt = (_mc_element->glnHead).head;
+
+   while(glnt->tlink != NULL) {
+     if(glnt->tlink->Access == TRUE)
+        break;
+     glnt = glnt->tlink;
+   }
+   //Set the mark as the new glnt...
+   if(glnt->Access == FALSE) {
+     glnt->Access = TRUE; //Actually, here, it has to be false 
+   }
+   *Chosen = glnt->Chosen; 
+}
+
Index: tos/lib/tossim/sim_gen_list.h
===================================================================
RCS file: tos/lib/tossim/sim_gen_list.h
diff -N tos/lib/tossim/sim_gen_list.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_gen_list.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,28 @@
+#ifndef SIM_GEN_LIST_H_INCLUDED
+#define SIM_GEN_LIST_H_INCLUDED
+
+typedef struct gen_list_node gen_list_node_t;
+
+struct gen_list_node {
+    uint8_t Cand;
+    uint8_t Chosen;
+    bool Access;
+    gen_list_node_t* tlink; // next element in the same level
+};
+
+typedef struct gen_list_node_header {
+    bool FirstAccess; //Flag to determine whether the corresponding toss internal node be added or not
+    gen_list_node_t* head; // always last element in the same level
+} gen_list_node_header_t;
+
+gen_list_node_t* sim_allocate_gen_list_node(uint8_t Cand);
+void sim_clear_gen_list_node(gen_list_node_t* node);
+
+gen_list_node_t* sim_copy_multi_gen_list_node(gen_list_node_t* glnt);
+bool sim_decrease_gen_list_node_set(gen_list_node_t* head);
+
+bool sim_compare_two_glnt_set(gen_list_node_t* lHead, gen_list_node_t* rHead);
+gen_list_node_t* sim_insert_gen_list_node_to_element(uint8_t Cand);
+void sim_traverse_toss_internal_choose(uint8_t* Chosen);
+
+#endif
Index: tos/lib/tossim/sim_log.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_log.c,v
retrieving revision 1.7
diff -u -b -p -r1.7 sim_log.c
--- tos/lib/tossim/sim_log.c	29 Jun 2010 22:07:51 -0000	1.7
+++ tos/lib/tossim/sim_log.c	9 Jul 2010 19:45:16 -0000
@@ -166,7 +166,21 @@ void sim_log_init() {
     outputs[i].files = (FILE**)malloc(sizeof(FILE*));
     outputs[i].files[0] = fdopen(1, "w"); // STDOUT
   }
+}
+
+void sim_log_destroy() {
+  int i;
+
+  for (i = 0; i < SIM_LOG_OUTPUT_COUNT; i++) {
+    if (outputs[i].files != NULL) {
+      outputs[i].num = 0;
+      free(outputs[i].files);
+      outputs[i].files = NULL;
+    }
+  }
+  hashtable_destroy(channelTable, 1);
   
+  return;
 }
 
 void sim_log_add_channel(char* name, FILE* file) {
@@ -254,7 +268,14 @@ void sim_log_debug(uint16_t id, char* st
     va_start(args, format);
     fprintf(file, "DEBUG (%i): ", (int)sim_node());
     vfprintf(file, format, args); 
+
+    if(whichFile != NULL) {
+      fprintf(whichFile, "DEBUG (%i): ", (int)sim_node()); 
+      vfprintf(whichFile, format, args); 
+    }
+
     fflush(file);
+    fflush(whichFile);
   }
 }
 
@@ -269,7 +290,14 @@ void sim_log_error(uint16_t id, char* st
     va_start(args, format);
     fprintf(file, "ERROR (%i): ", (int)sim_node());
     vfprintf(file, format, args);
+  
+    if(whichFile != NULL) {
+      fprintf(whichFile, "DEBUG (%i): ", (int)sim_node()); 
+      vfprintf(whichFile, format, args); 
+    }
+    
     fflush(file);
+    fflush(whichFile);
   }
 }
 
@@ -283,7 +311,14 @@ void sim_log_debug_clear(uint16_t id, ch
     FILE* file = outputs[id].files[i];
     va_start(args, format);
     vfprintf(file, format, args);
+  
+    if(whichFile != NULL) {
+      fprintf(whichFile, "DEBUG (%i): ", (int)sim_node()); 
+      vfprintf(whichFile, format, args); 
+    }
+    
     fflush(file);
+    fflush(whichFile);
   }
 }
 
Index: tos/lib/tossim/sim_log.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_log.h,v
retrieving revision 1.5
diff -u -b -p -r1.5 sim_log.h
--- tos/lib/tossim/sim_log.h	29 Jun 2010 22:07:51 -0000	1.5
+++ tos/lib/tossim/sim_log.h	9 Jul 2010 19:45:16 -0000
@@ -62,10 +62,18 @@
 extern "C" {
 #endif
 
+void sim_log_file_open(bool isSafety);
+void sim_log_file_close();
+//void sim_log_file_change_to_safety_violating_path();
+//void sim_log_file_change_to_liveness_fulfillment_path();
+//void sim_log_file_change_to_liveness_violating_path();
+//void sim_log_file_change_name();
+
 void sim_log_init();
 void sim_log_add_channel(char* output, FILE* file);
 bool sim_log_remove_channel(char* output, FILE* file);
 void sim_log_commit_change();
+void sim_log_destroy();
 
 void sim_log_debug(uint16_t id, char* string, const char* format, ...);
 void sim_log_error(uint16_t id, char* string, const char* format, ...);
Index: tos/lib/tossim/sim_mote.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_mote.h,v
retrieving revision 1.5
diff -u -b -p -r1.5 sim_mote.h
--- tos/lib/tossim/sim_mote.h	29 Jun 2010 22:07:51 -0000	1.5
+++ tos/lib/tossim/sim_mote.h	9 Jul 2010 19:45:16 -0000
@@ -59,8 +59,10 @@ void sim_mote_set_start_time(int mote, l
 bool sim_mote_is_on(int mote);
 void sim_mote_turn_on(int mote);
 void sim_mote_turn_off(int mote);
+void sim_mote_reset(int mote);
 int sim_mote_get_variable_info(int mote, char* name, void** addr, size_t* len);
 void sim_mote_enqueue_boot_event(int mote);
+void sim_mote_blink_show_error(int ledsc, int on_or_off);
 
 #ifdef __cplusplus
 }
Index: tos/lib/tossim/sim_noise.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_noise.c,v
retrieving revision 1.13
diff -u -b -p -r1.13 sim_noise.c
--- tos/lib/tossim/sim_noise.c	29 Jun 2010 22:07:51 -0000	1.13
+++ tos/lib/tossim/sim_noise.c	9 Jul 2010 19:45:16 -0000
@@ -53,9 +53,12 @@ int numCase2 = 0;
 int numTotal = 0;
 //End Tal Debug
 
+//This is just for the backup
+
 uint32_t FreqKeyNum = 0;
 
 sim_noise_node_t noiseData[TOSSIM_MAX_NODES];
+sim_noise_node_t_bak noiseDataBackup[TOSSIM_MAX_NODES];
 
 static unsigned int sim_noise_hash(void *key);
 static int sim_noise_eq(void *key1, void *key2);
@@ -81,9 +84,22 @@ void sim_noise_init()__attribute__ ((C, 
   //printf("Done with sim_noise_init()\n");
 }
 
+void sim_noise_destroy() {
+  int j;
+  for (j=0; j < TOSSIM_MAX_NODES; j++) {
+    //struct hashtable *pnoiseTable = noiseData[j].noiseTable;
+    //hashtable_destroy(pnoiseTable, 0);
+    noiseData[j].noiseGenTime = 0;
+    free(noiseData[j].noiseTrace);
+    noiseData[j].noiseTraceLen = NOISE_MIN_TRACE;
+    noiseData[j].noiseTraceIndex = 0;
+  }
+}
+
 void sim_noise_create_model(uint16_t node_id)__attribute__ ((C, spontaneous)) {
   makeNoiseModel(node_id);
   makePmfDistr(node_id);
+  sim_noise_copy();
 }
 
 char sim_real_noise(uint16_t node_id, uint32_t cur_t) {
@@ -361,6 +377,26 @@ char sim_noise_gen(uint16_t node_id)__at
   return noise;
 }
 
+void sim_noise_copy() {
+   int i;
+   for(i = 0; i < TOSSIM_MAX_NODES; i++) {
+       noiseDataBackup[i].lastNoiseVal_bak = noiseData[i].lastNoiseVal;
+       noiseDataBackup[i].noiseGenTime_bak = noiseData[i].noiseGenTime;
+       memcpy(noiseDataBackup[i].key_bak, noiseData[i].key, sizeof(char)*NOISE_HISTORY);
+       memcpy(noiseDataBackup[i].freqKey_bak, noiseData[i].freqKey, sizeof(char)*NOISE_HISTORY);
+   }
+}
+
+void sim_noise_copyback() {
+   int i;
+   for(i = 0; i < TOSSIM_MAX_NODES; i++) {
+       noiseData[i].lastNoiseVal = noiseDataBackup[i].lastNoiseVal_bak;
+       noiseData[i].noiseGenTime = noiseDataBackup[i].noiseGenTime_bak;
+       memcpy(noiseData[i].key, noiseDataBackup[i].key_bak, sizeof(char)*NOISE_HISTORY);
+       memcpy(noiseData[i].freqKey, noiseDataBackup[i].freqKey_bak, sizeof(char)*NOISE_HISTORY);
+   }
+}
+
 char sim_noise_generate(uint16_t node_id, uint32_t cur_t)__attribute__ ((C, spontaneous)) {
   uint32_t i;
   uint32_t prev_t;
@@ -384,9 +420,13 @@ char sim_noise_generate(uint16_t node_id
 
   if (prev_t == 0)
     delta_t = cur_t - (NOISE_HISTORY-1);
-  else
+  else {
+   // delta_t = cur_t - prev_t;
+     if(cur_t >= prev_t)
     delta_t = cur_t - prev_t;
-  
+     else
+	delta_t = prev_t - cur_t;
+  }
   dbg_clear("HASH", "delta_t = %d\n", delta_t);
   
   if (delta_t == 0)
Index: tos/lib/tossim/sim_noise.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_noise.h,v
retrieving revision 1.8
diff -u -b -p -r1.8 sim_noise.h
--- tos/lib/tossim/sim_noise.h	29 Jun 2010 22:07:51 -0000	1.8
+++ tos/lib/tossim/sim_noise.h	9 Jul 2010 19:45:16 -0000
@@ -82,11 +82,21 @@ typedef struct sim_noise_node_t {
   bool generated;
 } sim_noise_node_t;
 
+typedef struct sim_noise_node_t_bak {
+  char lastNoiseVal_bak;
+  uint32_t noiseGenTime_bak;
+  char key_bak[NOISE_HISTORY];
+  char freqKey_bak[NOISE_HISTORY];
+} sim_noise_node_t_bak;
+
 void sim_noise_init();
 char sim_real_noise(uint16_t node_id, uint32_t cur_t);
 char sim_noise_generate(uint16_t node_id, uint32_t cur_t);
 void sim_noise_trace_add(uint16_t node_id, char val);
 void sim_noise_create_model(uint16_t node_id);
+void sim_noise_copy();
+void sim_noise_copyback();
+void sim_noise_destroy();
   
 #ifdef __cplusplus
 }
Index: tos/lib/tossim/sim_packet.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_packet.c,v
retrieving revision 1.6
diff -u -b -p -r1.6 sim_packet.c
--- tos/lib/tossim/sim_packet.c	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/sim_packet.c	9 Jul 2010 19:45:16 -0000
@@ -43,50 +43,50 @@
 #include <sim_packet.h>
 #include <message.h>
 
-// NOTE: This function is defined in lib/tossim/ActiveMessageC. It
+// NOTE: This function is defined in lib/cc2420/ActiveMessageC. It
 // has to be predeclared here because it is defined within that component.
 void active_message_deliver(int node, message_t* m, sim_time_t t);
 
-static tossim_header_t* getHeader(message_t* msg) {
-  return (tossim_header_t*)(msg->data - sizeof(tossim_header_t));
+static cc2420_header_t* getHeader(message_t* msg) {
+  return (cc2420_header_t*)(msg->data - sizeof(cc2420_header_t));
 }
 
 void sim_packet_set_source(sim_packet_t* msg, uint16_t src)__attribute__ ((C, spontaneous)) {
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   hdr->src = src;
 }
 
 uint16_t sim_packet_source(sim_packet_t* msg)__attribute__ ((C, spontaneous)) {
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   return hdr->src;
 }
 
 void sim_packet_set_destination(sim_packet_t* msg, uint16_t dest)__attribute__ ((C, spontaneous)) {
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   hdr->dest = dest;
 }
 
 uint16_t sim_packet_destination(sim_packet_t* msg)__attribute__ ((C, spontaneous)) {
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   return hdr->dest;
 }
   
 void sim_packet_set_length(sim_packet_t* msg, uint8_t length)__attribute__ ((C, spontaneous)) {
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   hdr->length = length;
 }
 uint16_t sim_packet_length(sim_packet_t* msg)__attribute__ ((C, spontaneous)) {
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   return hdr->length;
 }
 
 void sim_packet_set_type(sim_packet_t* msg, uint8_t type) __attribute__ ((C, spontaneous)){
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   hdr->type = type;
 }
 
 uint8_t sim_packet_type(sim_packet_t* msg) __attribute__ ((C, spontaneous)){
-  tossim_header_t* hdr = getHeader((message_t*)msg);
+  cc2420_header_t* hdr = getHeader((message_t*)msg);
   return hdr->type;
 }
 
@@ -96,9 +96,10 @@ uint8_t* sim_packet_data(sim_packet_t* p
 }
 void sim_packet_set_strength(sim_packet_t* p, uint16_t str) __attribute__ ((C, spontaneous)){
   message_t* msg = (message_t*)p;
-  tossim_metadata_t* md = (tossim_metadata_t*)(&msg->metadata);
+  cc2420_metadata_t* md = (cc2420_metadata_t*)(&msg->metadata);
   md->strength = str;
 }
+
 void sim_packet_deliver(int node, sim_packet_t* msg, sim_time_t t) __attribute__ ((C, spontaneous)){
   if (t < sim_time()) {
     t = sim_time();
Index: tos/lib/tossim/sim_property_check.h
===================================================================
RCS file: tos/lib/tossim/sim_property_check.h
diff -N tos/lib/tossim/sim_property_check.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_property_check.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,10 @@
+#ifndef SIM_PROPERTY_CHECK_H_INCLUDED
+#define SIM_PROPERTY_CHECK_H_INCLUDED
+
+#define UQ_CTP_PROPERTY "CTP.Property"
+
+void sim_safety_property_check();
+void sim_liveness_property_check();
+void sim_property_check();
+
+#endif
Index: tos/lib/tossim/sim_random_walk.c
===================================================================
RCS file: tos/lib/tossim/sim_random_walk.c
diff -N tos/lib/tossim/sim_random_walk.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_random_walk.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,323 @@
+#include <sim_random_walk.h>
+#include <sim_random_walk_assist.h>
+#include <sim_delta_debugging.h>
+#include <sim_property_check.h>
+#include <sim_statistic_info.h>
+
+void sim_move_to_new_state(queue_t* rw_bak, int length) { 
+     int i;
+     // Here mc_state is MC_RW_REPEAT implicitly
+     sim_reset_and_re_execute(FALSE);
+     for(i = 0; i < length; i++) {
+	transition_t* trans = (transition_t*)sim_queue_get(rw_bak, i+1);
+        sim_one_transition_re_execute(trans);
+	sim_increase_transition_explored_number();
+     }
+     // The C_TIMER must be set here...
+     for(i = 0; i<MAX_NODES; i++) {
+        C_TIMER[i] = TRUE;
+        C_TMP_TIMER[i] = TRUE;
+     }
+}
+
+static void sim_stress_testing(queue_t* rw_bak) {
+     int i, j, length = queue_size(rw_bak);
+     //Here mc_state is MC_RW_REPEAT implicitly
+     for(j = 0; j < 10; j++) {
+       sim_reset_and_re_execute(FALSE);
+       for(i = 0; i < length; i++) {
+	 transition_t* trans = (transition_t*)sim_queue_get(rw_bak, i+1);
+         sim_one_transition_re_execute(trans);
+       }
+     }
+}
+
+static void sim_random_walk_with_bound(int BOUND) {
+     int i;
+     mc_state = RANDOM_WALK;
+
+     for(i = 0; i < BOUND; i++) {
+	element_t* elem = sim_random_choose_element(FALSE);
+	if(elem != NULL) {
+	  sim_output_element(elem);
+	  printf("end\n");
+
+          sim_mc_run_next_event(elem);
+	  sim_build_transition_without_saving(elem);
+          sim_increase_transition_explored_number();
+          sim_element_gen_list_node_access_clearance(elem);
+
+          //In the new state, check the corresponding safety and liveness property...
+          sim_property_check(); 
+          sim_free_element(elem);
+
+	  //If the bug occurs, then change the log
+          if(sim_safety_bug_occur()) {
+	    dbg("TOSMC", "During finding critical transition, a safety violation occurs unocassionnally, the random walk stops!\n");
+	    return;
+	  }
+	  if(sim_single_liveness_fulfill()) {
+	    dbg("TOSMC", "During finding critical transition, the random walk stops since the liveness property is fulfilled!\n");
+	    return;
+	  }
+	}
+	else {
+	  // Here, that means implicitly the enable pool is empty, return...
+	  return;
+	}
+     }
+}
+
+bool sim_random_walk_with_bound_for_delta(queue_t* deltaWalk, int BOUND, bool buggyNodeFlag) {
+     int i;
+     element_t* elem = NULL;
+     mc_state = RANDOM_WALK;
+
+     for(i = 0; i<BOUND; i++) {
+        elem = sim_random_choose_element(buggyNodeFlag);
+
+	if(elem != NULL) {
+          //printf("DELTA DEBUGGING, this is the %dth random event\n", i+1);
+	  //sim_output_element(elem);
+	  //printf("end\n");
+
+          sim_mc_run_next_event(elem);
+	  sim_build_transition(deltaWalk, elem);
+          sim_increase_transition_explored_number();
+          sim_element_gen_list_node_access_clearance(elem);
+
+          sim_property_check(); 
+	  //If the bug occurs, then change the log
+	  if(sim_safety_bug_occur()) {
+	    dbg("TOSMC", "In delta debugging, a safety violation occurs, the random walk for delta debugging stops!\n");
+	    return TRUE;
+	  }
+	}
+	else {
+	  // Here, that means implicitly the enable pool is empty, return...
+	  return FALSE;
+	}
+     }
+     return FALSE;
+}
+
+static bool sim_random_walk_recover(queue_t* rw_bak, int rwBound, int prefix, int k) {
+     int idx;
+     bool recover = FALSE;
+     char info[256];
+
+     for(idx = 0; idx < k; idx++) {
+        sim_move_to_new_state(rw_bak, prefix);
+	sim_random_walk_with_bound(rwBound - prefix);
+
+	if(sim_safety_bug_occur())
+	  continue;
+	else {
+	  if(sim_single_liveness_fulfill()) {
+	    recover = TRUE; 
+            break;
+	  }
+	}
+     }
+     if(recover) 
+       sprintf(info, "Based on %dth common prefix and %dth retry, liveness property is fulfilled!\n", prefix, idx+1);
+     else 
+       sprintf(info, "Based on %dth common prefix, liveness property is violated!\n", prefix);
+
+     sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+     return recover;
+}
+
+static bool sim_random_walk_double_bound_recover(int rwBound, int k) {
+     int idx;
+     char info[256];
+     bool recover = FALSE;
+
+     for(idx = 0; idx < k; idx++) {
+       sim_move_to_new_state(NULL, 0);
+       sim_random_walk_with_bound(2*rwBound);
+
+       if(sim_safety_bug_occur())
+	 continue;
+       else {
+	 if(sim_single_liveness_fulfill()) {
+	   recover = TRUE; 
+           break;
+	 }
+       }
+     }
+     if(recover) 
+       sprintf(info, "Based on new double bound: %d and %dth retry, liveness property is fulfilled!\n", 2*rwBound, idx+1);
+     else 
+       sprintf(info, "Based on new double bound %d, liveness property is still violated!\n", 2*rwBound);
+
+     sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+     return recover;
+}
+
+static void sim_find_critical_transition(queue_t* rw_bak, int rwBound, int k, int* criticalNum) {
+     //Here, we think there is the potential liveness violation...
+     char info[256];
+     int d_init = 1, d_prev = 0, d_curr = 0, d_mid = 0;
+
+     if(!sim_random_walk_recover(rw_bak, rwBound, d_init, k)) {
+        sprintf(info, "Starting from the initial transition, system can't recover, consider increasing current bound: %d!\n", rwBound);
+        sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+
+        if(sim_random_walk_double_bound_recover(rwBound, k)) {
+           sprintf(info, "Increasing rwBound from %d to %d, system recovers, suggest using this new bound!\n", rwBound, 2*rwBound);
+           sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+	}
+	else {
+           sprintf(info, "Increasing rwBound from %d to %d, system still can't recover and \"critical transition\" can not be found, please analyze the whole trace by yourselves!\n", rwBound, 2*rwBound);
+           sim_log_liveness_violating_path(info, rw_bak, FALSE, queue_size(rw_bak));
+	}
+	exit(0);
+     }
+
+     //Exponential search stage.....
+     d_curr = d_init;
+     do {
+        d_prev = d_curr;
+	d_curr = 2 * d_curr;
+	if(d_curr > rwBound/2) {
+           sprintf(info, "Critical transition does not appear early enough before the step: %d, consider increasing bound\n", d_curr);
+           sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+	   exit(0);
+	}
+     } while(sim_random_walk_recover(rw_bak, rwBound, d_curr, k));
+
+     //Binary search stage.....
+     while(TRUE) {
+        if(d_prev == d_curr - 1) { 
+           sprintf(info, "Critical transition occurs in %dth step in original buggy random walk!\n", d_curr);
+           sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+	   *criticalNum = d_curr;
+           return;
+	}
+
+        d_mid = (d_prev + d_curr) / 2;
+	if(sim_random_walk_recover(rw_bak, rwBound, d_mid, k))
+           d_prev = d_mid;
+	else
+           d_curr = d_mid;
+     }
+}
+
+void sim_random_walk(int rwBound) { 
+     int i;
+     uint8_t j;
+     char info[256];
+     int criticalNum = 0;
+     queue_t* rw_bak = sim_transition_queue_init();
+     mc_state = RANDOM_WALK;
+
+     for(i = 0; i < rwBound; i++) {
+	element_t* elem = NULL;
+	turn_over_steps++;
+        elem = sim_random_choose_element(FALSE);
+
+	if(elem != NULL) {
+          printf("This is the %dth random event in random walk\n", i+1);
+          sim_output_element(elem);
+	  printf("end\n");
+
+          sim_mc_run_next_event(elem);
+#ifdef LIVENESS
+	  sim_build_transition(rw_bak, elem);
+	  sim_element_gen_list_node_access_clearance(elem);
+#else
+	  if(delta_debugging) {
+	    sim_build_transition(rw_bak, elem);
+	    sim_element_gen_list_node_access_clearance(elem);
+	  }
+	  else {
+	    sim_build_transition_without_saving(elem);
+	    sim_element_gen_list_node_access_clearance(elem);
+	    sim_free_element(elem);
+	  }
+#endif
+          sim_increase_transition_explored_number();
+          //At each new state, check the corresponding safety and liveness properties ...
+          sim_property_check(); 
+
+	  if(sim_safety_bug_occur()) {
+	     dbg("TOSMC", "A safety violation occurs, the random walk must stop!\n");
+	     if(delta_debugging) {
+               stats_state = DELTA_DEBUGGING;
+	       sim_reduce_random_path(&rw_bak);
+               stats_state = MC_AND_RW;
+	       sim_transition_queue_destroy(rw_bak);
+	     }
+	     sim_safety_report_statistics_data();
+	     return;
+	  }
+	  // Since it is found that the coarse-grain node-level non-determinism
+	  // will disturb the liveness property checking. i.e., for the parent 
+	  // finding liveness property, from the start point of random walking to 
+	  // the non-determinism occurring point, the liveness property is fulfilled,
+	  // however, we do not want to quit the random walk. 
+	  // Hence, we postpone the liveness checking of network system containing 
+	  // node-level non-determinism to the end of random walking. In this way, after
+	  // the whole random walking ends, if the liveness is fulfilled, 
+	  // the property "eventually" is satisfied, otherwise, something wrong happens...
+	  if(!node_level_non_determinism) {
+             if(sim_liveness_fulfill()) {
+               sprintf(info, "All liveness properties are satisfied in path %d without node level non-determinism\n", path+1);
+               sim_log_liveness_fulfillment(info);
+	       sim_transition_queue_destroy(rw_bak);
+	       return;
+             }
+	  }
+	}
+	else  
+	  return;
+     }
+#ifdef LIVENESS
+     // Random walk ends, then check whether the liveness property is satisfied or not...
+     if(node_level_non_determinism) {
+       if(sim_liveness_fulfill()) {
+         sprintf(info, "All liveness property is fulfilled in path %d for node level non-determinism\n", path+1);
+         sim_log_liveness_fulfillment(info);
+	 sim_transition_queue_destroy(rw_bak);
+	 return;
+       }
+     }
+     if(sim_tossim_mode) {
+       bool tossim_pass = sim_tossim_assist_random_walk(rwBound);
+       if(tossim_pass) {
+         sprintf(info, "All liveness properties are fulfilled in path %d upon tossim support\n", path+1);
+         sim_log_liveness_fulfillment(info);
+         sim_transition_queue_destroy(rw_bak);
+         return;
+       }
+       else {
+         sprintf(info, "Some or all liveness properties can't be satisfied in path %d\n", path+1);
+         sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+       }
+     }
+
+     stats_state = FIND_CRITICAL;
+     for(j = 0; j < sim_get_property_number(); j++) {
+       sprintf(info, "The status of liveness property %d is %d\n", j+1, sim_get_mote_liveness_status(j));
+       sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+
+       if(!sim_get_mote_liveness_status(j)) {
+	 sim_set_liveness_bug_source(j);
+
+         sprintf(info, "The %dth liveness property can not be satisfied, T-Check will start isolating critical transition!\n", j+1);
+         sim_log_liveness_violating_path(info, NULL, FALSE, 0);
+
+         sim_find_critical_transition(rw_bak, rwBound, 50, &criticalNum);
+         if(criticalNum != 0) {
+	   sprintf(info, "The orignal liveness violating path including critical transition is shown below:\n");
+           sim_log_liveness_violating_path(info, rw_bak, TRUE, criticalNum); 
+         }
+       }
+     }
+     stats_state = MC_AND_RW;
+#endif
+     //sim_stress_testing(rw_bak); 
+     //exit(0);
+     sim_transition_queue_destroy(rw_bak);
+}
Index: tos/lib/tossim/sim_random_walk.h
===================================================================
RCS file: tos/lib/tossim/sim_random_walk.h
diff -N tos/lib/tossim/sim_random_walk.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_random_walk.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,12 @@
+#ifndef SIM_RANDOM_WALK_H_INCLUDED
+#define SIM_RANDOM_WALK_H_INCLUDED
+
+typedef struct NonEmptyLength {
+  uint32_t length;
+} NonEmptyLength_t;
+
+void sim_move_to_new_state(queue_t* rw_bak, int length);
+bool sim_random_walk_with_bound_for_delta(queue_t* deltaWalk, int BOUND, bool buggyNodeFlag);
+void sim_random_walk(int rwBound); 
+
+#endif
Index: tos/lib/tossim/sim_random_walk_assist.c
===================================================================
RCS file: tos/lib/tossim/sim_random_walk_assist.c
diff -N tos/lib/tossim/sim_random_walk_assist.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_random_walk_assist.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,321 @@
+#include <sim_random_walk_assist.h>
+
+int Module = 10;
+
+int sendNum = 0;
+int receiveNum = 0;
+int ackNum = 0;
+
+rand_pos_node_t* sendRandPosHead = NULL;
+rand_pos_node_t* receiveRandPosHead = NULL;
+rand_pos_node_t* ackRandPosHead = NULL;
+
+/*************************** Tossim walk ****************************/
+bool sim_tossim_assist_random_walk(int rwBound) {
+     int i;
+     sim_reset_for_tossim();
+     for(i = 0; i < rwBound; i++) {
+	int mote = 0;
+	turn_over_steps++;
+	sim_simulate_turn_on_or_off_event(&mote);
+        sim_run_next_event();    
+        sim_property_check(); 
+	if(!node_level_non_determinism) {
+          if(sim_liveness_fulfill()) {
+            dbg("TOSMC", "In tossim assist stage, liveness property is fulfilled!\n");
+	    return TRUE;
+          }
+	}
+     }
+     if(node_level_non_determinism) {
+       if(sim_liveness_fulfill()) {
+         dbg("TOSMC", "In tossim assist stage, liveness property is fulfilled!\n");
+	 return TRUE;
+       }
+     }
+     return FALSE;
+}
+
+// Flattening random walk..... 
+static element_t* sim_flattening_random_choose_element(queue_t* enableQ) {
+     if(queue_size(enableQ) != 0) {
+        int randNum = RandomInt(1, queue_size(enableQ));
+	return (element_t*)sim_queue_get(enableQ, randNum);
+     }
+     dbg("TOSMC", "The enable event pool is empty!\n");
+     return NULL;
+}
+
+// Random walk with Biasing..... 
+static int sim_random_choose_element_in_same_node(int mote, queue_t* enableQ, bool buggyNodeFlag) {
+     int t_start = -1, t_end = -1;
+     int sr_start = -1, sr_end = -1; //record the send and receive position...
+     bool moteProbe = FALSE;  
+
+     if(queue_size(enableQ) != 0) {
+        int i;
+	for(i = 0; i<queue_size(enableQ); i++) {
+	   element_t* elem = (element_t*)sim_queue_get(enableQ, i+1);
+	   if(elem->MoteID == mote) {
+	      if(t_start == -1)
+		 t_start = t_end = i+1;
+	      else 
+		 t_end = i+1;
+
+	      if(elem->eventType == SEND || elem->eventType == RECEIVE) {
+		// compute the send and receive position...
+	        if(sr_start == -1)
+		  sr_start = sr_end = i+1;
+	        else 
+		  sr_end = i+1;
+	      }
+	      moteProbe = TRUE;
+	   }
+	   else {
+	      if(moteProbe)
+		break;
+	   }
+	}
+
+	if(t_start == -1) { 
+	   dbg("TOSMC", "There is no available event for the mote: %d\n", mote); 
+	   return -1;
+	}
+	else {
+	   int randNum = 0;
+	   if(buggyNodeFlag) 
+              randNum = RandomInt(t_start, t_end);
+	   else {
+             if(sr_start == -1) {
+                randNum = RandomInt(t_start, t_end);
+	     }
+	     else { 
+                randNum = RandomInt(sr_start, sr_end);
+	     }
+	   }
+	   return randNum;
+	}
+     }
+     dbg("TOSMC", "%s: The enable event pool is empty!\n", __FUNCTION__);
+     return -1;
+}
+
+static element_t* sim_biasing_random_choose_element(queue_t* enableQ) {
+     int mote;
+     uint8_t nodesCandidate[MAX_NODES]; 
+     int candNum = 0; 
+     element_t* retElem = NULL;
+
+     if(queue_size(enableQ) != 0) {
+       for(mote = 0; mote < MAX_NODES; mote++) {
+          if(sim_mote_status(mote) == ON) {
+	     int num = sim_random_choose_element_in_same_node(mote, enableQ, FALSE); 
+	     if(num != -1) 
+		nodesCandidate[candNum++] = num;
+	  }
+       }
+     }
+     // Here, we bias the communication events... 
+     if(candNum != 0) {
+        int randNum = RandomInt(0, candNum-1);
+        retElem = (element_t*)sim_queue_get(enableQ, nodesCandidate[randNum]);
+     }
+     else 
+	dbg("TOSMC", "%s: The enable event pool is empty!\n", __FUNCTION__);
+
+     return retElem;
+}
+
+element_t* sim_random_choose_element(bool buggyNodeFlag) {
+     queue_t* enableQ = sim_element_queue_init();
+     element_t* elem = NULL;
+     element_t* elem_t = NULL;
+
+     sim_find_enabled_event_set(enableQ, FALSE);
+
+     if(buggyNodeFlag) {
+        int num = sim_random_choose_element_in_same_node(buggy_node, enableQ, TRUE);
+	if(num != -1)
+	  elem = (element_t*)sim_queue_get(enableQ, num);
+     }
+     else {
+        if(sim_bias_mode) 
+	  elem = sim_biasing_random_choose_element(enableQ);
+        else 
+          elem = sim_flattening_random_choose_element(enableQ);
+     }
+
+     if(elem != NULL) 
+	elem_t = sim_copy_element(elem);
+     // Destroy the enable queue...
+     sim_element_queue_destroy(enableQ);
+     return elem_t;
+}
+
+// For example, sendProb is 0.9, that is, 90% send events will be successful..
+static rand_pos_node_t* sim_allocate_rand_pos_node(int randPos) {
+     rand_pos_node_t* rpn = (rand_pos_node_t*)malloc(sizeof(rand_pos_node_t));
+     rpn->randPos = randPos;
+     rpn->next = NULL;
+     return rpn;
+}
+
+static bool sim_insert_rand_pos_queue(rand_pos_node_t** randPosHead, int randNum) {
+     rand_pos_node_t* rpn = NULL;
+     rand_pos_node_t* randNode = NULL;
+     bool insertSucceed = FALSE;
+
+     if(*randPosHead == NULL) {
+        randNode = sim_allocate_rand_pos_node(randNum);
+        *randPosHead = randNode;
+	return TRUE;
+     }
+     rpn = *randPosHead;
+     while(rpn != NULL) {
+	if(randNum < rpn->randPos) {
+           randNode = sim_allocate_rand_pos_node(randNum);
+	   randNode->next = *randPosHead;
+	   *randPosHead = randNode;
+	   insertSucceed = TRUE;
+	   break;
+	}
+	else if(randNum == rpn->randPos) {
+	   insertSucceed = FALSE;
+	   break;
+	}
+	else {
+           if(rpn->next == NULL) {
+              randNode = sim_allocate_rand_pos_node(randNum);
+	      rpn->next = randNode;
+	      insertSucceed = TRUE;
+	      break;
+	   }
+	   else {
+              if(randNum < rpn->next->randPos) {
+                 randNode = sim_allocate_rand_pos_node(randNum);
+	         randNode->next = rpn->next;
+		 rpn->next = randNode;
+	         insertSucceed = TRUE;
+		 break;
+	      }
+	      else
+		 rpn = rpn->next;
+	   }
+	}
+     }
+     return insertSucceed;
+}
+
+static void sim_clear_rand_pos_queue(rand_pos_node_t** head) {
+     if(*head == NULL)
+	return;
+     while(*head != NULL) {
+	rand_pos_node_t* tmpRpn = *head;
+        *head = (*head)->next;    
+	tmpRpn->next = NULL;
+	free(tmpRpn);
+     }
+}
+
+static void sim_reset_rand_pos_queue(int eventType) {
+     int i, failNum = 0;
+     rand_pos_node_t** randPosHead = NULL;
+
+     switch (eventType) {
+        case SEND:
+	   failNum = sendFailNum;
+           sim_clear_rand_pos_queue(&sendRandPosHead);
+	   randPosHead = &sendRandPosHead;
+	   break;
+	case RECEIVE:
+           failNum = receiveFailNum;
+           sim_clear_rand_pos_queue(&receiveRandPosHead);
+	   randPosHead = &receiveRandPosHead;
+	   break;
+	case ACK:
+           failNum = ackFailNum;
+           sim_clear_rand_pos_queue(&ackRandPosHead);
+	   randPosHead = &ackRandPosHead;
+	   break;
+     }
+
+     for(i = 0; i<failNum; i++) {
+	while(TRUE) {
+          int randNum = RandomInt(1, Module); 
+          if(sim_insert_rand_pos_queue(randPosHead, randNum)) 
+	      break;
+	}
+     }
+}
+
+void sim_reset_num_and_rand_pos_queue(int eventType) {
+     if(eventType == SEND) {
+       sendNum = 0;
+       sim_reset_rand_pos_queue(SEND); 
+     }
+     else if(eventType == RECEIVE) {
+       receiveNum = 0;
+       sim_reset_rand_pos_queue(RECEIVE); 
+     }
+     else {
+       ackNum = 0;
+       sim_reset_rand_pos_queue(ACK); 
+     }
+}
+
+void sim_handle_element_with_loss_probability(element_t* elem) {
+     if(elem->eventType == SEND) {
+	sendNum++;
+	if(sendRandPosHead != NULL) {
+           int sendMissPos = sendRandPosHead->randPos;
+           if(sendNum == sendMissPos) {
+	      rand_pos_node_t* tmpNode;
+	      // send will be failed...
+	      elem->num = FALSE;
+	      tmpNode = sendRandPosHead;
+	      sendRandPosHead = sendRandPosHead->next; 
+	      tmpNode->next = NULL;
+	      free(tmpNode);
+	   }
+	}
+	if(sendNum == Module) {
+	   sim_reset_num_and_rand_pos_queue(SEND); 
+	}
+     }
+     else if(elem->eventType == RECEIVE) {
+	receiveNum++;
+	if(receiveRandPosHead != NULL) {
+           int receiveMissPos = receiveRandPosHead->randPos;
+           if(receiveNum == receiveMissPos) {
+	      rand_pos_node_t* tmpNode;
+	      // receive will be failed...
+	      elem->num = FALSE;
+	      tmpNode = receiveRandPosHead;
+	      receiveRandPosHead = receiveRandPosHead->next; 
+	      tmpNode->next = NULL;
+	      free(tmpNode);
+	   }
+	}
+	if(receiveNum == Module) {
+	   sim_reset_num_and_rand_pos_queue(RECEIVE); 
+	}
+     }
+     else {
+	ackNum++;
+	if(ackRandPosHead != NULL) {
+           int ackMissPos = ackRandPosHead->randPos;
+           if(ackNum == ackMissPos) {
+	      rand_pos_node_t* tmpNode;
+	      // ack will be failed...
+	      elem->num = FALSE; 
+	      tmpNode = ackRandPosHead;
+	      ackRandPosHead = ackRandPosHead->next; 
+	      tmpNode->next = NULL;
+	      free(tmpNode);
+	   }
+	}
+	if(ackNum == Module) {
+	   sim_reset_num_and_rand_pos_queue(ACK); 
+	}
+     }
+}
Index: tos/lib/tossim/sim_random_walk_assist.c.old
===================================================================
RCS file: tos/lib/tossim/sim_random_walk_assist.c.old
diff -N tos/lib/tossim/sim_random_walk_assist.c.old
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_random_walk_assist.c.old	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,338 @@
+#include <sim_random_walk_assist.h>
+
+int Module = 10;
+
+int sendNum = 0;
+int receiveNum = 0;
+int ackNum = 0;
+
+rand_pos_node_t* sendRandPosHead = NULL;
+rand_pos_node_t* receiveRandPosHead = NULL;
+rand_pos_node_t* ackRandPosHead = NULL;
+
+/*************************** Tossim walk ****************************/
+bool sim_tossim_assist_random_walk(int rwBound) {
+     int i;
+     sim_reset_for_tossim();
+     for(i = 0; i < rwBound; i++) {
+	int mote = 0;
+	turn_over_steps++;
+	sim_simulate_turn_on_or_off_event(&mote);
+        sim_run_next_event();    
+        sim_property_check(); 
+	if(!node_level_non_determinism) {
+          if(sim_liveness_fulfill()) {
+            dbg("TOSMC", "In tossim assist stage, liveness property is fulfilled!\n");
+	    return TRUE;
+          }
+	}
+     }
+     if(node_level_non_determinism) {
+       if(sim_liveness_fulfill()) {
+         dbg("TOSMC", "In tossim assist stage, liveness property is fulfilled!\n");
+	 return TRUE;
+       }
+     }
+     return FALSE;
+}
+
+// Flattening random walk..... 
+static element_t* sim_flattening_random_choose_element(queue_t* enableQ) {
+     if(queue_size(enableQ) != 0) {
+        int randNum = RandomInt(1, queue_size(enableQ));
+	return (element_t*)sim_queue_get(enableQ, randNum);
+     }
+     dbg("TOSMC", "The enable event pool is empty!\n");
+     return NULL;
+}
+
+// Random walk with Biasing..... 
+//static int sim_random_choose_element_in_same_node(int mote, queue_t* enableQ, bool buggyNodeFlag, bool* priority) {
+static int sim_random_choose_element_in_same_node(int mote, queue_t* enableQ, bool buggyNodeFlag) {
+     int t_start = -1, t_end = -1;
+     int sr_start = -1, sr_end = -1; //record the send and receive position...
+     bool moteProbe = FALSE;  
+
+     if(queue_size(enableQ) != 0) {
+        int i;
+	for(i = 0; i<queue_size(enableQ); i++) {
+	   element_t* elem = (element_t*)sim_queue_get(enableQ, i+1);
+	   if(elem->MoteID == mote) {
+	      if(t_start == -1)
+		 t_start = t_end = i+1;
+	      else 
+		 t_end = i+1;
+
+	      if(elem->eventType == SEND || elem->eventType == RECEIVE) {
+		// compute the send and receive position...
+	        if(sr_start == -1)
+		  sr_start = sr_end = i+1;
+	        else 
+		  sr_end = i+1;
+	      }
+	      moteProbe = TRUE;
+	   }
+	   else {
+	      if(moteProbe)
+		break;
+	   }
+	}
+
+	if(t_start == -1) { 
+	   dbg("TOSMC", "There is no available event for the mote: %d\n", mote); 
+	   return -1;
+	}
+	else {
+	   int randNum = 0;
+	   if(buggyNodeFlag) 
+              randNum = RandomInt(t_start, t_end);
+	   else {
+             if(sr_start == -1) {
+                randNum = RandomInt(t_start, t_end);
+                //*priority = FALSE;
+	     }
+	     else { 
+                randNum = RandomInt(sr_start, sr_end);
+		//*priority = TRUE;
+	     }
+	   }
+	   return randNum;
+	}
+     }
+     dbg("TOSMC", "%s: The enable event pool is empty!\n", __FUNCTION__);
+     return -1;
+}
+
+static element_t* sim_biasing_random_choose_element(queue_t* enableQ) {
+     int mote;
+     uint8_t nodesCandidate[MAX_NODES]; 
+     //uint8_t nodesPriority[MAX_NODES]; 
+     int candNum = 0; 
+     //prioriNum = 0; 
+     element_t* retElem = NULL;
+
+     if(queue_size(enableQ) != 0) {
+       for(mote = 0; mote < MAX_NODES; mote++) {
+          if(sim_mote_status(mote) == ON) {
+             //bool priority = FALSE;
+	     int num = sim_random_choose_element_in_same_node(mote, enableQ, FALSE); 
+
+	     if(num != -1) {
+		//if(priority) 
+		//   nodesPriority[prioriNum++] = num;
+		//else 
+		nodesCandidate[candNum++] = num;
+	     }
+	  }
+       }
+     }
+     // Here, we bias the communication events... 
+     if(prioriNum != 0) {
+        int randNum = RandomInt(0, prioriNum-1);
+        retElem = (element_t*)sim_queue_get(enableQ, nodesPriority[randNum]);
+     }
+     else {
+        if(candNum != 0) {
+          int randNum = RandomInt(0, candNum-1);
+	  retElem = (element_t*)sim_queue_get(enableQ, nodesCandidate[randNum]);
+	}
+	else 
+	  dbg("TOSMC", "%s: The enable event pool is empty!\n", __FUNCTION__);
+     }
+     return retElem;
+}
+
+element_t* sim_random_choose_element(bool buggyNodeFlag) {
+     queue_t* enableQ = sim_element_queue_init();
+     element_t* elem = NULL;
+     element_t* elem_t = NULL;
+
+     sim_find_enabled_event_set(enableQ, FALSE);
+
+     if(buggyNodeFlag) {
+	bool priority = FALSE;
+        int num = sim_random_choose_element_in_same_node(buggy_node, enableQ, TRUE, &priority);
+	if(num != -1)
+	  elem = (element_t*)sim_queue_get(enableQ, num);
+     }
+     else {
+        if(sim_bias_mode) 
+	  elem = sim_biasing_random_choose_element(enableQ);
+        else 
+          elem = sim_flattening_random_choose_element(enableQ);
+     }
+
+     if(elem != NULL) 
+	elem_t = sim_copy_element(elem);
+     // Destroy the enable queue...
+     sim_element_queue_destroy(enableQ);
+     return elem_t;
+}
+
+// For example, sendProb is 0.9, that is, 90% send events will be successful..
+static rand_pos_node_t* sim_allocate_rand_pos_node(int randPos) {
+     rand_pos_node_t* rpn = (rand_pos_node_t*)malloc(sizeof(rand_pos_node_t));
+     rpn->randPos = randPos;
+     rpn->next = NULL;
+     return rpn;
+}
+
+static bool sim_insert_rand_pos_queue(rand_pos_node_t** randPosHead, int randNum) {
+     rand_pos_node_t* rpn = NULL;
+     rand_pos_node_t* randNode = NULL;
+     bool insertSucceed = FALSE;
+
+     if(*randPosHead == NULL) {
+        randNode = sim_allocate_rand_pos_node(randNum);
+        *randPosHead = randNode;
+	return TRUE;
+     }
+     rpn = *randPosHead;
+     while(rpn != NULL) {
+	if(randNum < rpn->randPos) {
+           randNode = sim_allocate_rand_pos_node(randNum);
+	   randNode->next = *randPosHead;
+	   *randPosHead = randNode;
+	   insertSucceed = TRUE;
+	   break;
+	}
+	else if(randNum == rpn->randPos) {
+	   insertSucceed = FALSE;
+	   break;
+	}
+	else {
+           if(rpn->next == NULL) {
+              randNode = sim_allocate_rand_pos_node(randNum);
+	      rpn->next = randNode;
+	      insertSucceed = TRUE;
+	      break;
+	   }
+	   else {
+              if(randNum < rpn->next->randPos) {
+                 randNode = sim_allocate_rand_pos_node(randNum);
+	         randNode->next = rpn->next;
+		 rpn->next = randNode;
+	         insertSucceed = TRUE;
+		 break;
+	      }
+	      else
+		 rpn = rpn->next;
+	   }
+	}
+     }
+     return insertSucceed;
+}
+
+static void sim_clear_rand_pos_queue(rand_pos_node_t** head) {
+     if(*head == NULL)
+	return;
+     while(*head != NULL) {
+	rand_pos_node_t* tmpRpn = *head;
+        *head = (*head)->next;    
+	tmpRpn->next = NULL;
+	free(tmpRpn);
+     }
+}
+
+static void sim_reset_rand_pos_queue(int eventType) {
+     int i, failNum = 0;
+     rand_pos_node_t** randPosHead = NULL;
+
+     switch (eventType) {
+        case SEND:
+	   failNum = sendFailNum;
+           sim_clear_rand_pos_queue(&sendRandPosHead);
+	   randPosHead = &sendRandPosHead;
+	   break;
+	case RECEIVE:
+           failNum = receiveFailNum;
+           sim_clear_rand_pos_queue(&receiveRandPosHead);
+	   randPosHead = &receiveRandPosHead;
+	   break;
+	case ACK:
+           failNum = ackFailNum;
+           sim_clear_rand_pos_queue(&ackRandPosHead);
+	   randPosHead = &ackRandPosHead;
+	   break;
+     }
+
+     for(i = 0; i<failNum; i++) {
+	while(TRUE) {
+          int randNum = RandomInt(1, Module); 
+          if(sim_insert_rand_pos_queue(randPosHead, randNum)) 
+	      break;
+	}
+     }
+}
+
+void sim_reset_num_and_rand_pos_queue(int eventType) {
+     if(eventType == SEND) {
+       sendNum = 0;
+       sim_reset_rand_pos_queue(SEND); 
+     }
+     else if(eventType == RECEIVE) {
+       receiveNum = 0;
+       sim_reset_rand_pos_queue(RECEIVE); 
+     }
+     else {
+       ackNum = 0;
+       sim_reset_rand_pos_queue(ACK); 
+     }
+}
+
+void sim_handle_element_with_loss_probability(element_t* elem) {
+     if(elem->eventType == SEND) {
+	sendNum++;
+	if(sendRandPosHead != NULL) {
+           int sendMissPos = sendRandPosHead->randPos;
+           if(sendNum == sendMissPos) {
+	      rand_pos_node_t* tmpNode;
+	      // send will be failed...
+	      elem->num = FALSE;
+	      tmpNode = sendRandPosHead;
+	      sendRandPosHead = sendRandPosHead->next; 
+	      tmpNode->next = NULL;
+	      free(tmpNode);
+	   }
+	}
+	if(sendNum == Module) {
+	   sim_reset_num_and_rand_pos_queue(SEND); 
+	}
+     }
+     else if(elem->eventType == RECEIVE) {
+	receiveNum++;
+	if(receiveRandPosHead != NULL) {
+           int receiveMissPos = receiveRandPosHead->randPos;
+           if(receiveNum == receiveMissPos) {
+	      rand_pos_node_t* tmpNode;
+	      // receive will be failed...
+	      elem->num = FALSE;
+	      tmpNode = receiveRandPosHead;
+	      receiveRandPosHead = receiveRandPosHead->next; 
+	      tmpNode->next = NULL;
+	      free(tmpNode);
+	   }
+	}
+	if(receiveNum == Module) {
+	   sim_reset_num_and_rand_pos_queue(RECEIVE); 
+	}
+     }
+     else {
+	ackNum++;
+	if(ackRandPosHead != NULL) {
+           int ackMissPos = ackRandPosHead->randPos;
+           if(ackNum == ackMissPos) {
+	      rand_pos_node_t* tmpNode;
+	      // ack will be failed...
+	      elem->num = FALSE; 
+	      tmpNode = ackRandPosHead;
+	      ackRandPosHead = ackRandPosHead->next; 
+	      tmpNode->next = NULL;
+	      free(tmpNode);
+	   }
+	}
+	if(ackNum == Module) {
+	   sim_reset_num_and_rand_pos_queue(ACK); 
+	}
+     }
+}
Index: tos/lib/tossim/sim_random_walk_assist.h
===================================================================
RCS file: tos/lib/tossim/sim_random_walk_assist.h
diff -N tos/lib/tossim/sim_random_walk_assist.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_random_walk_assist.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,16 @@
+#ifndef SIM_RANDOM_WALK_ASSIST_H_INCLUDED
+#define SIM_RANDOM_WALK_ASSIST_H_INCLUDED
+
+typedef struct rand_pos_node rand_pos_node_t;
+
+struct rand_pos_node {
+   int randPos;
+   rand_pos_node_t* next;
+};
+
+bool sim_tossim_assist_random_walk(int rwBound); 
+element_t* sim_random_choose_element(bool buggyNodeFlag);
+void sim_reset_num_and_rand_pos_queue(int eventType); 
+void sim_handle_element_with_loss_probability(element_t* elem); 
+
+#endif
Index: tos/lib/tossim/sim_stateless_no_por.c
===================================================================
RCS file: tos/lib/tossim/sim_stateless_no_por.c
diff -N tos/lib/tossim/sim_stateless_no_por.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_stateless_no_por.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,158 @@
+#include <sim_tossim_assist.h>
+#include <sim_stateless_no_por.h>
+
+int turn_over_steps;
+bool sim_send_check_clear_channel();
+
+static bool sim_exists_same_source_receive(queue_t* queue, int source) {
+    int i;
+    for(i = 0; i<queue_size(queue); i++) {
+        element_t* elem = (element_t*)sim_queue_get(queue, i+1);
+	if(elem->eventType == RECEIVE && elem->source == source) {
+	   return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+static void sim_send_enabled_event_in_mc_running(queue_t* elementQ, sim_event_t* sendEvt) {
+    element_t* trueElem = sim_allocate_element(sendEvt->mote, SEND, sendEvt->source, sendEvt->mark); // mark should implicitly be TRUE;
+    sim_element_queue_insert(elementQ, trueElem);
+      
+    if(sendEvt->source == BACKOFF && sim_loss_mode != NOLOSS) {
+       // Actually, explicitly mark is true...
+       element_t* falseElem = sim_allocate_element(sendEvt->mote, SEND, sendEvt->source, FALSE); 
+       sim_element_queue_insert(elementQ, falseElem);
+    }
+}
+
+static void sim_send_enabled_event_set(queue_t* elementQ, sim_event_t* sendEvt) {
+    if(sendEvt->source == BACKOFF || (sendEvt->source == TRANSMITDONE && sim_is_all_neighbor_transmit(sendEvt->mote))) {
+
+       if(sim_loss_mode != LOSS_WITH_NOISE) {
+          sim_send_enabled_event_in_mc_running(elementQ, sendEvt);
+       }
+       else {
+	  if(mc_state == MC_RUNNING) {
+             sim_send_enabled_event_in_mc_running(elementQ, sendEvt);
+	  }
+	  else {
+             element_t* sendElement = NULL;
+  	     if(sendEvt->source == BACKOFF) {
+	       // In noise support mode, use "sim_send_check_clear_channel()" as auxiliary function 
+	       // to decide the success of send backoff event...  
+	       // Note that we only consider the send event when it is in Backoff stage...  
+	       if(sim_send_check_clear_channel()) 
+                 sendElement = sim_allocate_element(sendEvt->mote, SEND, BACKOFF, TRUE);
+	       else
+                 sendElement = sim_allocate_element(sendEvt->mote, SEND, BACKOFF, FALSE);
+               sim_element_queue_insert(elementQ, sendElement);
+	     }
+	     else {
+               sendElement = sim_allocate_element(sendEvt->mote, SEND, TRANSMITDONE, TRUE);
+               sim_element_queue_insert(elementQ, sendElement);
+	     }
+	  }
+       }
+    }
+}
+
+static void sim_receive_enabled_event_set(queue_t* elementQ, sim_event_t* receiveEvt) {
+     element_t* trueElem = sim_allocate_element(receiveEvt->mote, RECEIVE, receiveEvt->source, receiveEvt->mark);
+     sim_element_queue_insert(elementQ, trueElem);
+
+     if(sim_loss_mode != NOLOSS) {
+       if(receiveEvt->mark == TRUE) {
+	 element_t* falseElem = sim_allocate_element(receiveEvt->mote, RECEIVE, receiveEvt->source, FALSE);
+	 sim_element_queue_insert(elementQ, falseElem);
+       }
+     }
+}
+
+void sim_find_other_enabled_event_set(int mote, queue_t* elementQ, bool Flag) {
+    int i;
+    element_t* backElement = NULL;
+
+    if(queue_size(nodeEqs[mote].SchedulerQ) != 0) {
+       sim_event_t* evt = (sim_event_t*)sim_queue_get(nodeEqs[mote].SchedulerQ, 1);
+
+       backElement = sim_allocate_element(evt->mote, SCHEDULER, evt->source, evt->mark);    
+       sim_element_queue_insert(elementQ, backElement);
+    }
+
+    for(i = 0; i < VECTOR_SIZE; i++) {
+       if(nodeEqs[mote].InterruptSet[i] != NULL) {
+	  sim_event_t* evt = (sim_event_t*)nodeEqs[mote].InterruptSet[i];
+	  if(evt->mark == TRUE) {
+            backElement = sim_allocate_element(evt->mote, INTERRUPT, evt->source, TRUE);
+	    sim_element_queue_insert(elementQ, backElement);
+	  }
+       }
+    }
+
+    if(mc_state == MC_RUNNING && alarmSet[mote]) {
+      if(heap_size(nodeEqs[mote].TimerH) != 0) {
+        backElement = sim_allocate_element(mote, TIMER, 0, TRUE);    
+        sim_element_queue_insert(elementQ, backElement);
+      }
+    }
+   
+    if(queue_size(nodeEqs[mote].GeneralQ) != 0) {
+       sim_event_t* evt = (sim_event_t*)sim_queue_get(nodeEqs[mote].GeneralQ, 1);
+       backElement = sim_allocate_element(evt->mote, GENERAL, evt->source, evt->mark);
+       sim_element_queue_insert(elementQ, backElement);
+    }
+
+    if(queue_size(nodeEqs[mote].SendQ) != 0) {
+       sim_event_t* sendEvt = (sim_event_t*)sim_queue_get(nodeEqs[mote].SendQ, 1);
+       sim_send_enabled_event_set(elementQ, sendEvt);
+    }
+
+    if(queue_size(nodeEqs[mote].ReceiveQ) != 0) {
+       sim_event_t* receiveEvt = (sim_event_t*)sim_queue_get(nodeEqs[mote].ReceiveQ, 1);
+
+       if(Flag == TRUE) {
+         if(!sim_exists_same_source_receive(elementQ, receiveEvt->source)) {
+           sim_receive_enabled_event_set(elementQ, receiveEvt);
+         }
+       }
+       else {
+	 sim_receive_enabled_event_set(elementQ, receiveEvt);
+       }
+    }
+
+    if(mc_state == RANDOM_WALK) {
+      if(heap_size(nodeEqs[mote].TimerH) != 0) {
+        backElement = sim_allocate_element(mote, TIMER, 0, TRUE);    
+        sim_element_queue_insert(elementQ, backElement);
+      }
+    }
+}
+
+void sim_find_enabled_event_set(queue_t* elementQ, bool Flag) {
+     int mote = 0; 
+     element_t* bootElement = NULL;
+     bool turnOver = sim_simulate_turn_on_or_off_event(&mote);
+
+     if(turnOver) {
+       if(nodeEqs[mote].BootEvt != NULL) {
+	  sim_event_t* BootEvt = (sim_event_t*)nodeEqs[mote].BootEvt;
+          bootElement = sim_allocate_element(mote, BOOT, BootEvt->source, TRUE);
+          sim_element_queue_insert(elementQ, bootElement);
+       }
+     }
+     else {
+       for(mote = 0; mote < MAX_NODES; mote++) {
+           if(nodeEqs[mote].Status == ACTIVE) { 
+	     // "mote" is chosen as one of the simulated motes, but not booted yet..
+	     sim_event_t* BootEvt = (sim_event_t*)nodeEqs[mote].BootEvt;
+             bootElement = sim_allocate_element(mote, BOOT, BootEvt->source, TRUE);
+             sim_element_queue_insert(elementQ, bootElement);
+           }
+           else {
+	     if(nodeEqs[mote].Status == ON)
+               sim_find_other_enabled_event_set(mote, elementQ, Flag); 
+           }
+         }
+     }
+}
Index: tos/lib/tossim/sim_stateless_no_por.h
===================================================================
RCS file: tos/lib/tossim/sim_stateless_no_por.h
diff -N tos/lib/tossim/sim_stateless_no_por.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_stateless_no_por.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,6 @@
+#ifndef SIM_STATELESS_NO_POR_H_INCLUDED
+#define SIM_STATELESS_NO_POR_H_INCLUDED
+
+void sim_find_enabled_event_set(queue_t* enabledQ, bool Flag);
+
+#endif
Index: tos/lib/tossim/sim_stateless_sleep_reduce.c
===================================================================
RCS file: tos/lib/tossim/sim_stateless_sleep_reduce.c
diff -N tos/lib/tossim/sim_stateless_sleep_reduce.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_stateless_sleep_reduce.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,221 @@
+#include <sim_stateless_no_por.h>
+#include <sim_gain.h>
+
+enum { DFALSE = 0, DTRUE, DEQUAL };
+
+/* function for determining whether two motes are neighbors */
+static bool sim_is_neighbor(int source, int other) {
+     gain_entry_t* neighbor = sim_gain_first(source);
+     while(neighbor != NULL) {
+	 if(neighbor->mote == other)
+	    return TRUE;  
+	 neighbor = sim_gain_next(neighbor);
+     }
+     return FALSE;
+}
+
+static bool sim_same_mote_send_receive_relation(element_t* element1, element_t* element2) {
+     bool dependency = FALSE;
+
+     if(element1->eventType == SEND) {
+	 if(element2->eventType == SEND) {
+	    dependency = TRUE;
+	 }
+	 else if(element2->eventType == RECEIVE) {
+	     if(element1->num == TRUE && element2->num == TRUE) 
+                 dependency = TRUE;		 
+	     else 
+		 dependency = FALSE;
+	 }
+	 else
+             dependency = TRUE;
+     }
+
+     if(element1->eventType == RECEIVE) {
+         if(element2->eventType == RECEIVE) 
+	     dependency = TRUE;
+	 else if(element2->eventType == SEND) {
+	     if(element1->num == TRUE && element2->num == TRUE) 
+                 dependency = TRUE;		 
+	     else 
+		 dependency = FALSE;
+	 }
+	 else 
+	    dependency = TRUE;
+     }
+
+     return dependency;
+}
+
+static int sim_dependency_in_same_mote(element_t* elem1, element_t* elem2) {
+     bool dependency = DFALSE;
+
+     switch(elem1->eventType) {
+	 case BOOT:
+             // if the elem1 is BOOT event, there is no chance to meet other events ...
+	     break;
+	 case SCHEDULER:
+             // in same mote, scheduler event is dependent with other events...
+	     dependency = DTRUE;
+	     break;
+	 case SEND:
+             if(elem2->eventType == SEND) 
+	         // both send alternatives meet together...
+		 dependency = DEQUAL; 
+	     else 
+		 // For other events, they are all dependent...
+	         dependency = DTRUE; 
+	     break;
+         case RECEIVE:
+             if(elem2->eventType == RECEIVE) 
+	         // both receive alternatives meet together...
+		 dependency = DEQUAL; 
+	     else 
+		 // For other events, they are all dependent...
+	         dependency = DTRUE; 
+	     break;
+         case TIMER:
+             // in same mote, timer event is always dependent with other events...
+	     dependency = DTRUE;
+	     break;
+	 case INTERRUPT:
+	     dependency = DTRUE; 
+	     break;
+     }
+     return dependency;
+}
+
+static int sim_dependency_in_different_mote(element_t* elem1, element_t* elem2) {
+     bool dependency = DFALSE;
+
+     switch(elem1->eventType) {
+	 case BOOT:
+            if(sim_is_neighbor(elem1->MoteID, elem2->MoteID)) {
+	       if(elem2->eventType == SEND && elem2->source == BACKOFF)
+	          dependency = DTRUE;
+	    }
+	    break;
+	 case SEND:
+	    if(elem2->eventType == BOOT) {
+               if(sim_is_neighbor(elem1->MoteID, elem2->MoteID)) {
+	          dependency = DTRUE;
+	       }
+	    }
+	    if(elem2->eventType == RECEIVE) {
+	       if(sim_is_neighbor(elem1->MoteID, elem2->MoteID)) {
+	          dependency = DTRUE;
+	       }
+	    }
+	    break;
+	  case RECEIVE:
+	    if(elem2->eventType == SEND) {
+	       if(sim_is_neighbor(elem1->MoteID, elem2->MoteID)) {
+	          dependency = DTRUE;
+	       }
+	    }
+	    break;
+	 case SCHEDULER:
+	 case GENERAL:
+	 case TIMER:
+	 case INTERRUPT:
+	 default:
+	   break;
+     }
+
+     return dependency;
+}
+
+/* dependent table */
+static bool sim_elements_dependent(element_t* elem1, element_t* elem2){
+      bool dependency = FALSE;
+
+      if(elem1->MoteID == elem2->MoteID) {
+          switch(sim_dependency_in_same_mote(elem1, elem2)) {
+	      case DFALSE:
+	          break;
+	      case DTRUE:
+		  dependency = TRUE;
+		  break;
+	      case DEQUAL:
+		  dependency = TRUE;
+		  break;
+	  }
+      }
+      else {
+          switch(sim_dependency_in_different_mote(elem1, elem2)) {
+	      case DFALSE:
+	          break;
+	      case DTRUE:
+		  dependency = TRUE;
+		  break;
+	  }
+      }
+
+      return dependency;
+}
+
+/* based on the dependence table, we can find the new sleep set, which
+ * is composed of events independent with the element */
+queue_t* sim_find_sleep_set(queue_t* sleepSet, element_t* element) {
+      if(sleepSet == NULL) {
+          dbg("TOSMC", "The sleep set is NULL!\n"); 
+	  return NULL;
+      }
+      else {
+	  int i;
+          int size = queue_size(sleepSet);
+          queue_t* newSleepSet = sim_element_queue_init();
+
+	  for(i = 0; i<size; i++) {
+	     element_t* elementT = (element_t*)sim_queue_get(sleepSet, i+1);
+             
+	     if(!sim_element_is_equal(element, elementT)) {
+               if(!sim_elements_dependent(element, elementT)) {
+                 element_t* ano_element = sim_allocate_element(elementT->MoteID, elementT->eventType, elementT->source, elementT->num);
+                 sim_element_queue_insert(newSleepSet, ano_element);
+	       }
+	     }
+	  }
+	  return newSleepSet;
+      }
+}
+
+void sim_sleep_set_insert(queue_t* sleepSet, element_t* elem) {
+      if(elem->eventType == SEND && elem->source == BACKOFF && elem->num == FALSE) {
+          sim_free_element(elem);
+	  return;
+      }
+      if(elem->eventType == RECEIVE && elem->num == FALSE) {
+          sim_free_element(elem);
+	  return;
+      }
+      sim_element_queue_insert(sleepSet, elem);
+}
+
+queue_t* sim_find_enabled_set(queue_t* persistentSet, queue_t* sleepSet) {
+      if(persistentSet == NULL || sleepSet == NULL){
+         return NULL;
+      }
+      else {
+         int sleep_size = queue_size(sleepSet);
+         queue_t* enabledSet = NULL;
+
+         if(sleep_size == 0) {
+            enabledSet = persistentSet;
+	    return enabledSet;
+         }
+	 enabledSet = sim_element_queue_init();
+
+         while(!queue_is_empty(persistentSet)) {
+            element_t* element = sim_element_queue_pop(persistentSet);
+	    if(element != NULL) {
+	       if(sim_element_in_queue(sleepSet, element)) 
+		  sim_free_element(element);
+	       else 
+	          sim_element_queue_insert(enabledSet, element);
+            }
+         }
+         free(persistentSet);
+         return enabledSet;
+     }
+}
Index: tos/lib/tossim/sim_stateless_sleep_reduce.h
===================================================================
RCS file: tos/lib/tossim/sim_stateless_sleep_reduce.h
diff -N tos/lib/tossim/sim_stateless_sleep_reduce.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_stateless_sleep_reduce.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,10 @@
+#ifndef SIM_STATELESS_SLEEP_REDUCE_H_INCLUDED
+#define SIM_STATELESS_SLEEP_REDUCE_H_INCLUDED
+
+#include <sim_transition.h>
+
+queue_t* sim_find_sleep_set(queue_t* sleepSet, element_t* element);
+void sim_sleep_set_insert(queue_t* sleepSet, element_t* elem);
+queue_t* sim_find_enabled_set(queue_t* persistentSet, queue_t* sleepSet);
+
+#endif
Index: tos/lib/tossim/sim_statistic_info.c
===================================================================
RCS file: tos/lib/tossim/sim_statistic_info.c
diff -N tos/lib/tossim/sim_statistic_info.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_statistic_info.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,200 @@
+#include <sim_statistic_info.h>
+
+static bool set_deviation = FALSE;
+static uint32_t event_explored_min = 0;
+static uint32_t event_explored_sqr = 0;
+static uint32_t event_explored_avg = 0;
+
+static void sim_output_transition_trace(queue_t* rwPath, int length) {
+  int i;
+  for(i = 0; i < length; i++) {
+    transition_t* trans = (transition_t*)sim_queue_get(rwPath, i+1);
+    sim_output_element_in_debugging(trans->vis_execution);
+    sim_one_transition_re_execute(trans);
+  }
+}
+
+void sim_log_safety_violating_path(queue_t* rwPath) {
+  char changedName[256];
+  sprintf(changedName, "SafetyViolating%d.txt", path+1);
+  safetyViolateFile = fopen(changedName, "w+");
+
+  if(safetyViolateFile) {
+     dbg("TOSMC", "Safety violating file opening successful!\n");
+
+     whichFile = safetyViolateFile;
+     sim_reset_and_re_execute(FALSE); // Here, the argument could be TRUE or FALSE.
+     if(rwPath != NULL) {
+       int qSize = queue_size(rwPath); 
+       sim_output_transition_trace(rwPath, qSize);
+     }
+     fclose(safetyViolateFile);
+     safetyViolateFile = NULL;
+     whichFile = NULL;
+  }
+  else
+     dbg("TOSMC", "Safety violating file opening failure!\n");
+}
+
+void sim_log_liveness_fulfillment(char* sentence) {
+   liveFulfillFile = fopen("LivenessFulfill.txt", "a+");
+   if(liveFulfillFile) { 
+      fputs(sentence, liveFulfillFile);
+      fclose(liveFulfillFile);
+      liveFulfillFile = NULL;
+   }
+}
+
+void sim_log_liveness_violating_path(char* sentence, queue_t* rwPath, bool critical, int position) {
+   char changedName[256];
+   sprintf(changedName, "LiveViolating%d.txt", path+1);
+   liveViolateFile = fopen(changedName, "a+");
+   
+   if(liveViolateFile) {
+     dbg("TOSMC", "Liveness violating file opening successful!\n");
+     fputs(sentence, liveViolateFile);
+
+     if(rwPath != NULL) {
+       whichFile = liveViolateFile;
+       sim_reset_and_re_execute(FALSE); // Here, the argument must be FALSE;
+
+       if(critical) {
+	 transition_t* trans = NULL;
+         sim_output_transition_trace(rwPath, position-1);
+
+         fputs("The critical transition shows below:\n", liveViolateFile);
+         trans = (transition_t*)sim_queue_get(rwPath, position);
+         sim_output_element_in_debugging(trans->vis_execution);
+         sim_one_transition_re_execute(trans);
+       }
+       else {
+         sim_output_transition_trace(rwPath, position);
+       }
+     }
+     fclose(liveViolateFile);
+     liveViolateFile = NULL;
+     whichFile = NULL;
+   }
+   else
+     dbg("TOSMC", "Liveness violating file opening failure!\n");
+}
+
+/********************* Compute the safety error consumption ***********************/
+// Userd as the safety bugs testing...
+void sim_safety_report_statistics_data() __attribute__ ((C, spontaneous)) {
+   //Here, we just consider to statistic data
+   long int eclipse = 0;
+   statisticFile = fopen("StatisticData.txt", "a+");
+
+   if(statisticFile) {
+     gettimeofday(&tossimEtv, NULL);
+     eclipse = tossimEtv.tv_sec - tossimStv.tv_sec;
+     fprintf(statisticFile, "This safety bug is caught in the %d path, and %d stage\n", (path+1), mc_state);
+     fprintf(statisticFile, "Until the occurance of this safety bug, the %u transitions in one path have explored\n", transition_explored);
+     fprintf(statisticFile, "Until the occurance of this safety bug, the %u events in one path have explored\n", event_explored);
+
+     transition_explored_sum += transition_explored;
+     event_explored_sum += event_explored;
+     if(set_deviation) {
+	 event_explored_sqr += event_explored * event_explored;
+	 if(event_explored_min == 0)
+            event_explored_min = event_explored;
+	 else {
+	    if(event_explored < event_explored_min)
+	      event_explored_min = event_explored;
+	 }
+     }
+
+     fprintf(statisticFile, "Until the occurance of this safety bug, total %u transitions have explored\n", transition_explored_sum);
+     fprintf(statisticFile, "Until the occurance of this safety bug, total %u events have explored\n", event_explored_sum);
+
+     transition_explored = 0;
+     event_explored = 0;
+
+     if(eclipse == 0) {
+       eclipse = tossimEtv.tv_usec - tossimStv.tv_usec;
+       fprintf(statisticFile, "From the start point to this safety bug point, the eclipsed time is %ld ms\n", eclipse);
+     }
+     else {
+       fprintf(statisticFile, "From the start point to this safety bug point, the eclipsed time is %ld s\n", eclipse);
+     }
+
+     fputs("\n\n\n", statisticFile);
+     fclose(statisticFile);
+   }
+   gettimeofday(&tossimStv, NULL);
+}
+
+/********************* Compute the whole process resource consumption ***********************/
+// Userd as the POR vs no-POR
+void sim_start_statistic_whole_process(int type, int mc_bound) {
+   statisticFile = fopen("StatisticData.txt", "a+");
+   if(statisticFile) {
+      if(type == 0) {
+        fprintf(statisticFile, "Let's start the DFS here, mc_bound is %d!\n", mc_bound);
+      }
+      else {
+        fprintf(statisticFile, "Let's start the DFSPOR here, mc_bound is %d!\n", mc_bound);
+      }
+   }
+}
+
+void sim_finish_statistic_whole_process() {
+   long int eclipse = 0;
+   double substract = 0; 
+   uint32_t deviation = 0;
+
+   sim_sum_event_transition_explored();
+   statisticFile = fopen("StatisticData.txt", "a+");
+
+   if(statisticFile) {
+     gettimeofday(&tosmcEtv, NULL);
+     eclipse = tosmcEtv.tv_sec - tosmcStv.tv_sec;
+     fprintf(statisticFile, "At the end, the %u path have explored\n", path+1);
+     fprintf(statisticFile, "At the end, the %u random walk path have explored\n", rw_path);
+     // Used as the statistics for comparison of POR and Non-POR...
+     fprintf(statisticFile, "At the end, total %u transitions have explored\n", transition_explored_sum);
+     fprintf(statisticFile, "At the end, total %u events have explored\n", event_explored_sum);
+
+     if(set_deviation) {
+       event_explored_avg = event_explored_sum / rw_rounds;
+       substract = event_explored_sqr/rw_rounds - event_explored_avg * event_explored_avg;  
+       deviation = (uint32_t)sqrt(substract/rw_rounds);
+
+       fprintf(statisticFile, "After the test, the average steps is %u\n", event_explored_avg);
+       fprintf(statisticFile, "The standard deviation is %u\n", deviation);
+       fprintf(statisticFile, "The min step is %u\n", event_explored_min);
+     }
+
+     if(eclipse == 0) {
+       eclipse = tosmcEtv.tv_usec - tosmcStv.tv_usec;
+       fprintf(statisticFile, "From the start poin to end point, the eclipsed time is %ld ms\n", eclipse);
+     }
+     else 
+       fprintf(statisticFile, "From the start poin to end point, the eclipsed time is %ld s\n", eclipse);
+     fputs("\n\n\n", statisticFile);
+     fclose(statisticFile);
+   }
+}
+
+/********************** Compute the explored transition or event **************************/
+void sim_set_statistic_deviation() {
+   set_deviation = TRUE;
+}
+
+void sim_increase_transition_explored_number() {
+     transition_explored++;
+}
+
+void sim_increase_event_explored_number() {
+     event_explored++;
+}
+
+void sim_sum_event_transition_explored() {
+    if(stats_state == MC_AND_RW) {
+       transition_explored_sum += transition_explored;
+       event_explored_sum += event_explored;
+    }
+    transition_explored = 0;
+    event_explored = 0;
+}
Index: tos/lib/tossim/sim_statistic_info.h
===================================================================
RCS file: tos/lib/tossim/sim_statistic_info.h
diff -N tos/lib/tossim/sim_statistic_info.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_statistic_info.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,18 @@
+#ifndef SIM_STATISTIC_INFO_H_INCLUDED
+#define SIM_STATISTIC_INFO_H_INCLUDED
+
+void sim_log_safety_violating_path(queue_t* rwPath);
+void sim_log_liveness_fulfillment(char* sentence);
+void sim_log_liveness_violating_path(char* sentence, queue_t* rwPath, bool critical, int position);
+
+void sim_safety_report_statistics_data();
+void sim_start_statistic_whole_process();
+void sim_finish_statistic_whole_process();
+
+void sim_set_statistic_deviation();
+void sim_increase_transition_explored_number();
+void sim_increase_event_explored_number();
+void sim_sum_event_transition_explored();
+
+
+#endif
Index: tos/lib/tossim/sim_tossim.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_tossim.c,v
retrieving revision 1.8
diff -u -b -p -r1.8 sim_tossim.c
--- tos/lib/tossim/sim_tossim.c	29 Jun 2010 22:07:51 -0000	1.8
+++ tos/lib/tossim/sim_tossim.c	9 Jul 2010 19:45:16 -0000
@@ -44,16 +44,142 @@
 #include <sim_event_queue.h>
 #include <sim_mote.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <sys/time.h>
+#include <sim_property_check.h>
+#include <sim_depth_first_search.h>
+#include <sim_random_walk.h>
+#include <sim_stateless_no_por.h>
+#include <sim_statistic_info.h>
+#include <randomlib.h>
+
+#include <atm128hardware.h>
+#include <atm128_sim.h>
 
 #include <sim_noise.h> //added by HyungJune Lee
 
 static sim_time_t sim_ticks;
-static unsigned long current_node;
 static int sim_seed;
+static unsigned long current_node;
+
+static sim_time_t _mc_sim_ticks;
+static unsigned long _mc_current_node;
+static int _mc_sim_seed;
+
+static bool mem_safety_bug_occur = FALSE;
+// Suppose the number of user-specified properties can not be over 100;
+static bool user_safety_bug_occur[100];
+static bool liveness_fulfill[100];
+static uint8_t propertyNum; // We believe the property number will not be over 100;
+// This variable pinpoints the source of safety bug, the memory safety violation or user-specified safety violation...
+static int safety_bug_source; // 0, memory bug; 1 ..., represents the sequence of user-specified property 
+static int liveness_bug_source; // what the specific liveness property currently being checked is 
+// This array records which user-specified liveness properties are eventually fulfilled or violated, guiding which properties should be further traced down to find critical transitions. 
+static bool liveness_status[100];
+
+static int MC_BOUND;
+static int RW_BOUND;
+// For calculating some values...
+uint32_t transition_explored_sum = 0;
+uint32_t event_explored_sum = 0;
+uint32_t transition_explored = 0;
+uint32_t event_explored = 0;
+uint32_t path = 0;
+uint32_t steps = 0;
+uint32_t rw_path = 0; 
+uint32_t rw_rounds = 0; 
+/**********************************/
+
+// Variables set in python driver programs....
+int delta_debugging;
+int sim_loss_mode;
+int sim_bias_mode;
+int sim_tossim_mode;
+
+double sendProb;
+double receiveProb;
+double ackProb;
+
+int sendFailNum;
+int receiveFailNum;
+int ackFailNum;
+
+// # of steps explored in Tossim phase...
+int tossim_step;
+// # of steps explored to guide the node-level non-determinism ..
+int turn_over_steps = 0;
+
+static sim_event_t* tRcvEvt = NULL;
+element_t* _mc_element;
+queue_t* Transition_Stack;
+node_status_t _mc_status[MAX_NODES];
+event_queue_set_t nodeEqs[MAX_NODES];
+queue_t* _mc_nodeEqs;
+bool node_level_non_determinism = FALSE;
+// Recording the neighboring status to guide transimission...
+neighbor_info_t* neighborHead[MAX_NODES];
+neighbor_info_t* _mc_neighborHead[MAX_NODES];
+uint8_t _mc_atm128RegFile[TOSSIM_MAX_NODES][0xa0];
+queue_t* InjectSet;
+
+uint8_t total_simulated_mote_num;
+uint8_t _mc_total_simulated_mote_num;
+
+// Current state ...
+uint8_t mc_state;
+uint8_t stats_state = 0;
+unsigned long buggy_node;
+bool C_TIMER[MAX_NODES];
+bool C_TMP_TIMER[MAX_NODES];     
+bool alarmSet[MAX_NODES];
+bool _mc_alarmSet[MAX_NODES];
+
+struct timeval tossimStv, tossimEtv;
+struct timeval tosmcStv, tosmcEtv;
+
+FILE* statisticFile = NULL;
+FILE* safetyViolateFile = NULL;
+FILE* liveFulfillFile = NULL;
+FILE* liveViolateFile = NULL;
+FILE* whichFile = NULL;
 
 static int __nesc_nido_resolve(int mote, char* varname, uintptr_t* addr, size_t* size);
 
+/******** Beyond the tossim execution, turn on or off the mote  ********/
+uint8_t sim_max_mote_num() __attribute__ ((C, spontaneous)) {
+   return MAX_NODES; 
+}
+
+uint8_t sim_simulated_mote_num() __attribute__ ((C, spontaneous)) {
+   return total_simulated_mote_num; 
+}
+
+uint8_t sim_mote_status(int mote) __attribute__ ((C, spontaneous)) {
+   return nodeEqs[mote].Status; 
+}
+
+void sim_signal_turn_on_mote() __attribute__ ((C, spontaneous)) {
+   nodeEqs[sim_node()].Status = ON; 
+}
+
+void sim_signal_turn_off_mote() __attribute__ ((C, spontaneous)) {
+   nodeEqs[sim_node()].Status = OFF; 
+}
+
+/******** MC register operation ****************/
+void sim_mc_register_copy(int node) {
+   memcpy(_mc_atm128RegFile[node], atm128RegFile[node], sizeof(atm128RegFile[node]));
+}
+
+void sim_mc_register_copyback(int node) {
+   memcpy(atm128RegFile[node], _mc_atm128RegFile[node], sizeof(atm128RegFile[node]));
+}
+
+void sim_clear_register(int node) {
+   memset(atm128RegFile[node], 0, sizeof(atm128RegFile[node]));
+}
+
+/* it will be called by the init function of tossim.c*/
 void sim_init() __attribute__ ((C, spontaneous)) {
   sim_queue_init();
   sim_log_init();
@@ -77,11 +203,107 @@ void sim_init() __attribute__ ((C, spont
   } 
 }
 
+/***************************** Some functions related to the python driver *****************************/
+static void sim_init_safety_liveness_related_variables() {
+  uint8_t i;
+  mem_safety_bug_occur = FALSE;
+  safety_bug_source = -1;
+  liveness_bug_source = -1;
+
+  for(i = 0; i<100; i++) {
+     user_safety_bug_occur[i] = FALSE;
+     liveness_fulfill[i] = FALSE;
+     liveness_status[i] = FALSE;
+  }
+}
+
+static void sim_safety_liveness_status_clearance() {
+    uint8_t i;
+    safety_bug_source = -1;
+    liveness_bug_source = -1;
+    for(i = 0; i < propertyNum; i++) 
+       liveness_status[i] = FALSE;
+}
+
+static void sim_safety_liveness_clearance() {
+    uint8_t i;
+    mem_safety_bug_occur = FALSE;
+    for(i = 0; i<propertyNum; i++) {
+      user_safety_bug_occur[i] = FALSE;
+      liveness_fulfill[i] = FALSE;
+    }
+}
+
+/* it is to tell the model checker the number of motes in the network */
+void sim_init_mote_num(int moteNum, int propertyCount) __attribute__ ((C, spontaneous)) {
+  total_simulated_mote_num = moteNum;
+  mc_state = TOSSIM_RUNNING;
+  tossim_step = 0;
+
+  sim_init_safety_liveness_related_variables();
+  propertyNum = (uint8_t)propertyCount;
+  sim_init_neighbor_head();
+  sim_init_event_queue_set();
+  sim_init_inject_set(); 
+}
+
+void sim_set_delta_debugging(int delta) __attribute__ ((C, spontaneous)) {
+  delta_debugging = delta;
+}
+
+void sim_set_loss_bias_tossim(int loss_mode, int bias_mode, int tossim_mode) __attribute__ ((C, spontaneous)) {
+  sim_loss_mode = loss_mode;
+  sim_bias_mode = bias_mode;
+  sim_tossim_mode = tossim_mode;
+}
+
+void sim_mc_mote_revival(int mote, int turnOverStep) __attribute__ ((C, spontaneous)) {
+  _mc_status[mote].boot_chosen = TRUE;
+  _mc_status[mote].turnOnStep = turnOverStep;
+}
+
+void sim_mc_mote_death(int mote, int turnOverStep) __attribute__ ((C, spontaneous)) {
+  _mc_status[mote].boot_chosen = TRUE;
+  _mc_status[mote].turnOffStep = turnOverStep;
+}
+
+void sim_mc_mote_reboot(int mote, int turnOverStep) __attribute__ ((C, spontaneous)) {
+  _mc_status[mote].boot_chosen = TRUE;
+  _mc_status[mote].rebootStep = turnOverStep;
+}
+
+void sim_set_send_probability(double prob) __attribute__ ((C, spontaneous)) {
+  sendProb = prob; 
+  sendFailNum = 10*(1-sendProb);
+}
+
+void sim_set_receive_probability(double prob) __attribute__ ((C, spontaneous)) {
+  receiveProb = prob; 
+  receiveFailNum = 10*(1-receiveProb); 
+}
+
+void sim_set_ack_probability(double prob) __attribute__ ((C, spontaneous)) {
+  ackProb = prob; 
+  ackFailNum = 10*(1-ackProb);
+}
+
+/*****************************************************************************************************/
 void sim_end() __attribute__ ((C, spontaneous)) {
   sim_queue_init();
 }
 
+void sim_alarm_set() __attribute__ ((C, spontaneous)) {
+   alarmSet[sim_node()] = TRUE;
+}
 
+void sim_alarm_timer_signal() __attribute__ ((C, spontaneous)) {
+   C_TMP_TIMER[sim_node()] = FALSE;
+   alarmSet[sim_node()] = FALSE;
+}
+
+void sim_timer0_compare_signal() __attribute__ ((C, spontaneous)) {
+   C_TIMER[sim_node()] = FALSE;     
+}
 
 int sim_random() __attribute__ ((C, spontaneous)) {
   uint32_t mlcg,p,q;
@@ -126,6 +348,68 @@ void sim_set_node(unsigned long node) __
   TOS_NODE_ID = node;
 }
 
+/******************************* when tossim_step: 0, reset other info of motes ********************/
+static void sim_restore_zero_mc_state() {
+    int i;
+    for(i = 0; i<MAX_NODES; i++) {
+       if(_mc_status[i].status != UNACTIVE) {
+         nodeEqs[i].Status = UNACTIVE;
+	 sim_clear_register(i);
+	 sim_turn_off_clearance(i);
+         sim_mc_status_copyback(i);
+         sim_reset_all_neighbor_status(i);
+       }
+    }
+}
+
+/* reset all motes to initial state, in which all of the motes are in the boot state */
+static void sim_reset_system_to_initial_state() {
+     int i;
+     //Here, to restore the original noise setting....
+     sim_restore_zero_mc_state();
+     sim_noise_copyback();
+
+     for(i = 0; i < MAX_NODES; i++) {   
+	 if(nodeEqs[i].Status != UNACTIVE) {
+	   sim_mote_reset(i);
+	   sim_mote_set_start_time(i, nodeEqs[i].StartTime);
+	   sim_mote_enqueue_boot_event(i);
+	 }
+         C_TIMER[i] = TRUE;
+	 C_TMP_TIMER[i] = TRUE;
+	 alarmSet[i] = FALSE;
+     }
+     sim_copyback_from_inject_set();
+}
+
+/************************** Various event execution driving functions ****************/
+static void sim_clear_tmp_receive_event() {
+     if(tRcvEvt != NULL) {
+        sim_cleanup_event_receive_message(tRcvEvt);
+        tRcvEvt->cleanup(tRcvEvt);
+        tRcvEvt = NULL;
+     }
+}
+
+static void sim_set_mc_element(element_t* elem) {
+    _mc_element = elem;
+}
+
+void sim_set_mc_element_num(int mark) __attribute__ ((C, spontaneous)) {
+    _mc_element->num = mark; 
+}
+
+void sim_property_check() {
+#ifdef SAFETY
+      sim_safety_property_check();
+#endif
+
+#ifdef LIVENESS
+      sim_liveness_property_check();
+#endif
+}
+
+/* original function for running next event, called by runNextEvent of tossim.c */
 bool sim_run_next_event() __attribute__ ((C, spontaneous)) {
   bool result = FALSE;
   if (!sim_queue_is_empty()) {
@@ -141,6 +425,9 @@ bool sim_run_next_event() __attribute__ 
       result = TRUE;
       dbg_clear("Tossim", " mote is on (or forced event), run it.\n");
       event->handle(event);
+
+      if(mc_state == TOSSIM_RUNNING)
+         tossim_step++;
     }
     else {
       dbg_clear("Tossim", "\n");
@@ -153,6 +440,548 @@ bool sim_run_next_event() __attribute__ 
   return result;
 }
 
+bool sim_run_specific_event(void* event) {
+    bool result = FALSE;
+    sim_event_t* evt = (sim_event_t*)event;
+    
+    if(evt != NULL) {
+      sim_set_time(evt->time);
+      sim_set_node(evt->mote);
+
+      dbg("Tossim", "CORE: popping event 0x%p for %i at %llu with handler %p... \n", evt, sim_node(), sim_time(), evt->handle);
+      if ((sim_mote_is_on(evt->mote) || evt->force) && evt->handle != NULL) {
+         result = TRUE;
+         dbg_clear("Tossim", " mote is on (or forced event), run it.\n");
+         evt->handle(evt);
+      }
+      else {
+         dbg_clear("Tossim", "\n");
+      }
+      if (evt->cleanup != NULL) {
+         evt->cleanup(evt);
+      }
+    }
+    return result;
+}
+
+/* function for running next event in model checker mode */
+bool sim_mc_run_next_event(element_t* element) {
+    bool result = FALSE;
+    sim_event_t* event = NULL;
+    sim_set_mc_element(element);
+    event = sim_mc_queue_pop(element);
+    sim_increase_event_explored_number();
+    
+    if(event != NULL) {
+      if(mc_state == MC_RUNNING || mc_state == RANDOM_WALK) {
+        element->time = event->time;
+      }
+      else {
+        if(event->time != element->time)
+	   event->time = element->time;
+      }
+      // This is the operation only for receive event....
+      if(event->type == RECEIVE) {
+	 sim_clear_tmp_receive_event();
+	 tRcvEvt = sim_queue_allocate_event();
+         sim_copy_event(event, tRcvEvt); 
+      }
+      sim_set_time(event->time);
+      sim_set_node(event->mote);
+
+      // Need to test whether function pointers are for statically
+      // allocted events that are zeroed out on reboot
+      dbg("Tossim", "CORE: popping event 0x%p for %i at %llu with handler %p... \n", event, sim_node(), sim_time(), event->handle);
+      if ((sim_mote_is_on(event->mote) || event->force) && event->handle != NULL) {
+          event->handle(event);
+          result = TRUE;
+      }
+      else {
+        dbg_clear("Tossim", "\n");
+      }
+      if (event->cleanup != NULL) {
+        event->cleanup(event);
+      }
+    }
+    else {
+      //Actually, the null case is not what we want...
+      if(element->eventType == ACK) {
+       //We think ack is the most possible case...
+       event = sim_apply_ack_event(element); 
+       sim_run_specific_event((void*)event);
+       result = TRUE;
+      }
+    }
+    return result;
+}
+
+bool sim_get_timer_mark(int mote) {
+     bool timerMark = FALSE;
+
+     if(mc_state == MC_RUNNING) {
+        timerMark = C_TMP_TIMER[mote];
+     }
+     if(mc_state == RANDOM_WALK) {
+	timerMark = C_TIMER[mote];
+     }
+     return timerMark;
+}
+
+void sim_mc_build_timer_event_set(queue_t* unvisQ, int mote) {
+     heap_t* heap = nodeEqs[mote].TimerH;
+     sim_time_t time;
+     bool timerMark = sim_get_timer_mark(mote);
+
+     while(timerMark) {
+	sim_event_t* timer = (sim_event_t*)heap_pop_min_data(heap, &time);
+	if(timer != NULL) {
+	   element_t* timerElem = NULL;
+           timerElem = sim_allocate_element(timer->mote, TIMER, 0, TRUE);
+           timerElem->time = timer->time;
+	   sim_element_queue_insert(unvisQ, timerElem);
+	   sim_run_specific_event(timer);
+           sim_increase_event_explored_number();
+	}
+	else {
+           dbg("TOSMC", "This is the really unexpected case!\n");
+	   break;
+	}
+	timerMark = sim_get_timer_mark(mote);
+     }
+     C_TIMER[mote] = TRUE;
+     C_TMP_TIMER[mote] = TRUE;
+}
+
+void sim_mc_run_timer_event_set(int mote) {
+     heap_t* heap = nodeEqs[mote].TimerH;
+     sim_time_t time;
+     bool timerMark = sim_get_timer_mark(mote); 
+
+     while(timerMark) {
+	sim_event_t* timer = (sim_event_t*)heap_pop_min_data(heap, &time);
+	if(timer != NULL) {
+	   sim_run_specific_event(timer);
+           sim_increase_event_explored_number();
+	}
+	else {
+           dbg("TOSMC", "This is the really unexpected case!\n");
+	   break;
+	}
+
+	timerMark = sim_get_timer_mark(mote);
+     }
+     C_TIMER[mote] = TRUE;
+     C_TMP_TIMER[mote] = TRUE;
+}
+
+/*************************************************************************/
+void sim_one_transition_re_execute(transition_t* transition) {
+      bool keepOn = FALSE;
+      element_t* elem = transition->vis_execution;
+      //Debugging purpose
+      sim_output_element(elem);
+      printf("end\n");
+
+      keepOn = sim_mc_run_next_event(elem);
+      sim_element_gen_list_node_access_clearance(elem);
+
+      if(!keepOn) {
+         printf("During the re-execution of mc visable part, unmatching case occurs!\n");
+	 exit(0);
+      }
+
+      if(transition->unvis_execution != NULL) {
+          queue_t* unvisQ = transition->unvis_execution;
+	  int j, size = queue_size(unvisQ);
+
+	  for(j = 0; j < size; j++) {
+	     element_t* elem_t = (element_t*)sim_queue_get(unvisQ, j+1);
+             //Debugging purpose
+	     //sim_output_element(elem_t);
+	     //printf("end\n");
+             keepOn = sim_mc_run_next_event(elem_t);
+             sim_element_gen_list_node_access_clearance(elem_t);
+
+	     if(!keepOn) {
+	       printf("During the re-execution of mc unvisable part, unmatching case occurs, tricky!\n");
+	       exit(0);
+	     }
+	  }
+       }
+}
+
+/* In model checking stage, based on the transition stack queue, replay previously explored events */
+static void sim_re_execute() {
+     //Debugging purpose, to see whether the restored event queue set is matching with....
+     sim_output_event_queue_set();
+
+     if(!queue_is_empty(Transition_Stack)) {
+         int i, size = queue_size(Transition_Stack);
+
+         for(i = 0; i < size; i++) {
+            transition_t* trans = (transition_t*)sim_queue_get(Transition_Stack, i+1); 
+	    sim_output_element_in_debugging(trans->vis_execution);
+	    sim_one_transition_re_execute(trans);
+	    sim_increase_transition_explored_number();
+	 }
+     }
+}
+
+static void sim_other_static_variables_copy() {
+     _mc_sim_ticks = sim_ticks;
+     _mc_sim_seed = sim_seed;
+     _mc_current_node = current_node;
+}
+
+static void sim_other_static_variables_copyback() {
+     sim_ticks = _mc_sim_ticks;
+     sim_seed = _mc_sim_seed;
+     current_node = _mc_current_node;
+}
+
+/**************************************** Reset the system for TOSSIM **********************************************/
+static void sim_restore_non_zero_mc_state() {
+    int i;
+
+    for(i = 0; i < MAX_NODES; i++) {
+       C_TIMER[i] = TRUE;
+       C_TMP_TIMER[i] = TRUE;
+
+       if(_mc_status[i].status != UNACTIVE) {
+	 sim_clear_register(i);
+	 sim_clear_specific_mote_eqs_and_interrupt(i);
+         sim_mote_reset(i);
+
+         sim_mc_state_copyback(i);
+         sim_mc_status_copyback(i);
+         sim_mc_register_copyback(i);
+         sim_mc_neighbor_set_copyback(i);
+         sim_mc_alarm_copyback(i);
+
+	 //Here, due to the copyback operation, thus, we need this clearance operation...
+	 sim_clear_receive_and_timer(i);
+       }
+    }
+    //Here, to restore the original noise setting....
+    sim_noise_copyback();
+}
+
+/************************************* Reset the system for Tossim execution ******************************************************************/
+void sim_auxiliary_restore(bool reset) {
+     sim_clear_tmp_receive_event();
+     if(reset)
+	sim_safety_liveness_status_clearance();
+     sim_safety_liveness_clearance();
+     sim_other_static_variables_copyback();
+     sim_total_mote_num_copyback();
+     sim_destroy_event_heap();
+     if(sim_loss_mode == LOSS_WITH_PROB) {
+        sim_reset_num_and_rand_pos_queue(SEND); 
+        sim_reset_num_and_rand_pos_queue(RECEIVE); 
+        sim_reset_num_and_rand_pos_queue(ACK); 
+     }
+}
+
+void sim_reset_for_tossim() {
+     turn_over_steps = 0;
+     mc_state = TOSSIM_RE_RUNNING;
+
+     sim_auxiliary_restore(FALSE);
+     if(tossim_step > 0) {
+        sim_restore_non_zero_mc_state();	
+	sim_queue_init();
+	sim_copyback_from_mc_eqs_to_alternatives();
+     }
+     else {
+	sim_queue_init();
+        sim_reset_system_to_initial_state();
+     }
+}
+
+/************************************* Reset the system and re-execute the Transition Stack ******************************************************************/
+void sim_reset_and_re_execute(bool reset) {
+     int i;
+     turn_over_steps = 0;
+     mc_state = MC_RW_REPEAT;
+     sim_sum_event_transition_explored();
+
+     sim_auxiliary_restore(reset);
+
+     if(tossim_step > 0) {
+        sim_restore_non_zero_mc_state();	
+	sim_copyback_from_mc_eqs_to_alternatives();
+     }
+     else 
+        sim_reset_system_to_initial_state();
+
+     sim_re_execute();
+     if(reset)
+       mc_state = MC_RUNNING;
+     // The C_TIMER must be reset here...
+     for(i = 0; i<MAX_NODES; i++) {
+       C_TIMER[i] = TRUE;
+       C_TMP_TIMER[i] = TRUE;
+     }
+}
+
+/************************************  Internal non-determinism handling  *******************************/
+static bool sim_handle_gen_list_node_set(element_t* srcElem, element_t* dstElem) {
+   if((dstElem->glnHead).FirstAccess == TRUE)
+       (dstElem->glnHead).FirstAccess = FALSE;
+
+   if((srcElem->glnHead).head == NULL) {
+       (srcElem->glnHead).head = sim_copy_multi_gen_list_node((dstElem->glnHead).head); 
+       (srcElem->glnHead).FirstAccess = FALSE;
+   }
+
+   return sim_decrease_gen_list_node_set((srcElem->glnHead).head); 
+}
+
+void Toss_Internal_Choose(uint8_t Cand, uint8_t* Chosen) __attribute__ ((C, spontaneous)) {
+   if(mc_state == MC_RUNNING) {
+     if((_mc_element->glnHead).FirstAccess == FALSE) {
+       sim_traverse_toss_internal_choose(Chosen);
+     }
+     else {
+       gen_list_node_t* glnt = sim_insert_gen_list_node_to_element(Cand); 
+       *Chosen = glnt->Chosen;
+     }
+   }
+
+   if(mc_state == RANDOM_WALK || mc_state == TOSSIM_RE_RUNNING) {
+     gen_list_node_t* glnt = sim_insert_gen_list_node_to_element(Cand);
+     glnt->Chosen = RandomInt(0, Cand);
+     *Chosen = glnt->Chosen; 
+   }
+
+   if(mc_state == MC_RW_REPEAT) {
+     sim_traverse_toss_internal_choose(Chosen);
+   }
+}
+
+/******************************** safety and liveness  *************************************/
+void sim_signal_mem_safety_bug_occur() __attribute__ ((C, spontaneous)) {
+   buggy_node = sim_node(); // Record the node that is expected to show the property execution...
+   mem_safety_bug_occur = TRUE;
+}
+
+void sim_signal_user_safety_bug_occur(uint8_t num) __attribute__ ((C, spontaneous)) {
+   buggy_node = sim_node(); // Record the node that is expected to show the property execution...
+   user_safety_bug_occur[num] = TRUE;
+}
+
+// signal the specific liveness property is fulfilled..
+void sim_signal_liveness_fulfill(uint8_t num, bool fulfill) __attribute__ ((C, spontaneous)) {
+   liveness_fulfill[num] = fulfill;
+   if(stats_state == MC_AND_RW) 
+     liveness_status[num] = fulfill;
+}
+
+bool sim_safety_bug_occur() {
+    if(mem_safety_bug_occur) {
+       safety_bug_source = 0;
+       return TRUE;
+    }
+    else {
+       uint8_t i;
+       for(i = 0; i<propertyNum; i++) {
+         if(user_safety_bug_occur[i]){ 
+           safety_bug_source = i+1;
+           return TRUE;
+	 }
+       }
+    }
+    return FALSE;
+}
+
+bool sim_single_liveness_fulfill() {
+    return liveness_fulfill[liveness_bug_source]; 
+}
+
+bool sim_liveness_fulfill() {
+    uint8_t i;
+    uint8_t totalFulfill;
+
+    for(i = 0; i<propertyNum; i++) {
+      if(liveness_status[i]){ 
+        totalFulfill++;
+      }
+    }
+    if(totalFulfill == propertyNum) 
+      return TRUE;
+    else
+      return FALSE;
+}
+
+bool sim_property_should_be_checked(uint8_t count) __attribute__ ((C, spontaneous)) {
+    if(stats_state == MC_AND_RW && !node_level_non_determinism && liveness_status[count])
+       return FALSE;
+    else if(stats_state == FIND_CRITICAL && count != liveness_bug_source)
+       return FALSE;
+    else
+       return TRUE;
+}
+
+void sim_set_liveness_bug_source(uint8_t source) {
+    liveness_bug_source = source;
+}
+
+uint8_t sim_get_safety_bug_source() {
+    return safety_bug_source;
+}
+
+uint8_t sim_get_liveness_bug_source() {
+    return liveness_bug_source;
+}
+
+uint8_t sim_get_property_number() {
+    return propertyNum;
+}
+
+bool sim_get_mote_liveness_status(uint8_t propertyCount) {
+    return liveness_status[propertyCount];
+}
+
+/******************************** Main function *************************************/
+
+static void sim_record_non_zero_mc_state() {
+    int i;
+    for(i = 0; i < MAX_NODES; i++) {
+       C_TIMER[i] = TRUE;
+       C_TMP_TIMER[i] = TRUE;
+       if(nodeEqs[i].Status != UNACTIVE) {
+         sim_mc_state_copy(i);
+         sim_mc_status_copy(i);
+         sim_mc_register_copy(i);
+         sim_mc_neighbor_set_copy(i);
+         sim_mc_alarm_copy(i);
+	 if(_mc_status[i].boot_chosen)
+           node_level_non_determinism = TRUE;
+       }
+    }
+}
+
+static void sim_record_zero_mc_state() {
+    int i;
+    for(i = 0; i < MAX_NODES; i++) {
+       C_TIMER[i] = TRUE;
+       C_TMP_TIMER[i] = TRUE;
+       if(nodeEqs[i].Status != UNACTIVE) {
+         sim_mc_status_copy(i);
+	 if(_mc_status[i].boot_chosen)
+           node_level_non_determinism = TRUE;
+       }
+    }
+}
+
+static void sim_preparing_for_model_checking() {
+    Transition_Stack = sim_transition_queue_init();
+    sim_safety_liveness_status_clearance();
+    sim_safety_liveness_clearance();
+
+    //First copy the events into eqs from TOSSIM eventHeap...
+    if(mc_state == MC_RUNNING || mc_state == RANDOM_WALK) {
+      sim_copy_from_tossim_to_eqs();
+      sim_destroy_event_heap();
+    }
+
+    sim_noise_copy();
+    sim_total_mote_num_copy();
+    sim_other_static_variables_copy();
+
+    if(tossim_step > 0) {
+      sim_record_non_zero_mc_state();
+    }
+    else {
+      sim_record_zero_mc_state();
+    }
+}
+
+/* function entrance of pure tossim */
+void sim_run_pure_tossim(int tossimBound) {
+    int i;
+    
+    for(i = 0; i < tossimBound; i++) {
+       sim_run_next_event();    
+       sim_increase_event_explored_number();
+       sim_property_check(); 
+
+       if(sim_safety_bug_occur()) {
+	 dbg("TOSMC", "In tossim assist stage, the tossim walk stops due to the fulfillment of liveness property!\n");
+	 sim_safety_report_statistics_data();
+	 break;
+       }
+    }
+    tossim_step = 0;
+}
+
+void sim_start_tossim(int tossim_bound, int rounds) __attribute__ ((C, spontaneous)) {
+    mc_state = TOSSIM_RUNNING;
+    rw_rounds = rounds;
+    sim_preparing_for_model_checking();
+    sim_set_statistic_deviation();
+     
+    gettimeofday(&tossimStv, NULL);
+    gettimeofday(&tosmcStv, NULL);
+
+    for(rw_path = 0; rw_path < rw_rounds; rw_path++) { 
+       sim_run_pure_tossim(tossim_bound);
+       sim_reset_for_tossim();
+    }
+    dbg("TOSMC", "The sole tossim walk is finished!\n");
+    sim_finish_statistic_whole_process();
+    sim_destroy_all_variable();
+}
+
+
+/* function entrance of model checker */
+void sim_start_model_checking(char* mode, int mc_bound, int rw_bound) __attribute__ ((C, spontaneous)) {
+    MC_BOUND = mc_bound;
+    RW_BOUND = rw_bound;
+    
+    mc_state = MC_RUNNING;
+    sim_preparing_for_model_checking();
+
+    dbg("TOSMC", "sim_start_model_checking: this is the %dth path\n", path+1);
+    gettimeofday(&tossimStv, NULL);
+    gettimeofday(&tosmcStv, NULL);
+    sim_output_event_queue_set();
+
+    if(strcmp(mode, "DFS") == 0) {
+       sim_start_statistic_whole_process(0, MC_BOUND);
+       DFS();
+    }
+    else {
+       queue_t* sleepSet = sim_element_queue_init();
+       sim_start_statistic_whole_process(1, MC_BOUND);
+       DFS_POR(sleepSet);
+    }
+
+    dbg("TOSMC", "The whole checking is finished!\n");
+    sim_finish_statistic_whole_process();
+    sim_destroy_all_variable();
+}
+
+/* function entrance of pure random walk */
+void sim_start_random_walk(int rw_bound, int rounds) __attribute__ ((C, spontaneous)) {
+    mc_state = RANDOM_WALK;
+    rw_rounds = rounds;
+    sim_preparing_for_model_checking();
+    sim_set_statistic_deviation();
+     
+    gettimeofday(&tossimStv, NULL);
+    gettimeofday(&tosmcStv, NULL);
+    sim_output_event_queue_set();
+
+    for(rw_path = 0; rw_path < rw_rounds; rw_path++) {
+       sim_random_walk(rw_bound);
+       sim_reset_and_re_execute(TRUE);
+    }
+    dbg("TOSMC", "The sole random walk is finished!\n");
+    sim_finish_statistic_whole_process();
+    sim_destroy_all_variable();
+}
+
 int sim_print_time(char* buf, int len, sim_time_t ftime) __attribute__ ((C, spontaneous)) {
   int hours;
   int minutes;
@@ -193,3 +1022,4 @@ void sim_add_channel(char* channel, FILE
 bool sim_remove_channel(char* channel, FILE* file)  __attribute__ ((C, spontaneous)) {
   return sim_log_remove_channel(channel, file);
 }
+
Index: tos/lib/tossim/sim_tossim.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sim_tossim.h,v
retrieving revision 1.5
diff -u -b -p -r1.5 sim_tossim.h
--- tos/lib/tossim/sim_tossim.h	29 Jun 2010 22:07:51 -0000	1.5
+++ tos/lib/tossim/sim_tossim.h	9 Jul 2010 19:45:16 -0000
@@ -43,12 +43,114 @@
 #define SIM_TOSSIM_H_INCLUDED
 
 #include <stdio.h>
+#include <heap.h>
+#include <sim_transition.h>
+#include <sim_tossim_assist.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef long long int sim_time_t;
+#define MAX_NODES 100
+#define VECTOR_SIZE 40
+
+enum {
+     RADIO = 1,
+     SERIAL = 2
+};
+
+enum {
+     ELEMENT = 0,
+     BOOT = 1,
+     SCHEDULER = 2,
+     GENERAL = 3,
+     SEND = 4,
+     RECEIVE = 5,
+     TIMER = 6,
+     ACK = 7,
+     INTERRUPT = 8
+};
+
+enum { UNACTIVE = 0, ACTIVE, ON, OFF, REBOOT };
+
+enum { MC_AND_RW = 0, FIND_CRITICAL, DELTA_DEBUGGING};
+
+enum { TOSSIM_RUNNING = 0, MC_RUNNING, RANDOM_WALK, MC_RW_REPEAT, TOSSIM_RE_RUNNING};
+
+enum { BACKOFF = 0, TRANSMIT, TRANSMITDONE };
+
+enum { NOLOSS = 0, LOSS_RANDOM, LOSS_WITH_NOISE, LOSS_WITH_PROB};
+
+enum {
+    INT_INTERRUPT0, INT_INTERRUPT1, INT_INTERRUPT2, INT_INTERRUPT3, INT_INTERRUPT4, INT_INTERRUPT5, INT_INTERRUPT6, INT_INTERRUPT7, INT_OUTPUT_COMPARE2, INT_OVERFLOW2, INT_INPUT_CAPTURE1, INT_OUTPUT_COMPARE1, INT_OUTPUT_COMPARE1A, INT_OUTPUT_COMPARE1B, INT_OVERFLOW1, INT_OUTPUT_COMPARE0, INT_OVERFLOW0, INT_SPI, INT_USART0_RECV, INT_USART0_DATA, INT_USART0_TRANS, INT_ADC, INT_EEPROM_READY, INT_COMPARATOR, INT_OUTPUT_COMPARE1C, INT_INPUT_CAPTURE3, INT_OUTPUT_COMPARE3A, INT_OUTPUT_COMPARE3B, INT_OUTPUT_COMPARE3C, INT_OVERFLOW3, INT_USART1_RECV, INT_USART1_DATA, INT_USART_TRANS, INT_2WIRE_SERIAL, INT_SPM_READY
+};
+
+typedef struct node_status {
+   int turnOnStep;
+   int turnOffStep;
+   int rebootStep;
+   uint8_t status;
+   bool boot_chosen;
+} node_status_t;
+
+extern uint32_t transition_explored_sum;
+extern uint32_t event_explored_sum;
+extern uint32_t transition_explored;
+extern uint32_t event_explored;
+extern uint32_t path; 
+extern uint32_t steps; 
+extern uint32_t rw_path; 
+extern uint32_t rw_rounds; 
+
+extern int delta_debugging;
+extern int sim_loss_mode;
+extern int sim_bias_mode;
+extern int sim_tossim_mode;
+
+extern double sendProb;
+extern double receiveProb;
+extern double ackProb;
+
+extern int sendFailNum;
+extern int receiveFailNum;
+extern int ackFailNum;
+
+extern int tossim_step;
+extern int turn_over_steps;
+
+extern element_t* _mc_element;
+extern queue_t* Transition_Stack;
+extern node_status_t _mc_status[MAX_NODES];
+extern event_queue_set_t nodeEqs[MAX_NODES];
+extern queue_t* _mc_nodeEqs;
+extern bool node_level_non_determinism;
+
+extern neighbor_info_t* neighborHead[MAX_NODES];
+extern neighbor_info_t* _mc_neighborHead[MAX_NODES];
+extern queue_t* InjectSet;
+
+extern uint8_t total_simulated_mote_num;
+extern uint8_t _mc_total_simulated_mote_num;
+
+extern uint8_t mc_state;
+extern uint8_t stats_state;
+extern unsigned long buggy_node;
+extern bool C_TIMER[MAX_NODES];
+extern bool C_TMP_TIMER[MAX_NODES];
+extern bool alarmSet[MAX_NODES];
+extern bool _mc_alarmSet[MAX_NODES];
+
+extern FILE* statisticFile;
+extern FILE* safetyViolateFile;
+extern FILE* liveFulfillFile;
+extern FILE* liveViolateFile;
+extern FILE* whichFile;
+
+uint8_t sim_total_mote_num();
+uint8_t sim_simulated_mote_num();
+uint8_t sim_mote_status();
+void sim_signal_turn_on_mote();
+void sim_signal_turn_off_mote();
   
 void sim_init();
 void sim_start();
@@ -63,6 +165,7 @@ sim_time_t sim_ticks_per_sec();
   
 unsigned long sim_node();
 void sim_set_node(unsigned long node);
+void sim_log_file_change_name(); 
 
 int sim_print_time(char* buf, int bufLen, sim_time_t time);
 int sim_print_now(char* buf, int bufLen);
@@ -71,8 +174,55 @@ char* sim_time_string();
 void sim_add_channel(char* channel, FILE* file);
 bool sim_remove_channel(char* channel, FILE* file);
   
+void sim_init_mote_num(int moteNum, int propertyCount);
+void sim_set_delta_debugging(int delta);
+void sim_set_loss_bias_tossim(int loss_mode, int bias_mode, int tossim_mode); 
+void sim_mc_mote_revival(int mote, int step);
+void sim_mc_mote_death(int mote, int step);
+void sim_mc_mote_reboot(int mote, int step);
+void sim_set_send_probability(double prob); 
+void sim_set_receive_probability(double prob); 
+void sim_set_ack_probability(double prob); 
+
+void sim_alarm_set(); 
+void sim_alarm_timer_signal();
+void sim_timer0_compare_signal();
+
+void sim_reset_for_tossim();
+void sim_reset_and_re_execute(bool reset);
+
+void sim_signal_mem_safety_bug_occur();
+void sim_signal_user_safety_bug_occur(uint8_t num);
+void sim_signal_liveness_fulfill(uint8_t num, bool fulfill);
+bool sim_safety_bug_occur();
+bool sim_single_liveness_fulfill();
+bool sim_liveness_fulfill();
+bool sim_property_should_be_checked(uint8_t count);
+void sim_set_liveness_bug_source(uint8_t source); 
+uint8_t sim_get_safety_bug_source(); 
+uint8_t sim_get_liveness_bug_source(); 
+uint8_t sim_get_property_number(); 
+bool sim_get_mote_liveness_status(uint8_t propertyCount); 
+
+void sim_set_mc_element_num(int mark);
 bool sim_run_next_event();
+bool sim_run_specific_event(void* evt);
+bool sim_mc_run_next_event(element_t* element);
+
+void sim_set_tmp_alarm_set(int mote);
+bool sim_get_timer_mark(int mote);
+void sim_mc_build_timer_event_set(queue_t* unvisQ, int mote);
+void sim_mc_run_timer_event_set(int mote);
+
+void sim_one_transition_re_execute(transition_t* transition);
+
+void sim_start_tossim(int tossim_bound, int rounds);
+void sim_start_model_checking(char* mode, int mc_bound, int rw_bound);
+void sim_start_random_walk(int rw_bound, int rounds);
+void Toss_Internal_Choose(uint8_t Cand, uint8_t* Chosen);
 
+void sim_mc_state_copy(int node);
+void sim_mc_state_copyback(int node);
   
 #ifdef __cplusplus
 }
Index: tos/lib/tossim/sim_tossim_assist.c
===================================================================
RCS file: tos/lib/tossim/sim_tossim_assist.c
diff -N tos/lib/tossim/sim_tossim_assist.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_tossim_assist.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,392 @@
+#include <sim_tossim_assist.h>
+#include <sim_noise.h>
+#include <sim_gain.h>
+#include <randomlib.h>
+
+void sim_init_event_queue_set() {
+     int i, j;
+     for(i = 0; i<MAX_NODES; i++) {
+	 nodeEqs[i].Status = UNACTIVE;
+	 nodeEqs[i].StartTime = -1;
+         nodeEqs[i].BootEvt = NULL;
+         nodeEqs[i].SchedulerQ = NULL;
+         nodeEqs[i].GeneralQ = NULL;
+         nodeEqs[i].SendQ = NULL;
+         nodeEqs[i].ReceiveQ = NULL;
+         nodeEqs[i].AckQ = NULL;
+         nodeEqs[i].TimerH = NULL;
+	 for(j=0; j<VECTOR_SIZE; j++) {
+            nodeEqs[i].InterruptSet[j] = NULL;
+	 }
+         
+	 _mc_status[i].status = UNACTIVE;
+	 _mc_status[i].boot_chosen = FALSE;
+	 _mc_status[i].turnOnStep = -1;
+	 _mc_status[i].turnOffStep = -1;
+	 _mc_status[i].rebootStep = -1;
+     }
+     _mc_nodeEqs = init_queue();
+}
+
+void sim_allocate_specific_mote_eqs(int mote) {
+     nodeEqs[mote].Status = ACTIVE;
+     nodeEqs[mote].BootEvt = NULL;
+     nodeEqs[mote].SchedulerQ = init_queue(); 
+     nodeEqs[mote].GeneralQ = init_queue();
+     nodeEqs[mote].SendQ = init_queue();
+     nodeEqs[mote].ReceiveQ = init_queue();
+     nodeEqs[mote].AckQ = init_queue();
+     nodeEqs[mote].TimerH = (heap_t*)malloc(sizeof(heap_t));
+     init_heap(nodeEqs[mote].TimerH);
+}
+
+void sim_init_inject_set() {
+     InjectSet = init_queue();        
+}
+
+/***************************  Code about neighbor set **************************************************/
+static neighbor_info_t* sim_allocate_neighbor_info_node(int other) {
+     neighbor_info_t* nit = (neighbor_info_t*)malloc(sizeof(neighbor_info_t));
+     nit->neighborID = other;
+     nit->status = BACKOFF;
+     nit->next = NULL;
+     return nit;
+}
+
+void sim_init_neighbor_head() {
+     int i;
+     for(i = 0; i<MAX_NODES; i++) {
+       neighborHead[i] = NULL;
+       _mc_neighborHead[i] = NULL;
+     }
+}
+
+void sim_build_neighbor_set(int source) {
+     gain_entry_t* neighborEntry = sim_gain_first(source);
+     neighbor_info_t* subseq = neighborHead[source];
+
+     while(neighborEntry != NULL) {
+        int other = neighborEntry->mote;
+        neighbor_info_t* newNeighbor = sim_allocate_neighbor_info_node(other);
+
+        if(subseq == NULL) {
+	   neighborHead[source] = newNeighbor;
+	}
+	else {
+	   subseq->next = newNeighbor;
+	}
+	subseq = newNeighbor;
+        neighborEntry = sim_gain_next(neighborEntry);
+     }
+}
+
+void sim_set_neighbor_receive(int source, int other) __attribute__ ((C, spontaneous)) {
+     neighbor_info_t* nit = neighborHead[source];
+
+     while(nit != NULL) {
+        if(nit->neighborID == other){
+           nit->status = TRANSMIT;
+	   break;
+	}
+	nit = nit->next;
+     }
+}
+
+bool sim_is_all_neighbor_transmit(int source)  __attribute__ ((C, spontaneous)) {
+     neighbor_info_t* nit = neighborHead[source];
+
+     while(nit != NULL) {
+        if(nit->status == BACKOFF)
+	    return FALSE;
+        nit = nit->next;
+     }
+     return TRUE;
+}
+
+void sim_reset_all_neighbor_status(int source)  __attribute__ ((C, spontaneous)) {
+     neighbor_info_t* nit = neighborHead[source];
+     dbg("TOSMC", "%s, source mote: %d sends done\n", __FUNCTION__, source);
+
+     while(nit != NULL) {
+	nit->status = BACKOFF;
+        nit = nit->next;
+     }
+}
+
+void sim_destroy_neighbor_set() {
+     int i;
+     for(i = 0; i<MAX_NODES; i++) {
+	if(nodeEqs[i].Status != UNACTIVE) {
+          neighbor_info_t* nit = neighborHead[i];
+	  while(neighborHead[i] != NULL) {
+	     neighborHead[i] = nit->next;
+	     nit->next = NULL;
+	     free(nit);
+	     nit = neighborHead[i];
+	  }
+	}
+     }
+}
+
+void sim_output_neighbor_set() {
+     int i;
+     for(i = 0; i<MAX_NODES; i++) {
+	if(nodeEqs[i].Status != UNACTIVE) {
+	  neighbor_info_t* nit = neighborHead[i];
+          printf("mote: %d: ", i);
+	  while(nit != NULL) {
+	    printf("(nei:%d, status: %d)->", nit->neighborID, nit->status);
+            nit = nit->next;
+	  }
+	  printf("end\n");
+	}
+     }
+}
+
+/************************************ Copy and Copyback operations ***********************************************************/
+void sim_mc_status_copy(int mote) {
+    _mc_status[mote].status = nodeEqs[mote].Status;
+}
+
+void sim_mc_status_copyback(int mote) {
+    nodeEqs[mote].Status = _mc_status[mote].status;
+}
+
+void sim_mc_alarm_copy(int mote) { 
+    _mc_alarmSet[mote] = alarmSet[mote]; 
+}
+
+void sim_mc_alarm_copyback(int mote) {
+    alarmSet[mote] = _mc_alarmSet[mote]; 
+}
+
+void sim_mc_neighbor_set_copy(int i) {
+     if(neighborHead[i] != NULL) {
+        neighbor_info_t* neighbor = neighborHead[i];
+        neighbor_info_t* _mc_tmp = _mc_neighborHead[i];
+
+        while(neighbor != NULL) {
+	  neighbor_info_t* _mc_neighbor = sim_allocate_neighbor_info_node(neighbor->neighborID);
+	  _mc_neighbor->status = neighbor->status;
+
+          if(_mc_tmp == NULL) {
+	    _mc_neighborHead[i] = _mc_neighbor;
+	  }
+	  else {
+	   _mc_tmp->next = _mc_neighbor;
+	  }
+	  _mc_tmp = _mc_neighbor;
+	  neighbor = neighbor->next;
+        }
+     }
+}
+
+void sim_mc_neighbor_set_copyback(int i) {
+     if(_mc_neighborHead[i] != NULL) {
+        neighbor_info_t* _mc_neighbor = _mc_neighborHead[i];
+        neighbor_info_t* neighbor = neighborHead[i];
+
+        while(_mc_neighbor != NULL) {
+	   neighbor->status = _mc_neighbor->status;
+	   _mc_neighbor = _mc_neighbor->next;
+	   neighbor = neighbor->next;
+	}
+     }
+}
+
+void sim_total_mote_num_copy() {
+     _mc_total_simulated_mote_num = total_simulated_mote_num;
+}
+
+void sim_total_mote_num_copyback() {
+     total_simulated_mote_num = _mc_total_simulated_mote_num;
+}
+
+/****************************************************************************************************/
+void sim_destroy_all_motes_eqs() {
+     int i;
+     for(i = 0; i<MAX_NODES; i++) { 
+	if(nodeEqs[i].Status != UNACTIVE) {
+           int j;
+           sim_clear_specific_mote_eqs(i);
+
+           for(j = 0; j < VECTOR_SIZE; j++) {
+	     sim_event_t* evt = (sim_event_t*)nodeEqs[i].InterruptSet[j];
+             if(evt != NULL) 
+	       nodeEqs[i].InterruptSet[j] = NULL;
+           }
+	}
+     }
+}
+
+void sim_destroy_all_variable() {
+    sim_transition_queue_destroy(Transition_Stack);
+    sim_destroy_all_motes_eqs();
+    sim_destroy_mc_node_eqs();
+    sim_queue_destroy(InjectSet, GENERAL);
+
+    sim_log_destroy();
+    sim_noise_destroy();
+}
+
+static element_t* sim_random_ack_enabled_event_set(element_t* revElem) {
+     element_t* ackElem = NULL; 
+     if(sim_loss_mode == NOLOSS) {
+       ackElem = sim_allocate_element(revElem->source, ACK, revElem->MoteID, TRUE);
+     }
+     else{
+       uint8_t choose = RandomInt(0, 1);
+       dbg("Acks", "%s: the rand num chosen in ACK event is %u\n", __FUNCTION__, choose);
+       ackElem = sim_allocate_element(revElem->source, ACK, revElem->MoteID, choose);
+     }
+     return ackElem;
+}
+
+void sim_build_transition_without_saving(element_t* element) {
+     int moteID = element->MoteID;	  
+     element_t* newElement = NULL;
+
+     if(element->eventType == SEND) {
+	if(element->source == BACKOFF) {
+	  if(element->num == TRUE) {
+	    newElement = sim_allocate_element(moteID, SEND, TRANSMIT, TRUE);
+	    sim_mc_run_next_event(newElement);
+	  }
+	}
+     }
+     else if(element->eventType == RECEIVE) {
+	 int i = 0;
+	 int source = element->source;
+
+	 if(!queue_is_empty(nodeEqs[source].AckQ)) {
+            int size = queue_size(nodeEqs[source].AckQ);
+	    for(; i< size; i++) {
+	       sim_event_t* event = (sim_event_t*)sim_queue_get(nodeEqs[source].AckQ,i+1);
+	       if(event->source == element->MoteID) {
+	          bool keepOn = FALSE;
+		  //We make the random choice to decide whether the ack can be sent successfully or not
+                  newElement = sim_mc_ack_enabled_event_set(element);
+	          keepOn = sim_mc_run_next_event(newElement);
+                  // This should not happen
+		  if(!keepOn) {
+	             dbg("Acks", "During the execution of ack event, unmatching case occurs!\n");
+		     exit(0);
+		  }
+		  break;
+	       }
+	    }
+	 }
+     }
+     else { 
+        if(element->eventType == TIMER) {
+	   sim_mc_run_timer_event_set(element->MoteID);
+        }
+     }
+}
+
+void sim_handling_turn_off_specific_mote(sim_event_t* e) {
+     int mote = sim_node();
+     // It must be ON status...
+     if(nodeEqs[mote].Status == ON) {
+        dbg("TOSMC", "The mote %d is turned off!\n", mote);
+	sim_clear_register(mote);
+	sim_turn_off_clearance(mote);
+        sim_reset_all_neighbor_status(mote);
+        if(mc_state == TOSSIM_RE_RUNNING)
+           sim_turn_off_remove_from_eventHeap(mote);
+
+        sim_mote_turn_off(mote);
+	sim_mote_reset(mote);
+
+	C_TIMER[mote] = TRUE;
+	C_TMP_TIMER[mote] = TRUE;
+	alarmSet[mote] = FALSE;
+     }
+     else {
+        dbg("TOSMC", "There must happen some errors, this is not what we want!\n");
+	return;
+     }
+}
+
+void sim_handling_reboot_specific_mote(sim_event_t* e) {
+     int mote = sim_node();
+     // It must be ON status...
+     if(nodeEqs[mote].Status == ON) {
+	sim_clear_register(mote);
+	sim_turn_off_clearance(mote);
+        sim_reset_all_neighbor_status(mote);
+        if(mc_state == TOSSIM_RE_RUNNING)
+           sim_turn_off_remove_from_eventHeap(mote);
+        sim_mote_turn_off(mote);
+	sim_mote_reset(mote);
+        sim_mote_turn_on(mote);
+
+	C_TIMER[mote] = TRUE;
+	C_TMP_TIMER[mote] = TRUE;
+	alarmSet[mote] = FALSE;
+     }
+     else {
+        dbg("TOSMC", "There must happen some errors, this is not what we want!\n");
+	return;
+     }
+}
+
+/**************************************** Mote death, revival and reboot ********************************************/ 
+void sim_turn_on_specific_mote(int mote) {
+     //turn on handling, the status can be UNACTIVE, OFF... 
+     sim_mote_reset(mote);
+     sim_mote_set_start_time(mote, sim_time());
+     sim_mote_enqueue_boot_event(mote);
+}
+
+void sim_turn_off_specific_mote(int mote) {
+     //turn off handling
+     sim_event_t* turnOff = sim_queue_allocate_event(); 
+     turnOff->mote = mote;
+     turnOff->handle = sim_handling_turn_off_specific_mote;
+     turnOff->cleanup = sim_queue_cleanup_event;
+     turnOff->type = BOOT;
+     turnOff->source = OFF;
+     turnOff->mark = TRUE;
+     turnOff->time = sim_time();
+
+     sim_queue_insert_turn_off_event(turnOff); 
+}
+
+void sim_reboot_specific_mote(int mote) {
+     sim_event_t* reboot = sim_queue_allocate_event(); 
+     reboot->mote = mote;
+     reboot->handle = sim_handling_reboot_specific_mote;
+     reboot->cleanup = sim_queue_cleanup_event;
+     reboot->type = BOOT;
+     reboot->source = REBOOT; 
+     reboot->mark = TRUE;
+     reboot->time = sim_time();
+
+     sim_queue_insert_turn_off_event(reboot); 
+}
+
+bool sim_simulate_turn_on_or_off_event(int *mote) {
+    int i = 0;
+
+    for(; i<MAX_NODES; i++) {
+      if(nodeEqs[i].Status != UNACTIVE && _mc_status[i].boot_chosen) {
+         if(turn_over_steps == _mc_status[i].turnOnStep){ 
+            sim_turn_on_specific_mote(i);
+            *mote = i;
+	    return TRUE;
+	 }
+         if(turn_over_steps == _mc_status[i].turnOffStep) {
+            sim_turn_off_specific_mote(i);
+            *mote = i;
+	    return TRUE;
+	 }
+         if(turn_over_steps == _mc_status[i].rebootStep) {
+            sim_reboot_specific_mote(i);
+            *mote = i;
+	    return TRUE;
+	 }
+      }
+    } 
+    return FALSE;
+}
Index: tos/lib/tossim/sim_tossim_assist.h
===================================================================
RCS file: tos/lib/tossim/sim_tossim_assist.h
diff -N tos/lib/tossim/sim_tossim_assist.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_tossim_assist.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,53 @@
+#ifndef SIM_TOSSIM_ASSIST_H_INCLUDED
+#define SIM_TOSSIM_ASSIST_H_INCLUDED
+
+#include <sim_transition.h>
+
+typedef long long int sim_time_t;
+
+typedef struct mote_info {
+     int MoteID;
+     sim_time_t MoteTime;
+} mote_info_t;
+
+typedef struct neighbor_info neighbor_info_t;
+
+struct neighbor_info {
+     int neighborID;
+     int status;
+     neighbor_info_t* next;
+};
+
+void sim_init_event_queue_set();
+void sim_allocate_specific_mote_eqs(int mote);
+void sim_init_inject_set();
+
+void sim_init_neighbor_head();
+void sim_build_neighbor_set();
+void sim_set_neighbor_receive(int source, int other);
+bool sim_is_all_neighbor_transmit(int source);
+void sim_reset_all_neighbor_status(int source);
+void sim_destroy_neighbor_set();
+void sim_output_neighbor_set();
+
+void sim_mc_status_copy(int mote);
+void sim_mc_status_copyback(int mote);
+void sim_mc_alarm_copy(int mote);
+void sim_mc_alarm_copyback(int mote);
+void sim_mc_neighbor_set_copy(int i);
+void sim_mc_neighbor_set_copyback(int i);
+void sim_total_mote_num_copy(); 
+void sim_total_mote_num_copyback(); 
+
+void sim_destroy_all_motes_eqs();
+void sim_destroy_all_variable();
+
+void sim_build_transition_without_saving(element_t*);
+
+void sim_turn_on_specific_mote(int mote);
+void sim_turn_off_specific_mote(int mote);
+void sim_reboot_specific_mote(int mote);
+bool sim_simulate_turn_on_or_off_event(int *mote);
+
+#endif
+
Index: tos/lib/tossim/sim_tossim_other_assist.c
===================================================================
RCS file: tos/lib/tossim/sim_tossim_other_assist.c
diff -N tos/lib/tossim/sim_tossim_other_assist.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_tossim_other_assist.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,49 @@
+#include <stdio.h>
+
+#ifdef SIM_ASSIST_COMM
+void sim_clear_outstandingReceptionHead(int node) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+void sim_reset_outstandingReceptionHead(sim_event_t* evt) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+void sim_apply_send_event(sim_event_t* evt) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+void sim_copy_general_event(sim_event_t* gen, sim_event_t* _mc_gen) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+void sim_copy_receive_event(sim_event_t* rcv, sim_event_t* _mc_rcv) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+void sim_cleanup_event_receive_message(sim_event_t* evt) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+sim_event_t* sim_apply_ack_event(element_t* element) {
+   sim_event_t* fakeAck = NULL;
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+   return fakeAck;
+}
+
+bool sim_send_check_clear_channel() {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+   return FALSE;
+    
+}
+#endif
+
+#ifdef SIM_ASSIST_TIMER
+void sim_clear_compare_overflow(int node) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+
+void sim_reset_compare_overflow(sim_event_t* evt) {
+   dbg("ASSIST", "%s: This is a function for assisting compliation!\n", __FUNCTION__);    
+}
+#endif
Index: tos/lib/tossim/sim_transition.c
===================================================================
RCS file: tos/lib/tossim/sim_transition.c
diff -N tos/lib/tossim/sim_transition.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_transition.c	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,434 @@
+/* This file includes series of functions handling elements and transitions */
+#include <sim_transition.h>
+#include <randomlib.h>
+
+element_t* sim_allocate_element(int mote, int eventType, int source, int num) {
+     element_t* element = (element_t*)malloc(sizeof(element_t));
+     element->MoteID = mote;
+     element->eventType = eventType;
+     element->source = source;
+     element->num = num;
+     element->time = 0;
+
+     (element->glnHead).FirstAccess = TRUE;
+     (element->glnHead).head = NULL;
+
+     return element;
+}
+
+element_t* sim_copy_element(element_t* elem) {
+     element_t* elem_t = sim_allocate_element(elem->MoteID, elem->eventType, elem->source, elem->num);
+     (elem_t->glnHead).FirstAccess = (elem->glnHead).FirstAccess;
+
+     if((elem->glnHead).head != NULL) {
+        (elem_t->glnHead).head = sim_copy_multi_gen_list_node((elem->glnHead).head); 
+     }
+     return elem_t;
+}
+
+void sim_element_gen_list_node_access_clearance(element_t* elem) {
+   if((elem->glnHead).head != NULL) {
+     gen_list_node_t* glnt = (elem->glnHead).head;
+
+     while(glnt->tlink != NULL) {
+        glnt->Access = FALSE;
+	glnt = glnt->tlink; 
+     }
+     glnt->Access = FALSE;
+   }
+}
+
+bool sim_element_is_equal(element_t* element1, element_t* element2) {
+   return ((element1->MoteID == element2->MoteID) 
+	    && (element1->eventType == element2->eventType)
+	     && (element1->source == element2->source)
+	      && (element1->num == element2->num));
+}
+
+void sim_free_element(element_t* element) {
+   if(element != NULL) {
+      sim_clear_gen_list_node((element->glnHead).head);
+      free(element);
+   }
+}
+
+void sim_output_element(element_t* element) {
+     printf("(%d:", element->MoteID);
+     switch(element->eventType){
+         case BOOT:
+	      printf("Boot:%d:%d)->", element->source, element->num);
+	      break;
+         case SCHEDULER:
+	      printf("Scheduler:%d:%d)->", element->source, element->num);
+	      break;
+	 case GENERAL:
+	      printf("General:%d:%d)->", element->source, element->num);
+	      break;
+	 case SEND:
+	      printf("Send:%d:%d)->", element->source, element->num);
+	      break;
+	 case RECEIVE:
+	      printf("Receive:%d:%d)->", element->source, element->num);
+	      break;
+	 case TIMER:
+	      printf("Timer:%d:%d)->", element->source, element->num);
+	      break;
+	 case ACK:
+	      printf("Ack:%d:%d)->", element->source, element->num);
+	      break;
+	 case INTERRUPT:
+	      printf("Interrupt:%d:%d)->", element->source, element->num);
+	      break;
+     }
+}
+
+void sim_output_element_in_debugging(element_t* element) {
+     switch(element->eventType){
+         case BOOT:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Boot:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+         case SCHEDULER:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Scheduler:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+	 case GENERAL:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:General:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+	 case SEND:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Send:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+	 case RECEIVE:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Receive:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+	 case TIMER:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Timer:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+	 case ACK:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Ack:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+	 case INTERRUPT:
+              if(whichFile)
+	        fprintf(whichFile, "(%d:Interrupt:%d:%d)->end\n", element->MoteID, element->source, element->num);
+	      break;
+     }
+}
+
+queue_t* sim_element_queue_init() {
+     queue_t* queue = init_queue();
+     return queue;
+}
+
+void sim_element_queue_insert(queue_t* queue, element_t* element) {
+     queue_insert(queue, element);
+}
+
+element_t* sim_element_queue_get_first(queue_t* elemQ) {
+     return (element_t*)sim_queue_get(elemQ, 1);
+}
+
+element_t* sim_element_queue_pop(queue_t* elemQ) {
+     return (element_t*)queue_pop_first_data(elemQ);
+}
+
+void sim_element_queue_clearance(queue_t* elementQ) {
+    node_t* node = NULL;
+
+    if(elementQ == NULL || queue_is_empty(elementQ)) {
+       return;
+    }
+    while(elementQ->head != NULL) {
+       node = elementQ->head;   
+       elementQ->head = node->next;
+       elementQ->size--;
+       free_node(node);
+    }
+    elementQ->tail = NULL;
+    free(elementQ);
+    return;
+}
+
+void sim_element_queue_destroy(queue_t* elementQ) {
+    node_t* node = NULL;
+    element_t* elem = NULL;
+
+    if(elementQ == NULL || queue_is_empty(elementQ)) {
+       return;
+    }
+    while(elementQ->head != NULL) {
+       node = elementQ->head;   
+       elementQ->head = node->next;
+       elementQ->size--;
+
+       elem = (element_t*)node->data;
+       sim_free_element(elem);
+       free_node(node);
+    }
+    elementQ->tail = NULL;
+    free(elementQ);
+    return;
+}
+
+void sim_output_element_queue(queue_t* queue) {
+     int i;
+     int qSize = queue_size(queue);
+     for(i = 0; i<qSize; i++) {
+         element_t* element = (element_t*)queue_get_data(queue, i+1);
+         sim_output_element(element);
+     }
+     printf("done\n");
+}
+
+bool sim_element_is_three_equal(element_t* element1, element_t* element2) {
+   return ((element1->MoteID == element2->MoteID) 
+	    && (element1->eventType == element2->eventType)
+	     && (element1->source == element2->source));
+}
+
+bool sim_element_in_queue(queue_t* queue, element_t* element){
+      if(queue == NULL) {
+	  dbg("TOSMC", "The pertinent queue is NULL!\n");
+	  return FALSE;
+      }
+      else {
+	  int i;
+          int size = queue_size(queue);
+          for(i=0; i<size; i++) {
+	      element_t* elementT = (element_t*)sim_queue_get(queue, i+1);
+	      if(element->eventType == SEND || element->eventType == RECEIVE) {
+	         if(sim_element_is_three_equal(element, elementT))
+	            return TRUE;
+	      }
+	      else {
+                 if(sim_element_is_equal(element, elementT))
+		    return TRUE;
+	      }
+	  }
+	  return FALSE;
+      }
+}
+
+queue_t* sim_copy_element_queue(queue_t* srcElemQ) {
+      int i;
+      queue_t* destElemQ = sim_element_queue_init();
+
+      for(i = 0; i < queue_size(srcElemQ); i++) {
+	 element_t* srcElem = (element_t*)sim_queue_get(srcElemQ, i+1);
+         element_t* destElem = sim_copy_element(srcElem);
+	 sim_element_queue_insert(destElemQ, destElem);
+      }
+
+      return destElemQ;
+}
+
+static transition_t* sim_copy_transition(transition_t* srcTrans) {
+      transition_t* destTrans = (transition_t*)malloc(sizeof(transition_t)); 
+      destTrans->vis_execution = sim_copy_element(srcTrans->vis_execution);
+      destTrans->unvis_execution = sim_copy_element_queue(srcTrans->unvis_execution);
+      return destTrans;
+}
+
+static element_t* sim_mc_ack_enabled_event_set(element_t* revElem) {
+      element_t* ackElem = NULL;
+      if(sim_loss_mode == NOLOSS) {
+        ackElem = sim_allocate_element(revElem->source, ACK, revElem->MoteID, TRUE);
+      }
+      else{
+        uint8_t cand = 1;
+        uint8_t choose = 0;
+        Toss_Internal_Choose(cand, &choose);
+        if(choose)
+          ackElem = sim_allocate_element(revElem->source, ACK, revElem->MoteID, TRUE);
+        else
+          ackElem = sim_allocate_element(revElem->source, ACK, revElem->MoteID, FALSE);
+      }
+      return ackElem;
+}
+
+void sim_build_transition(queue_t* transQ, element_t* elem) {
+     transition_t* newTransition = (transition_t*)malloc(sizeof(transition_t));
+     int moteID = elem->MoteID;	  
+     element_t* newElem = NULL;
+
+     newTransition->vis_execution = elem;
+     newTransition->unvis_execution = NULL;
+
+     if(elem->eventType == SEND) {
+	 if(elem->source == BACKOFF) {
+	    if(elem->num == TRUE) {
+	      queue_t* unvisQ = sim_element_queue_init();
+	      newElem = sim_allocate_element(moteID, SEND, TRANSMIT, TRUE);
+	      sim_element_queue_insert(unvisQ, newElem);
+
+	      sim_mc_run_next_event(newElem);
+	      newTransition->unvis_execution = unvisQ;
+	      sim_transition_queue_insert(transQ, newTransition);
+	    }
+	    else {
+	      sim_transition_queue_insert(transQ, newTransition);
+	    }
+	 }
+	 else {
+	    sim_transition_queue_insert(transQ, newTransition);
+	 }
+     }
+     else if(elem->eventType == RECEIVE) {
+	 int i = 0;
+	 int source = elem->source;
+         
+	 if(!queue_is_empty(nodeEqs[source].AckQ)) {
+	     int size = queue_size(nodeEqs[source].AckQ);
+	     for(; i< size; i++) {
+	        sim_event_t* ackEvt = (sim_event_t*)sim_queue_get(nodeEqs[source].AckQ, i+1);
+	        if(ackEvt->source == moteID) {
+	           bool keepOn = FALSE;
+		   queue_t* unvisQ = sim_element_queue_init();
+                   newElem = sim_mc_ack_enabled_event_set(elem);
+	           keepOn = sim_mc_run_next_event(newElem);
+
+	           sim_element_queue_insert(unvisQ, newElem);
+	           newTransition->unvis_execution = unvisQ;
+                   // This should not happen
+		   if(!keepOn) {
+	              dbg("Acks", "During the execution of ack event, unmatching case occurs!\n");
+		      exit(0);
+		   }
+		   break;
+	        }
+	     }
+	 }
+	 sim_transition_queue_insert(transQ, newTransition);
+     }
+     else {
+       if(elem->eventType == TIMER) {
+	  queue_t* unvisQ = sim_element_queue_init();
+	  sim_mc_build_timer_event_set(unvisQ, elem->MoteID);
+	  newTransition->unvis_execution = unvisQ;
+          sim_transition_queue_insert(transQ, newTransition);
+       }
+       else {
+	  sim_transition_queue_insert(transQ, newTransition);
+       }
+     }
+}
+
+void sim_transition_destroy(transition_t* transition) {
+     if(transition->vis_execution != NULL) {
+        sim_free_element(transition->vis_execution);
+        transition->vis_execution = NULL;
+     }
+
+     if(transition->unvis_execution != NULL) {
+	sim_element_queue_destroy(transition->unvis_execution); 
+	transition->unvis_execution = NULL;
+     }
+}
+
+queue_t* sim_transition_queue_init() {
+     return init_queue();
+}
+
+void sim_transition_queue_insert(queue_t* transQ, transition_t* transition) {
+     queue_insert(transQ, transition);
+}
+
+void sim_transition_queue_pop(queue_t* transitionQ) {
+     transition_t* transition = (transition_t*)queue_pop_last_data(transitionQ);
+
+     if(transition != NULL) {
+        sim_transition_destroy(transition);
+        free(transition);
+     }
+}
+
+element_t* sim_por_transition_queue_pop(queue_t* transQ) {
+     element_t* element = NULL;
+     transition_t* transition = (transition_t*)queue_pop_last_data(transQ);
+
+     if(transition != NULL) {
+	element = transition->vis_execution;
+	transition->vis_execution = NULL;
+        sim_transition_destroy(transition);
+        free(transition);
+     }
+
+     if((element->glnHead).head != NULL) {
+        sim_clear_gen_list_node((element->glnHead).head);
+	(element->glnHead).head = NULL;
+     }
+     return element;
+}
+
+void sim_transition_queue_destroy(queue_t* transitionQ) {
+     if(transitionQ == NULL)
+	return;
+
+     while(!queue_is_empty(transitionQ)) {
+	sim_transition_queue_pop(transitionQ);
+     }
+     free(transitionQ);
+     return;
+}
+
+void sim_output_transition_queue(queue_t* transQ) {
+     int i;
+     if(!queue_is_empty(transQ)){
+        int size = queue_size(transQ);
+         for(i = 0; i<size; i++) {
+	     transition_t* transition = (transition_t*)queue_get_data(transQ, i+1);
+	     element_t* element = transition->vis_execution;
+	     sim_output_element(element);
+	 }
+	 printf("end!\n");
+     }
+}
+
+transition_t* sim_transition_queue_pop_first(queue_t* transQ) {
+     return (transition_t*)queue_pop_first_data(transQ);
+}
+
+queue_t* sim_copy_transition_queue(queue_t* srcTransQ) {
+     int i;
+     queue_t* destTransQ = sim_transition_queue_init();
+
+      for(i = 0; i < queue_size(srcTransQ); i++) {
+	 transition_t* srcTrans = (transition_t*)sim_queue_get(srcTransQ, i+1);
+         transition_t* destTrans = sim_copy_transition(srcTrans);
+	 sim_transition_queue_insert(destTransQ, destTrans);
+      }
+
+      return destTransQ;
+}
+
+void sim_intercept_transition_queue(queue_t** transQ, int prefix) {
+     int i;
+     queue_t* tmpQ = sim_transition_queue_init(); 
+
+     for(i = 0; i < prefix; i++) {
+        transition_t* trans = sim_transition_queue_pop_first(*transQ);
+	sim_transition_queue_insert(tmpQ, trans);
+     }
+
+     sim_transition_queue_destroy(*transQ);
+     *transQ = tmpQ;
+}
+
+void sim_combine_transition_queues(queue_t* transQ1, queue_t* transQ2) { 
+     if(transQ2 == NULL) {
+       printf("%s: the transition Q2 is NULL!\n", __FUNCTION__);
+     }
+     else {
+       while(queue_size(transQ2) != 0) {
+          transition_t* trans = sim_transition_queue_pop_first(transQ2);
+	  sim_transition_queue_insert(transQ1, trans);
+       }
+       sim_transition_queue_destroy(transQ2);
+       transQ2 = NULL;
+     }
+}
+
Index: tos/lib/tossim/sim_transition.h
===================================================================
RCS file: tos/lib/tossim/sim_transition.h
diff -N tos/lib/tossim/sim_transition.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sim_transition.h	9 Jul 2010 19:45:16 -0000
@@ -0,0 +1,59 @@
+#ifndef SIM_TRANSITION_H_INCLUDED
+#define SIM_TRANSITION_H_INCLUDED
+
+#include <sim_gen_list.h>
+
+typedef struct element {
+    int MoteID;
+    int eventType;
+    int source;
+    int num;
+    long long int time;
+    gen_list_node_header_t glnHead;
+} element_t;
+
+typedef struct element_node element_node_t;
+
+struct element_node {
+    element_t* element;
+    element_node_t* next;
+};
+
+typedef struct transition {
+    element_t* vis_execution;
+    queue_t* unvis_execution;
+} transition_t;
+
+element_t* sim_allocate_element(int mote, int eventType, int source, int num);
+element_t* sim_copy_element(element_t* element);
+void sim_element_gen_list_node_access_clearance(element_t* elem);
+bool sim_element_is_equal(element_t* element1, element_t* element2);
+void sim_free_element(element_t* element);
+void sim_output_element(element_t* element);
+void sim_output_element_in_debugging(element_t* element);
+
+queue_t* sim_element_queue_init();
+void sim_element_queue_insert(queue_t* queue, element_t* element);
+element_t* sim_element_queue_get_first(queue_t* elemQ);
+element_t* sim_element_queue_pop(queue_t* elemQ);
+void sim_element_queue_clearance(queue_t* elemQ); 
+void sim_element_queue_destroy(queue_t* elemQ);
+void sim_output_element_queue(queue_t* elemQ);
+bool sim_element_in_queue(queue_t* queue, element_t* element);
+queue_t* sim_copy_element_queue(queue_t* elemQ);
+
+void sim_build_transition(queue_t* transQ, element_t* element);
+void sim_transition_destroy(transition_t* transition);
+queue_t* sim_transition_queue_init();
+void sim_transition_queue_insert(queue_t* transQ, transition_t* transition);
+void sim_transition_queue_pop(queue_t* transQ);
+element_t* sim_por_transition_queue_pop(queue_t* transQ);
+void sim_transition_queue_destroy(queue_t* transQ);
+void sim_output_transition_queue(queue_t* transQ);
+transition_t* sim_transition_queue_pop_first(queue_t* transQ);
+queue_t* sim_copy_transition_queue(queue_t* transQ);
+
+void sim_intercept_transition_queue(queue_t** transQ, int prefix);
+void sim_combine_transition_queues(queue_t* transQ1, queue_t* transQ2);
+
+#endif
Index: tos/lib/tossim/tos.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/tos.h,v
retrieving revision 1.6
diff -u -b -p -r1.6 tos.h
--- tos/lib/tossim/tos.h	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/tos.h	9 Jul 2010 19:45:16 -0000
@@ -63,6 +63,7 @@
 
 #ifndef __cplusplus
 typedef uint8_t bool;
+typedef nx_int8_t nx_bool;
 #endif
 
 /* 
@@ -83,6 +84,8 @@ extern uint16_t TOS_NODE_ID;
 #define TOSSIM_MAX_NODES 1000
 #endif
 
+#define MAX_NODES 100
+
 #include <sim_event_queue.h>
 #include <sim_tossim.h>
 #include <sim_mote.h>
@@ -101,7 +104,22 @@ struct @exactlyonce { };
 #include <sim_log.c>
 #include <heap.c>
 #include <sim_event_queue.c>
+#include <sim_transition.c>
+#include <sim_stateless_no_por.c>
+#include <sim_stateless_sleep_reduce.c>
 #include <sim_tossim.c>
+#include <sim_tossim_assist.c>
+#include <sim_depth_first_search.c>
+#include <sim_random_walk.c>
+#include <sim_random_walk_assist.c>
+#include <sim_delta_debugging.c>
+#include <sim_statistic_info.c>
+
+#if SIM_ASSIST_TIMER || SIM_ASSIST_COMM
+  #include <sim_tossim_other_assist.c>
+#endif
+
+#include <sim_gen_list.c>
 #include <sim_mac.c>
 #include <sim_packet.c>
 #endif
Index: tos/lib/tossim/tossim.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/tossim.c,v
retrieving revision 1.7
diff -u -b -p -r1.7 tossim.c
--- tos/lib/tossim/tossim.c	29 Jun 2010 22:07:51 -0000	1.7
+++ tos/lib/tossim/tossim.c	9 Jul 2010 19:45:16 -0000
@@ -226,6 +226,30 @@ void Tossim::init() {
   memset(motes, 0, sizeof(Mote*) * TOSSIM_MAX_NODES);
 }
 
+void Tossim::initMoteNum(int moteNum, int propertyNum) {
+  sim_init_mote_num(moteNum, propertyNum);
+}
+
+void Tossim::setDeltaDebugging(int delta) {
+  sim_set_delta_debugging(delta);
+}
+
+void Tossim::setLossAndBiasingAndTossim(int loss_mode, int bias_mode, int tossim_mode) {
+  sim_set_loss_bias_tossim(loss_mode, bias_mode, tossim_mode);
+}
+
+void Tossim::mcMoteRevival(int mote, int step) {
+  sim_mc_mote_revival(mote, step);
+}
+
+void Tossim::mcMoteDeath(int mote, int step) {
+  sim_mc_mote_death(mote, step);
+}
+
+void Tossim::mcMoteReboot(int mote, int step) {
+  sim_mc_mote_reboot(mote, step);
+}
+
 long long int Tossim::time() {
   return sim_time();
 }
@@ -286,6 +310,30 @@ bool Tossim::runNextEvent() {
   return sim_run_next_event();
 }
 
+void Tossim::startTossim(int TOSSIM_BOUND, int Rounds) {
+  sim_start_tossim(TOSSIM_BOUND, Rounds);
+}
+
+void Tossim::startModelChecking(char* mode, int MC_BOUND, int RW_BOUND) {
+  sim_start_model_checking(mode, MC_BOUND, RW_BOUND);
+}
+
+void Tossim::startRandomWalk(int RW_BOUND, int Rounds) {
+  sim_start_random_walk(RW_BOUND, Rounds);
+}
+
+void Tossim::setSendProb(double prob) {
+  sim_set_send_probability(prob);
+}
+
+void Tossim::setReceiveProb(double prob) {
+  sim_set_receive_probability(prob);
+}
+
+void Tossim::setAckProb(double prob) {
+  sim_set_ack_probability(prob);
+}
+
 MAC* Tossim::mac() {
   return new MAC();
 }
Index: tos/lib/tossim/tossim.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/tossim.h,v
retrieving revision 1.6
diff -u -b -p -r1.6 tossim.h
--- tos/lib/tossim/tossim.h	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/tossim.h	9 Jul 2010 19:45:16 -0000
@@ -118,6 +118,12 @@ class Tossim {
   ~Tossim();
   
   void init();
+  void initMoteNum(int moteNum, int propertyNum);
+  void setDeltaDebugging(int delta);
+  void setLossAndBiasingAndTossim(int loss_mode, int bias_mode, int tossim_mode);
+  void mcMoteRevival(int mote, int step);
+  void mcMoteDeath(int mote, int step);
+  void mcMoteReboot(int mote, int step);
   
   long long int time();
   long long int ticksPerSecond();
@@ -133,6 +139,13 @@ class Tossim {
   void randomSeed(int seed);
   
   bool runNextEvent();
+  void startTossim(int TOSSIM_BOUND, int Rounds);
+  void startModelChecking(char* mode, int MC_BOUND, int RW_BOUND);
+  void startRandomWalk(int RW_BOUND, int Rounds);
+
+  void setSendProb(double prob);
+  void setReceiveProb(double prob);
+  void setAckProb(double prob);
 
   MAC* mac();
   Radio* radio();
Index: tos/lib/tossim/tossim.i
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/tossim.i,v
retrieving revision 1.6
diff -u -b -p -r1.6 tossim.i
--- tos/lib/tossim/tossim.i	29 Jun 2010 22:07:51 -0000	1.6
+++ tos/lib/tossim/tossim.i	9 Jul 2010 19:45:16 -0000
@@ -366,6 +366,12 @@ class Tossim {
   ~Tossim();
   
   void init();
+  void initMoteNum(int moteNum, int propertyNum);
+  void setDeltaDebugging(int delta);
+  void setLossAndBiasingAndTossim(int loss_mode, int bias_mode, int tossim_mode);
+  void mcMoteRevival(int mote, int step);
+  void mcMoteDeath(int mote, int step);
+  void mcMoteReboot(int mote, int step);
   
   long long int time();
   long long int ticksPerSecond(); 
@@ -381,6 +387,14 @@ class Tossim {
   void randomSeed(int seed);
 
   bool runNextEvent();
+  void startTossim(int TOSSIM_BOUND, int Rounds);
+  void startModelChecking(char* mode, int MC_BOUND, int RW_BOUND);
+  void startRandomWalk(int RW_BOUND, int Rounds);
+
+  void setSendProb(double prob);
+  void setReceiveProb(double prob);
+  void setAckProb(double prob);
+
   MAC* mac();
   Radio* radio();
   Packet* newPacket();
Index: tos/lib/tossim/tossim_wrap.cxx
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/tossim_wrap.cxx,v
retrieving revision 1.6
diff -u -b -p -r1.6 tossim_wrap.cxx
--- tos/lib/tossim/tossim_wrap.cxx	15 Aug 2008 18:34:36 -0000	1.6
+++ tos/lib/tossim/tossim_wrap.cxx	9 Jul 2010 19:45:16 -0000
@@ -6068,6 +6068,269 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Tossim_initMoteNum(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_initMoteNum",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_initMoteNum" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_initMoteNum" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_initMoteNum" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->initMoteNum(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setDeltaDebugging(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setDeltaDebugging",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setDeltaDebugging" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setDeltaDebugging" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  (arg1)->setDeltaDebugging(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setLossAndBiasingAndTossim(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  int arg4 ;
+  int val4 ;
+  int ecode4 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:Tossim_setLossAndBiasingAndTossim",&obj0, &obj1, &obj2, &obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+
+  (arg1)->setLossAndBiasingAndTossim(arg2, arg3, arg4);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_mcMoteRevival(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_mcMoteRevival",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_mcMoteRevival" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_mcMoteRevival" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_mcMoteRevival" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->mcMoteRevival(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_mcMoteDeath(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_mcMoteDeath",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_mcMoteDeath" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_mcMoteDeath" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_mcMoteDeath" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->mcMoteDeath(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_mcMoteReboot(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_mcMoteReboot",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_mcMoteReboot" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_mcMoteReboot" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_mcMoteReboot" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->mcMoteReboot(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
 SWIGINTERN PyObject *_wrap_Tossim_time(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Tossim *arg1 = (Tossim *) 0 ;
@@ -6384,6 +6647,239 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Tossim_startTossim(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_startTossim",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_startTossim" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_startTossim" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_startTossim" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  (arg1)->startTossim(arg2,arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_startModelChecking(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  
+  char *arg2 = (char *) 0 ;
+  int res2;
+  char *buf2 = 0 ;
+  int alloc2 = 0 ;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  int arg4 ;
+  int val4 ;
+  int ecode4 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:Tossim_startModelChecking",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_startModelChecking" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Tossim_startModelChecking" "', argument " "2"" of type '" "char *""'");
+  }
+  arg2 = reinterpret_cast< char * >(buf2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_startModelChecking" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Tossim_startModelChecking" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+
+  (arg1)->startModelChecking(arg2, arg3, arg4);
+  resultobj = SWIG_Py_Void();
+  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  return resultobj;
+fail:
+  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_startRandomWalk(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_startRandomWalk",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_startRandomWalk" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_startRandomWalk" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_startRandomWalk" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  (arg1)->startRandomWalk(arg2,arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setSendProb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  double arg2 ;
+  double val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setSendProb",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setSendProb" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setSendProb" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setSendProb(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setReceiveProb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  double arg2 ;
+  double val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setReceiveProb",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setReceiveProb" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setReceiveProb" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setReceiveProb(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setAckProb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  double arg2 ;
+  double val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setAckProb",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setAckProb" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setAckProb" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setAckProb(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
 SWIGINTERN PyObject *_wrap_Tossim_mac(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Tossim *arg1 = (Tossim *) 0 ;
@@ -6555,6 +7051,12 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"new_Tossim", _wrap_new_Tossim, METH_VARARGS, NULL},
 	 { (char *)"delete_Tossim", _wrap_delete_Tossim, METH_VARARGS, NULL},
 	 { (char *)"Tossim_init", _wrap_Tossim_init, METH_VARARGS, NULL},
+	 { (char *)"Tossim_initMoteNum", _wrap_Tossim_initMoteNum, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setDeltaDebugging", _wrap_Tossim_setDeltaDebugging, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setLossAndBiasingAndTossim", _wrap_Tossim_setLossAndBiasingAndTossim, METH_VARARGS, NULL},
+	 { (char *)"Tossim_mcMoteRevival", _wrap_Tossim_mcMoteRevival, METH_VARARGS, NULL},
+	 { (char *)"Tossim_mcMoteDeath", _wrap_Tossim_mcMoteDeath, METH_VARARGS, NULL},
+	 { (char *)"Tossim_mcMoteReboot", _wrap_Tossim_mcMoteReboot, METH_VARARGS, NULL},
 	 { (char *)"Tossim_time", _wrap_Tossim_time, METH_VARARGS, NULL},
 	 { (char *)"Tossim_ticksPerSecond", _wrap_Tossim_ticksPerSecond, METH_VARARGS, NULL},
 	 { (char *)"Tossim_setTime", _wrap_Tossim_setTime, METH_VARARGS, NULL},
@@ -6566,6 +7068,12 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"Tossim_removeChannel", _wrap_Tossim_removeChannel, METH_VARARGS, NULL},
 	 { (char *)"Tossim_randomSeed", _wrap_Tossim_randomSeed, METH_VARARGS, NULL},
 	 { (char *)"Tossim_runNextEvent", _wrap_Tossim_runNextEvent, METH_VARARGS, NULL},
+	 { (char *)"Tossim_startTossim", _wrap_Tossim_startTossim, METH_VARARGS, NULL},
+	 { (char *)"Tossim_startModelChecking", _wrap_Tossim_startModelChecking, METH_VARARGS, NULL},
+	 { (char *)"Tossim_startRandomWalk", _wrap_Tossim_startRandomWalk, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setSendProb", _wrap_Tossim_setSendProb, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setReceiveProb", _wrap_Tossim_setReceiveProb, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setAckProb", _wrap_Tossim_setAckProb, METH_VARARGS, NULL},
 	 { (char *)"Tossim_mac", _wrap_Tossim_mac, METH_VARARGS, NULL},
 	 { (char *)"Tossim_radio", _wrap_Tossim_radio, METH_VARARGS, NULL},
 	 { (char *)"Tossim_newPacket", _wrap_Tossim_newPacket, METH_VARARGS, NULL},
Index: tos/lib/tossim/sf/TOSSIM.py
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/TOSSIM.py,v
retrieving revision 1.1
diff -u -b -p -r1.1 TOSSIM.py
--- tos/lib/tossim/sf/TOSSIM.py	3 Oct 2007 01:50:20 -0000	1.1
+++ tos/lib/tossim/sf/TOSSIM.py	9 Jul 2010 19:45:17 -0000
@@ -310,6 +310,12 @@ class Tossim(_object):
     __swig_destroy__ = _TOSSIM.delete_Tossim
     __del__ = lambda self : None;
     def init(*args): return _TOSSIM.Tossim_init(*args)
+    def initMoteNum(*args): return _TOSSIM.Tossim_initMoteNum(*args)
+    def setDeltaDebugging(*args): return _TOSSIM.Tossim_setDeltaDebugging(*args)
+    def setLossAndBiasingAndTossim(*args): return _TOSSIM.Tossim_setLossAndBiasingAndTossim(*args)
+    def mcMoteRevival(*args): return _TOSSIM.Tossim_mcMoteRevival(*args)
+    def mcMoteDeath(*args): return _TOSSIM.Tossim_mcMoteDeath(*args)
+    def mcMoteReboot(*args): return _TOSSIM.Tossim_mcMoteReboot(*args)
     def time(*args): return _TOSSIM.Tossim_time(*args)
     def ticksPerSecond(*args): return _TOSSIM.Tossim_ticksPerSecond(*args)
     def setTime(*args): return _TOSSIM.Tossim_setTime(*args)
@@ -321,6 +327,12 @@ class Tossim(_object):
     def removeChannel(*args): return _TOSSIM.Tossim_removeChannel(*args)
     def randomSeed(*args): return _TOSSIM.Tossim_randomSeed(*args)
     def runNextEvent(*args): return _TOSSIM.Tossim_runNextEvent(*args)
+    def startTossim(*args): return _TOSSIM.Tossim_startTossim(*args)
+    def startModelChecking(*args): return _TOSSIM.Tossim_startModelChecking(*args)
+    def startRandomWalk(*args): return _TOSSIM.Tossim_startRandomWalk(*args)
+    def setSendProb(*args): return _TOSSIM.Tossim_setSendProb(*args)
+    def setReceiveProb(*args): return _TOSSIM.Tossim_setReceiveProb(*args)
+    def setAckProb(*args): return _TOSSIM.Tossim_setAckProb(*args)
     def mac(*args): return _TOSSIM.Tossim_mac(*args)
     def radio(*args): return _TOSSIM.Tossim_radio(*args)
     def newPacket(*args): return _TOSSIM.Tossim_newPacket(*args)
Index: tos/lib/tossim/sf/tossim.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/tossim.c,v
retrieving revision 1.2
diff -u -b -p -r1.2 tossim.c
--- tos/lib/tossim/sf/tossim.c	29 Jun 2010 22:07:51 -0000	1.2
+++ tos/lib/tossim/sf/tossim.c	9 Jul 2010 19:45:17 -0000
@@ -228,6 +228,30 @@ void Tossim::init() {
   memset(motes, 0, sizeof(Mote*) * TOSSIM_MAX_NODES);
 }
 
+void Tossim::initMoteNum(int moteNum, int propertyNum) {
+  sim_init_mote_num(moteNum, propertyNum);
+}
+
+void Tossim::setDeltaDebugging(int delta) {
+  sim_set_delta_debugging(delta);
+}
+
+void Tossim::setLossAndBiasingAndTossim(int loss_mode, int bias_mode, int tossim_mode) {
+  sim_set_loss_bias_tossim(loss_mode, bias_mode, tossim_mode);
+}
+
+void Tossim::mcMoteRevival(int mote, int step) {
+  sim_mc_mote_revival(mote, step);
+}
+
+void Tossim::mcMoteDeath(int mote, int step) {
+  sim_mc_mote_death(mote, step);
+}
+
+void Tossim::mcMoteReboot(int mote, int step) {
+  sim_mc_mote_reboot(mote, step);
+}
+
 long long int Tossim::time() {
   return sim_time();
 }
@@ -288,6 +312,30 @@ bool Tossim::runNextEvent() {
   return sim_run_next_event();
 }
 
+void Tossim::startTossim(int TOSSIM_BOUND, int Rounds) {
+  sim_start_tossim(TOSSIM_BOUND, Rounds);
+}
+
+void Tossim::startModelChecking(char* mode, int MC_BOUND, int RW_BOUND) {
+  sim_start_model_checking(mode, MC_BOUND, RW_BOUND);
+}
+
+void Tossim::startRandomWalk(int RW_BOUND, int Rounds) {
+  sim_start_random_walk(RW_BOUND, Rounds);
+}
+
+void Tossim::setSendProb(double prob) {
+  sim_set_send_probability(prob);
+}
+
+void Tossim::setReceiveProb(double prob) {
+  sim_set_receive_probability(prob);
+}
+
+void Tossim::setAckProb(double prob) {
+  sim_set_ack_probability(prob);
+}
+
 MAC* Tossim::mac() {
   return new MAC();
 }
Index: tos/lib/tossim/sf/tossim.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/tossim.h,v
retrieving revision 1.2
diff -u -b -p -r1.2 tossim.h
--- tos/lib/tossim/sf/tossim.h	29 Jun 2010 22:07:51 -0000	1.2
+++ tos/lib/tossim/sf/tossim.h	9 Jul 2010 19:45:17 -0000
@@ -120,6 +120,12 @@ class Tossim {
   ~Tossim();
   
   void init();
+  void initMoteNum(int moteNum, int propertyNum);
+  void setDeltaDebugging(int delta);
+  void setLossAndBiasingAndTossim(int loss_mode, int bias_mode, int tossim_mode);
+  void mcMoteRevival(int mote, int step);
+  void mcMoteDeath(int mote, int step);
+  void mcMoteReboot(int mote, int step);
   
   long long int time();
   long long int ticksPerSecond();
@@ -135,6 +141,13 @@ class Tossim {
   void randomSeed(int seed);
   
   bool runNextEvent();
+  void startTossim(int TOSSIM_BOUND, int Rounds);
+  void startModelChecking(char* mode, int MC_BOUND, int RW_BOUND);
+  void startRandomWalk(int RW_BOUND, int Rounds);
+  
+  void setSendProb(double prob); 
+  void setReceiveProb(double prob); 
+  void setAckProb(double prob); 
 
   MAC* mac();
   Radio* radio();
Index: tos/lib/tossim/sf/tossim.i
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/tossim.i,v
retrieving revision 1.2
diff -u -b -p -r1.2 tossim.i
--- tos/lib/tossim/sf/tossim.i	29 Jun 2010 22:07:51 -0000	1.2
+++ tos/lib/tossim/sf/tossim.i	9 Jul 2010 19:45:17 -0000
@@ -372,6 +372,12 @@ class Tossim {
   ~Tossim();
   
   void init();
+  void initMoteNum(int moteNum, int propertyNum);
+  void setDeltaDebugging(int delta);
+  void setLossAndBiasingAndTossim(int loss_mode, int bias_mode, int tossim_mode);
+  void mcMoteRevival(int mote, int step);
+  void mcMoteDeath(int mote, int step);
+  void mcMoteReboot(int mote, int step);
   
   long long int time();
   long long int ticksPerSecond(); 
@@ -387,6 +393,14 @@ class Tossim {
   void randomSeed(int seed);
 
   bool runNextEvent();
+  void startTossim(int TOSSIM_BOUND, int Rounds);
+  void startModelChecking(char* mode, int MC_BOUND, int RW_BOUND);
+  void startRandomWalk(int RW_BOUND, int Rounds);
+
+  void setSendProb(double prob);
+  void setReceiveProb(double prob);
+  void setAckProb(double prob);
+
   MAC* mac();
   Radio* radio();
   Packet* newPacket();
Index: tos/lib/tossim/sf/tossim_wrap.cxx
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/tossim_wrap.cxx,v
retrieving revision 1.1
diff -u -b -p -r1.1 tossim_wrap.cxx
--- tos/lib/tossim/sf/tossim_wrap.cxx	3 Oct 2007 01:50:20 -0000	1.1
+++ tos/lib/tossim/sf/tossim_wrap.cxx	9 Jul 2010 19:45:17 -0000
@@ -6706,6 +6706,269 @@ fail:
   return NULL;
 }
 
+SWIGINTERN PyObject *_wrap_Tossim_initMoteNum(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+ 
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_initMoteNum",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_initMoteNum" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_initMoteNum" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_initMoteNum" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->initMoteNum(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setDeltaDebugging(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setDeltaDebugging",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setDeltaDebugging" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setDeltaDebugging" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  (arg1)->setDeltaDebugging(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setLossAndBiasingAndTossim(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  int arg4 ;
+  int val4 ;
+  int ecode4 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:Tossim_setLossAndBiasingAndTossim",&obj0, &obj1, &obj2, &obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Tossim_setLossAndBiasingAndTossim" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+
+  (arg1)->setLossAndBiasingAndTossim(arg2, arg3, arg4);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_mcMoteRevival(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_mcMoteRevival",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_mcMoteRevival" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_mcMoteRevival" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_mcMoteRevival" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->mcMoteRevival(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_mcMoteDeath(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_mcMoteDeath",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_mcMoteDeath" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_mcMoteDeath" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_mcMoteDeath" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->mcMoteDeath(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_mcMoteReboot(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_mcMoteReboot",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_mcMoteReboot" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_mcMoteReboot" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_mcMoteReboot" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  (arg1)->mcMoteReboot(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
 
 SWIGINTERN PyObject *_wrap_Tossim_time(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
@@ -7022,6 +7285,238 @@ fail:
   return NULL;
 }
 
+SWIGINTERN PyObject *_wrap_Tossim_startTossim(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_startTossim",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_startTossim" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_startTossim" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_startTossim" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  (arg1)->startTossim(arg2,arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_startModelChecking(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  char *arg2 = (char *) 0 ;
+  int res2;
+  char *buf2 = 0 ;
+  int alloc2 = 0 ;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  int arg4 ;
+  int val4 ;
+  int ecode4 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:Tossim_startModelChecking",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_startModelChecking" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+
+  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Tossim_startModelChecking" "', argument " "2"" of type '" "char *""'");
+  }
+  arg2 = reinterpret_cast< char * >(buf2);
+
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_startModelChecking" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Tossim_startModelChecking" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+
+  (arg1)->startModelChecking(arg2, arg3, arg4);
+  resultobj = SWIG_Py_Void();
+  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  return resultobj;
+fail:
+  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_startRandomWalk(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  int arg2 ;
+  int val2 ;
+  int ecode2 = 0;
+
+  int arg3 ;
+  int val3 ;
+  int ecode3 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Tossim_startRandomWalk",&obj0, &obj1, &obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_startRandomWalk" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_startRandomWalk" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Tossim_startRandomWalk" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  (arg1)->startRandomWalk(arg2, arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setSendProb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  double arg2 ;
+  double val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setSendProb",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setSendProb" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setSendProb" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setSendProb(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setReceiveProb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  double arg2 ;
+  double val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setReceiveProb",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setReceiveProb" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setReceiveProb" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setReceiveProb(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+SWIGINTERN PyObject *_wrap_Tossim_setAckProb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Tossim *arg1 = (Tossim *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+
+  double arg2 ;
+  double val2 ;
+  int ecode2 = 0;
+
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+
+  if (!PyArg_ParseTuple(args,(char *)"OO:Tossim_setAckProb",&obj0, &obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Tossim, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tossim_setAckProb" "', argument " "1"" of type '" "Tossim *""'"); 
+  }
+  arg1 = reinterpret_cast< Tossim * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tossim_setAckProb" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setAckProb(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
 
 SWIGINTERN PyObject *_wrap_Tossim_mac(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
@@ -7243,6 +7738,12 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"new_Tossim", _wrap_new_Tossim, METH_VARARGS, NULL},
 	 { (char *)"delete_Tossim", _wrap_delete_Tossim, METH_VARARGS, NULL},
 	 { (char *)"Tossim_init", _wrap_Tossim_init, METH_VARARGS, NULL},
+	 { (char *)"Tossim_initMoteNum", _wrap_Tossim_initMoteNum, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setDeltaDebugging", _wrap_Tossim_setDeltaDebugging, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setLossAndBiasingAndTossim", _wrap_Tossim_setLossAndBiasingAndTossim, METH_VARARGS, NULL},
+	 { (char *)"Tossim_mcMoteRevival", _wrap_Tossim_mcMoteRevival, METH_VARARGS, NULL},
+	 { (char *)"Tossim_mcMoteDeath", _wrap_Tossim_mcMoteDeath, METH_VARARGS, NULL},
+	 { (char *)"Tossim_mcMoteReboot", _wrap_Tossim_mcMoteReboot, METH_VARARGS, NULL},
 	 { (char *)"Tossim_time", _wrap_Tossim_time, METH_VARARGS, NULL},
 	 { (char *)"Tossim_ticksPerSecond", _wrap_Tossim_ticksPerSecond, METH_VARARGS, NULL},
 	 { (char *)"Tossim_setTime", _wrap_Tossim_setTime, METH_VARARGS, NULL},
@@ -7254,6 +7755,12 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"Tossim_removeChannel", _wrap_Tossim_removeChannel, METH_VARARGS, NULL},
 	 { (char *)"Tossim_randomSeed", _wrap_Tossim_randomSeed, METH_VARARGS, NULL},
 	 { (char *)"Tossim_runNextEvent", _wrap_Tossim_runNextEvent, METH_VARARGS, NULL},
+	 { (char *)"Tossim_startTossim", _wrap_Tossim_startTossim, METH_VARARGS, NULL},
+	 { (char *)"Tossim_startModelChecking", _wrap_Tossim_startModelChecking, METH_VARARGS, NULL},
+	 { (char *)"Tossim_startRandomWalk", _wrap_Tossim_startRandomWalk, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setSendProb", _wrap_Tossim_setSendProb, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setReceiveProb", _wrap_Tossim_setReceiveProb, METH_VARARGS, NULL},
+	 { (char *)"Tossim_setAckProb", _wrap_Tossim_setAckProb, METH_VARARGS, NULL},
 	 { (char *)"Tossim_mac", _wrap_Tossim_mac, METH_VARARGS, NULL},
 	 { (char *)"Tossim_radio", _wrap_Tossim_radio, METH_VARARGS, NULL},
 	 { (char *)"Tossim_newPacket", _wrap_Tossim_newPacket, METH_VARARGS, NULL},
Index: tos/lib/tossim/sf/sim/MainC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/sim/MainC.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 MainC.nc
--- tos/lib/tossim/sf/sim/MainC.nc	29 Jun 2010 22:07:51 -0000	1.2
+++ tos/lib/tossim/sf/sim/MainC.nc	9 Jul 2010 19:45:17 -0000
@@ -57,6 +57,10 @@ implementation {
   // includes functionality many other systems depend on.
   components SimMoteP;
   
+#ifdef SAFE_TINYOS
+  components SimSafeFailureHandlerP;
+#endif
+
   SimMainP.Scheduler -> TinySchedulerC;
   SimMainP.PlatformInit -> PlatformC;
 
@@ -70,8 +74,12 @@ implementation {
   // the application does not wire this up to, e.g., ActiveMessageC,
   // the default handlers make sure nothing happens when a script
   // tries to deliver a packet to a node that has no radio stack.
+
   components TossimActiveMessageC;
   components SerialActiveMessageC;
   
+#if defined(SAFETY) || defined(LIVENESS) 
+  components SimPropertyCheckC;
+#endif
 }
 
Index: tos/lib/tossim/sf/sim/SerialActiveMessageC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/sim/SerialActiveMessageC.nc,v
retrieving revision 1.3
diff -u -b -p -r1.3 SerialActiveMessageC.nc
--- tos/lib/tossim/sf/sim/SerialActiveMessageC.nc	22 Jun 2010 20:50:43 -0000	1.3
+++ tos/lib/tossim/sf/sim/SerialActiveMessageC.nc	9 Jul 2010 19:45:17 -0000
@@ -1,296 +1,82 @@
-// $Id: SerialActiveMessageC.nc,v 1.3 2010/06/22 20:50:43 scipio Exp $
+//$Id: SerialActiveMessageC.nc,v 1.4 2006/12/12 18:23:31 vlahan Exp $
+
 /*
  * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the
- *   distribution.
- * - Neither the name of Toilers Research Group - Colorado School of 
- *   Mines  nor the names of its contributors may be used to endorse 
- *   or promote products derived from this software without specific
- *   prior written permission.
+ * 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.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
- * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 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: Chad Metcalf
- * Date: July 9, 2007
+ * Sending active messages over the serial port.
  *
- * The Serial Active Message implementation for use with the TOSSIM Live
- * extensions.
+ * @author Philip Levis
+ * @author Ben Greenstein
+ * @date August 7 2005
  *
  */
 
 #include <AM.h>
-#include <Serial.h>
-#include "sim_serial_forwarder.h"
+#include "Serial.h"
 
-module SerialActiveMessageC {
+configuration SerialActiveMessageC {
     provides {
         interface SplitControl;
 
         interface AMSend[am_id_t id];
         interface Receive[am_id_t id];
-        interface Receive as Snoop[am_id_t id];
 
         interface Packet;
         interface AMPacket;
-        interface PacketAcknowledgements as Acks;
-    }
-    uses {
-        interface TossimPacketModel as Model;
-        command am_addr_t amAddress();
+    interface PacketAcknowledgements;
     }
+#ifdef UARTON
+  uses interface Leds;
+#endif
 }
 implementation {
 
-    message_t buffer;
-    message_t* bufferPointer = &buffer;
-    
-    message_t* sendMsgPtr = NULL;
-
-    serial_header_t* getHeader(message_t* amsg) {
-        return (serial_header_t*)(amsg->data - sizeof(serial_header_t));
-    }
-
-    task void startDone() { signal SplitControl.startDone(SUCCESS); }
-    task void stopDone() { signal SplitControl.stopDone(SUCCESS); }
-
-    command error_t SplitControl.start() {
-        post startDone();
-        return SUCCESS;
-    }
-
-    command error_t SplitControl.stop() {
-        post stopDone();
-        return SUCCESS;
-    }
-
-    command error_t AMSend.send[am_id_t id](am_addr_t addr,
-                                            message_t* amsg,
-                                            uint8_t len) {
-        error_t err;
-        serial_header_t* header = getHeader(amsg);
-        
-        header->type = id;
-        header->dest = addr;
-        // For out going serial messages we'll use the real TOS_NODE_ID
-        header->src = TOS_NODE_ID;
-        header->length = len;
-        err = call Model.send((int)addr, amsg, len + sizeof(serial_header_t));
-        return err;
-    }
-
-    command error_t AMSend.cancel[am_id_t id](message_t* msg) {
-        dbg("Serial", "SerialAM: cancelled a packet\n");
-        return call Model.cancel(msg);
-    }
-
-    command uint8_t AMSend.maxPayloadLength[am_id_t id]() {
-        return call Packet.maxPayloadLength();
-    }
-
-    command void* AMSend.getPayload[am_id_t id](message_t* m, uint8_t len) {
-        return call Packet.getPayload(m, len);
-    }
-
-    event void Model.sendDone(message_t* msg, error_t result) {
-        signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);
-    }
-
-    task void modelSendDone ()
-    {
-        signal Model.sendDone(sendMsgPtr, SUCCESS);
-    }
-
-    default command error_t Model.send(int node, message_t* msg, uint8_t len) {
-
-        sendMsgPtr = msg;
-
-        dbg("Serial", "Sending serial message (%p) of type %hhu and length %hhu @ %s.\n",
-            msg, call AMPacket.type(msg), len, sim_time_string());
-        sim_sf_dispatch_packet((void*)msg, len);
-        
-        post modelSendDone ();
-
-        return SUCCESS;
-    }
-
-    /* Receiving a packet */
-
-    event void Model.receive(message_t* msg) {
-        uint8_t len;
-        void* payload;
-
-        memcpy(bufferPointer, msg, sizeof(message_t));
-	
-	if (msg != NULL) {
-	  free(msg);
-	}
-	
-        payload = call Packet.getPayload(bufferPointer, call Packet.maxPayloadLength());
-        len = call Packet.payloadLength(bufferPointer);
-
-        dbg("Serial", "Received serial message (%p) of type %hhu and length %hhu @ %s.\n",
-            bufferPointer, call AMPacket.type(bufferPointer), len, sim_time_string());
-        bufferPointer = signal Receive.receive[call AMPacket.type(bufferPointer)]
-            (bufferPointer, payload, len);
-    }
-
-    event bool Model.shouldAck(message_t* msg) {
-        serial_header_t* header = getHeader(msg);
-        if (header->dest == call amAddress()) {
-            dbg("Acks", "Received packet addressed to me so ack it\n");
-            return TRUE;
-        }
-        return FALSE;
-    }
-
-    command am_addr_t AMPacket.address() {
-        return call amAddress();
-    }
-
-    command am_addr_t AMPacket.destination(message_t* amsg) {
-        serial_header_t* header = getHeader(amsg);
-        return header->dest;
-    }
-
-    command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {
-        serial_header_t* header = getHeader(amsg);
-        header->dest = addr;
-    }
-
-    command am_addr_t AMPacket.source(message_t* amsg) {
-        serial_header_t* header = getHeader(amsg);
-        return header->src;
-    }
-
-    command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {
-        serial_header_t* header = getHeader(amsg);
-        header->src = addr;
-    }
-
-    command bool AMPacket.isForMe(message_t* amsg) {
-        return (call AMPacket.destination(amsg) == call AMPacket.address() ||
-                call AMPacket.destination(amsg) == AM_BROADCAST_ADDR);
-    }
-
-    command am_id_t AMPacket.type(message_t* amsg) {
-        serial_header_t* header = getHeader(amsg);
-        return header->type;
-    }
-
-    command void AMPacket.setType(message_t* amsg, am_id_t t) {
-        serial_header_t* header = getHeader(amsg);
-        header->type = t;
-    }
-
-    command am_group_t AMPacket.group(message_t* amsg) {
-        serial_header_t* header = getHeader(amsg);
-        return header->group;
-    }
-
-    command void AMPacket.setGroup(message_t* msg, am_group_t group) {
-        serial_header_t* header = getHeader(msg);
-        header->group = group;
-    }
-
-    command am_group_t AMPacket.localGroup() {
-        return TOS_AM_GROUP;
-    }
-    command void Packet.clear(message_t* msg) {}
-
-    command void* Packet.getPayload(message_t* msg, uint8_t len) {
-        if (len <= TOSH_DATA_LENGTH) {
-            return msg->data;
-        } else {
-            return NULL;
-        }
-    }
-
-    command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
-        getHeader(msg)->length = len;
-    }
-
-    command uint8_t Packet.maxPayloadLength() {
-        return TOSH_DATA_LENGTH;
-    }
-
-    command uint8_t Packet.payloadLength(message_t* msg) {
-        return getHeader(msg)->length;
-    }
-
-    async command error_t Acks.requestAck(message_t* msg) {
-        return FAIL;
-    }
-
-    async command error_t Acks.noAck(message_t* msg) {
-        return SUCCESS;
-    }
-
-    async command bool Acks.wasAcked(message_t* msg) {
-        return FALSE;
-    }
-    default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
-        return msg;
-    }
-
-    default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
-        return msg;
-    }
+#ifdef UARTON
+  components SerialActiveMessageP as AM, SerialDispatcherC;
+  components SerialPacketInfoActiveMessageP as Info, MainC;
+  MainC.SoftwareInit -> SerialDispatcherC;
+  Leds = SerialDispatcherC;
+  SplitControl = SerialDispatcherC;
+
+  AMSend = AM;
+  Receive = AM;
+  Packet = AM;
+  AMPacket = AM;
+  PacketAcknowledgements = AM;
+  
+  AM.SubSend -> SerialDispatcherC.Send[TOS_SERIAL_ACTIVE_MESSAGE_ID];
+  AM.SubReceive -> SerialDispatcherC.Receive[TOS_SERIAL_ACTIVE_MESSAGE_ID];
+  
+  SerialDispatcherC.SerialPacketInfo[TOS_SERIAL_ACTIVE_MESSAGE_ID] -> Info;
+#else
+  components SerialActiveMessageOrigP as AM;
+
+  SplitControl = AM;
+  AMSend = AM;
+  Receive = AM.Receive;
+
+  Packet = AM;
+  AMPacket = AM;
+  PacketAcknowledgements = AM;
+#endif
 
-    default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {
-        return;
-    }
-
-    default command error_t Model.cancel(message_t* msg) {
-        return FAIL;
-    }
-
-    default command am_addr_t amAddress() {
-        return 0;
-    }
-
-    void serial_active_message_deliver_handle(sim_event_t* evt) {
-        message_t* m = (message_t*)evt->data;
-        signal Model.receive(m);
-    }
-
-    sim_event_t* allocate_serial_deliver_event(int node, message_t* msg, sim_time_t t) {
-        sim_event_t* evt = (sim_event_t*)malloc(sizeof(sim_event_t));
-	message_t* newMsg = (message_t*)malloc(sizeof(message_t));
-	memcpy(newMsg, msg, sizeof(message_t));
-	
-        evt->mote = node;
-        evt->time = t;
-        evt->handle = serial_active_message_deliver_handle;
-        evt->cleanup = sim_queue_cleanup_event;
-        evt->cancelled = 0;
-        evt->force = 0;
-        evt->data = newMsg;
-        return evt;
-    }
-
-    void serial_active_message_deliver(int node, message_t* msg, sim_time_t t) @C() @spontaneous() {
-        sim_event_t* evt = allocate_serial_deliver_event(node, msg, t);
-        sim_queue_insert(evt);
-    }
 }
Index: tos/lib/tossim/sf/sim/SerialActiveMessageOrigP.nc
===================================================================
RCS file: tos/lib/tossim/sf/sim/SerialActiveMessageOrigP.nc
diff -N tos/lib/tossim/sf/sim/SerialActiveMessageOrigP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sf/sim/SerialActiveMessageOrigP.nc	9 Jul 2010 19:45:17 -0000
@@ -0,0 +1,300 @@
+// $Id: SerialActiveMessageC.nc,v 1.2 2007/12/03 02:17:49 hiro Exp $
+/*
+ * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of Toilers Research Group - Colorado School of 
+ *   Mines  nor the names of its contributors may be used to endorse 
+ *   or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * Author: Chad Metcalf
+ * Date: July 9, 2007
+ *
+ * The Serial Active Message implementation for use with the TOSSIM Live
+ * extensions.
+ *
+ */
+
+#include <AM.h>
+#include <Serial.h>
+#include "sim_serial_forwarder.h"
+
+module SerialActiveMessageOrigP {
+    provides {
+        interface SplitControl;
+
+        interface AMSend[am_id_t id];
+        interface Receive[am_id_t id];
+        interface Receive as Snoop[am_id_t id];
+
+        interface Packet;
+        interface AMPacket;
+        interface PacketAcknowledgements as Acks;
+    }
+    uses {
+        interface TossimPacketModel as Model;
+        command am_addr_t amAddress();
+    }
+}
+implementation {
+
+    message_t buffer;
+    message_t* bufferPointer = &buffer;
+    
+    message_t* sendMsgPtr = NULL;
+
+    serial_header_t* getHeader(message_t* amsg) {
+        return (serial_header_t*)(amsg->data - sizeof(serial_header_t));
+    }
+
+    task void startDone() { signal SplitControl.startDone(SUCCESS); }
+    task void stopDone() { signal SplitControl.stopDone(SUCCESS); }
+
+    command error_t SplitControl.start() {
+        post startDone();
+        return SUCCESS;
+    }
+
+    command error_t SplitControl.stop() {
+        post stopDone();
+        return SUCCESS;
+    }
+
+    command error_t AMSend.send[am_id_t id](am_addr_t addr,
+                                            message_t* amsg,
+                                            uint8_t len) {
+        error_t err;
+        serial_header_t* header = getHeader(amsg);
+        
+        header->type = id;
+        header->dest = addr;
+        // For out going serial messages we'll use the real TOS_NODE_ID
+        header->src = TOS_NODE_ID;
+        header->length = len;
+        err = call Model.send((int)addr, amsg, len + sizeof(serial_header_t));
+        return err;
+    }
+
+    command error_t AMSend.cancel[am_id_t id](message_t* msg) {
+        dbg("Serial", "SerialAM: cancelled a packet\n");
+        return call Model.cancel(msg);
+    }
+
+    command uint8_t AMSend.maxPayloadLength[am_id_t id]() {
+        return call Packet.maxPayloadLength();
+    }
+
+    command void* AMSend.getPayload[am_id_t id](message_t* m, uint8_t len) {
+        return call Packet.getPayload(m, len);
+    }
+
+    event void Model.sendDone(message_t* msg, error_t result) {
+        signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);
+    }
+
+    task void modelSendDone ()
+    {
+        signal Model.sendDone(sendMsgPtr, SUCCESS);
+    }
+
+    default command error_t Model.send(int node, message_t* msg, uint8_t len) {
+
+        sendMsgPtr = msg;
+
+        dbg("Serial", "Sending serial message (%p) of type %hhu and length %hhu @ %s.\n",
+            msg, call AMPacket.type(msg), len, sim_time_string());
+        sim_sf_dispatch_packet((void*)msg, len);
+        
+        post modelSendDone ();
+
+        return SUCCESS;
+    }
+
+    /* Receiving a packet */
+
+    event void Model.receive(message_t* msg) {
+        uint8_t len;
+        void* payload;
+
+        memcpy(bufferPointer, msg, sizeof(message_t));
+
+	if (msg != NULL) {
+	  free(msg);
+	}
+
+	if (msg != NULL) {
+	  free(msg);
+	}
+
+        payload = call Packet.getPayload(bufferPointer, call Packet.maxPayloadLength());
+        len = call Packet.payloadLength(bufferPointer);
+
+        dbg("Serial", "Received serial message (%p) of type %hhu and length %hhu @ %s.\n",
+            bufferPointer, call AMPacket.type(bufferPointer), len, sim_time_string());
+        bufferPointer = signal Receive.receive[call AMPacket.type(bufferPointer)]
+            (bufferPointer, payload, len);
+    }
+
+    event bool Model.shouldAck(message_t* msg) {
+        serial_header_t* header = getHeader(msg);
+        if (header->dest == call amAddress()) {
+            dbg("Acks", "Received packet addressed to me so ack it\n");
+            return TRUE;
+        }
+        return FALSE;
+    }
+
+    command am_addr_t AMPacket.address() {
+        return call amAddress();
+    }
+
+    command am_addr_t AMPacket.destination(message_t* amsg) {
+        serial_header_t* header = getHeader(amsg);
+        return header->dest;
+    }
+
+    command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {
+        serial_header_t* header = getHeader(amsg);
+        header->dest = addr;
+    }
+
+    command am_addr_t AMPacket.source(message_t* amsg) {
+        serial_header_t* header = getHeader(amsg);
+        return header->src;
+    }
+
+    command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {
+        serial_header_t* header = getHeader(amsg);
+        header->src = addr;
+    }
+
+    command bool AMPacket.isForMe(message_t* amsg) {
+        return (call AMPacket.destination(amsg) == call AMPacket.address() ||
+                call AMPacket.destination(amsg) == AM_BROADCAST_ADDR);
+    }
+
+    command am_id_t AMPacket.type(message_t* amsg) {
+        serial_header_t* header = getHeader(amsg);
+        return header->type;
+    }
+
+    command void AMPacket.setType(message_t* amsg, am_id_t t) {
+        serial_header_t* header = getHeader(amsg);
+        header->type = t;
+    }
+
+    command am_group_t AMPacket.group(message_t* amsg) {
+        serial_header_t* header = getHeader(amsg);
+        return header->group;
+    }
+
+    command void AMPacket.setGroup(message_t* msg, am_group_t group) {
+        serial_header_t* header = getHeader(msg);
+        header->group = group;
+    }
+
+    command am_group_t AMPacket.localGroup() {
+        return TOS_AM_GROUP;
+    }
+    command void Packet.clear(message_t* msg) {}
+
+    command void* Packet.getPayload(message_t* msg, uint8_t len) {
+        if (len <= TOSH_DATA_LENGTH) {
+            return msg->data;
+        } else {
+            return NULL;
+        }
+    }
+
+    command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+        getHeader(msg)->length = len;
+    }
+
+    command uint8_t Packet.maxPayloadLength() {
+        return TOSH_DATA_LENGTH;
+    }
+
+    command uint8_t Packet.payloadLength(message_t* msg) {
+        return getHeader(msg)->length;
+    }
+
+    async command error_t Acks.requestAck(message_t* msg) {
+        return FAIL;
+    }
+
+    async command error_t Acks.noAck(message_t* msg) {
+        return SUCCESS;
+    }
+
+    async command bool Acks.wasAcked(message_t* msg) {
+        return FALSE;
+    }
+    default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
+        return msg;
+    }
+
+    default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
+        return msg;
+    }
+
+    default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {
+        return;
+    }
+
+    default command error_t Model.cancel(message_t* msg) {
+        return FAIL;
+    }
+
+    default command am_addr_t amAddress() {
+        return 0;
+    }
+
+    void serial_active_message_deliver_handle(sim_event_t* evt) {
+        message_t* m = (message_t*)evt->data;
+        signal Model.receive(m);
+    }
+
+    sim_event_t* allocate_serial_deliver_event(int node, message_t* msg, sim_time_t t) {
+        sim_event_t* evt = (sim_event_t*)malloc(sizeof(sim_event_t));
+	message_t* newMsg = (message_t*)malloc(sizeof(message_t));
+	memcpy(newMsg, msg, sizeof(message_t));
+
+        evt->mote = node;
+        evt->time = t;
+        evt->handle = serial_active_message_deliver_handle;
+        evt->cleanup = sim_queue_cleanup_event;
+        evt->cancelled = 0;
+        evt->force = 0;
+        evt->data = newMsg;
+        return evt;
+    }
+
+    void serial_active_message_deliver(int node, message_t* msg, sim_time_t t) @C() @spontaneous() {
+        sim_event_t* evt = allocate_serial_deliver_event(node, msg, t);
+        sim_queue_insert_general(evt, SERIAL);
+    }
+}
Index: tos/lib/tossim/sf/sim/SerialActiveMessageP.nc
===================================================================
RCS file: tos/lib/tossim/sf/sim/SerialActiveMessageP.nc
diff -N tos/lib/tossim/sf/sim/SerialActiveMessageP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/lib/tossim/sf/sim/SerialActiveMessageP.nc	9 Jul 2010 19:45:17 -0000
@@ -0,0 +1,231 @@
+//$Id: SerialActiveMessageP.nc,v 1.9 2008/06/04 03:43:50 regehr 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."
+ */
+
+/**
+ * Sending active messages over the serial port.
+ *
+ * @author Philip Levis
+ * @author Ben Greenstein
+ * @date August 7 2005
+ *
+ */
+
+#include <Serial.h>
+
+module SerialActiveMessageP @safe() {
+  provides {
+    interface AMSend[am_id_t id];
+    interface Receive[am_id_t id];
+    interface AMPacket;
+    interface Packet;
+    interface PacketAcknowledgements;
+  }
+  uses {
+    interface Send as SubSend;
+    interface Receive as SubReceive;
+  }
+}
+implementation {
+
+  message_t buffer;
+  message_t* ONE_NOK bufferPointer = &buffer;
+
+  serial_header_t* ONE getHeader(message_t* ONE msg) {
+    return TCAST(serial_header_t* ONE, (uint8_t*)msg + offsetof(message_t, data) - sizeof(serial_header_t));
+  }
+
+  serial_metadata_t* getMetadata(message_t* msg) {
+    return (serial_metadata_t*)(msg->metadata);
+  }
+  
+  command error_t AMSend.send[am_id_t id](am_addr_t dest,
+					  message_t* msg,
+					  uint8_t len) {
+    serial_header_t* header = getHeader(msg);
+    
+    if (len > call Packet.maxPayloadLength()) {
+       return ESIZE;
+    }
+
+    header->dest = dest;
+    // Do not set the source address or group, as doing so
+    // prevents transparent bridging. Need a better long-term
+    // solution for this.
+    //header->src = call AMPacket.address();
+    //header->group = TOS_AM_GROUP;
+    header->type = id;
+    header->length = len;
+
+    return call SubSend.send(msg, len);
+  }
+
+  command error_t AMSend.cancel[am_id_t id](message_t* msg) {
+    return call SubSend.cancel(msg);
+  }
+
+  command uint8_t AMSend.maxPayloadLength[am_id_t id]() {
+    return call Packet.maxPayloadLength();
+  }
+
+  command void* AMSend.getPayload[am_id_t id](message_t* m, uint8_t len) {
+    return call Packet.getPayload(m, len);
+  }
+  
+  event void SubSend.sendDone(message_t* msg, error_t result) {
+    signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);
+  }
+
+ default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t result) {
+    return;
+ }
+
+ default event message_t* Receive.receive[uint8_t id](message_t* msg, void* payload, uint8_t len) {
+   return msg;
+ }
+ 
+ event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) {
+    return signal Receive.receive[call AMPacket.type(msg)](msg, msg->data, len);
+  }
+
+  command void Packet.clear(message_t* msg) {
+    memset(getHeader(msg), 0, sizeof(serial_header_t));
+    return;
+  }
+
+  command uint8_t Packet.payloadLength(message_t* msg) {
+    serial_header_t* header = getHeader(msg);    
+    return header->length;
+  }
+
+  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+    getHeader(msg)->length  = len;
+  }
+  
+  command uint8_t Packet.maxPayloadLength() {
+    return TOSH_DATA_LENGTH;
+  }
+  
+  command void* Packet.getPayload(message_t* msg, uint8_t len) {
+    if (len > call Packet.maxPayloadLength()) {
+      return NULL;
+    }
+    else {
+      return (void * COUNT_NOK(len))msg->data;
+    }
+  }
+
+  command am_addr_t AMPacket.address() {
+    return 0;
+  }
+
+  command am_addr_t AMPacket.destination(message_t* amsg) {
+    serial_header_t* header = getHeader(amsg);
+    return header->dest;
+  }
+
+  command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {
+    serial_header_t* header = getHeader(amsg);
+    header->dest = addr;
+  }
+
+  command am_addr_t AMPacket.source(message_t* amsg) {
+    serial_header_t* header = getHeader(amsg);
+    return header->src;
+  }
+
+  command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {
+    serial_header_t* header = getHeader(amsg);
+    header->src = addr;
+  }
+  
+  command bool AMPacket.isForMe(message_t* amsg) {
+    return TRUE;
+  }
+
+  command am_id_t AMPacket.type(message_t* amsg) {
+    serial_header_t* header = getHeader(amsg);
+    return header->type;
+  }
+
+  command void AMPacket.setType(message_t* amsg, am_id_t type) {
+    serial_header_t* header = getHeader(amsg);
+    header->type = type;
+  }
+
+  async command error_t PacketAcknowledgements.requestAck( message_t* msg ) {
+    return FAIL;
+  }
+  async command error_t PacketAcknowledgements.noAck( message_t* msg ) {
+    return SUCCESS;
+  }
+  
+  command void AMPacket.setGroup(message_t* msg, am_group_t group) {
+    serial_header_t* header = getHeader(msg);
+    header->group = group;
+  }
+
+  command am_group_t AMPacket.group(message_t* msg) {
+    serial_header_t* header = getHeader(msg);
+    return header->group;
+  }
+
+  command am_group_t AMPacket.localGroup() {
+    return TOS_AM_GROUP;
+  }
+
+ 
+  async command bool PacketAcknowledgements.wasAcked(message_t* msg) {
+    return FALSE;
+  }
+
+  void serial_active_message_deliver_handle(sim_event_t* evt) {
+    message_t* m = (message_t*)evt->data;
+    uint8_t len;
+    void* payload;
+
+    memcpy(bufferPointer, m, sizeof(message_t));
+    payload = call Packet.getPayload(bufferPointer, call Packet.maxPayloadLength());
+    len = call Packet.payloadLength(bufferPointer);
+
+    dbg("Serial", "Received serial message (%p) of type %hhu and length %hhu @ %s.\n",
+         bufferPointer, call AMPacket.type(bufferPointer), len, sim_time_string());
+    bufferPointer = signal SubReceive.receive(bufferPointer, payload, len);
+  }
+
+  TRUSTEDBLOCK sim_event_t* allocate_serial_deliver_event(int node, message_t* msg, sim_time_t t) {
+    sim_event_t* evt = (sim_event_t*)malloc(sizeof(sim_event_t));
+    evt->mote = node;
+    evt->time = t;
+    evt->handle = serial_active_message_deliver_handle;
+    evt->cleanup = sim_queue_cleanup_event;
+    evt->cancelled = 0;
+    evt->force = 0;
+    evt->data = msg;
+    return evt;
+  }
+
+  void serial_active_message_deliver(int node, message_t* msg, sim_time_t t) @C() @spontaneous() 
+  {
+    sim_event_t* evt = allocate_serial_deliver_event(node, msg, t);
+    sim_queue_insert_general(evt,SERIAL);
+  }
+}
Index: tos/lib/tossim/sf/sim/tos.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf/sim/tos.h,v
retrieving revision 1.3
diff -u -b -p -r1.3 tos.h
--- tos/lib/tossim/sf/sim/tos.h	29 Jun 2010 22:07:51 -0000	1.3
+++ tos/lib/tossim/sf/sim/tos.h	9 Jul 2010 19:45:17 -0000
@@ -72,6 +72,7 @@
 
 #ifndef __cplusplus
 typedef uint8_t bool;
+typedef nx_int8_t nx_bool;
 #endif
 
 enum { FALSE = 0, TRUE = 1 };
@@ -84,6 +85,8 @@ extern uint16_t TOS_NODE_ID;
 #define TOSSIM_MAX_NODES 1000
 #endif
 
+#define MAX_NODES 100
+
 #include <sim_event_queue.h>
 #include <sim_tossim.h>
 #include <sim_mote.h>
@@ -102,7 +105,22 @@ struct @exactlyonce { };
 #include <sim_log.c>
 #include <heap.c>
 #include <sim_event_queue.c>
+#include <sim_transition.c>
+#include <sim_stateless_no_por.c>
+#include <sim_stateless_sleep_reduce.c>
 #include <sim_tossim.c>
+#include <sim_tossim_assist.c>
+#include <sim_depth_first_search.c>
+#include <sim_random_walk.c>
+#include <sim_random_walk_assist.c>
+#include <sim_delta_debugging.c>
+#include <sim_statistic_info.c>
+
+#if SIM_ASSIST_TIMER || SIM_ASSIST_COMM
+  #include <sim_tossim_other_assist.c>
+#endif
+
+#include <sim_gen_list.c>
 #include <sim_mac.c>
 #include <sim_packet.c>
 #include <sim_serial_packet.c>
Index: tos/platforms/mica/sim/AlarmMicro32C.nc
===================================================================
RCS file: tos/platforms/mica/sim/AlarmMicro32C.nc
diff -N tos/platforms/mica/sim/AlarmMicro32C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/platforms/mica/sim/AlarmMicro32C.nc	9 Jul 2010 19:45:18 -0000
@@ -0,0 +1,41 @@
+// $Id: AlarmMicro32C.nc,v 1.4 2006/12/12 18:23:42 vlahan Exp $
+/*
+ * Copyright (c) 2005-2006 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.
+ */
+/**
+ * 32-bit microsecond Alarm component as per TEP102 HAL guidelines. The
+ * mica family microsecond Alarm is built on hardware timer 3, and actually
+ * runs at CPU frequency / 8. You can use the MeasureClockC.cyclesPerJiffy() 
+ * command to figure out the exact frequency, or the 
+ * MeasureClockC.calibrateMicro() command to convert a number of microseconds
+ * to the near-microsecond units used by this component.
+ * <p>
+ * Upto three of these alarms can be created (one per hardware compare
+ * register). Note that creating one of these Alarms consumes a 16-bit
+ * microsecond Alarm (see AlarmMicro16C).
+ *
+ * @author David Gay <dgay@intel-research.net>
+ */
+
+#include <MicaTimer.h>
+
+generic configuration AlarmMicro32C()
+{
+  provides interface Alarm<TMicro, uint32_t>;
+}
+implementation
+{
+  components new AlarmThree16C() as Alarm16, CounterMicro32C as Counter32,
+    new TransformAlarmC(TMicro, uint32_t, TThree, uint16_t,
+			MICA_DIVIDE_THREE_FOR_MICRO_LOG2) as Transform32;
+
+  Alarm = Transform32;
+  Transform32.AlarmFrom -> Alarm16;
+  Transform32.Counter -> Counter32;
+}
Index: tos/platforms/mica/sim/AlarmOne16C.nc
===================================================================
RCS file: tos/platforms/mica/sim/AlarmOne16C.nc
diff -N tos/platforms/mica/sim/AlarmOne16C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/platforms/mica/sim/AlarmOne16C.nc	9 Jul 2010 19:45:18 -0000
@@ -0,0 +1,45 @@
+// $Id: AlarmOne16C.nc,v 1.4 2006/12/12 18:23:42 vlahan Exp $
+/*
+ * Copyright (c) 2005-2006 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.
+ */
+/**
+ * 16-bit 32kHz Alarm component as per TEP102 HAL guidelines. The mica
+ * family 32kHz Alarm is built on hardware timer 1, and actually runs at
+ * CPU frequency / 256. You can use the MeasureClockC.cyclesPerJiffy()
+ * command to figure out the exact frequency.
+ * <p>
+ * Assumes an ~8MHz CPU clock, replace this component if you are running at
+ * a radically different frequency.
+ * <p>
+ * Upto three of these alarms can be created (one per hardware compare
+ * register).
+ *
+ * @author David Gay <dgay@intel-research.net>
+ */
+
+#include <MicaTimer.h>
+
+generic configuration AlarmOne16C()
+{
+  provides interface Alarm<TOne, uint16_t>;
+}
+implementation
+{
+  components HplAtm128Timer1C as HWTimer, InitOneP,
+    new Atm128AlarmC(TOne, uint16_t, 3) as NAlarm;
+  
+  enum {
+    COMPARE_ID = unique(UQ_TIMER1_COMPARE)
+  };
+
+  Alarm = NAlarm;
+
+  //NAlarm.HplAtm128Timer -> HWTimer.Timer;
+  NAlarm.HplAtm128Compare -> HWTimer.Compare[COMPARE_ID];
+}
Index: tos/platforms/mica/sim/AlarmThree16C.nc
===================================================================
RCS file: tos/platforms/mica/sim/AlarmThree16C.nc
diff -N tos/platforms/mica/sim/AlarmThree16C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/platforms/mica/sim/AlarmThree16C.nc	9 Jul 2010 19:45:18 -0000
@@ -0,0 +1,47 @@
+// $Id: AlarmThree16C.nc,v 1.4 2006/12/12 18:23:42 vlahan Exp $
+/*
+ * Copyright (c) 2005-2006 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.
+ */
+/**
+ * 16-bit microsecond Alarm component as per TEP102 HAL guidelines. The
+ * mica family microsecond Alarm is built on hardware timer 3, and actually
+ * runs at CPU frequency / 8. You can use the MeasureClockC.cyclesPerJiffy() 
+ * command to figure out the exact frequency, or the 
+ * MeasureClockC.calibrateMicro() command to convert a number of microseconds
+ * to the near-microsecond units used by this component.
+ * <p>
+ * Assumes an ~8MHz CPU clock, replace this component if you are running at
+ * a radically different frequency.
+ * <p>
+ * Upto three of these alarms can be created (one per hardware compare
+ * register). 
+ *
+ * @author David Gay <dgay@intel-research.net>
+ */
+
+#include <MicaTimer.h>
+
+generic configuration AlarmThree16C()
+{
+  provides interface Alarm<TThree, uint16_t>;
+}
+implementation
+{
+  components HplAtm128Timer3C as HWTimer, InitThreeP,
+    new Atm128AlarmC(TThree, uint16_t, 100) as NAlarm;
+  
+  enum {
+    COMPARE_ID = unique(UQ_TIMER3_COMPARE)
+  };
+
+  Alarm = NAlarm;
+
+  NAlarm.HplAtm128Timer -> HWTimer.Timer;
+  NAlarm.HplAtm128Compare -> HWTimer.Compare[COMPARE_ID];
+}
Index: tos/platforms/mica/sim/CounterMicro32C.nc
===================================================================
RCS file: tos/platforms/mica/sim/CounterMicro32C.nc
diff -N tos/platforms/mica/sim/CounterMicro32C.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/platforms/mica/sim/CounterMicro32C.nc	9 Jul 2010 19:45:18 -0000
@@ -0,0 +1,35 @@
+// $Id: CounterMicro32C.nc,v 1.4 2006/12/12 18:23:42 vlahan Exp $
+/*
+ * Copyright (c) 2005-2006 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.
+ */
+/**
+ * 32-bit microsecond Counter component as per TEP102 HAL guidelines. The
+ * mica family microsecond clock is built on hardware timer 3, and actually
+ * runs at CPU frequency / 8. You can use the MeasureClockC.cyclesPerJiffy() 
+ * command to figure out the exact frequency.
+ *
+ * @author David Gay <dgay@intel-research.net>
+ */
+
+#include <MicaTimer.h>
+
+configuration CounterMicro32C
+{
+  provides interface Counter<TMicro, uint32_t>;
+}
+implementation
+{
+  components CounterThree16C as Counter16, 
+    new TransformCounterC(TMicro, uint32_t, TThree, uint16_t,
+			  MICA_DIVIDE_THREE_FOR_MICRO_LOG2,
+			  counter_three_overflow_t) as Transform32;
+
+  Counter = Transform32;
+  Transform32.CounterFrom -> Counter16;
+}
Index: tos/platforms/mica/sim/MeasureClockC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/platforms/mica/sim/MeasureClockC.nc,v
retrieving revision 1.2
diff -u -b -p -r1.2 MeasureClockC.nc
--- tos/platforms/mica/sim/MeasureClockC.nc	12 Jul 2006 17:02:52 -0000	1.2
+++ tos/platforms/mica/sim/MeasureClockC.nc	9 Jul 2010 19:45:18 -0000
@@ -10,6 +10,7 @@
 module MeasureClockC {
   /* This code MUST be called from PlatformP only, hence the exactlyonce */
   provides interface Init @exactlyonce();
+  provides interface Atm128Calibrate;
 
   provides {
     command uint16_t cyclesPerJiffy();
@@ -29,4 +30,52 @@ implementation 
   command uint32_t calibrateMicro(uint32_t n) {
     return scale32(n + 122, 244, (1 << 32));
   }
+
+  async command uint16_t Atm128Calibrate.cyclesPerJiffy() {
+    return (1<<8);
+  }
+
+  async command uint32_t Atm128Calibrate.calibrateMicro(uint32_t n) {
+    return 0;
+  }
+
+  /*
+  async command uint32_t Atm128Calibrate.actualMicro(uint32_t n) {
+    return 0;
+  }
+
+  async command uint8_t Atm128Calibrate.adcPrescaler() {
+    return (uint8_t)(1<<8);
+  }
+
+  async command uint16_t Atm128Calibrate.baudrateRegister(uint32_t baudrate) {
+    return (1<<8);
+  }
+  */
+
+  async command uint32_t Atm128Calibrate.actualMicro(uint32_t n) {
+    return scale32(n + (1 << 7), (1 << 32), (1 << 8));
+  }
+
+  async command uint8_t Atm128Calibrate.adcPrescaler() {
+    /* This is also log2(cycles/3.05). But that's a pain to compute */
+    //if (cycles >= 390)
+    //  return ATM128_ADC_PRESCALE_128;
+    //if (cycles >= 195)
+      return ATM128_ADC_PRESCALE_64;
+    //if (cycles >= 97)
+    //  return ATM128_ADC_PRESCALE_32;
+    //if (cycles >= 48)
+    //  return ATM128_ADC_PRESCALE_16;
+    //if (cycles >= 24)
+    //  return ATM128_ADC_PRESCALE_8;
+    //if (cycles >= 12)
+    //  return ATM128_ADC_PRESCALE_4;
+    //return ATM128_ADC_PRESCALE_2;
+  }
+
+  async command uint16_t Atm128Calibrate.baudrateRegister(uint32_t baudrate) {
+    // value is (cycles*32768) / (8*baudrate) - 1
+    return ((uint32_t)(1 << 8) << 12) / 57600 - 1;
+  }
 }
Index: tos/platforms/mica/sim/PlatformC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/platforms/mica/sim/PlatformC.nc,v
retrieving revision 1.5
diff -u -b -p -r1.5 PlatformC.nc
--- tos/platforms/mica/sim/PlatformC.nc	29 Jun 2010 22:07:53 -0000	1.5
+++ tos/platforms/mica/sim/PlatformC.nc	9 Jul 2010 19:45:18 -0000
@@ -41,6 +41,8 @@ configuration PlatformC {
   provides {
     interface Init;
     command uint32_t calibrateMicro(uint32_t n);
+
+    interface Atm128Calibrate;
   }
   uses interface Init as SubInit;
 }
@@ -49,9 +51,10 @@ implementation
   components PlatformP, MotePlatformC, MeasureClockC;
   
   Init = PlatformP;
+  Atm128Calibrate = MeasureClockC;
+
   PlatformP.MoteInit -> MotePlatformC;
   MotePlatformC.SubInit = SubInit;
   PlatformP.MeasureClock -> MeasureClockC;
-
 }
 
Index: tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsC.nc
===================================================================
RCS file: tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsC.nc
diff -N tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsC.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsC.nc	9 Jul 2010 19:45:18 -0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2005 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.5 $ $Date: 2007/04/30 17:31:08 $
+ */
+
+configuration HplCC2420InterruptsC {
+
+  provides interface GpioCapture as CaptureSFD;
+#ifdef SIM_CC2420
+  provides interface TriggerInterrupt as TriggerFIFOP;
+#endif
+  provides interface GpioInterrupt as InterruptCCA;
+  provides interface GpioInterrupt as InterruptFIFOP;
+
+}
+
+implementation {
+
+  components new Atm128GpioCaptureC() as CaptureSFDC;
+  components HplAtm128Timer1C as Timer1C;
+  CaptureSFD = CaptureSFDC;
+  CaptureSFDC.Atm128Capture -> Timer1C.Capture;
+
+  components new Atm128GpioInterruptC() as InterruptFIFOPC;
+  components HplAtm128InterruptC as Interrupts;
+  InterruptFIFOP = InterruptFIFOPC;
+  InterruptFIFOPC.Atm128Interrupt -> Interrupts.Int6;
+
+#ifdef SIM_CC2420
+  TriggerFIFOP = InterruptFIFOPC;
+#endif
+
+  components HplCC2420InterruptsP;
+  components HplCC2420PinsC;
+  InterruptCCA   = HplCC2420InterruptsP.CCA;
+  HplCC2420InterruptsP.CC_CCA -> HplCC2420PinsC.CCA;
+  
+}
Index: tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsP.nc
===================================================================
RCS file: tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsP.nc
diff -N tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsP.nc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tos/platforms/micaz/chips/cc2420/sim/HplCC2420InterruptsP.nc	9 Jul 2010 19:45:18 -0000
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2005-2006 Rincon Research Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Rincon Research Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * MicaZ implementation of the CC2420 interrupts. FIFOP is a real
+ * interrupt, while CCA and FIFO are emulated through timer polling.
+ * <pre>
+ *  $Id: HplCC2420InterruptsP.nc,v 1.6 2008/06/26 04:39:12 regehr Exp $
+ * <pre>
+ *
+ * @author Philip Levis
+ * @author Matt Miller
+ * @author David Moss
+ * @version @version $Revision: 1.6 $ $Date: 2008/06/26 04:39:12 $
+ */
+
+module HplCC2420InterruptsP @safe() {
+  provides {
+    interface GpioInterrupt as CCA;
+  }
+  
+  uses {
+    interface GeneralIO as CC_CCA;
+  }
+}
+implementation {
+
+  norace uint8_t ccaWaitForState;
+  
+  norace uint8_t ccaLastState;
+  
+  bool ccaCheckDisabled = FALSE;
+
+  // ************* CCA Interrupt handlers and dispatch *************
+  
+  /**
+   * enable an edge interrupt on the CCA pin
+   * NOT an interrupt in MICAz. Implement as a task polled pin monitor
+   */
+
+  task void CCATask() {
+    uint8_t CCAState;
+    atomic {
+      if (ccaCheckDisabled) {
+        return;
+      }
+    }
+    
+    //check CCA state
+    //CCAState = call CC_CCA.get(); //get current state here if waiting for edge
+    // Here, CCAState can be 0 or 1 as CC_CCA.get() gets the value of register set by hardware. 
+    Toss_Internal_Choose(1, &CCAState); 
+
+    if ((ccaLastState != ccaWaitForState) && (CCAState == ccaWaitForState)) {
+      signal CCA.fired();
+    }
+    
+    //if CCA Pin is correct and edge found
+    //repost task and try again
+    ccaLastState = CCAState;
+    post CCATask();
+  }
+  
+  async command error_t CCA.enableRisingEdge() { 
+    atomic ccaWaitForState = TRUE; //save the state we are waiting for
+    atomic ccaCheckDisabled = FALSE;
+    //ccaLastState = call CC_CCA.get(); //get current state
+    // Here, CCAState can be 0 or 1 as CC_CCA.get() gets the value of register set by hardware. 
+    Toss_Internal_Choose(1, &ccaLastState); 
+    post CCATask();
+    return SUCCESS;
+  }
+
+  async command error_t CCA.enableFallingEdge() { 
+    atomic ccaWaitForState = FALSE; //save the state we are waiting for
+    atomic ccaCheckDisabled = FALSE;
+    //ccaLastState = call CC_CCA.get(); //get current state
+    // Here, CCAState can be 0 or 1 as CC_CCA.get() gets the value of register set by hardware. 
+    Toss_Internal_Choose(1, &ccaLastState); 
+    post CCATask();
+    return SUCCESS;
+  }
+  
+  async command error_t CCA.disable() {
+    atomic ccaCheckDisabled = TRUE;
+    return SUCCESS;
+  }
+
+
+  /***************** Defaults ****************/
+  default async event void CCA.fired() {
+  }
+
+}
+
Index: tos/platforms/micaz/sim/.platform
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/platforms/micaz/sim/.platform,v
retrieving revision 1.6
diff -u -b -p -r1.6 .platform
--- tos/platforms/micaz/sim/.platform	14 Nov 2009 02:12:39 -0000	1.6
+++ tos/platforms/micaz/sim/.platform	9 Jul 2010 19:45:18 -0000
@@ -15,6 +15,20 @@ push( @includes, qw(
   %T/platforms/mica
   %T/platforms/micaz/chips/cc2420
   %T/chips/cc2420
+  %T/chips/cc2420/alarm
+  %T/chips/cc2420/control
+  %T/chips/cc2420/csma
+  %T/chips/cc2420/interfaces
+  %T/chips/cc2420/link
+  %T/chips/cc2420/lowpan
+  %T/chips/cc2420/lpl
+  %T/chips/cc2420/packet
+  %T/chips/cc2420/receive
+  %T/chips/cc2420/spi
+  %T/chips/cc2420/transmit
+  %T/chips/cc2420/unique
+  %T/platforms/mica2/chips/at45db
+  %T/platforms/mica/chips/at45db
   %T/chips/atm128
   %T/chips/atm128/adc
   %T/chips/atm128/pins
Index: tos/platforms/micaz/sim/platform_hardware.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/platforms/micaz/sim/platform_hardware.h,v
retrieving revision 1.6
diff -u -b -p -r1.6 platform_hardware.h
--- tos/platforms/micaz/sim/platform_hardware.h	29 Jun 2010 22:07:54 -0000	1.6
+++ tos/platforms/micaz/sim/platform_hardware.h	9 Jul 2010 19:45:18 -0000
@@ -50,6 +50,12 @@
 #include <atm128hardware.h>
 #include <Atm128Adc.h>
 
+#ifndef MHZ
+/* Clock rate is ~8MHz except if specified by user 
+   (this value must be a power of 2, see MicaTimer.h and MeasureClockC.nc) */
+#define MHZ 8
+#endif
+
 // A/D constants (channels, etc)
 enum {
   CHANNEL_RSSI       = ATM128_ADC_SNGL_ADC0,
@@ -61,5 +67,8 @@ enum {
   ATM128_TIMER0_TICKSPPS = 32768,
 };
 
+enum {
+  PLATFORM_BAUDRATE = 57600L
+};
 
 #endif //HARDWARE_H
Index: tos/system/PoolP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/system/PoolP.nc,v
retrieving revision 1.7
diff -u -b -p -r1.7 PoolP.nc
--- tos/system/PoolP.nc	20 Jan 2010 19:59:07 -0000	1.7
+++ tos/system/PoolP.nc	9 Jul 2010 19:45:18 -0000
@@ -50,7 +50,7 @@
  *  @date   $Date: 2010/01/20 19:59:07 $
  */
 
-generic module PoolP(typedef pool_t, uint8_t size) {
+generic module PoolP(typedef pool_t, uint8_t size) @safe(){
   provides {
     interface Init;
     interface Pool<pool_t>;
Index: tos/system/QueueC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/system/QueueC.nc,v
retrieving revision 1.7
diff -u -b -p -r1.7 QueueC.nc
--- tos/system/QueueC.nc	25 Jun 2009 18:37:24 -0000	1.7
+++ tos/system/QueueC.nc	9 Jul 2010 19:45:18 -0000
@@ -39,7 +39,7 @@
  */
 
    
-generic module QueueC(typedef queue_t, uint8_t QUEUE_SIZE) {
+generic module QueueC(typedef queue_t, uint8_t QUEUE_SIZE) @safe(){
   provides interface Queue<queue_t>;
 }
 
@@ -66,7 +66,7 @@ implementation {
     return queue[head];
   }
 
-  void printQueue() {
+  void TRUSTEDBLOCK printQueue() {
 #ifdef TOSSIM
     int i, j;
     dbg("QueueC", "head <-");
diff -urN tos/chips/atm128/adc/sim/AdcStreamP.nc tos/chips/atm128/adc/sim/AdcStreamP.nc
--- tos/chips/atm128/adc/sim/AdcStreamP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/atm128/adc/sim/AdcStreamP.nc	2010-04-24 13:10:15.585435639 -0600
@@ -0,0 +1,277 @@
+/* $Id: AdcStreamP.nc,v 1.12 2008/06/23 23:38:28 idgay Exp $
+ * Copyright (c) 2005 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.
+ *
+ * Copyright (c) 2004, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names 
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * Convert ATmega128 HAL A/D interface to the HIL interfaces.
+ * @author David Gay
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ */
+#include "Timer.h"
+#include <stdlib.h>
+
+module AdcStreamP @safe(){
+  provides {
+    interface Init @atleastonce();
+    interface ReadStream<uint16_t>[uint8_t client];
+  }
+  uses {
+    interface Atm128AdcSingle;
+    interface Atm128AdcConfig[uint8_t client];
+    interface Atm128Calibrate;
+    interface Alarm<TMicro, uint32_t>;
+  }
+}
+implementation {
+  enum {
+    NSTREAM = uniqueCount(UQ_ADC_READSTREAM)
+  };
+
+  /* Resource reservation is required, and it's incorrect to call getData
+     again before dataReady is signaled, so there are no races in correct
+     programs */
+  norace uint8_t client = NSTREAM;
+
+  /* Stream data */
+  struct list_entry_t {
+    uint16_t count;
+    struct list_entry_t * ONE_NOK next;
+  };
+  struct list_entry_t *bufferQueue[NSTREAM];
+  struct list_entry_t * ONE_NOK * bufferQueueEnd[NSTREAM];
+  uint16_t * lastBuffer, lastCount;
+
+  norace uint16_t count;
+  norace uint16_t * buffer; 
+  norace uint16_t * pos;
+  norace uint32_t now, period;
+
+
+  void nextBuffer();
+
+  command error_t Init.init() {
+    uint8_t i;
+
+    for (i = 0; i != NSTREAM; i++)
+      bufferQueueEnd[i] = &bufferQueue[i];
+    
+    return SUCCESS;
+  }
+
+  uint8_t channel() {
+    return call Atm128AdcConfig.getChannel[client]();
+  }
+
+  uint8_t refVoltage() {
+    return call Atm128AdcConfig.getRefVoltage[client]();
+  }
+
+  uint8_t prescaler() {
+    return call Atm128AdcConfig.getPrescaler[client]();
+  }
+
+  void sample() {
+    call Atm128AdcSingle.getData(channel(), refVoltage(), FALSE, prescaler());
+  }
+
+  command error_t ReadStream.postBuffer[uint8_t c](uint16_t *buf, uint16_t n) {
+    if (n < sizeof(struct list_entry_t))
+      return ESIZE;
+    atomic
+      {
+	struct list_entry_t * ONE newEntry = TCAST(struct list_entry_t * ONE, buf);
+
+	if (!bufferQueueEnd[c]) // Can't post right now.
+	  return FAIL;
+
+	newEntry->count = n;
+	newEntry->next = NULL;
+	*bufferQueueEnd[c] = newEntry;
+	bufferQueueEnd[c] = &newEntry->next;
+      }
+    return SUCCESS;
+  }
+
+  task void readStreamDone() {
+    uint8_t c = client;
+    uint32_t actualPeriod = call Atm128Calibrate.actualMicro(period);
+
+    atomic
+      {
+	bufferQueue[c] = NULL;
+	bufferQueueEnd[c] = &bufferQueue[c];
+      }
+
+    client = NSTREAM;
+    signal ReadStream.readDone[c](SUCCESS, actualPeriod);
+  }
+
+  task void readStreamFail() {
+    /* By now, the pending bufferDone has been signaled (see readStream). */
+    struct list_entry_t *entry;
+    uint8_t c = client;
+
+    atomic entry = bufferQueue[c];
+    for (; entry; entry = entry->next){
+      uint16_t tmp_count __DEPUTY_UNUSED__ = entry->count;
+      signal ReadStream.bufferDone[c](FAIL, TCAST(uint16_t * COUNT_NOK(tmp_count),entry), entry->count);
+    }
+
+    atomic
+      {
+	bufferQueue[c] = NULL;
+	bufferQueueEnd[c] = &bufferQueue[c];
+      }
+
+    client = NSTREAM;
+    signal ReadStream.readDone[c](FAIL, 0);
+  }
+
+  task TRUSTEDBLOCK void bufferDone() {
+    uint16_t *b, c;
+    atomic
+      {
+	b = lastBuffer;
+	c = lastCount;
+	lastBuffer = NULL;
+      }
+
+    signal ReadStream.bufferDone[client](SUCCESS, b, c);
+  }
+
+  void nextAlarm() {
+    call Alarm.startAt(now, period);
+    now += period;
+  }
+
+  async event void Alarm.fired() {
+    sample();
+  }
+
+  command error_t ReadStream.read[uint8_t c](uint32_t usPeriod)
+  {
+    /* The first reading may be imprecise. So we just do a dummy read
+       to get things rolling - this is indicated by setting count to 0 */
+    buffer = pos = NULL;
+    count = 0;
+    period = call Atm128Calibrate.calibrateMicro(usPeriod);
+    client = c;
+    sample();
+
+    return SUCCESS;
+  }
+
+  void nextBuffer() {
+    atomic
+      {
+	struct list_entry_t *entry = bufferQueue[client];
+
+	if (!entry)
+	  {
+	    // all done
+	    bufferQueueEnd[client] = NULL; // prevent post
+	    post readStreamDone();
+	  }
+	else
+	  {
+            uint16_t tmp_count;
+	    bufferQueue[client] = entry->next;
+	    if (!bufferQueue[client])
+	      bufferQueueEnd[client] = &bufferQueue[client];
+	    pos = buffer = NULL;
+	    count = entry->count;
+            tmp_count = count;
+	    pos = buffer = TCAST(uint16_t * COUNT_NOK(tmp_count), entry);
+            nextAlarm();
+	  }
+      }
+  }
+
+  async event TRUSTEDBLOCK void Atm128AdcSingle.dataReady(uint16_t data, bool precise) {
+    if (client == NSTREAM)
+      return;
+
+    if (count == 0)
+      {
+	now = call Alarm.getNow();
+	nextBuffer();
+      }
+    else
+      {
+        if(pos + 1 > buffer + count) {
+	   dbg("AdcStreamP", "%s: The out-of-bound error happens here!\n", __FUNCTION__);
+	   exit(0);
+	}
+	*pos++ = data;
+	if (pos == buffer + count)
+	  {
+	    atomic
+	      {
+		if (lastBuffer)
+		  {
+		    /* We failed to signal bufferDone in time. Fail. */
+		    bufferQueueEnd[client] = NULL; // prevent post
+		    post readStreamFail();
+		    return;
+		  }
+		else
+		  {
+		    lastCount = count;
+		    lastBuffer = buffer;
+		  }
+	      }
+	    post bufferDone();
+	    nextBuffer();
+	  }
+	else
+	  nextAlarm();
+      }       
+  }
+
+  /* Configuration defaults. Read ground fast! ;-) */
+  default async command uint8_t Atm128AdcConfig.getChannel[uint8_t c]() {
+    return ATM128_ADC_SNGL_GND;
+  }
+
+  default async command uint8_t Atm128AdcConfig.getRefVoltage[uint8_t c]() {
+    return ATM128_ADC_VREF_OFF;
+  }
+
+  default async command uint8_t Atm128AdcConfig.getPrescaler[uint8_t c]() {
+    return ATM128_ADC_PRESCALE_2;
+  }
+}
diff -urN tos/chips/atm128/adc/sim/Atm128AdcC.nc tos/chips/atm128/adc/sim/Atm128AdcC.nc
--- tos/chips/atm128/adc/sim/Atm128AdcC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/atm128/adc/sim/Atm128AdcC.nc	2010-04-24 13:10:15.585435639 -0600
@@ -0,0 +1,69 @@
+/// $Id: Atm128AdcC.nc,v 1.6 2007/02/04 19:54:59 klueska Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ *
+ * Copyright (c) 2005 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.
+ */
+
+#include "Atm128Adc.h"
+
+/**
+ * HAL for the Atmega128 A/D conversion susbsystem.
+ *
+ * @author Hu Siquan <husq@xbow.com>
+ * @author David Gay
+ */
+
+configuration Atm128AdcC
+{
+  provides {
+    interface Resource[uint8_t client];
+    interface Atm128AdcSingle;
+    interface Atm128AdcMultiple;
+  }
+  uses interface ResourceConfigure[uint8_t client];
+}
+implementation
+{
+  components Atm128AdcP, HplAtm128AdcC, PlatformC, MainC,
+    new RoundRobinArbiterC(UQ_ATM128ADC_RESOURCE) as AdcArbiter,
+    new AsyncStdControlPowerManagerC() as PM;
+
+  Resource = AdcArbiter;
+  ResourceConfigure = AdcArbiter;
+  Atm128AdcSingle = Atm128AdcP;
+  Atm128AdcMultiple = Atm128AdcP;
+
+  PlatformC.SubInit -> Atm128AdcP;
+
+  Atm128AdcP.HplAtm128Adc -> HplAtm128AdcC;
+  Atm128AdcP.Atm128Calibrate -> PlatformC;
+
+  PM.AsyncStdControl -> Atm128AdcP;
+  PM.ResourceDefaultOwner -> AdcArbiter;
+}
diff -urN tos/chips/atm128/adc/sim/Atm128AdcP.nc tos/chips/atm128/adc/sim/Atm128AdcP.nc
--- tos/chips/atm128/adc/sim/Atm128AdcP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/atm128/adc/sim/Atm128AdcP.nc	2010-04-24 13:10:15.585435639 -0600
@@ -0,0 +1,251 @@
+/* $Id: Atm128AdcP.nc,v 1.7 2008/06/26 04:39:03 regehr Exp $
+ * "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-2005 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.
+ *
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+#include "Atm128Adc.h"
+
+/**
+ * Internal component of the Atmega128 A/D HAL.
+ *
+ * @author Jason Hill
+ * @author David Gay
+ * @author Philip Levis
+ * @author Phil Buonadonna
+ * @author Hu Siquan <husq@xbow.com>
+ */
+
+module Atm128AdcP @safe()
+{
+  provides {
+    interface Init;
+    interface AsyncStdControl;
+    interface Atm128AdcSingle;
+    interface Atm128AdcMultiple;
+  }
+  uses {
+    interface HplAtm128Adc;
+    interface Atm128Calibrate;
+  }
+}
+implementation
+{  
+  /* State for the current and next (multiple-sampling only) conversion */
+  struct {
+    bool multiple : 1;		/* single and multiple-sampling mode */
+    bool precise : 1;		/* is this result going to be precise? */
+    uint8_t channel : 5;	/* what channel did this sample come from? */
+  } f, nextF;
+  
+  command error_t Init.init() {
+    atomic
+      {
+	Atm128Adcsra_t adcsr;
+
+	adcsr.aden = ATM128_ADC_ENABLE_OFF;
+	adcsr.adsc = ATM128_ADC_START_CONVERSION_OFF;  
+	adcsr.adfr = ATM128_ADC_FREE_RUNNING_OFF; 
+	adcsr.adif = ATM128_ADC_INT_FLAG_OFF;               
+	adcsr.adie = ATM128_ADC_INT_ENABLE_OFF;       
+	adcsr.adps = ATM128_ADC_PRESCALE_2;
+	call HplAtm128Adc.setAdcsra(adcsr);
+      }
+    return SUCCESS;
+  }
+
+  /* We enable the A/D when start is called, and disable it when stop is
+     called. This drops A/D conversion latency by a factor of two (but
+     increases idle mode power consumption a little). 
+  */
+  async command error_t AsyncStdControl.start() {
+    atomic call HplAtm128Adc.enableAdc();
+    return SUCCESS;
+  }
+
+  async command error_t AsyncStdControl.stop() {
+    atomic call HplAtm128Adc.disableAdc();
+
+    return SUCCESS;
+  }
+
+  /* Return TRUE if switching to 'channel' with reference voltage 'refVoltage'
+     will give a precise result (the first sample after changing reference
+     voltage or switching to/between a differential channel is imprecise)
+  */
+  inline bool isPrecise(Atm128Admux_t admux, uint8_t channel, uint8_t refVoltage) {
+    return refVoltage == admux.refs &&
+      (channel <= ATM128_ADC_SNGL_ADC7 || channel >= ATM128_ADC_SNGL_1_23 || channel == admux.mux);
+  }
+
+  async event void HplAtm128Adc.dataReady(uint16_t data) {
+    bool precise, multiple;
+    uint8_t channel;
+
+    atomic 
+      {
+	channel = f.channel;
+	precise = f.precise;
+	multiple = f.multiple;
+      }
+
+    if (!multiple)
+      {
+	/* A single sample. Disable the ADC interrupt to avoid starting
+	   a new sample at the next "sleep" instruction. */
+	call HplAtm128Adc.disableInterruption();
+	/* Just set the second argument of dataReady as TRUE instead of precise, 
+	   avoid resampling the data. Since, in simulation, the data is constant
+         forever: 0xbeef */
+	//signal Atm128AdcSingle.dataReady(data, precise);
+	signal Atm128AdcSingle.dataReady(data, TRUE);
+      }
+    else
+      {
+	/* Multiple sampling. The user can:
+	   - tell us to stop sampling
+	   - or, to continue sampling on a new channel, possibly with a
+	     new reference voltage; however this change applies not to
+	     the next sample (the hardware has already started working on
+	     that), but on the one after.
+	*/
+	bool cont;
+	uint8_t nextChannel, nextVoltage;
+	Atm128Admux_t admux;
+
+	atomic 
+	  {
+	    admux = call HplAtm128Adc.getAdmux();
+	    nextVoltage = admux.refs;
+	    nextChannel = admux.mux;
+	  }
+
+	cont = signal Atm128AdcMultiple.dataReady(data, precise, channel,
+						  &nextChannel, &nextVoltage);
+	atomic
+	  if (cont)
+	    {
+	      /* Switch channels and update our internal channel+precision
+		 tracking state (f and nextF). Note that this tracking will
+		 be incorrect if we take too long to get to this point. */
+	      admux.refs = nextVoltage;
+	      admux.mux = nextChannel;
+	      call HplAtm128Adc.setAdmux(admux);
+
+	      f = nextF;
+	      nextF.channel = nextChannel;
+	      nextF.precise = isPrecise(admux, nextChannel, nextVoltage);
+	    }
+	  else
+	    call HplAtm128Adc.cancel();
+      }
+  }
+
+  /* Start sampling based on request parameters */
+  void getData(uint8_t channel, uint8_t refVoltage, bool leftJustify, uint8_t prescaler) {
+    Atm128Admux_t admux;
+    Atm128Adcsra_t adcsr;
+
+    admux = call HplAtm128Adc.getAdmux();
+    f.precise = isPrecise(admux, channel, refVoltage);
+    f.channel = channel;
+
+    admux.refs = refVoltage;
+    admux.adlar = leftJustify;
+    admux.mux = channel;
+    call HplAtm128Adc.setAdmux(admux);
+
+    adcsr.aden = ATM128_ADC_ENABLE_ON;
+    adcsr.adsc = ATM128_ADC_START_CONVERSION_ON;
+    adcsr.adfr = f.multiple;
+    adcsr.adif = ATM128_ADC_INT_FLAG_ON; // clear any stale flag
+    adcsr.adie = ATM128_ADC_INT_ENABLE_ON;
+    if (prescaler == ATM128_ADC_PRESCALE)
+      prescaler = call Atm128Calibrate.adcPrescaler();
+    adcsr.adps = prescaler;
+    call HplAtm128Adc.setAdcsra(adcsr);
+  }
+
+  async command bool Atm128AdcSingle.getData(uint8_t channel, uint8_t refVoltage,
+					     bool leftJustify, uint8_t prescaler) {
+    atomic
+      {
+	f.multiple = FALSE;
+	getData(channel, refVoltage, leftJustify, prescaler);
+
+	return f.precise;
+      }
+  }
+
+  async command bool Atm128AdcSingle.cancel() {
+    /* There is no Atm128AdcMultiple.cancel, for reasons discussed in that
+       interface */
+
+    return call HplAtm128Adc.cancel();
+  }
+
+  async command bool Atm128AdcMultiple.getData(uint8_t channel, uint8_t refVoltage,
+					       bool leftJustify, uint8_t prescaler) {
+    atomic
+      {
+	f.multiple = TRUE;
+	getData(channel, refVoltage, leftJustify, prescaler);
+	nextF = f;
+	/* We assume the 2nd sample is precise */
+	nextF.precise = TRUE;
+
+	return f.precise;
+      }
+  }
+
+  default async event void Atm128AdcSingle.dataReady(uint16_t data, bool precise) {
+  }
+
+  default async event bool Atm128AdcMultiple.dataReady(uint16_t data, bool precise, uint8_t channel,
+						       uint8_t *newChannel, uint8_t *newRefVoltage) {
+    return FALSE; // stop conversion if we somehow end up here.
+  }
+}
diff -urN tos/chips/atm128/adc/sim/HplAtm128AdcC.nc tos/chips/atm128/adc/sim/HplAtm128AdcC.nc
--- tos/chips/atm128/adc/sim/HplAtm128AdcC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/atm128/adc/sim/HplAtm128AdcC.nc	2010-04-24 13:10:15.585435639 -0600
@@ -0,0 +1,43 @@
+/// $Id: HplAtm128AdcC.nc,v 1.6 2008/06/11 00:42:13 razvanm Exp $
+
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+#include "Atm128Adc.h"
+
+/**
+ * HPL for the Atmega128 A/D conversion susbsystem.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author Hu Siquan <husq@xbow.com>
+ * @author David Gay
+ */
+
+configuration HplAtm128AdcC {
+  provides interface HplAtm128Adc;
+}
+implementation {
+  components HplAtm128AdcP, McuSleepC;
+
+  HplAtm128Adc = HplAtm128AdcP;
+  HplAtm128AdcP.McuPowerState -> McuSleepC;
+}
diff -urN tos/chips/atm128/adc/sim/HplAtm128AdcP.nc tos/chips/atm128/adc/sim/HplAtm128AdcP.nc
--- tos/chips/atm128/adc/sim/HplAtm128AdcP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/atm128/adc/sim/HplAtm128AdcP.nc	2010-04-24 13:10:15.585435639 -0600
@@ -0,0 +1,174 @@
+/// $Id: HplAtm128AdcP.nc,v 1.8 2008/06/26 04:39:03 regehr Exp $
+/*
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+#include "Atm128Adc.h"
+
+/**
+ * HPL for the Atmega128 A/D conversion susbsystem.
+ *
+ * @author Martin Turon <mturon@xbow.com>
+ * @author Hu Siquan <husq@xbow.com>
+ * @author David Gay
+ */
+
+module HplAtm128AdcP @safe() {
+  provides interface HplAtm128Adc;
+  uses interface McuPowerState;
+}
+implementation {
+  sim_event_t sim_adc_intr;
+
+  //=== Direct read of HW registers. =================================
+  async command Atm128Admux_t HplAtm128Adc.getAdmux() { 
+    return *(Atm128Admux_t*)&ADMUX; 
+  }
+  async command Atm128Adcsra_t HplAtm128Adc.getAdcsra() { 
+    return *(Atm128Adcsra_t*)&ADCSRA; 
+  }
+  async command uint16_t HplAtm128Adc.getValue() { 
+    return ADC; 
+  }
+
+  DEFINE_UNION_CAST(Admux2int, Atm128Admux_t, uint8_t);
+  DEFINE_UNION_CAST(Adcsra2int, Atm128Adcsra_t, uint8_t);
+
+  //=== Direct write of HW registers. ================================
+  async command void HplAtm128Adc.setAdmux( Atm128Admux_t x ) { 
+    ADMUX = Admux2int(x); 
+  }
+
+  /* A/D interrupt handlers. signals dataReady event with interrupts enabled */
+  AVR_ATOMIC_HANDLER(SIG_ADC) {
+    uint16_t data = 0xbeef;
+    
+    __nesc_enable_interrupt();
+    signal HplAtm128Adc.dataReady(data);
+  }
+
+  void adc_interrupt_handle(sim_event_t* evt) {
+     /* Here just emulate the occurrence of adc interrupt, omitting the analysis of value
+	of register*/ 
+     if(evt->cancelled) {
+        return;
+     }
+     if(READ_BIT(ATM128_ADCSRA, ADIE)) {
+       SIG_ADC(); 
+     }
+  }
+
+  void allocate_adc_interrupt() {
+    dbg("HplAtm128AdcP", "Allocated adc completion interrupt at 0x%p\n", &sim_adc_intr);
+    sim_adc_intr.mote = sim_node();
+    sim_adc_intr.force = 0;
+    sim_adc_intr.cancelled = 0;
+    sim_adc_intr.time = sim_time() + 10000;   
+
+    sim_adc_intr.handle = adc_interrupt_handle;
+    sim_adc_intr.cleanup = sim_queue_cleanup_none;
+    sim_adc_intr.type = INTERRUPT;
+    sim_adc_intr.source = INT_ADC;
+    sim_adc_intr.mark = TRUE;     
+  }
+
+  void isAdcEnabled() {
+    Atm128Adcsra_t current_val = call HplAtm128Adc.getAdcsra(); 
+    if(current_val.adie == TRUE) { 
+      allocate_adc_interrupt();  
+      sim_queue_insert(&sim_adc_intr);
+    }
+  }
+
+  async command void HplAtm128Adc.setAdcsra( Atm128Adcsra_t x ) { 
+    ADCSRA = Adcsra2int(x);
+    /*In simulation, we will determine whether the interrupt handler 
+      is enabled or not*/
+    isAdcEnabled();
+  }
+
+  async command void HplAtm128Adc.setPrescaler(uint8_t scale){
+    Atm128Adcsra_t  current_val = call HplAtm128Adc.getAdcsra(); 
+    current_val.adif = FALSE;
+    current_val.adps = scale;
+    call HplAtm128Adc.setAdcsra(current_val);
+  }
+
+  // Individual bit manipulation. These all clear any pending A/D interrupt.
+  async command void HplAtm128Adc.enableAdc() {
+    SET_BIT(ATM128_ADCSRA, ADEN); 
+    call McuPowerState.update();
+  }
+  async command void HplAtm128Adc.disableAdc() {
+    CLR_BIT(ATM128_ADCSRA, ADEN); 
+    call McuPowerState.update();
+  }
+  async command void HplAtm128Adc.enableInterruption() { SET_BIT(ATM128_ADCSRA, ADIE); }
+  async command void HplAtm128Adc.disableInterruption() { 
+     CLR_BIT(ATM128_ADCSRA, ADIE); 
+     sim_adc_intr.mark = FALSE;
+  }
+  async command void HplAtm128Adc.setContinuous() { SET_BIT(ATM128_ADCSRA, ADFR); }
+  async command void HplAtm128Adc.setSingle() { CLR_BIT(ATM128_ADCSRA, ADFR); }
+  async command void HplAtm128Adc.resetInterrupt() { SET_BIT(ATM128_ADCSRA, ADIF); }
+  async command void HplAtm128Adc.startConversion() { SET_BIT(ATM128_ADCSRA, ADSC); }
+
+
+  /* A/D status checks */
+  async command bool HplAtm128Adc.isEnabled()     {       
+    return (call HplAtm128Adc.getAdcsra()).aden; 
+  }
+
+  async command bool HplAtm128Adc.isStarted()     {
+    return (call HplAtm128Adc.getAdcsra()).adsc; 
+  }
+  
+  async command bool HplAtm128Adc.isComplete()    {
+    return (call HplAtm128Adc.getAdcsra()).adif; 
+  }
+
+  default async event void HplAtm128Adc.dataReady(uint16_t done) { }
+
+  async command bool HplAtm128Adc.cancel() { 
+    /* This is tricky */
+    atomic
+      {
+	Atm128Adcsra_t oldSr = call HplAtm128Adc.getAdcsra(), newSr;
+
+	/* To cancel a conversion, first turn off ADEN, then turn off
+	   ADSC. We also cancel any pending interrupt.
+	   Finally we reenable the ADC.
+	*/
+	newSr = oldSr;
+	newSr.aden = FALSE;
+	newSr.adif = TRUE; /* This clears a pending interrupt... */
+	newSr.adie = FALSE; /* We don't want to start sampling again at the
+			       next sleep */
+	call HplAtm128Adc.setAdcsra(newSr);
+	newSr.adsc = FALSE;
+	call HplAtm128Adc.setAdcsra(newSr);
+	newSr.aden = TRUE;
+	call HplAtm128Adc.setAdcsra(newSr);
+
+	return oldSr.adif || oldSr.adsc;
+      }
+  }
+}
diff -urN tos/chips/cc2420/control/sim/CC2420ControlC.nc tos/chips/cc2420/control/sim/CC2420ControlC.nc
--- tos/chips/cc2420/control/sim/CC2420ControlC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/control/sim/CC2420ControlC.nc	2010-04-24 13:12:26.913435677 -0600
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation for configuring a ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.3 $ $Date: 2008/05/14 21:33:07 $
+ */
+
+#include "CC2420.h"
+#include "IEEE802154.h"
+
+configuration CC2420ControlC {
+
+  provides interface Resource;
+  provides interface CC2420Config;
+  provides interface CC2420Power;
+  provides interface Read<uint16_t> as ReadRssi;
+  
+}
+
+implementation {
+  
+  components CC2420ControlP;
+  Resource = CC2420ControlP;
+  CC2420Config = CC2420ControlP;
+  CC2420Power = CC2420ControlP;
+  ReadRssi = CC2420ControlP;
+
+  components MainC;
+  MainC.SoftwareInit -> CC2420ControlP;
+  
+  components AlarmMultiplexC as Alarm;
+  CC2420ControlP.StartupTimer -> Alarm;
+
+  components HplCC2420PinsC as Pins;
+  CC2420ControlP.CSN -> Pins.CSN;
+  CC2420ControlP.RSTN -> Pins.RSTN;
+  CC2420ControlP.VREN -> Pins.VREN;
+
+  components HplCC2420InterruptsC as Interrupts;
+  CC2420ControlP.InterruptCCA -> Interrupts.InterruptCCA;
+
+  components new CC2420SpiC() as Spi;
+  CC2420ControlP.SpiResource -> Spi;
+  CC2420ControlP.SRXON -> Spi.SRXON;
+  CC2420ControlP.SRFOFF -> Spi.SRFOFF;
+  CC2420ControlP.SXOSCON -> Spi.SXOSCON;
+  CC2420ControlP.SXOSCOFF -> Spi.SXOSCOFF;
+  CC2420ControlP.FSCTRL -> Spi.FSCTRL;
+  CC2420ControlP.IOCFG0 -> Spi.IOCFG0;
+  CC2420ControlP.IOCFG1 -> Spi.IOCFG1;
+  CC2420ControlP.MDMCTRL0 -> Spi.MDMCTRL0;
+  CC2420ControlP.MDMCTRL1 -> Spi.MDMCTRL1;
+  CC2420ControlP.PANID -> Spi.PANID;
+  CC2420ControlP.RXCTRL1 -> Spi.RXCTRL1;
+  CC2420ControlP.RSSI  -> Spi.RSSI;
+
+  components new CC2420SpiC() as SyncSpiC;
+  CC2420ControlP.SyncResource -> SyncSpiC;
+
+  components new CC2420SpiC() as RssiResource;
+  CC2420ControlP.RssiResource -> RssiResource;
+  
+  components ActiveMessageAddressC;
+  CC2420ControlP.ActiveMessageAddress -> ActiveMessageAddressC;
+
+}
+
diff -urN tos/chips/cc2420/control/sim/CC2420ControlP.nc tos/chips/cc2420/control/sim/CC2420ControlP.nc
--- tos/chips/cc2420/control/sim/CC2420ControlP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/control/sim/CC2420ControlP.nc	2010-04-24 13:12:26.913435677 -0600
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Urs Hunkeler (ReadRssi implementation)
+ * @version $Revision: 1.8 $ $Date: 2009/10/28 16:18:44 $
+ */
+
+#include "Timer.h"
+
+module CC2420ControlP @safe() {
+
+  provides interface Init;
+  provides interface Resource;
+  provides interface CC2420Config;
+  provides interface CC2420Power;
+  provides interface Read<uint16_t> as ReadRssi;
+
+  uses interface Alarm<T32khz,uint32_t> as StartupTimer;
+  uses interface GeneralIO as CSN;
+  uses interface GeneralIO as RSTN;
+  uses interface GeneralIO as VREN;
+  uses interface GpioInterrupt as InterruptCCA;
+  uses interface ActiveMessageAddress;
+
+  uses interface CC2420Ram as PANID;
+  uses interface CC2420Register as FSCTRL;
+  uses interface CC2420Register as IOCFG0;
+  uses interface CC2420Register as IOCFG1;
+  uses interface CC2420Register as MDMCTRL0;
+  uses interface CC2420Register as MDMCTRL1;
+  uses interface CC2420Register as RXCTRL1;
+  uses interface CC2420Register as RSSI;
+  uses interface CC2420Strobe as SRXON;
+  uses interface CC2420Strobe as SRFOFF;
+  uses interface CC2420Strobe as SXOSCOFF;
+  uses interface CC2420Strobe as SXOSCON;
+  
+  uses interface Resource as SpiResource;
+  uses interface Resource as RssiResource;
+  uses interface Resource as SyncResource;
+
+  uses interface Leds;
+
+}
+
+implementation {
+
+  typedef enum {
+    S_VREG_STOPPED,
+    S_VREG_STARTING,
+    S_VREG_STARTED,
+    S_XOSC_STARTING,
+    S_XOSC_STARTED,
+  } cc2420_control_state_t;
+
+  uint8_t m_channel;
+  
+  uint8_t m_tx_power;
+  
+  uint16_t m_pan;
+  
+  uint16_t m_short_addr;
+  
+  bool m_sync_busy;
+  
+  /** TRUE if acknowledgments are enabled */
+  bool autoAckEnabled;
+  
+  /** TRUE if acknowledgments are generated in hardware only */
+  bool hwAutoAckDefault;
+  
+  /** TRUE if software or hardware address recognition is enabled */
+  bool addressRecognition;
+  
+  /** TRUE if address recognition should also be performed in hardware */
+  bool hwAddressRecognition;
+  
+  norace cc2420_control_state_t m_state = S_VREG_STOPPED;
+  
+  /***************** Prototypes ****************/
+
+  void writeFsctrl();
+  void writeMdmctrl0();
+  void writeId();
+
+  task void sync();
+  task void syncDone();
+    
+  /***************** Init Commands ****************/
+  command error_t Init.init() {
+    call CSN.makeOutput();
+    call RSTN.makeOutput();
+    call VREN.makeOutput();
+    
+    m_short_addr = call ActiveMessageAddress.amAddress();
+    m_pan = call ActiveMessageAddress.amGroup();
+    m_tx_power = CC2420_DEF_RFPOWER;
+    m_channel = CC2420_DEF_CHANNEL;
+    
+    
+#if defined(CC2420_NO_ADDRESS_RECOGNITION)
+    addressRecognition = FALSE;
+#else
+    addressRecognition = TRUE;
+#endif
+    
+#if defined(CC2420_HW_ADDRESS_RECOGNITION)
+    hwAddressRecognition = TRUE;
+#else
+    hwAddressRecognition = FALSE;
+#endif
+    
+    
+#if defined(CC2420_NO_ACKNOWLEDGEMENTS)
+    autoAckEnabled = FALSE;
+#else
+    autoAckEnabled = TRUE;
+#endif
+    
+#if defined(CC2420_HW_ACKNOWLEDGEMENTS)
+    hwAutoAckDefault = TRUE;
+    hwAddressRecognition = TRUE;
+#else
+    hwAutoAckDefault = FALSE;
+#endif
+    
+    
+    return SUCCESS;
+  }
+
+  /***************** Resource Commands ****************/
+  async command error_t Resource.immediateRequest() {
+    error_t error = call SpiResource.immediateRequest();
+    if ( error == SUCCESS ) {
+      call CSN.clr();
+    }
+    return error;
+  }
+
+  async command error_t Resource.request() {
+    return call SpiResource.request();
+  }
+
+  async command uint8_t Resource.isOwner() {
+    return call SpiResource.isOwner();
+  }
+
+  async command error_t Resource.release() {
+    atomic {
+      call CSN.set();
+      return call SpiResource.release();
+    }
+  }
+
+  /***************** CC2420Power Commands ****************/
+  async command error_t CC2420Power.startVReg() {
+    atomic {
+      if ( m_state != S_VREG_STOPPED ) {
+        return FAIL;
+      }
+      m_state = S_VREG_STARTING;
+    }
+    call VREN.set();
+    call StartupTimer.start( CC2420_TIME_VREN );
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.stopVReg() {
+    m_state = S_VREG_STOPPED;
+    call RSTN.clr();
+    call VREN.clr();
+    call RSTN.set();
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.startOscillator() {
+    atomic {
+      if ( m_state != S_VREG_STARTED ) {
+        return FAIL;
+      }
+        
+      m_state = S_XOSC_STARTING;
+      call IOCFG1.write( CC2420_SFDMUX_XOSC16M_STABLE << 
+                         CC2420_IOCFG1_CCAMUX );
+                         
+      call InterruptCCA.enableRisingEdge();
+      call SXOSCON.strobe();
+      
+      call IOCFG0.write( ( 1 << CC2420_IOCFG0_FIFOP_POLARITY ) |
+          ( 127 << CC2420_IOCFG0_FIFOP_THR ) );
+                         
+      writeFsctrl();
+      writeMdmctrl0();
+  
+      call RXCTRL1.write( ( 1 << CC2420_RXCTRL1_RXBPF_LOCUR ) |
+          ( 1 << CC2420_RXCTRL1_LOW_LOWGAIN ) |
+          ( 1 << CC2420_RXCTRL1_HIGH_HGM ) |
+          ( 1 << CC2420_RXCTRL1_LNA_CAP_ARRAY ) |
+          ( 1 << CC2420_RXCTRL1_RXMIX_TAIL ) |
+          ( 1 << CC2420_RXCTRL1_RXMIX_VCM ) |
+          ( 2 << CC2420_RXCTRL1_RXMIX_CURRENT ) );
+    }
+    return SUCCESS;
+  }
+
+
+  async command error_t CC2420Power.stopOscillator() {
+    atomic {
+      if ( m_state != S_XOSC_STARTED ) {
+        return FAIL;
+      }
+      m_state = S_VREG_STARTED;
+      call SXOSCOFF.strobe();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.rxOn() {
+    atomic {
+      if ( m_state != S_XOSC_STARTED ) {
+        return FAIL;
+      }
+      call SRXON.strobe();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.rfOff() {
+    atomic {  
+      if ( m_state != S_XOSC_STARTED ) {
+        return FAIL;
+      }
+      call SRFOFF.strobe();
+    }
+    return SUCCESS;
+  }
+
+  
+  /***************** CC2420Config Commands ****************/
+  command uint8_t CC2420Config.getChannel() {
+    atomic return m_channel;
+  }
+
+  command void CC2420Config.setChannel( uint8_t channel ) {
+    atomic m_channel = channel;
+  }
+
+  async command uint16_t CC2420Config.getShortAddr() {
+    atomic return m_short_addr;
+  }
+
+  command void CC2420Config.setShortAddr( uint16_t addr ) {
+    atomic m_short_addr = addr;
+  }
+
+  async command uint16_t CC2420Config.getPanAddr() {
+    atomic return m_pan;
+  }
+
+  command void CC2420Config.setPanAddr( uint16_t pan ) {
+    atomic m_pan = pan;
+  }
+
+  /**
+   * Sync must be called to commit software parameters configured on
+   * the microcontroller (through the CC2420Config interface) to the
+   * CC2420 radio chip.
+   */
+  command error_t CC2420Config.sync() {
+    atomic {
+      if ( m_sync_busy ) {
+        return FAIL;
+      }
+      
+      m_sync_busy = TRUE;
+      if ( m_state == S_XOSC_STARTED ) {
+        call SyncResource.request();
+      } else {
+        post syncDone();
+      }
+    }
+    return SUCCESS;
+  }
+
+  /**
+   * @param enableAddressRecognition TRUE to turn address recognition on
+   * @param useHwAddressRecognition TRUE to perform address recognition first
+   *     in hardware. This doesn't affect software address recognition. The
+   *     driver must sync with the chip after changing this value.
+   */
+  command void CC2420Config.setAddressRecognition(bool enableAddressRecognition, bool useHwAddressRecognition) {
+    atomic {
+      addressRecognition = enableAddressRecognition;
+      hwAddressRecognition = useHwAddressRecognition;
+    }
+  }
+  
+  /**
+   * @return TRUE if address recognition is enabled
+   */
+  async command bool CC2420Config.isAddressRecognitionEnabled() {
+    atomic return addressRecognition;
+  }
+  
+  /**
+   * @return TRUE if address recognition is performed first in hardware.
+   */
+  async command bool CC2420Config.isHwAddressRecognitionDefault() {
+    atomic return hwAddressRecognition;
+  }
+  
+  
+  /**
+   * Sync must be called for acknowledgement changes to take effect
+   * @param enableAutoAck TRUE to enable auto acknowledgements
+   * @param hwAutoAck TRUE to default to hardware auto acks, FALSE to
+   *     default to software auto acknowledgements
+   */
+  command void CC2420Config.setAutoAck(bool enableAutoAck, bool hwAutoAck) {
+    atomic autoAckEnabled = enableAutoAck;
+    atomic hwAutoAckDefault = hwAutoAck;
+  }
+  
+  /**
+   * @return TRUE if hardware auto acks are the default, FALSE if software
+   *     acks are the default
+   */
+  async command bool CC2420Config.isHwAutoAckDefault() {
+    atomic return hwAutoAckDefault;    
+  }
+  
+  /**
+   * @return TRUE if auto acks are enabled
+   */
+  async command bool CC2420Config.isAutoAckEnabled() {
+    atomic return autoAckEnabled;
+  }
+  
+  /***************** ReadRssi Commands ****************/
+  command error_t ReadRssi.read() { 
+    return call RssiResource.request();
+  }
+  
+  /***************** Spi Resources Events ****************/
+  event void SyncResource.granted() {
+    call CSN.clr();
+    call SRFOFF.strobe();
+    writeFsctrl();
+    writeMdmctrl0();
+    writeId();
+    call CSN.set();
+    call CSN.clr();
+    call SRXON.strobe();
+    call CSN.set();
+    call SyncResource.release();
+    post syncDone();
+  }
+
+  event void SpiResource.granted() {
+    call CSN.clr();
+    signal Resource.granted();
+  }
+
+  event void RssiResource.granted() { 
+    uint16_t data = 0;
+    call CSN.clr();
+    call RSSI.read(&data);
+    call CSN.set();
+    
+    call RssiResource.release();
+    data += 0x7f;
+    data &= 0x00ff;
+    signal ReadRssi.readDone(SUCCESS, data); 
+  }
+  
+  /***************** StartupTimer Events ****************/
+  async event void StartupTimer.fired() {
+    if ( m_state == S_VREG_STARTING ) {
+      m_state = S_VREG_STARTED;
+      call RSTN.clr();
+      call RSTN.set();
+      signal CC2420Power.startVRegDone();
+    }
+  }
+
+  /***************** InterruptCCA Events ****************/
+  async event void InterruptCCA.fired() {
+    m_state = S_XOSC_STARTED;
+    call InterruptCCA.disable();
+    call IOCFG1.write( 0 );
+    writeId();
+    call CSN.set();
+    call CSN.clr();
+    signal CC2420Power.startOscillatorDone();
+  }
+ 
+  /***************** ActiveMessageAddress Events ****************/
+  async event void ActiveMessageAddress.changed() {
+    atomic {
+      m_short_addr = call ActiveMessageAddress.amAddress();
+      m_pan = call ActiveMessageAddress.amGroup();
+    }
+    
+    post sync();
+  }
+  
+  /***************** Tasks ****************/
+  /**
+   * Attempt to synchronize our current settings with the CC2420
+   */
+  task void sync() {
+    call CC2420Config.sync();
+  }
+  
+  task void syncDone() {
+    atomic m_sync_busy = FALSE;
+    signal CC2420Config.syncDone( SUCCESS );
+  }
+  
+  
+  /***************** Functions ****************/
+  /**
+   * Write teh FSCTRL register
+   */
+  void writeFsctrl() {
+    uint8_t channel;
+    
+    atomic {
+      channel = m_channel;
+    }
+    
+    call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
+          ( ( (channel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) );
+  }
+
+  /**
+   * Write the MDMCTRL0 register
+   * Disabling hardware address recognition improves acknowledgment success
+   * rate and low power communications reliability by causing the local node
+   * to do work while the real destination node of the packet is acknowledging.
+   */
+  void writeMdmctrl0() {
+    atomic {
+      call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) |
+          ( (addressRecognition && hwAddressRecognition) << CC2420_MDMCTRL0_ADR_DECODE ) |
+          ( 2 << CC2420_MDMCTRL0_CCA_HYST ) |
+          ( 3 << CC2420_MDMCTRL0_CCA_MOD ) |
+          ( 1 << CC2420_MDMCTRL0_AUTOCRC ) |
+          ( (autoAckEnabled && hwAutoAckDefault) << CC2420_MDMCTRL0_AUTOACK ) |
+          ( 0 << CC2420_MDMCTRL0_AUTOACK ) |
+          ( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) );
+    }
+    // Jon Green:
+    // MDMCTRL1.CORR_THR is defaulted to 20 instead of 0 like the datasheet says
+    // If we add in changes to MDMCTRL1, be sure to include this fix.
+  }
+  
+  /**
+   * Write the PANID register
+   */
+  void writeId() {
+    nxle_uint16_t id[ 2 ];
+
+    atomic {
+      id[ 0 ] = m_pan;
+      id[ 1 ] = m_short_addr;
+    }
+    
+    call PANID.write(0, (uint8_t*)&id, sizeof(id));
+  }
+
+
+  
+  /***************** Defaults ****************/
+  default event void CC2420Config.syncDone( error_t error ) {
+  }
+
+  default event void ReadRssi.readDone(error_t error, uint16_t data) {
+  }
+  
+}
diff -urN tos/chips/cc2420/interfaces/sim/CC2420PacketBody.nc tos/chips/cc2420/interfaces/sim/CC2420PacketBody.nc
--- tos/chips/cc2420/interfaces/sim/CC2420PacketBody.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/interfaces/sim/CC2420PacketBody.nc	2010-04-24 13:13:06.169435555 -0600
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2005-2006 Rincon Research Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Rincon Research Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Internal interface for the CC2420 to get portions of a packet.
+ * @author David Moss
+ */
+
+#include "CC2420.h"
+
+interface CC2420PacketBody {
+
+  /**
+   * @return pointer to the cc2420_header_t of the given message
+   */
+  async command cc2420_header_t * ONE getHeader(message_t * ONE msg);
+  
+  /**
+   * @return pointer to the cc2420_metadata_t of the given message
+   */
+  async command cc2420_metadata_t * ONE getMetadata(message_t * ONE msg);
+  
+}
+
diff -urN tos/chips/cc2420/interfaces/sim/CC2420Packet.nc tos/chips/cc2420/interfaces/sim/CC2420Packet.nc
--- tos/chips/cc2420/interfaces/sim/CC2420Packet.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/interfaces/sim/CC2420Packet.nc	2010-04-24 13:13:06.169435555 -0600
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Chad Metcalf
+ */
+
+#include "message.h"
+
+interface CC2420Packet {
+  
+  /**
+   * Get transmission power setting for current packet.
+   *
+   * @param the message
+   */
+  async command uint8_t getPower( message_t* p_msg );
+
+  /**
+   * Set transmission power for a given packet. Valid ranges are
+   * between 0 and 31.
+   *
+   * @param p_msg the message.
+   * @param power transmission power.
+   */
+  async command void setPower( message_t* p_msg, uint8_t power );
+  
+  /**
+   * Get rssi value for a given packet. For received packets, it is
+   * the received signal strength when receiving that packet. For sent
+   * packets, it is the received signal strength of the ack if an ack
+   * was received.
+   */
+  async command int8_t getRssi( message_t* p_msg );
+
+  /**
+   * Get lqi value for a given packet. For received packets, it is the
+   * link quality indicator value when receiving that packet. For sent
+   * packets, it is the link quality indicator value of the ack if an
+   * ack was received.
+   */
+  async command uint8_t getLqi( message_t* p_msg );
+
+  /**
+   * @param  'message_t* ONE p_msg' the message.
+   */
+  async command uint8_t getNetwork( message_t* p_msg );
+
+  /**
+   * @param  'message_t* ONE p_msg' the message.
+   * @param  network id.
+   */
+  async command void setNetwork( message_t* p_msg, uint8_t networkId );
+  
+}
diff -urN tos/chips/cc2420/interfaces/sim/CC2420Receive.nc tos/chips/cc2420/interfaces/sim/CC2420Receive.nc
--- tos/chips/cc2420/interfaces/sim/CC2420Receive.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/interfaces/sim/CC2420Receive.nc	2010-04-24 13:13:06.169435555 -0600
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Low-level abstraction of the receive path implementation for the
+ * ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2008/06/17 07:28:24 $
+ */
+
+#include "message.h"
+
+interface CC2420Receive {
+
+  /**
+   * Notification that an SFD capture has occured.
+   *
+   * @param time at which the capture happened.
+   */
+  async command void sfd( uint32_t timet );
+
+  /**
+   * Notification that the packet has been dropped by the radio
+   * (e.g. due to address rejection).
+   */
+  async command void sfd_dropped();
+
+  /**
+   * Signals that a message has been received.
+   *
+   * @param type of the message received.
+   * @param message pointer to message received.
+   */
+  async event void receive( uint8_t type, message_t* ONE_NOK message );
+
+}
+
diff -urN tos/chips/cc2420/interfaces/sim/TriggerInterrupt.nc tos/chips/cc2420/interfaces/sim/TriggerInterrupt.nc
--- tos/chips/cc2420/interfaces/sim/TriggerInterrupt.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/interfaces/sim/TriggerInterrupt.nc	2010-04-24 13:13:06.169435555 -0600
@@ -0,0 +1,36 @@
+// $Id: GpioInterrupt.nc,v 1.4 2006/12/12 18:23:14 vlahan 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 Jonathan Hui
+ * @author Joe Polastre
+ * Revision:  $Revision: 1.4 $
+ *
+ * Provides a microcontroller-independent presentation of interrupts
+ */
+
+
+interface TriggerInterrupt {
+
+  async command error_t enableIntr();
+
+}
diff -urN tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkC.nc tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkC.nc
--- tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkC.nc	2010-04-24 13:13:52.785435787 -0600
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2005-2006 Rincon Research Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Rincon Research Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+ 
+/**
+ * Original TinyOS T-Frames use a packet header that is not compatible with
+ * other 6LowPAN networks.  They do not include the network byte 
+ * responsible for identifying the packing as being sourced from a TinyOS
+ * network.
+ *
+ * TinyOS I-Frames are interoperability packets that do include a network
+ * byte as defined by 6LowPAN specifications.  The I-Frame header type is
+ * the default packet header used in TinyOS networks.
+ *
+ * Since either packet header is acceptable, this layer must do some 
+ * preprocessing (sorry) to figure out whether or not it needs to include 
+ * the functionality to process I-frames.  If I-Frames are used, then
+ * the network byte is added on the way out and checked on the way in.
+ * If the packet came from a network different from a TinyOS network, the
+ * user may access it through the DispatchP's NonTinyosReceive[] Receive 
+ * interface and process it in a different radio stack.
+ *
+ * If T-Frames are used instead, this layer is simply pass-through wiring to the
+ * layer beneath.  
+ *
+ * Define "CC2420_IFRAME_TYPE" to use the interoperability frame and 
+ * this layer
+ * 
+ * @author David Moss
+ */
+ 
+#include "CC2420.h"
+#include "Ieee154.h"
+
+configuration CC2420TinyosNetworkC {
+  provides {
+    interface Resource[uint8_t clientId];
+    interface Send;
+    interface Receive;
+
+    interface Send as ActiveSend;
+    interface Receive as ActiveReceive;
+  }
+  
+  uses {
+    interface Receive as SubReceive;
+    interface Send as SubSend;
+  }
+}
+
+implementation {
+
+  enum {
+    TINYOS_N_NETWORKS = uniqueCount(RADIO_SEND_RESOURCE),
+  };
+
+  components MainC;
+  components CC2420TinyosNetworkP;
+  components CC2420PacketC;
+  components new FcfsResourceQueueC(TINYOS_N_NETWORKS);
+
+  CC2420TinyosNetworkP.BareSend = Send;
+  CC2420TinyosNetworkP.BareReceive = Receive;
+  CC2420TinyosNetworkP.SubSend = SubSend;
+  CC2420TinyosNetworkP.SubReceive = SubReceive;
+  CC2420TinyosNetworkP.Resource = Resource;
+  CC2420TinyosNetworkP.ActiveSend = ActiveSend;
+  CC2420TinyosNetworkP.ActiveReceive = ActiveReceive;
+
+  CC2420TinyosNetworkP.CC2420Packet -> CC2420PacketC;
+  CC2420TinyosNetworkP.CC2420PacketBody -> CC2420PacketC;
+  CC2420TinyosNetworkP.Queue -> FcfsResourceQueueC;
+
+  MainC.SoftwareInit -> FcfsResourceQueueC;
+}
+
diff -urN tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkP.nc tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkP.nc
--- tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/lowpan/sim/CC2420TinyosNetworkP.nc	2010-04-24 13:13:52.785435787 -0600
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2005-2006 Rincon Research Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Rincon Research Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Fills in the network ID byte for outgoing packets for compatibility with
+ * other 6LowPAN networks.  Filters incoming packets that are not
+ * TinyOS network compatible.  Provides the 6LowpanSnoop interface to
+ * sniff for packets that were not originated from TinyOS.
+ *
+ * @author David Moss
+ */
+
+#include "CC2420.h"
+#include "Ieee154.h"
+
+module CC2420TinyosNetworkP @safe() {
+  provides {
+    interface Resource[uint8_t client];
+
+    interface Send as BareSend;
+    interface Receive as BareReceive;
+
+    interface Send as ActiveSend;
+    interface Receive as ActiveReceive;
+  }
+  
+  uses {
+    interface Send as SubSend;
+    interface Receive as SubReceive;
+    interface CC2420Packet;
+    interface CC2420PacketBody;
+    interface ResourceQueue as Queue;
+  }
+}
+
+implementation {
+
+  enum {
+    OWNER_NONE = 0xff,
+    TINYOS_N_NETWORKS = uniqueCount(RADIO_SEND_RESOURCE),
+  } state;
+
+  norace uint8_t resource_owner = OWNER_NONE, next_owner;
+
+  command error_t ActiveSend.send(message_t* msg, uint8_t len) {
+    call CC2420Packet.setNetwork(msg, TINYOS_6LOWPAN_NETWORK_ID);
+    return call SubSend.send(msg, len);
+  }
+
+  command error_t ActiveSend.cancel(message_t* msg) {
+    return call SubSend.cancel(msg);
+  }
+
+  command uint8_t ActiveSend.maxPayloadLength() {
+    return call SubSend.maxPayloadLength();
+  }
+
+  command void* ActiveSend.getPayload(message_t* msg, uint8_t len) {
+    if (len <= call ActiveSend.maxPayloadLength()) {
+      return msg->data;
+    } else {
+      return NULL;
+    }
+  }
+
+  /***************** Send Commands ****************/
+  command error_t BareSend.send(message_t* msg, uint8_t len) {
+    return call SubSend.send(msg, len - AM_OVERHEAD);
+  }
+
+  command error_t BareSend.cancel(message_t* msg) {
+    return call SubSend.cancel(msg);
+  }
+
+  command uint8_t BareSend.maxPayloadLength() {
+    return call SubSend.maxPayloadLength() + AM_OVERHEAD;
+  }
+
+  command void* BareSend.getPayload(message_t* msg, uint8_t len) {
+#ifndef TFRAMES_ENABLED                      
+    cc2420_header_t *hdr = call CC2420PacketBody.getHeader(msg);
+    return &hdr->network;
+#else
+    // you really can't use BareSend with TFRAMES
+#error "BareSend is not supported with TFRAMES: only the ActiveMessage layer is supported"
+#endif
+  }
+  
+  /***************** SubSend Events *****************/
+  event void SubSend.sendDone(message_t* msg, error_t error) {
+    if (call CC2420Packet.getNetwork(msg) == TINYOS_6LOWPAN_NETWORK_ID) {
+      signal ActiveSend.sendDone(msg, error);
+    } else {
+      signal BareSend.sendDone(msg, error);
+    }
+  }
+
+  /***************** SubReceive Events ***************/
+  event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len) {
+
+    if(!(call CC2420PacketBody.getMetadata(msg))->crc) {
+      return msg;
+    }
+#ifndef TFRAMES_ENABLED
+    if (call CC2420Packet.getNetwork(msg) == TINYOS_6LOWPAN_NETWORK_ID) {
+      return signal ActiveReceive.receive(msg, payload, len);
+    } else {
+      cc2420_header_t *hdr = call CC2420PacketBody.getHeader(msg);
+      return signal BareReceive.receive(msg, &hdr->network, len + AM_OVERHEAD);
+    }
+#else
+    return signal ActiveReceive.receive(msg, payload, len);
+#endif
+  }
+
+  /***************** Resource ****************/
+  // SDH : 8-7-2009 : testing if there's more then one client allows
+  // the compiler to eliminate most of the logic when there's only one
+  // client.
+  task void grantTask() {
+
+
+    if (TINYOS_N_NETWORKS > 1) {
+      if (resource_owner == OWNER_NONE && !(call Queue.isEmpty())) {
+        resource_owner = call Queue.dequeue();
+
+        if (resource_owner != OWNER_NONE) {
+          signal Resource.granted[resource_owner]();
+        }
+      }
+    } else {
+      if (next_owner != resource_owner) {
+        resource_owner = next_owner;
+        signal Resource.granted[resource_owner]();
+      }
+    }
+  }
+
+  async command error_t Resource.request[uint8_t id]() {
+
+    post grantTask();
+
+    if (TINYOS_N_NETWORKS > 1) {
+      return call Queue.enqueue(id);
+    } else {
+      if (id == resource_owner) {
+        return EALREADY;
+      } else {
+        next_owner = id;
+        return SUCCESS;
+      }
+    }
+  }
+
+  async command error_t Resource.immediateRequest[uint8_t id]() {
+    if (resource_owner == id) return EALREADY;
+
+    if (TINYOS_N_NETWORKS > 1) {
+      if (resource_owner == OWNER_NONE && call Queue.isEmpty()) {
+        resource_owner = id;
+        return SUCCESS;
+      }
+      return FAIL;
+    } else {
+      resource_owner = id;
+      return SUCCESS;
+    }
+  }
+  async command error_t Resource.release[uint8_t id]() {
+    if (TINYOS_N_NETWORKS > 1) {
+      post grantTask();
+    }
+    resource_owner = OWNER_NONE;
+    return SUCCESS;
+  }
+  async command bool Resource.isOwner[uint8_t id]() {
+    return (id == resource_owner);
+  }
+
+  /***************** Defaults ****************/
+  default event message_t *BareReceive.receive(message_t *msg, void *payload, uint8_t len) {
+    return msg;
+  }
+  default event void BareSend.sendDone(message_t *msg, error_t error) {
+
+  }
+  default event message_t *ActiveReceive.receive(message_t *msg, void *payload, uint8_t len) {
+    return msg;
+  }
+  default event void ActiveSend.sendDone(message_t *msg, error_t error) {
+
+  }
+  default event void Resource.granted[uint8_t client]() {
+    call Resource.release[client]();
+  }
+
+}
diff -urN tos/chips/cc2420/packet/sim/CC2420PacketC.nc tos/chips/cc2420/packet/sim/CC2420PacketC.nc
--- tos/chips/cc2420/packet/sim/CC2420PacketC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/packet/sim/CC2420PacketC.nc	2010-04-24 13:14:56.297435332 -0600
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Chad Metcalf
+ */
+
+configuration CC2420PacketC {
+
+  provides {
+    interface CC2420Packet;
+    interface PacketAcknowledgements as Acks;
+    interface CC2420PacketBody;
+    interface LinkPacketMetadata;
+
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+    interface PacketTimeSyncOffset;
+  }
+
+}
+
+implementation {
+  components CC2420PacketP;
+  CC2420Packet         = CC2420PacketP;
+  Acks                 = CC2420PacketP;
+  CC2420PacketBody     = CC2420PacketP;
+  LinkPacketMetadata   = CC2420PacketP;
+  PacketTimeStamp32khz = CC2420PacketP;
+  PacketTimeStampMilli = CC2420PacketP;
+  PacketTimeSyncOffset = CC2420PacketP;
+
+#ifdef TIMESYNC
+  components TossimActiveMessageC;
+  CC2420PacketP.Packet -> TossimActiveMessageC;
+#endif
+
+  components Counter32khz32C, new CounterToLocalTimeC(T32khz);
+  CounterToLocalTimeC.Counter -> Counter32khz32C;
+  CC2420PacketP.LocalTime32khz -> CounterToLocalTimeC;
+
+  //DummyTimer is introduced to compile apps that use no timers
+  components HilTimerMilliC, new TimerMilliC() as DummyTimer;
+  CC2420PacketP.LocalTimeMilli -> HilTimerMilliC;
+}
diff -urN tos/chips/cc2420/packet/sim/CC2420PacketP.nc tos/chips/cc2420/packet/sim/CC2420PacketP.nc
--- tos/chips/cc2420/packet/sim/CC2420PacketP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/packet/sim/CC2420PacketP.nc	2010-04-24 13:14:56.297435332 -0600
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Chad Metcalf
+ */
+
+#include "IEEE802154.h"
+#include "message.h"
+#include "CC2420.h"
+#include "CC2420TimeSyncMessage.h"
+
+module CC2420PacketP @safe() {
+
+  provides {
+    interface CC2420Packet;
+    interface PacketAcknowledgements as Acks;
+    interface CC2420PacketBody;
+    interface LinkPacketMetadata;
+
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+    interface PacketTimeSyncOffset;
+  }
+
+  uses interface Packet;
+  uses interface LocalTime<T32khz> as LocalTime32khz;
+  uses interface LocalTime<TMilli> as LocalTimeMilli;
+}
+
+implementation {
+
+
+  /***************** PacketAcknowledgement Commands ****************/
+  async command error_t Acks.requestAck( message_t* p_msg ) {
+    (call CC2420PacketBody.getHeader( p_msg ))->fcf |= 1 << IEEE154_FCF_ACK_REQ;
+    return SUCCESS;
+  }
+
+  async command error_t Acks.noAck( message_t* p_msg ) {
+    (call CC2420PacketBody.getHeader( p_msg ))->fcf &= ~(1 << IEEE154_FCF_ACK_REQ);
+    return SUCCESS;
+  }
+
+  async command bool Acks.wasAcked( message_t* p_msg ) {
+    return (call CC2420PacketBody.getMetadata( p_msg ))->ack;
+  }
+
+  /***************** CC2420Packet Commands ****************/
+  async command void CC2420Packet.setPower( message_t* p_msg, uint8_t power ) {
+    if ( power > 31 )
+      power = 31;
+    (call CC2420PacketBody.getMetadata( p_msg ))->tx_power = power;
+  }
+
+  async command uint8_t CC2420Packet.getPower( message_t* p_msg ) {
+    return (call CC2420PacketBody.getMetadata( p_msg ))->tx_power;
+  }
+   
+  async command int8_t CC2420Packet.getRssi( message_t* p_msg ) {
+    return (call CC2420PacketBody.getMetadata( p_msg ))->rssi;
+  }
+
+  async command uint8_t CC2420Packet.getLqi( message_t* p_msg ) {
+    return (call CC2420PacketBody.getMetadata( p_msg ))->lqi;
+  }
+
+  async command uint8_t CC2420Packet.getNetwork( message_t* p_msg ) {
+#if defined(TFRAMES_ENABLED)
+    return TINYOS_6LOWPAN_NETWORK_ID;
+#else
+    return (call CC2420PacketBody.getHeader( p_msg ))->network;
+#endif
+  }
+
+  async command void CC2420Packet.setNetwork( message_t* p_msg , uint8_t networkId ) {
+#if ! defined(TFRAMES_ENABLED)
+    (call CC2420PacketBody.getHeader( p_msg ))->network = networkId;
+#endif
+  }    
+
+
+  /***************** CC2420PacketBody Commands ****************/
+  async command cc2420_header_t * ONE CC2420PacketBody.getHeader( message_t* ONE msg ) {
+    return TCAST(cc2420_header_t* ONE, (uint8_t *)msg + offsetof(message_t, data) - sizeof( cc2420_header_t ));
+  }
+
+  async command TRUSTEDBLOCK cc2420_metadata_t *CC2420PacketBody.getMetadata( message_t* msg ) {
+    return (cc2420_metadata_t*)msg->metadata;
+  }
+
+  async command bool LinkPacketMetadata.highChannelQuality(message_t* msg) {
+    return call CC2420Packet.getLqi(msg) > 105;
+  }
+
+  /***************** PacketTimeStamp32khz Commands ****************/
+  async command bool PacketTimeStamp32khz.isValid(message_t* msg)
+  {
+    return ((call CC2420PacketBody.getMetadata( msg ))->timestamp != CC2420_INVALID_TIMESTAMP);
+  }
+
+  async command uint32_t PacketTimeStamp32khz.timestamp(message_t* msg)
+  {
+    return (call CC2420PacketBody.getMetadata( msg ))->timestamp;
+  }
+
+  async command void PacketTimeStamp32khz.clear(message_t* msg)
+  {
+    (call CC2420PacketBody.getMetadata( msg ))->timesync = FALSE;
+    (call CC2420PacketBody.getMetadata( msg ))->timestamp = CC2420_INVALID_TIMESTAMP;
+  }
+
+  async command void PacketTimeStamp32khz.set(message_t* msg, uint32_t value)
+  {
+    (call CC2420PacketBody.getMetadata( msg ))->timestamp = value;
+  }
+
+  /***************** PacketTimeStampMilli Commands ****************/
+  // over the air value is always T32khz, which is used to capture SFD interrupt
+  // (Timer1 on micaZ, B1 on telos)
+  async command bool PacketTimeStampMilli.isValid(message_t* msg)
+  { 
+    return call PacketTimeStamp32khz.isValid(msg);
+  }
+
+  //timestmap is always represented in 32khz
+  //28.1 is coefficient difference between T32khz and TMilli on MicaZ
+  async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
+  {
+    int32_t offset = (call LocalTime32khz.get()-call PacketTimeStamp32khz.timestamp(msg));
+    dbg("TimeSyncC","%s: offset: %d, localtime32Milli.get: %d\n", __FUNCTION__, offset, call LocalTimeMilli.get());
+    offset/=28.1;
+    return call LocalTimeMilli.get() - offset;
+  }
+
+  async command void PacketTimeStampMilli.clear(message_t* msg)
+  {
+    call PacketTimeStamp32khz.clear(msg);
+  }
+
+  async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
+  {
+    int32_t offset = (value - call LocalTimeMilli.get()) << 5;
+    call PacketTimeStamp32khz.set(msg, offset + call LocalTime32khz.get());
+  }
+  /*----------------- PacketTimeSyncOffset -----------------*/
+  async command bool PacketTimeSyncOffset.isSet(message_t* msg)
+  {
+    return ((call CC2420PacketBody.getMetadata( msg ))->timesync);
+  }
+
+  //returns offset of timestamp from the beginning of cc2420 header which is
+  //          sizeof(cc2420_header_t)+datalen-sizeof(timesync_radio_t)
+  //uses packet length of the message which is
+  //          MAC_HEADER_SIZE+MAC_FOOTER_SIZE+datalen
+  async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
+  {
+    return (call CC2420PacketBody.getHeader(msg))->length
+            + (sizeof(cc2420_header_t) - MAC_HEADER_SIZE)
+            - MAC_FOOTER_SIZE
+            - sizeof(timesync_radio_t);
+  }
+  
+  async command void PacketTimeSyncOffset.set(message_t* msg)
+  {
+    (call CC2420PacketBody.getMetadata( msg ))->timesync = TRUE;
+  }
+
+  async command void PacketTimeSyncOffset.cancel(message_t* msg)
+  {
+    (call CC2420PacketBody.getMetadata( msg ))->timesync = FALSE;
+  }
+}
diff -urN tos/chips/cc2420/receive/sim/CC2420ReceiveC.nc tos/chips/cc2420/receive/sim/CC2420ReceiveC.nc
--- tos/chips/cc2420/receive/sim/CC2420ReceiveC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/receive/sim/CC2420ReceiveC.nc	2010-04-24 13:15:45.953435712 -0600
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation of the receive path for the ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2009/08/14 20:33:43 $
+ */
+
+configuration CC2420ReceiveC {
+
+  provides interface StdControl;
+  provides interface CC2420Receive;
+  provides interface Receive;
+  provides interface ReceiveIndicator as PacketIndicator;
+
+}
+
+implementation {
+  components MainC;
+  components CC2420ReceiveP;
+  components CC2420PacketC;
+  components new CC2420SpiC() as Spi;
+  components CC2420ControlC;
+  
+  components HplCC2420PinsC as Pins;
+  components HplCC2420InterruptsC as InterruptsC;
+
+  components LedsC as Leds;
+  CC2420ReceiveP.Leds -> Leds;
+
+  StdControl = CC2420ReceiveP;
+  CC2420Receive = CC2420ReceiveP;
+  Receive = CC2420ReceiveP;
+  PacketIndicator = CC2420ReceiveP.PacketIndicator;
+
+  MainC.SoftwareInit -> CC2420ReceiveP;
+  
+  CC2420ReceiveP.CSN -> Pins.CSN;
+  CC2420ReceiveP.FIFO -> Pins.FIFO;
+  CC2420ReceiveP.FIFOP -> Pins.FIFOP;
+  CC2420ReceiveP.InterruptFIFOP -> InterruptsC.InterruptFIFOP;
+  CC2420ReceiveP.SpiResource -> Spi;
+  CC2420ReceiveP.RXFIFO -> Spi.RXFIFO;
+  CC2420ReceiveP.SFLUSHRX -> Spi.SFLUSHRX;
+  CC2420ReceiveP.SACK -> Spi.SACK;
+  CC2420ReceiveP.CC2420Packet -> CC2420PacketC;
+  CC2420ReceiveP.CC2420PacketBody -> CC2420PacketC;
+  CC2420ReceiveP.PacketTimeStamp -> CC2420PacketC;
+  CC2420ReceiveP.CC2420Config -> CC2420ControlC;
+
+  CC2420ReceiveP.SECCTRL0 -> Spi.SECCTRL0;
+  CC2420ReceiveP.SECCTRL1 -> Spi.SECCTRL1;
+  CC2420ReceiveP.SRXDEC -> Spi.SRXDEC;
+  CC2420ReceiveP.RXNONCE -> Spi.RXNONCE;
+  CC2420ReceiveP.KEY0 -> Spi.KEY0;
+  CC2420ReceiveP.KEY1 -> Spi.KEY1;
+  CC2420ReceiveP.RXFIFO_RAM -> Spi.RXFIFO_RAM;
+  CC2420ReceiveP.SNOP -> Spi.SNOP;
+
+}
diff -urN tos/chips/cc2420/receive/sim/CC2420ReceiveP.nc tos/chips/cc2420/receive/sim/CC2420ReceiveP.nc
--- tos/chips/cc2420/receive/sim/CC2420ReceiveP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/receive/sim/CC2420ReceiveP.nc	2010-04-24 13:15:45.953435712 -0600
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Jung Il Choi
+ * @author JeongGil Ko
+ * @author Razvan Musaloiu-E
+ * @version $Revision: 1.22 $ $Date: 2009/10/28 21:09:52 $
+ */
+
+#include "IEEE802154.h"
+#include "message.h"
+#include "AM.h"
+
+module CC2420ReceiveP @safe() {
+
+  provides interface Init;
+  provides interface StdControl;
+  provides interface CC2420Receive;
+  provides interface Receive;
+  provides interface ReceiveIndicator as PacketIndicator;
+
+  uses interface GeneralIO as CSN;
+  uses interface GeneralIO as FIFO;
+  uses interface GeneralIO as FIFOP;
+  uses interface GpioInterrupt as InterruptFIFOP;
+
+  uses interface Resource as SpiResource;
+  uses interface CC2420Fifo as RXFIFO;
+  uses interface CC2420Strobe as SACK;
+  uses interface CC2420Strobe as SFLUSHRX;
+  uses interface CC2420Packet;
+  uses interface CC2420PacketBody;
+  uses interface CC2420Config;
+  uses interface PacketTimeStamp<T32khz,uint32_t>;
+
+  uses interface CC2420Strobe as SRXDEC;
+  uses interface CC2420Register as SECCTRL0;
+  uses interface CC2420Register as SECCTRL1;
+  uses interface CC2420Ram as KEY0;
+  uses interface CC2420Ram as KEY1;
+  uses interface CC2420Ram as RXNONCE;
+  uses interface CC2420Ram as RXFIFO_RAM;
+  uses interface CC2420Strobe as SNOP;
+
+  uses interface Leds;
+}
+
+implementation {
+
+  typedef enum {
+    S_STOPPED,
+    S_STARTED,
+    S_RX_LENGTH,
+    S_RX_DEC,
+    S_RX_DEC_WAIT,
+    S_RX_FCF,
+    S_RX_PAYLOAD,
+  } cc2420_receive_state_t;
+
+  enum {
+    RXFIFO_SIZE = 128,
+    TIMESTAMP_QUEUE_SIZE = 8,
+    SACK_HEADER_LENGTH = 7,
+  };
+
+  uint32_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
+
+  uint8_t m_timestamp_head;
+  
+  uint8_t m_timestamp_size;
+  
+  /** Number of packets we missed because we were doing something else */
+#ifdef CC2420_HW_SECURITY
+  norace uint8_t m_missed_packets;
+#else
+  uint8_t m_missed_packets;
+#endif
+
+  /** TRUE if we are receiving a valid packet into the stack */
+  bool receivingPacket;
+  
+  /** The length of the frame we're currently receiving */
+  norace uint8_t rxFrameLength;
+  
+  norace uint8_t m_bytes_left;
+  
+  norace message_t* ONE_NOK m_p_rx_buf;
+
+  message_t m_rx_buf;
+#ifdef CC2420_HW_SECURITY
+  norace cc2420_receive_state_t m_state;
+  norace uint8_t packetLength = 0;
+  norace uint8_t pos = 0;
+  norace uint8_t secHdrPos = 0;
+  uint8_t nonceValue[16] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+  norace uint8_t skip;
+  norace uint8_t securityOn = 0;
+  norace uint8_t authentication = 0;
+  norace uint8_t micLength = 0;
+  uint8_t flush_flag = 0;
+  uint16_t startTime = 0;
+
+  void beginDec();
+  void dec();
+#else
+  cc2420_receive_state_t m_state;
+#endif
+
+  /***************** Prototypes ****************/
+  void reset_state();
+  void beginReceive();
+  void receive();
+  void waitForNextPacket();
+  void flush();
+  bool passesAddressCheck(message_t * ONE msg);
+
+  task void receiveDone_task();
+
+  /***************** Init Commands ****************/
+  command error_t Init.init() {
+    m_p_rx_buf = &m_rx_buf;
+    return SUCCESS;
+  }
+
+  /***************** StdControl ****************/
+  command error_t StdControl.start() {
+    atomic {
+      reset_state();
+      m_state = S_STARTED;
+      atomic receivingPacket = FALSE;
+      /* Note:
+         We use the falling edge because the FIFOP polarity is reversed. 
+         This is done in CC2420Power.startOscillator from CC2420ControlP.nc.
+       */
+      call InterruptFIFOP.enableFallingEdge();
+    }
+    return SUCCESS;
+  }
+  
+  command error_t StdControl.stop() {
+    atomic {
+      m_state = S_STOPPED;
+      reset_state();
+      call CSN.set();
+      call InterruptFIFOP.disable();
+    }
+    return SUCCESS;
+  }
+
+  /***************** CC2420Receive Commands ****************/
+  /**
+   * Start frame delimiter signifies the beginning/end of a packet
+   * See the CC2420 datasheet for details.
+   */
+  async command void CC2420Receive.sfd( uint32_t timet ) {
+    if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
+      uint8_t tail =  ( ( m_timestamp_head + m_timestamp_size ) % 
+                        TIMESTAMP_QUEUE_SIZE );
+      m_timestamp_queue[ tail ] = timet;
+      m_timestamp_size++;
+    }
+  }
+
+  async command void CC2420Receive.sfd_dropped() {
+    if ( m_timestamp_size ) {
+      m_timestamp_size--;
+    }
+  }
+
+  /***************** PacketIndicator Commands ****************/
+  command bool PacketIndicator.isReceiving() {
+    bool receiving;
+    atomic {
+      receiving = receivingPacket;
+    }
+    return receiving;
+  }
+  
+  
+  /***************** InterruptFIFOP Events ****************/
+  async event void InterruptFIFOP.fired() {
+    dbg("CC2420", "%s, interruptFIFOP fired!\n", __FUNCTION__);
+    if ( m_state == S_STARTED ) {
+#ifndef CC2420_HW_SECURITY
+      m_state = S_RX_LENGTH;
+      beginReceive();
+#else
+      m_state = S_RX_DEC;
+      atomic receivingPacket = TRUE;
+      beginDec();
+#endif
+    } else {
+      m_missed_packets++;
+    }
+  }
+
+  /*****************Decryption Options*********************/
+#ifdef CC2420_HW_SECURITY
+  task void waitTask(){
+
+    if(SECURITYLOCK == 1){
+      post waitTask();
+    }else{
+      m_state = S_RX_DEC;
+      beginDec();
+    }
+  }
+
+  void beginDec(){
+    if(call SpiResource.isOwner()) {
+      dec();
+    } else if (call SpiResource.immediateRequest() == SUCCESS) {
+      dec();
+    } else {
+      call SpiResource.request();
+    }
+  }
+
+  norace uint8_t decLoopCount = 0;
+
+  task void waitDecTask(){
+
+    cc2420_status_t status;
+
+    call CSN.clr();
+    status = call SNOP.strobe();
+    call CSN.set();
+
+    atomic decLoopCount ++;
+
+    if(decLoopCount > 10){
+      call CSN.clr();
+      atomic call SECCTRL0.write((0 << CC2420_SECCTRL0_SEC_MODE) |
+				 (0 << CC2420_SECCTRL0_SEC_M) |
+				 (0 << CC2420_SECCTRL0_SEC_RXKEYSEL) |
+				 (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
+				 (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
+      call CSN.set();
+      SECURITYLOCK = 0;
+      call SpiResource.release();
+      atomic flush_flag = 1;
+      beginReceive();
+    }else if(status & CC2420_STATUS_ENC_BUSY){
+      post waitDecTask();
+    }else{
+      call CSN.clr();
+      atomic call SECCTRL0.write((0 << CC2420_SECCTRL0_SEC_MODE) |
+				 (0 << CC2420_SECCTRL0_SEC_M) |
+				 (0 << CC2420_SECCTRL0_SEC_RXKEYSEL) |
+				 (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
+				 (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
+      call CSN.set();
+      SECURITYLOCK = 0;
+      call SpiResource.release();
+      beginReceive();
+    }
+
+  }
+
+  void waitDec(){
+    cc2420_status_t status;
+    call CSN.clr();
+    status = call SNOP.strobe();
+    call CSN.set();
+
+    if(status & CC2420_STATUS_ENC_BUSY){
+      atomic decLoopCount = 1;
+      post waitDecTask();
+    }else{
+      call CSN.clr();
+      atomic call SECCTRL0.write((0 << CC2420_SECCTRL0_SEC_MODE) |
+				 (0 << CC2420_SECCTRL0_SEC_M) |
+				 (0 << CC2420_SECCTRL0_SEC_RXKEYSEL) |
+				 (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
+				 (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
+      call CSN.set();
+      SECURITYLOCK = 0;
+      call SpiResource.release();
+      beginReceive();
+    }
+  }
+
+  void dec(){
+    cc2420_header_t header;
+    security_header_t secHdr;
+    uint8_t mode, key, temp, crc;
+
+    atomic pos = (packetLength+pos)%RXFIFO_SIZE;
+    atomic secHdrPos = (pos+10)%RXFIFO_SIZE;
+
+    if (pos + 3 > RXFIFO_SIZE){
+      temp = RXFIFO_SIZE - pos;
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, temp);
+      call CSN.set();
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(0,(uint8_t*)&header+temp, 3-temp);
+      call CSN.set();
+    }else{
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, 3);
+      call CSN.set();
+    }
+
+    packetLength = header.length+1;
+
+    if(packetLength == 6){ // ACK packet
+      m_state = S_RX_LENGTH;
+      call SpiResource.release();
+      beginReceive();
+      return;
+    }
+
+    if (pos + sizeof(cc2420_header_t) > RXFIFO_SIZE){
+      temp = RXFIFO_SIZE - pos;
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, temp);
+      call CSN.set();
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(0,(uint8_t*)&header+temp, sizeof(cc2420_header_t)-temp);
+      call CSN.set();
+    }else{
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, sizeof(cc2420_header_t));
+      call CSN.set();
+    }
+
+    if (pos+header.length+1 > RXFIFO_SIZE){
+      temp = header.length - (RXFIFO_SIZE - pos);
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(temp,&crc, 1);
+      call CSN.set();
+    }else{
+      call CSN.clr();
+      atomic call RXFIFO_RAM.read(pos+header.length,&crc, 1);
+      call CSN.set();
+    }
+
+    if(header.length+1 > RXFIFO_SIZE || !(crc << 7)){
+      atomic flush_flag = 1;
+      m_state = S_RX_LENGTH;
+      call SpiResource.release();
+      beginReceive();
+      return;
+    }
+    if( (header.fcf & (1 << IEEE154_FCF_SECURITY_ENABLED)) && (crc << 7) ){
+      if(call CC2420Config.isAddressRecognitionEnabled()){
+	if(!(header.dest==call CC2420Config.getShortAddr() || header.dest==AM_BROADCAST_ADDR)){
+	  packetLength = header.length + 1;
+	  m_state = S_RX_LENGTH;
+	  call SpiResource.release();
+	  beginReceive();
+	  return;
+	}
+      }
+      if(SECURITYLOCK == 1){
+	call SpiResource.release();
+	post waitTask();
+	return;
+      }else{
+	//We are going to decrypt so lock the registers
+	atomic SECURITYLOCK = 1;
+
+	if (secHdrPos + sizeof(security_header_t) > RXFIFO_SIZE){
+	  temp = RXFIFO_SIZE - secHdrPos;
+	  call CSN.clr();
+	  atomic call RXFIFO_RAM.read(secHdrPos,(uint8_t*)&secHdr, temp);
+	  call CSN.set();
+	  call CSN.clr();
+	  atomic call RXFIFO_RAM.read(0,(uint8_t*)&secHdr+temp, sizeof(security_header_t) - temp);
+	  call CSN.set();
+	} else {
+	  call CSN.clr();
+	  atomic call RXFIFO_RAM.read(secHdrPos,(uint8_t*)&secHdr, sizeof(security_header_t));
+	  call CSN.set();
+	}
+
+	key = secHdr.keyID[0];
+
+	if (secHdr.secLevel == NO_SEC){
+	  mode = CC2420_NO_SEC;
+	  micLength = 0;
+	}else if (secHdr.secLevel == CBC_MAC_4){
+	  mode = CC2420_CBC_MAC;
+	  micLength = 4;
+	}else if (secHdr.secLevel == CBC_MAC_8){
+	  mode = CC2420_CBC_MAC;
+	  micLength = 8;
+	}else if (secHdr.secLevel == CBC_MAC_16){
+	  mode = CC2420_CBC_MAC;
+	  micLength = 16;
+	}else if (secHdr.secLevel == CTR){
+	  mode = CC2420_CTR;
+	  micLength = 0;
+	}else if (secHdr.secLevel == CCM_4){
+	  mode = CC2420_CCM;
+	  micLength = 4;
+	}else if (secHdr.secLevel == CCM_8){
+	  mode = CC2420_CCM;
+	  micLength = 8;
+	}else if (secHdr.secLevel == CCM_16){
+	  mode = CC2420_CCM;
+	  micLength = 16;
+	}else{
+	  atomic SECURITYLOCK = 0;
+	  packetLength = header.length + 1;
+	  m_state = S_RX_LENGTH;
+	  call SpiResource.release();
+	  beginReceive();
+	  return;
+	}
+
+	if(mode < 4 && mode > 0) { // if mode is valid
+  
+	  securityOn = 1;
+
+	  memcpy(&nonceValue[3], &(secHdr.frameCounter), 4);
+	  skip = secHdr.reserved;
+
+	  if(mode == CC2420_CBC_MAC || mode == CC2420_CCM){
+	    authentication = 1;
+	    call CSN.clr();
+	    atomic call SECCTRL0.write((mode << CC2420_SECCTRL0_SEC_MODE) |
+				       ((micLength-2)/2 << CC2420_SECCTRL0_SEC_M) |
+				       (key << CC2420_SECCTRL0_SEC_RXKEYSEL) |
+				       (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
+				       (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
+	    call CSN.set();
+	  }else{
+	    call CSN.clr();
+	    atomic call SECCTRL0.write((mode << CC2420_SECCTRL0_SEC_MODE) |
+				       (1 << CC2420_SECCTRL0_SEC_M) |
+				       (key << CC2420_SECCTRL0_SEC_RXKEYSEL) |
+				       (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
+				       (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
+	    call CSN.set();
+	  }
+
+	  call CSN.clr();
+#ifndef TFRAMES_ENABLED
+	  atomic call SECCTRL1.write(skip+11+sizeof(security_header_t)+((skip+11+sizeof(security_header_t))<<8));
+#else
+	  atomic call SECCTRL1.write(skip+10+sizeof(security_header_t)+((skip+10+sizeof(security_header_t))<<8));
+#endif
+	  call CSN.set();
+
+	  call CSN.clr();
+	  atomic call RXNONCE.write(0, nonceValue, 16);
+	  call CSN.set();
+
+	  call CSN.clr();
+	  atomic call SRXDEC.strobe();
+	  call CSN.set();
+
+	  atomic decLoopCount = 0;
+	  post waitDecTask();
+	  return;
+
+	}else{
+	  atomic SECURITYLOCK = 0;
+	  packetLength = header.length + 1;
+	  m_state = S_RX_LENGTH;
+	  call SpiResource.release();
+	  beginReceive();
+	  return;
+	}
+      }
+    }else{
+      packetLength = header.length + 1;
+      m_state = S_RX_LENGTH;
+      call SpiResource.release();
+      beginReceive();
+      return;
+    }
+  }
+#endif
+  /***************** SpiResource Events ****************/
+  event void SpiResource.granted() {
+#ifdef CC2420_HW_SECURITY
+    if(m_state == S_RX_DEC){
+      dec();
+    }else{
+      receive();
+    }
+#else
+    receive();
+#endif
+  }
+  
+  /***************** RXFIFO Events ****************/
+  /**
+   * We received some bytes from the SPI bus.  Process them in the context
+   * of the state we're in.  Remember the length byte is not part of the length
+   */
+  async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len,
+                                    error_t error ) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf );
+    uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t));
+    uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header);
+    rxFrameLength = buf[ 0 ];
+
+    switch( m_state ) {
+
+    case S_RX_LENGTH:
+      m_state = S_RX_FCF;
+#ifdef CC2420_HW_SECURITY
+      packetLength = rxFrameLength+1;
+#endif
+      if ( rxFrameLength + 1 > m_bytes_left
+#ifdef CC2420_HW_SECURITY
+           || flush_flag == 1
+#endif
+           ) {
+        // Length of this packet is bigger than the RXFIFO, flush it out.
+        flush();
+        
+      } else {
+        if ( !call FIFO.get() && !call FIFOP.get() ) {
+          m_bytes_left -= rxFrameLength + 1;
+        }
+        
+        if(rxFrameLength <= MAC_PACKET_SIZE) {
+          if(rxFrameLength > 0) {
+            if(rxFrameLength > SACK_HEADER_LENGTH) {
+              // This packet has an FCF byte plus at least one more byte to read
+              call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH);
+              
+            } else {
+              // This is really a bad packet, skip FCF and get it out of here.
+              m_state = S_RX_PAYLOAD;
+              call RXFIFO.continueRead(buf + 1, rxFrameLength);
+            }
+                            
+          } else {
+            // Length == 0; start reading the next packet
+            atomic receivingPacket = FALSE;
+            call CSN.set();
+            call SpiResource.release();
+            waitForNextPacket();
+          }
+          
+        } else {
+          // Length is too large; we have to flush the entire Rx FIFO
+          flush();
+        }
+      }
+      break;
+      
+    case S_RX_FCF:
+      m_state = S_RX_PAYLOAD;
+      
+      /*
+       * The destination address check here is not completely optimized. If you 
+       * are seeing issues with dropped acknowledgements, try removing
+       * the address check and decreasing SACK_HEADER_LENGTH to 2.
+       * The length byte and the FCF byte are the only two bytes required
+       * to know that the packet is valid and requested an ack.  The destination
+       * address is useful when we want to sniff packets from other transmitters
+       * while acknowledging packets that were destined for our local address.
+       */
+      if(call CC2420Config.isAutoAckEnabled() && !call CC2420Config.isHwAutoAckDefault()) {
+        if (((( header->fcf >> IEEE154_FCF_ACK_REQ ) & 0x01) == 1)
+            && ((header->dest == call CC2420Config.getShortAddr())
+                || (header->dest == AM_BROADCAST_ADDR))
+            && ((( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7) == IEEE154_TYPE_DATA)) {
+          // CSn flippage cuts off our FIFO; SACK and begin reading again
+          call CSN.set();
+          call CSN.clr();
+          call SACK.strobe();
+          call CSN.set();
+          call CSN.clr();
+	  call RXFIFO.beginRead(buf + 1 + SACK_HEADER_LENGTH,
+				rxFrameLength - SACK_HEADER_LENGTH);
+          return;
+        }
+      }
+      // Didn't flip CSn, we're ok to continue reading.
+      call RXFIFO.continueRead(buf + 1 + SACK_HEADER_LENGTH, 
+			       rxFrameLength - SACK_HEADER_LENGTH);
+      break;
+
+    case S_RX_PAYLOAD:
+
+      call CSN.set();
+      if(!m_missed_packets) {
+        // Release the SPI only if there are no more frames to download
+        call SpiResource.release();
+      }
+      
+      //new packet is buffered up, or we don't have timestamp in fifo, or ack
+      if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get()
+            || !m_timestamp_size
+            || rxFrameLength <= 10) {
+        call PacketTimeStamp.clear(m_p_rx_buf);
+      }
+      else {
+          if (m_timestamp_size==1)
+            call PacketTimeStamp.set(m_p_rx_buf, m_timestamp_queue[ m_timestamp_head ]);
+          m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
+          m_timestamp_size--;
+
+          if (m_timestamp_size>0) {
+            call PacketTimeStamp.clear(m_p_rx_buf);
+            m_timestamp_head = 0;
+            m_timestamp_size = 0;
+          }
+      }
+
+      // We may have received an ack that should be processed by Transmit
+      // buf[rxFrameLength] >> 7 checks the CRC
+      if ( ( buf[ rxFrameLength ] >> 7 ) && rx_buf ) {
+        uint8_t type = ( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7;
+        signal CC2420Receive.receive( type, m_p_rx_buf );
+        if ( type == IEEE154_TYPE_DATA ) {
+          post receiveDone_task();
+          return;
+        }
+      }
+      
+      waitForNextPacket();
+      break;
+
+    default:
+      atomic receivingPacket = FALSE;
+      call CSN.set();
+      call SpiResource.release();
+      break;
+      
+    }
+    
+  }
+
+  async event void RXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
+  }  
+  
+  /***************** Tasks *****************/
+  /**
+   * Fill in metadata details, pass the packet up the stack, and
+   * get the next packet.
+   */
+  task void receiveDone_task() {
+    cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );
+    cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf);
+    uint8_t length = header->length;
+    uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t));
+    uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header);
+
+    metadata->crc = buf[ length ] >> 7;
+    metadata->lqi = buf[ length ] & 0x7f;
+    metadata->rssi = buf[ length - 1 ];
+
+    if (passesAddressCheck(m_p_rx_buf) && length >= CC2420_SIZE) {
+#ifdef CC2420_HW_SECURITY
+      if(securityOn == 1){
+	if(m_missed_packets > 0){
+	  m_missed_packets --;
+	}
+	if(authentication){
+	  length -= micLength;
+	}
+      }
+      micLength = 0;
+      securityOn = 0;
+      authentication = 0;
+#endif
+      m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data,
+					   length - CC2420_SIZE);
+    }
+    atomic receivingPacket = FALSE;
+    waitForNextPacket();
+  }
+
+  /****************** CC2420Config Events ****************/
+  event void CC2420Config.syncDone( error_t error ) {
+  }
+  
+  /****************** Functions ****************/
+  /**
+   * Attempt to acquire the SPI bus to receive a packet.
+   */
+  void beginReceive() { 
+    m_state = S_RX_LENGTH;
+    atomic receivingPacket = TRUE;
+    if(call SpiResource.isOwner()) {
+      receive();
+      
+    } else if (call SpiResource.immediateRequest() == SUCCESS) {
+      receive();
+      
+    } else {
+      call SpiResource.request();
+    }
+  }
+  
+  /**
+   * Flush out the Rx FIFO
+   */
+  void flush() {
+#ifdef CC2420_HW_SECURITY
+    flush_flag = 0;
+    pos =0;
+    packetLength =0;
+    micLength = 0;
+    securityOn = 0;
+    authentication = 0;
+#endif
+    reset_state();
+
+    call CSN.set();
+    call CSN.clr();
+    call SFLUSHRX.strobe();
+    call SFLUSHRX.strobe();
+    call CSN.set();
+    call SpiResource.release();
+    waitForNextPacket();
+  }
+  
+  /**
+   * The first byte of each packet is the length byte.  Read in that single
+   * byte, and then read in the rest of the packet.  The CC2420 could contain
+   * multiple packets that have been buffered up, so if something goes wrong, 
+   * we necessarily want to flush out the FIFO unless we have to.
+   */
+  void receive() {
+    call CSN.clr();
+    call RXFIFO.beginRead( (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf )), 1 );
+  }
+
+
+  /**
+   * Determine if there's a packet ready to go, or if we should do nothing
+   * until the next packet arrives
+   */
+  void waitForNextPacket() {
+    atomic {
+      if ( m_state == S_STOPPED ) {
+        call SpiResource.release();
+        return;
+      }
+      
+      atomic receivingPacket = FALSE;
+      
+      /*
+       * The FIFOP pin here is high when there are 0 bytes in the RX FIFO
+       * and goes low as soon as there are bytes in the RX FIFO.  The pin
+       * is inverted from what the datasheet says, and its threshold is 127.
+       * Whenever the FIFOP line goes low, as you can see from the interrupt
+       * handler elsewhere in this module, it means we received a new packet.
+       * If the line stays low without generating an interrupt, that means
+       * there's still more data to be received.
+       */
+
+      if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) {
+        // A new packet is buffered up and ready to go
+        if ( m_missed_packets ) {
+          m_missed_packets--;
+        }
+#ifdef CC2420_HW_SECURITY
+	call SpiResource.release();
+	m_state = S_RX_DEC;
+	beginDec();
+#else
+	beginReceive();
+#endif
+
+      } else {
+        // Wait for the next packet to arrive
+        m_state = S_STARTED;
+        m_missed_packets = 0;
+        call SpiResource.release();
+      }
+    }
+  }
+  
+  /**
+   * Reset this component
+   */
+  void reset_state() {
+    m_bytes_left = RXFIFO_SIZE;
+    atomic receivingPacket = FALSE;
+    m_timestamp_head = 0;
+    m_timestamp_size = 0;
+    m_missed_packets = 0;
+  }
+
+  /**
+   * @return TRUE if the given message passes address recognition
+   */
+  bool passesAddressCheck(message_t *msg) {
+    cc2420_header_t *header = call CC2420PacketBody.getHeader( msg );
+    
+    if(!(call CC2420Config.isAddressRecognitionEnabled())) {
+      return TRUE;
+    }
+    
+    return (header->dest == call CC2420Config.getShortAddr()
+        || header->dest == AM_BROADCAST_ADDR);
+  }
+
+}
diff -urN tos/chips/cc2420/sim/CC2420ActiveMessageC.nc tos/chips/cc2420/sim/CC2420ActiveMessageC.nc
--- tos/chips/cc2420/sim/CC2420ActiveMessageC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/sim/CC2420ActiveMessageC.nc	2010-04-24 13:16:50.633435536 -0600
@@ -0,0 +1,102 @@
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * The Active Message layer for the CC2420 radio. This configuration
+ * just layers the AM dispatch (CC2420ActiveMessageM) on top of the
+ * underlying CC2420 radio packet (CC2420CsmaCsmaCC), which is
+ * inherently an AM packet (acknowledgements based on AM destination
+ * addr and group). Note that snooping may not work, due to CC2420
+ * early packet rejection if acknowledgements are enabled.
+ *
+ * @author Philip Levis
+ * @author David Moss
+ * @version $Revision: 1.15 $ $Date: 2010/02/11 04:39:46 $
+ */
+
+#include "CC2420.h"
+#include "AM.h"
+#include "Ieee154.h"
+
+#ifdef IEEE154FRAMES_ENABLED
+#error "CC2420 AM layer cannot work when IEEE 802.15.4 frames only are used"
+#endif
+
+configuration CC2420ActiveMessageC {
+  provides {
+    interface SplitControl;
+    interface AMSend[am_id_t id];
+    interface Receive[am_id_t id];
+    interface Receive as Snoop[am_id_t id];
+    interface AMPacket;
+    interface Packet;
+    interface CC2420Packet;
+    interface PacketAcknowledgements;
+    interface LinkPacketMetadata;
+    interface RadioBackoff[am_id_t amId];
+    interface LowPowerListening;
+    interface PacketLink;
+    interface SendNotifier[am_id_t amId];
+  }
+}
+implementation {
+  enum {
+    CC2420_AM_SEND_ID     = unique(RADIO_SEND_RESOURCE),
+  };
+
+  components CC2420RadioC as Radio;
+  components CC2420ActiveMessageP as AM;
+  components ActiveMessageAddressC;
+  components CC2420CsmaC as CsmaC;
+  components CC2420ControlC;
+  components CC2420PacketC;
+  
+  SplitControl = Radio;
+  RadioBackoff = AM;
+  Packet = AM;
+  AMSend = AM;
+  SendNotifier = AM;
+  Receive = AM.Receive;
+  Snoop = AM.Snoop;
+  AMPacket = AM;
+  PacketLink = Radio;
+  LowPowerListening = Radio;
+  CC2420Packet = Radio;
+  PacketAcknowledgements = Radio;
+  LinkPacketMetadata = Radio;
+  
+  // Radio resource for the AM layer
+  AM.RadioResource -> Radio.Resource[CC2420_AM_SEND_ID];
+  AM.SubSend -> Radio.ActiveSend;
+  AM.SubReceive -> Radio.ActiveReceive;
+
+  AM.ActiveMessageAddress -> ActiveMessageAddressC;
+  AM.CC2420Packet -> CC2420PacketC;
+  AM.CC2420PacketBody -> CC2420PacketC;
+  AM.CC2420Config -> CC2420ControlC;
+  
+  AM.SubBackoff -> CsmaC;
+
+  components LedsC;
+  AM.Leds -> LedsC;
+}
diff -urN tos/chips/cc2420/sim/CC2420ActiveMessageP.nc tos/chips/cc2420/sim/CC2420ActiveMessageP.nc
--- tos/chips/cc2420/sim/CC2420ActiveMessageP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/sim/CC2420ActiveMessageP.nc	2010-04-24 13:16:50.633435536 -0600
@@ -0,0 +1,292 @@
+/*
+ * "Copyright (c) 2005 Stanford University. 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 STANFORD UNIVERSITY 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+
+/**
+ * Active message implementation on top of the CC2420 radio. This
+ * implementation uses the 16-bit addressing mode of 802.15.4: the
+ * only additional byte it adds is the AM id byte, as the first byte
+ * of the data payload.
+ *
+ * @author Philip Levis
+ * @version $Revision: 1.21 $ $Date: 2009/09/17 23:36:36 $
+ */
+ 
+#include "CC2420.h"
+
+module CC2420ActiveMessageP @safe() {
+  provides {
+    interface AMSend[am_id_t id];
+    interface Receive[am_id_t id];
+    interface Receive as Snoop[am_id_t id];
+    interface AMPacket;
+    interface Packet;
+    interface SendNotifier[am_id_t id];
+    interface RadioBackoff[am_id_t id];
+  }
+  
+  uses {
+    interface Send as SubSend;
+    interface Receive as SubReceive;
+    interface CC2420Packet;
+    interface CC2420PacketBody;
+    interface CC2420Config;
+    interface ActiveMessageAddress;
+    interface RadioBackoff as SubBackoff;
+
+    interface Resource as RadioResource;
+    interface Leds;
+  }
+}
+implementation {
+  uint16_t pending_length;
+  message_t * ONE_NOK pending_message = NULL;
+  /***************** Resource event  ****************/
+  event void RadioResource.granted() {
+    uint8_t rc;
+    cc2420_header_t* header = call CC2420PacketBody.getHeader( pending_message );
+
+    signal SendNotifier.aboutToSend[header->type](header->dest, pending_message);
+    rc = call SubSend.send( pending_message, pending_length );
+    if (rc != SUCCESS) {
+      call RadioResource.release();
+      signal AMSend.sendDone[header->type]( pending_message, rc );
+    }
+  }
+
+  /***************** AMSend Commands ****************/
+  command error_t AMSend.send[am_id_t id](am_addr_t addr,
+					  message_t* msg,
+					  uint8_t len) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader( msg );
+    
+    if (len > call Packet.maxPayloadLength()) {
+      return ESIZE;
+    }
+    
+    header->type = id;
+    header->dest = addr;
+    header->destpan = call CC2420Config.getPanAddr();
+    header->src = call AMPacket.address();
+    
+    if (call RadioResource.immediateRequest() == SUCCESS) {
+      error_t rc;
+      signal SendNotifier.aboutToSend[id](addr, msg);
+      
+      rc = call SubSend.send( msg, len );
+      if (rc != SUCCESS) {
+        call RadioResource.release();
+      }
+
+      return rc;
+    } else {
+      pending_length  = len;
+      pending_message = msg;
+      return call RadioResource.request();
+    }
+  }
+
+  command error_t AMSend.cancel[am_id_t id](message_t* msg) {
+    return call SubSend.cancel(msg);
+  }
+
+  command uint8_t AMSend.maxPayloadLength[am_id_t id]() {
+    return call Packet.maxPayloadLength();
+  }
+
+  command void* AMSend.getPayload[am_id_t id](message_t* m, uint8_t len) {
+    return call Packet.getPayload(m, len);
+  }
+
+  /***************** AMPacket Commands ****************/
+  command am_addr_t AMPacket.address() {
+    return call ActiveMessageAddress.amAddress();
+  }
+ 
+  command am_addr_t AMPacket.destination(message_t* amsg) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader(amsg);
+    return header->dest;
+  }
+ 
+  command am_addr_t AMPacket.source(message_t* amsg) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader(amsg);
+    return header->src;
+  }
+
+  command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader(amsg);
+    header->dest = addr;
+  }
+
+  command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader(amsg);
+    header->src = addr;
+  }
+
+  command bool AMPacket.isForMe(message_t* amsg) {
+    return (call AMPacket.destination(amsg) == call AMPacket.address() ||
+	    call AMPacket.destination(amsg) == AM_BROADCAST_ADDR);
+  }
+
+  command am_id_t AMPacket.type(message_t* amsg) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader(amsg);
+    return header->type;
+  }
+
+  command void AMPacket.setType(message_t* amsg, am_id_t type) {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader(amsg);
+    header->type = type;
+  }
+  
+  command am_group_t AMPacket.group(message_t* amsg) {
+    return (call CC2420PacketBody.getHeader(amsg))->destpan;
+  }
+
+  command void AMPacket.setGroup(message_t* amsg, am_group_t grp) {
+    // Overridden intentionally when we send()
+    (call CC2420PacketBody.getHeader(amsg))->destpan = grp;
+  }
+
+  command am_group_t AMPacket.localGroup() {
+    return call CC2420Config.getPanAddr();
+  }
+  
+
+  /***************** Packet Commands ****************/
+  command void Packet.clear(message_t* msg) {
+    memset(call CC2420PacketBody.getHeader(msg), 0x0, sizeof(cc2420_header_t));
+    memset(call CC2420PacketBody.getMetadata(msg), 0x0, sizeof(cc2420_metadata_t));
+  }
+  
+  command uint8_t Packet.payloadLength(message_t* msg) {
+    return (call CC2420PacketBody.getHeader(msg))->length - CC2420_SIZE;
+  }
+  
+  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+    (call CC2420PacketBody.getHeader(msg))->length  = len + CC2420_SIZE;
+  }
+  
+  command uint8_t Packet.maxPayloadLength() {
+    return call SubSend.maxPayloadLength();
+  }
+  
+  command void* Packet.getPayload(message_t* msg, uint8_t len) {
+    return call SubSend.getPayload(msg, len);
+  }
+
+  
+  /***************** SubSend Events ****************/
+  event void SubSend.sendDone(message_t* msg, error_t result) {
+    call RadioResource.release();
+    signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);
+  }
+
+  
+  /***************** SubReceive Events ****************/
+  event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) {
+    
+    if (call AMPacket.isForMe(msg)) {
+      return signal Receive.receive[call AMPacket.type(msg)](msg, payload, len);
+    }
+    else {
+      return signal Snoop.receive[call AMPacket.type(msg)](msg, payload, len);
+    }
+  }
+  
+
+  /***************** ActiveMessageAddress Events ****************/
+  async event void ActiveMessageAddress.changed() {
+  }
+  
+  /***************** CC2420Config Events ****************/
+  event void CC2420Config.syncDone( error_t error ) {
+  }
+  
+  
+  /***************** RadioBackoff ***********************/
+
+  async event void SubBackoff.requestInitialBackoff(message_t *msg) {
+    signal RadioBackoff.requestInitialBackoff[(TCAST(cc2420_header_t* ONE,
+        (uint8_t*)msg + offsetof(message_t, data) - sizeof(cc2420_header_t)))->type](msg);
+  }
+
+  async event void SubBackoff.requestCongestionBackoff(message_t *msg) {
+    signal RadioBackoff.requestCongestionBackoff[(TCAST(cc2420_header_t* ONE,
+        (uint8_t*)msg + offsetof(message_t, data) - sizeof(cc2420_header_t)))->type](msg);
+  }
+  async event void SubBackoff.requestCca(message_t *msg) {
+    // Lower layers than this do not configure the CCA settings
+    signal RadioBackoff.requestCca[(TCAST(cc2420_header_t* ONE,
+        (uint8_t*)msg + offsetof(message_t, data) - sizeof(cc2420_header_t)))->type](msg);
+  }
+
+  async command void RadioBackoff.setInitialBackoff[am_id_t amId](uint16_t backoffTime) {
+    call SubBackoff.setInitialBackoff(backoffTime);
+  }
+  
+  /**
+   * Must be called within a requestCongestionBackoff event
+   * @param backoffTime the amount of time in some unspecified units to backoff
+   */
+  async command void RadioBackoff.setCongestionBackoff[am_id_t amId](uint16_t backoffTime) {
+    call SubBackoff.setCongestionBackoff(backoffTime);
+  }
+
+      
+  /**
+   * Enable CCA for the outbound packet.  Must be called within a requestCca
+   * event
+   * @param ccaOn TRUE to enable CCA, which is the default.
+   */
+  async command void RadioBackoff.setCca[am_id_t amId](bool useCca) {
+    call SubBackoff.setCca(useCca);
+  }
+  
+  /***************** Defaults ****************/
+  default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
+    return msg;
+  }
+  
+  default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
+    return msg;
+  }
+
+  default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {
+    call RadioResource.release();
+  }
+
+  default event void SendNotifier.aboutToSend[am_id_t amId](am_addr_t addr, message_t *msg) {
+  }
+  default async event void RadioBackoff.requestInitialBackoff[am_id_t id](
+      message_t *msg) {
+  }
+
+  default async event void RadioBackoff.requestCongestionBackoff[am_id_t id](
+      message_t *msg) {
+  }
+  
+  default async event void RadioBackoff.requestCca[am_id_t id](
+      message_t *msg) {
+  }
+  
+}
diff -urN tos/chips/cc2420/sim/CC2420.h tos/chips/cc2420/sim/CC2420.h
--- tos/chips/cc2420/sim/CC2420.h	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/sim/CC2420.h	2010-04-24 13:16:50.633435536 -0600
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @version $Revision: 1.19 $ $Date: 2009/09/17 23:36:36 $
+ */
+
+#ifndef __CC2420_H__
+#define __CC2420_H__
+
+typedef uint8_t cc2420_status_t;
+
+#if defined(TFRAMES_ENABLED) && defined(IEEE154FRAMES_ENABLED)
+#error "Both TFRAMES and IEEE154FRAMES enabled!"
+#endif
+
+/**
+ * CC2420 header definition.
+ * 
+ * An I-frame (interoperability frame) header has an extra network 
+ * byte specified by 6LowPAN
+ * 
+ * Length = length of the header + payload of the packet, minus the size
+ *   of the length byte itself (1).  This is what allows for variable 
+ *   length packets.
+ * 
+ * FCF = Frame Control Field, defined in the 802.15.4 specs and the
+ *   CC2420 datasheet.
+ *
+ * DSN = Data Sequence Number, a number incremented for each packet sent
+ *   by a particular node.  This is used in acknowledging that packet, 
+ *   and also filtering out duplicate packets.
+ *
+ * DestPan = The destination PAN (personal area network) ID, so your 
+ *   network can sit side by side with another TinyOS network and not
+ *   interfere.
+ * 
+ * Dest = The destination address of this packet. 0xFFFF is the broadcast
+ *   address.
+ *
+ * Src = The local node ID that generated the message.
+ * 
+ * Network = The TinyOS network ID, for interoperability with other types
+ *   of 802.15.4 networks. 
+ * 
+ * Type = TinyOS AM type.  When you create a new AMSenderC(AM_MYMSG), 
+ *   the AM_MYMSG definition is the type of packet.
+ * 
+ * TOSH_DATA_LENGTH defaults to 28, it represents the maximum size of 
+ * the payload portion of the packet, and is specified in the 
+ * tos/types/message.h file.
+ *
+ * All of these fields will be filled in automatically by the radio stack 
+ * when you attempt to send a message.
+ */
+/**
+ * CC2420 Security Header
+ */
+typedef nx_struct security_header_t {
+  nx_uint8_t secLevel:3;
+  nx_uint8_t keyMode:2;
+  nx_uint8_t reserved:3;
+  nx_uint32_t frameCounter;
+  nx_uint8_t keyID[1]; // One byte for now
+} security_header_t;
+
+typedef nx_struct cc2420_header_t {
+  nxle_uint8_t length;
+  nxle_uint16_t fcf;
+  nxle_uint8_t dsn;
+  nxle_uint16_t destpan;
+  nxle_uint16_t dest;
+  nxle_uint16_t src;
+  nx_uint8_t group; // Added for the header part for Tossim...  
+
+  /** CC2420 802.15.4 header ends here */
+#ifdef CC2420_HW_SECURITY
+  security_header_t secHdr;
+#endif
+  
+#ifndef TFRAMES_ENABLED
+  /** I-Frame 6LowPAN interoperability byte */
+  nxle_uint8_t network;
+#endif
+
+  nxle_uint8_t type;
+} cc2420_header_t;
+
+/**
+ * CC2420 Packet Footer
+ */
+typedef nx_struct cc2420_footer_t {
+} cc2420_footer_t;
+
+/**
+ * CC2420 Packet metadata. Contains extra information about the message
+ * that will not be transmitted.
+ *
+ * Note that the first two bytes automatically take in the values of the
+ * FCS when the payload is full. Do not modify the first two bytes of metadata.
+ */
+typedef nx_struct cc2420_metadata_t {
+  nx_uint8_t rssi;
+  nx_uint8_t lqi;
+  nx_uint8_t tx_power;
+  nx_bool crc;
+  nx_bool ack;
+  nx_bool timesync;
+  nx_uint32_t timestamp;
+  nx_uint16_t rxInterval;
+  nx_int8_t strength; // Added for Tossim
+
+  /** Packet Link Metadata */
+#ifdef PACKET_LINK
+  nx_uint16_t maxRetries;
+  nx_uint16_t retryDelay;
+#endif
+} cc2420_metadata_t;
+
+
+typedef nx_struct cc2420_packet_t {
+  cc2420_header_t packet;
+  nx_uint8_t data[];
+} cc2420_packet_t;
+
+
+#ifndef TOSH_DATA_LENGTH
+#define TOSH_DATA_LENGTH 28
+#endif
+
+#ifndef CC2420_DEF_CHANNEL
+#define CC2420_DEF_CHANNEL 26
+#endif
+
+#ifndef CC2420_DEF_RFPOWER
+#define CC2420_DEF_RFPOWER 31
+#endif
+
+/**
+ * Ideally, your receive history size should be equal to the number of
+ * RF neighbors your node will have
+ */
+#ifndef RECEIVE_HISTORY_SIZE
+#define RECEIVE_HISTORY_SIZE 4
+#endif
+
+/** 
+ * The 6LowPAN NALP ID for a TinyOS network is 63 (TEP 125).
+ */
+#ifndef TINYOS_6LOWPAN_NETWORK_ID
+#define TINYOS_6LOWPAN_NETWORK_ID 0x3f
+#endif
+
+enum {
+  // size of the header not including the length byte
+  MAC_HEADER_SIZE = sizeof( cc2420_header_t ) - 1,
+  // size of the footer (FCS field)
+  MAC_FOOTER_SIZE = sizeof( uint16_t ),
+  // MDU
+  MAC_PACKET_SIZE = MAC_HEADER_SIZE + TOSH_DATA_LENGTH + MAC_FOOTER_SIZE,
+
+  CC2420_SIZE = MAC_HEADER_SIZE + MAC_FOOTER_SIZE,
+
+  AM_OVERHEAD = 2,
+};
+
+enum cc2420_enums {
+  CC2420_TIME_ACK_TURNAROUND = 7, // jiffies
+  CC2420_TIME_VREN = 20,          // jiffies
+  CC2420_TIME_SYMBOL = 2,         // 2 symbols / jiffy
+  CC2420_BACKOFF_PERIOD = ( 20 / CC2420_TIME_SYMBOL ), // symbols
+  CC2420_MIN_BACKOFF = ( 20 / CC2420_TIME_SYMBOL ),  // platform specific?
+  CC2420_ACK_WAIT_DELAY = 256,    // jiffies
+};
+
+enum cc2420_status_enums {
+  CC2420_STATUS_RSSI_VALID = 1 << 1,
+  CC2420_STATUS_LOCK = 1 << 2,
+  CC2420_STATUS_TX_ACTIVE = 1 << 3,
+  CC2420_STATUS_ENC_BUSY = 1 << 4,
+  CC2420_STATUS_TX_UNDERFLOW = 1 << 5,
+  CC2420_STATUS_XOSC16M_STABLE = 1 << 6,
+};
+
+enum cc2420_config_reg_enums {
+  CC2420_SNOP = 0x00,
+  CC2420_SXOSCON = 0x01,
+  CC2420_STXCAL = 0x02,
+  CC2420_SRXON = 0x03,
+  CC2420_STXON = 0x04,
+  CC2420_STXONCCA = 0x05,
+  CC2420_SRFOFF = 0x06,
+  CC2420_SXOSCOFF = 0x07,
+  CC2420_SFLUSHRX = 0x08,
+  CC2420_SFLUSHTX = 0x09,
+  CC2420_SACK = 0x0a,
+  CC2420_SACKPEND = 0x0b,
+  CC2420_SRXDEC = 0x0c,
+  CC2420_STXENC = 0x0d,
+  CC2420_SAES = 0x0e,
+  CC2420_MAIN = 0x10,
+  CC2420_MDMCTRL0 = 0x11,
+  CC2420_MDMCTRL1 = 0x12,
+  CC2420_RSSI = 0x13,
+  CC2420_SYNCWORD = 0x14,
+  CC2420_TXCTRL = 0x15,
+  CC2420_RXCTRL0 = 0x16,
+  CC2420_RXCTRL1 = 0x17,
+  CC2420_FSCTRL = 0x18,
+  CC2420_SECCTRL0 = 0x19,
+  CC2420_SECCTRL1 = 0x1a,
+  CC2420_BATTMON = 0x1b,
+  CC2420_IOCFG0 = 0x1c,
+  CC2420_IOCFG1 = 0x1d,
+  CC2420_MANFIDL = 0x1e,
+  CC2420_MANFIDH = 0x1f,
+  CC2420_FSMTC = 0x20,
+  CC2420_MANAND = 0x21,
+  CC2420_MANOR = 0x22,
+  CC2420_AGCCTRL = 0x23,
+  CC2420_AGCTST0 = 0x24,
+  CC2420_AGCTST1 = 0x25,
+  CC2420_AGCTST2 = 0x26,
+  CC2420_FSTST0 = 0x27,
+  CC2420_FSTST1 = 0x28,
+  CC2420_FSTST2 = 0x29,
+  CC2420_FSTST3 = 0x2a,
+  CC2420_RXBPFTST = 0x2b,
+  CC2420_FMSTATE = 0x2c,
+  CC2420_ADCTST = 0x2d,
+  CC2420_DACTST = 0x2e,
+  CC2420_TOPTST = 0x2f,
+  CC2420_TXFIFO = 0x3e,
+  CC2420_RXFIFO = 0x3f,
+};
+
+enum cc2420_ram_addr_enums {
+  CC2420_RAM_TXFIFO = 0x000,
+  CC2420_RAM_RXFIFO = 0x080,
+  CC2420_RAM_KEY0 = 0x100,
+  CC2420_RAM_RXNONCE = 0x110,
+  CC2420_RAM_SABUF = 0x120,
+  CC2420_RAM_KEY1 = 0x130,
+  CC2420_RAM_TXNONCE = 0x140,
+  CC2420_RAM_CBCSTATE = 0x150,
+  CC2420_RAM_IEEEADR = 0x160,
+  CC2420_RAM_PANID = 0x168,
+  CC2420_RAM_SHORTADR = 0x16a,
+};
+
+enum cc2420_nonce_enums {
+  CC2420_NONCE_BLOCK_COUNTER = 0,
+  CC2420_NONCE_KEY_SEQ_COUNTER = 2,
+  CC2420_NONCE_FRAME_COUNTER = 3,
+  CC2420_NONCE_SOURCE_ADDRESS = 7,
+  CC2420_NONCE_FLAGS = 15,
+};
+
+enum cc2420_main_enums {
+  CC2420_MAIN_RESETn = 15,
+  CC2420_MAIN_ENC_RESETn = 14,
+  CC2420_MAIN_DEMOD_RESETn = 13,
+  CC2420_MAIN_MOD_RESETn = 12,
+  CC2420_MAIN_FS_RESETn = 11,
+  CC2420_MAIN_XOSC16M_BYPASS = 0,
+};
+
+enum cc2420_mdmctrl0_enums {
+  CC2420_MDMCTRL0_RESERVED_FRAME_MODE = 13,
+  CC2420_MDMCTRL0_PAN_COORDINATOR = 12,
+  CC2420_MDMCTRL0_ADR_DECODE = 11,
+  CC2420_MDMCTRL0_CCA_HYST = 8,
+  CC2420_MDMCTRL0_CCA_MOD = 6,
+  CC2420_MDMCTRL0_AUTOCRC = 5,
+  CC2420_MDMCTRL0_AUTOACK = 4,
+  CC2420_MDMCTRL0_PREAMBLE_LENGTH = 0,
+};
+
+enum cc2420_mdmctrl1_enums {
+  CC2420_MDMCTRL1_CORR_THR = 6,
+  CC2420_MDMCTRL1_DEMOD_AVG_MODE = 5,
+  CC2420_MDMCTRL1_MODULATION_MODE = 4,
+  CC2420_MDMCTRL1_TX_MODE = 2,
+  CC2420_MDMCTRL1_RX_MODE = 0,
+};
+
+enum cc2420_rssi_enums {
+  CC2420_RSSI_CCA_THR = 8,
+  CC2420_RSSI_RSSI_VAL = 0,
+};
+
+enum cc2420_syncword_enums {
+  CC2420_SYNCWORD_SYNCWORD = 0,
+};
+
+enum cc2420_txctrl_enums {
+  CC2420_TXCTRL_TXMIXBUF_CUR = 14,
+  CC2420_TXCTRL_TX_TURNAROUND = 13,
+  CC2420_TXCTRL_TXMIX_CAP_ARRAY = 11,
+  CC2420_TXCTRL_TXMIX_CURRENT = 9,
+  CC2420_TXCTRL_PA_CURRENT = 6,
+  CC2420_TXCTRL_RESERVED = 5,
+  CC2420_TXCTRL_PA_LEVEL = 0,
+};
+
+enum cc2420_rxctrl0_enums {
+  CC2420_RXCTRL0_RXMIXBUF_CUR = 12,
+  CC2420_RXCTRL0_HIGH_LNA_GAIN = 10,
+  CC2420_RXCTRL0_MED_LNA_GAIN = 8,
+  CC2420_RXCTRL0_LOW_LNA_GAIN = 6,
+  CC2420_RXCTRL0_HIGH_LNA_CURRENT = 4,
+  CC2420_RXCTRL0_MED_LNA_CURRENT = 2,
+  CC2420_RXCTRL0_LOW_LNA_CURRENT = 0,
+};
+
+enum cc2420_rxctrl1_enums {
+  CC2420_RXCTRL1_RXBPF_LOCUR = 13,
+  CC2420_RXCTRL1_RXBPF_MIDCUR = 12,
+  CC2420_RXCTRL1_LOW_LOWGAIN = 11,
+  CC2420_RXCTRL1_MED_LOWGAIN = 10,
+  CC2420_RXCTRL1_HIGH_HGM = 9,
+  CC2420_RXCTRL1_MED_HGM = 8,
+  CC2420_RXCTRL1_LNA_CAP_ARRAY = 6,
+  CC2420_RXCTRL1_RXMIX_TAIL = 4,
+  CC2420_RXCTRL1_RXMIX_VCM = 2,
+  CC2420_RXCTRL1_RXMIX_CURRENT = 0,
+};
+
+enum cc2420_rsctrl_enums {
+  CC2420_FSCTRL_LOCK_THR = 14,
+  CC2420_FSCTRL_CAL_DONE = 13,
+  CC2420_FSCTRL_CAL_RUNNING = 12,
+  CC2420_FSCTRL_LOCK_LENGTH = 11,
+  CC2420_FSCTRL_LOCK_STATUS = 10,
+  CC2420_FSCTRL_FREQ = 0,
+};
+
+enum cc2420_secctrl0_enums {
+  CC2420_SECCTRL0_RXFIFO_PROTECTION = 9,
+  CC2420_SECCTRL0_SEC_CBC_HEAD = 8,
+  CC2420_SECCTRL0_SEC_SAKEYSEL = 7,
+  CC2420_SECCTRL0_SEC_TXKEYSEL = 6,
+  CC2420_SECCTRL0_SEC_RXKEYSEL = 5,
+  CC2420_SECCTRL0_SEC_M = 2,
+  CC2420_SECCTRL0_SEC_MODE = 0,
+};
+
+enum cc2420_secctrl1_enums {
+  CC2420_SECCTRL1_SEC_TXL = 8,
+  CC2420_SECCTRL1_SEC_RXL = 0,
+};
+
+enum cc2420_battmon_enums {
+  CC2420_BATTMON_BATT_OK = 6,
+  CC2420_BATTMON_BATTMON_EN = 5,
+  CC2420_BATTMON_BATTMON_VOLTAGE = 0,
+};
+
+enum cc2420_iocfg0_enums {
+  CC2420_IOCFG0_BCN_ACCEPT = 11,
+  CC2420_IOCFG0_FIFO_POLARITY = 10,
+  CC2420_IOCFG0_FIFOP_POLARITY = 9,
+  CC2420_IOCFG0_SFD_POLARITY = 8,
+  CC2420_IOCFG0_CCA_POLARITY = 7,
+  CC2420_IOCFG0_FIFOP_THR = 0,
+};
+
+enum cc2420_iocfg1_enums {
+  CC2420_IOCFG1_HSSD_SRC = 10,
+  CC2420_IOCFG1_SFDMUX = 5,
+  CC2420_IOCFG1_CCAMUX = 0,
+};
+
+enum cc2420_manfidl_enums {
+  CC2420_MANFIDL_PARTNUM = 12,
+  CC2420_MANFIDL_MANFID = 0,
+};
+
+enum cc2420_manfidh_enums {
+  CC2420_MANFIDH_VERSION = 12,
+  CC2420_MANFIDH_PARTNUM = 0,
+};
+
+enum cc2420_fsmtc_enums {
+  CC2420_FSMTC_TC_RXCHAIN2RX = 13,
+  CC2420_FSMTC_TC_SWITCH2TX = 10,
+  CC2420_FSMTC_TC_PAON2TX = 6,
+  CC2420_FSMTC_TC_TXEND2SWITCH = 3,
+  CC2420_FSMTC_TC_TXEND2PAOFF = 0,
+};
+
+enum cc2420_sfdmux_enums {
+  CC2420_SFDMUX_SFD = 0,
+  CC2420_SFDMUX_XOSC16M_STABLE = 24,
+};
+
+enum cc2420_security_enums{
+  CC2420_NO_SEC = 0,
+  CC2420_CBC_MAC = 1,
+  CC2420_CTR = 2,
+  CC2420_CCM = 3,
+  NO_SEC = 0,
+  CBC_MAC_4 = 1,
+  CBC_MAC_8 = 2,
+  CBC_MAC_16 = 3,
+  CTR = 4,
+  CCM_4 = 5,
+  CCM_8 = 6,
+  CCM_16 = 7
+};
+norace uint8_t SECURITYLOCK = 0;
+
+enum
+{
+  CC2420_INVALID_TIMESTAMP  = 0x80000000L,
+};
+
+#endif
diff -urN tos/chips/cc2420/sim/CC2420TimeSyncMessageC.nc tos/chips/cc2420/sim/CC2420TimeSyncMessageC.nc
--- tos/chips/cc2420/sim/CC2420TimeSyncMessageC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/sim/CC2420TimeSyncMessageC.nc	2010-04-24 13:16:50.633435536 -0600
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * 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 VANDERBILT UNIVERSITY 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 VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY 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 VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/**
+ * The Active Message layer for the CC2420 radio with timesync support. This
+ * configuration is just layer above CC2420ActiveMessageC that supports
+ * TimeSyncPacket and TimeSyncAMSend interfaces (TEP 133)
+ *
+ * @author: Miklos Maroti
+ * @author: Brano Kusy (CC2420 port)
+ */
+
+#include <Timer.h>
+#include <AM.h>
+#include "CC2420TimeSyncMessage.h"
+
+configuration CC2420TimeSyncMessageC
+{
+    provides
+    {
+        interface SplitControl;
+        interface Receive[am_id_t id];
+        interface Receive as Snoop[am_id_t id];
+        interface Packet;
+        interface AMPacket;
+        interface PacketAcknowledgements;
+
+        interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[am_id_t id];
+        interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+
+        interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+        interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+    }
+}
+
+implementation
+{
+        components CC2420TimeSyncMessageP, ActiveMessageC, CC2420PacketC, LedsC;
+
+        TimeSyncAMSend32khz = CC2420TimeSyncMessageP;
+        TimeSyncPacket32khz = CC2420TimeSyncMessageP;
+
+        TimeSyncAMSendMilli = CC2420TimeSyncMessageP;
+        TimeSyncPacketMilli = CC2420TimeSyncMessageP;
+
+        Packet = CC2420TimeSyncMessageP;
+        CC2420TimeSyncMessageP.SubSend -> ActiveMessageC.AMSend[AM_TIMESYNCMSG];
+      	CC2420TimeSyncMessageP.SubAMPacket -> ActiveMessageC.AMPacket;
+        CC2420TimeSyncMessageP.SubPacket -> ActiveMessageC.Packet;
+
+        CC2420TimeSyncMessageP.PacketTimeStamp32khz -> CC2420PacketC;
+        CC2420TimeSyncMessageP.PacketTimeStampMilli -> CC2420PacketC;
+        CC2420TimeSyncMessageP.PacketTimeSyncOffset -> CC2420PacketC;
+
+        components Counter32khz32C, new CounterToLocalTimeC(T32khz) as LocalTime32khzC, LocalTimeMilliC;
+        LocalTime32khzC.Counter -> Counter32khz32C;
+        CC2420TimeSyncMessageP.LocalTime32khz -> LocalTime32khzC;
+        CC2420TimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
+        CC2420TimeSyncMessageP.Leds -> LedsC;
+
+        SplitControl = ActiveMessageC;
+        PacketAcknowledgements = ActiveMessageC;
+
+        Receive = CC2420TimeSyncMessageP.Receive;
+        Snoop = CC2420TimeSyncMessageP.Snoop;
+        AMPacket = CC2420TimeSyncMessageP;
+        CC2420TimeSyncMessageP.SubReceive -> ActiveMessageC.Receive[AM_TIMESYNCMSG];
+        CC2420TimeSyncMessageP.SubSnoop -> ActiveMessageC.Snoop[AM_TIMESYNCMSG];
+}
diff -urN tos/chips/cc2420/sim/CC2420TimeSyncMessage.h tos/chips/cc2420/sim/CC2420TimeSyncMessage.h
--- tos/chips/cc2420/sim/CC2420TimeSyncMessage.h	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/sim/CC2420TimeSyncMessage.h	2010-04-24 13:16:50.633435536 -0600
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * 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 VANDERBILT UNIVERSITY 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 VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE VANDERBILT UNIVERSITY 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 VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __TIMESYNCMESSAGE_H__
+#define __TIMESYNCMESSAGE_H__
+
+#ifndef AM_TIMESYNCMSG
+#define AM_TIMESYNCMSG 0x3D
+#endif
+
+// this value is sent in the air
+typedef nx_uint32_t timesync_radio_t;
+
+typedef struct timesync_footer_t
+{
+  nx_am_id_t type;
+  timesync_radio_t timestamp;
+} timesync_footer_t;
+
+#endif//__TIMESYNCMESSAGE_H__
diff -urN tos/chips/cc2420/sim/CC2420TimeSyncMessageP.nc tos/chips/cc2420/sim/CC2420TimeSyncMessageP.nc
--- tos/chips/cc2420/sim/CC2420TimeSyncMessageP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/sim/CC2420TimeSyncMessageP.nc	2010-04-24 13:16:50.633435536 -0600
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * 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 VANDERBILT UNIVERSITY 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 VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY 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 VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * @author: Miklos Maroti
+ * @author: Brano Kusy (CC2420 port)
+ */
+#include "CC2420TimeSyncMessage.h"
+
+module CC2420TimeSyncMessageP
+{
+    provides
+    {
+        interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[uint8_t id];
+        interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
+        interface Packet;
+        interface AMPacket;
+
+        interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+        interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+        
+        interface Receive[am_id_t id];
+        interface Receive as Snoop[am_id_t id];
+    }
+
+    uses
+    {
+          interface AMSend as SubSend;
+        interface Packet as SubPacket;
+        interface AMPacket as SubAMPacket;
+
+        interface Receive as SubReceive;
+        interface Receive as SubSnoop;
+
+        interface PacketTimeStamp<T32khz,uint32_t> as PacketTimeStamp32khz;
+        interface PacketTimeStamp<TMilli,uint32_t> as PacketTimeStampMilli;
+        interface PacketTimeSyncOffset;
+
+        interface LocalTime<T32khz> as LocalTime32khz;
+        interface LocalTime<TMilli> as LocalTimeMilli;
+        interface Leds;
+    }
+}
+
+implementation
+{
+    // TODO: change the Packet.payloadLength and Packet.maxPayloadLength commands to async
+    inline timesync_footer_t* getFooter(message_t* msg)
+    {
+        // we use the payload length that we export (the smaller one)
+        return (timesync_footer_t*)(msg->data + call Packet.payloadLength(msg));
+    }
+
+/*----------------- Packet -----------------*/
+    command void Packet.clear(message_t* msg)
+    {
+        call PacketTimeSyncOffset.cancel(msg);
+        call SubPacket.clear(msg);
+    }
+
+    command void Packet.setPayloadLength(message_t* msg, uint8_t len)
+    {
+        call SubPacket.setPayloadLength(msg, len + sizeof(timesync_footer_t));
+    }
+
+    command uint8_t Packet.payloadLength(message_t* msg)
+    {
+        return call SubPacket.payloadLength(msg) - sizeof(timesync_footer_t);
+    }
+
+    command uint8_t Packet.maxPayloadLength()
+    {
+        return call SubPacket.maxPayloadLength() - sizeof(timesync_footer_t);
+    }
+
+    command void* Packet.getPayload(message_t* msg, uint8_t len)
+    {
+        return call SubPacket.getPayload(msg, len + sizeof(timesync_footer_t));
+    }
+
+/*----------------- AMPacket -----------------*/
+
+	inline command am_addr_t AMPacket.address()
+	{
+		return call SubAMPacket.address();
+	}
+
+	inline command am_group_t AMPacket.localGroup()
+	{
+		return call SubAMPacket.localGroup();
+	}
+
+	inline command bool AMPacket.isForMe(message_t* msg)
+	{
+		return call SubAMPacket.isForMe(msg) && call SubAMPacket.type(msg) == AM_TIMESYNCMSG;
+	}
+
+	inline command am_addr_t AMPacket.destination(message_t* msg)
+	{
+		return call SubAMPacket.destination(msg);
+	}
+
+	inline command void AMPacket.setDestination(message_t* msg, am_addr_t addr)
+	{
+		call SubAMPacket.setDestination(msg, addr);
+	}
+
+	inline command am_addr_t AMPacket.source(message_t* msg)
+	{
+		return call SubAMPacket.source(msg);
+	}
+
+	inline command void AMPacket.setSource(message_t* msg, am_addr_t addr)
+	{
+		call SubAMPacket.setSource(msg, addr);
+	}
+
+	inline command am_id_t AMPacket.type(message_t* msg)
+	{
+		return getFooter(msg)->type;
+	}
+
+	inline command void AMPacket.setType(message_t* msg, am_id_t type)
+	{
+		getFooter(msg)->type = type;
+	}
+
+	inline command am_group_t AMPacket.group(message_t* msg)
+	{
+		return call SubAMPacket.group(msg);
+	}
+
+	inline command void AMPacket.setGroup(message_t* msg, am_group_t grp)
+	{
+		call SubAMPacket.setGroup(msg, grp);
+	}
+
+/*----------------- TimeSyncAMSend32khz -----------------*/
+    command error_t TimeSyncAMSend32khz.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+    {
+        error_t err;
+        timesync_footer_t* footer = (timesync_footer_t*)(msg->data + len);
+        footer->type = id;
+        footer->timestamp = event_time;
+
+        err = call SubSend.send(addr, msg, len + sizeof(timesync_footer_t));
+        call PacketTimeSyncOffset.set(msg);
+        return err;
+    }
+
+    command error_t TimeSyncAMSend32khz.cancel[am_id_t id](message_t* msg)
+    {
+        call PacketTimeSyncOffset.cancel(msg);
+        return call SubSend.cancel(msg);
+    }
+
+    default event void TimeSyncAMSend32khz.sendDone[am_id_t id](message_t* msg, error_t error) {}
+
+    command uint8_t TimeSyncAMSend32khz.maxPayloadLength[am_id_t id]()
+    {
+        return call SubSend.maxPayloadLength() - sizeof(timesync_footer_t);
+    }
+
+    command void* TimeSyncAMSend32khz.getPayload[am_id_t id](message_t* msg, uint8_t len)
+    {
+        return call SubSend.getPayload(msg, len + sizeof(timesync_footer_t));
+    }
+
+/*----------------- TimeSyncAMSendMilli -----------------*/
+    command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+    {
+        // compute elapsed time in millisecond
+        event_time = ((event_time - call LocalTimeMilli.get()) << 5) + call LocalTime32khz.get();
+        return call TimeSyncAMSend32khz.send[id](addr, msg, len, event_time);
+    }
+
+    command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
+    {
+        return call TimeSyncAMSend32khz.cancel[id](msg);
+    }
+
+    default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error){}
+
+    command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
+    {
+        return call TimeSyncAMSend32khz.maxPayloadLength[id]();
+    }
+
+    command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
+    {
+        return call TimeSyncAMSend32khz.getPayload[id](msg, len);
+    }
+
+/*----------------- SubReceive -------------------*/
+
+    event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
+    {
+        am_id_t id = call AMPacket.type(msg);
+        return signal Receive.receive[id](msg, payload, len - sizeof(timesync_footer_t));
+    }
+
+    default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) { return msg; }
+
+/*----------------- SubSnoop -------------------*/
+
+    event message_t* SubSnoop.receive(message_t* msg, void* payload, uint8_t len)
+    {
+        am_id_t id = call AMPacket.type(msg);
+        return signal Snoop.receive[id](msg, payload, len - sizeof(timesync_footer_t));
+    }
+
+    default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) { return msg; }
+
+/*----------------- SubSend.sendDone -------------------*/
+    event void SubSend.sendDone(message_t* msg, error_t error)
+    {
+        am_id_t id = call AMPacket.type(msg);
+        signal TimeSyncAMSend32khz.sendDone[id](msg, error);
+        signal TimeSyncAMSendMilli.sendDone[id](msg, error);
+    }
+
+/*----------------- TimeSyncPacket32khz -----------------*/
+    command bool TimeSyncPacket32khz.isValid(message_t* msg)
+    {
+        return call PacketTimeStamp32khz.isValid(msg) && getFooter(msg)->timestamp != CC2420_INVALID_TIMESTAMP;
+    }
+
+    command uint32_t TimeSyncPacket32khz.eventTime(message_t* msg)
+    {
+        return (uint32_t)(getFooter(msg)->timestamp) + call PacketTimeStamp32khz.timestamp(msg);
+    }
+
+/*----------------- TimeSyncPacketMilli -----------------*/
+    command bool TimeSyncPacketMilli.isValid(message_t* msg)
+    {
+        return call PacketTimeStampMilli.isValid(msg) && getFooter(msg)->timestamp != CC2420_INVALID_TIMESTAMP;
+    }
+
+    command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
+    {
+        return ((int32_t)(getFooter(msg)->timestamp) >> 5) + call PacketTimeStampMilli.timestamp(msg);
+    }
+}
diff -urN tos/chips/cc2420/spi/sim/CC2420SpiC.nc tos/chips/cc2420/spi/sim/CC2420SpiC.nc
--- tos/chips/cc2420/spi/sim/CC2420SpiC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/spi/sim/CC2420SpiC.nc	2010-04-24 13:16:12.393435556 -0600
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation of basic SPI primitives for the ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2009/08/14 20:33:43 $
+ */
+
+generic configuration CC2420SpiC() {
+
+  provides interface Resource;
+  provides interface ChipSpiResource;
+
+  // commands
+  provides interface CC2420Strobe as SNOP;
+  provides interface CC2420Strobe as SXOSCON;
+  provides interface CC2420Strobe as STXCAL;
+  provides interface CC2420Strobe as SRXON;
+  provides interface CC2420Strobe as STXON;
+  provides interface CC2420Strobe as STXONCCA;
+  provides interface CC2420Strobe as SRFOFF;
+  provides interface CC2420Strobe as SXOSCOFF;
+  provides interface CC2420Strobe as SFLUSHRX;
+  provides interface CC2420Strobe as SFLUSHTX;
+  provides interface CC2420Strobe as SACK;
+  provides interface CC2420Strobe as SACKPEND;
+  provides interface CC2420Strobe as SRXDEC;
+  provides interface CC2420Strobe as STXENC;
+  provides interface CC2420Strobe as SAES;
+
+  // registers
+  provides interface CC2420Register as MAIN;
+  provides interface CC2420Register as MDMCTRL0;
+  provides interface CC2420Register as MDMCTRL1;
+  provides interface CC2420Register as RSSI;
+  provides interface CC2420Register as SYNCWORD;
+  provides interface CC2420Register as TXCTRL;
+  provides interface CC2420Register as RXCTRL0;
+  provides interface CC2420Register as RXCTRL1;
+  provides interface CC2420Register as FSCTRL;
+  provides interface CC2420Register as SECCTRL0;
+  provides interface CC2420Register as SECCTRL1;
+  provides interface CC2420Register as BATTMON;
+  provides interface CC2420Register as IOCFG0;
+  provides interface CC2420Register as IOCFG1;
+  provides interface CC2420Register as MANFIDL;
+  provides interface CC2420Register as MANFIDH;
+  provides interface CC2420Register as FSMTC;
+  provides interface CC2420Register as MANAND;
+  provides interface CC2420Register as MANOR;
+  provides interface CC2420Register as AGCCTRL;
+  provides interface CC2420Register as RXFIFO_REGISTER;
+
+  // ram
+  provides interface CC2420Ram as IEEEADR;
+  provides interface CC2420Ram as PANID;
+  provides interface CC2420Ram as SHORTADR;
+  provides interface CC2420Ram as TXFIFO_RAM;
+  provides interface CC2420Ram as RXFIFO_RAM;
+  provides interface CC2420Ram as KEY0;
+  provides interface CC2420Ram as KEY1;
+  provides interface CC2420Ram as SABUF;
+  provides interface CC2420Ram as TXNONCE;
+  provides interface CC2420Ram as RXNONCE;
+
+  // fifos
+  provides interface CC2420Fifo as RXFIFO;
+  provides interface CC2420Fifo as TXFIFO;
+
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( "CC2420Spi.Resource" ),
+  };
+  
+  components HplCC2420PinsC as Pins;
+  components CC2420SpiWireC as Spi;
+  
+  ChipSpiResource = Spi.ChipSpiResource;
+  Resource = Spi.Resource[ CLIENT_ID ];
+  
+  // commands
+  SNOP = Spi.Strobe[ CC2420_SNOP ];
+  SXOSCON = Spi.Strobe[ CC2420_SXOSCON ];
+  STXCAL = Spi.Strobe[ CC2420_STXCAL ];
+  SRXON = Spi.Strobe[ CC2420_SRXON ];
+  STXON = Spi.Strobe[ CC2420_STXON ];
+  STXONCCA = Spi.Strobe[ CC2420_STXONCCA ];
+  SRFOFF = Spi.Strobe[ CC2420_SRFOFF ];
+  SXOSCOFF = Spi.Strobe[ CC2420_SXOSCOFF ];
+  SFLUSHRX = Spi.Strobe[ CC2420_SFLUSHRX ];
+  SFLUSHTX = Spi.Strobe[ CC2420_SFLUSHTX ];
+  SACK = Spi.Strobe[ CC2420_SACK ];
+  SACKPEND = Spi.Strobe[ CC2420_SACKPEND ];
+  SRXDEC = Spi.Strobe[ CC2420_SRXDEC ];
+  STXENC = Spi.Strobe[ CC2420_STXENC ];
+  SAES = Spi.Strobe[ CC2420_SAES ];
+  
+  // registers
+  MAIN = Spi.Reg[ CC2420_MAIN ];
+  MDMCTRL0 = Spi.Reg[ CC2420_MDMCTRL0 ];
+  MDMCTRL1 = Spi.Reg[ CC2420_MDMCTRL1 ];
+  RSSI = Spi.Reg[ CC2420_RSSI ];
+  SYNCWORD = Spi.Reg[ CC2420_SYNCWORD ];
+  TXCTRL = Spi.Reg[ CC2420_TXCTRL ];
+  RXCTRL0 = Spi.Reg[ CC2420_RXCTRL0 ];
+  RXCTRL1 = Spi.Reg[ CC2420_RXCTRL1 ];
+  FSCTRL = Spi.Reg[ CC2420_FSCTRL ];
+  SECCTRL0 = Spi.Reg[ CC2420_SECCTRL0 ];
+  SECCTRL1 = Spi.Reg[ CC2420_SECCTRL1 ];
+  BATTMON = Spi.Reg[ CC2420_BATTMON ];
+  IOCFG0 = Spi.Reg[ CC2420_IOCFG0 ];
+  IOCFG1 = Spi.Reg[ CC2420_IOCFG1 ];
+  MANFIDL = Spi.Reg[ CC2420_MANFIDL ];
+  MANFIDH = Spi.Reg[ CC2420_MANFIDH ];
+  FSMTC = Spi.Reg[ CC2420_FSMTC ];
+  MANAND = Spi.Reg[ CC2420_MANAND ];
+  MANOR = Spi.Reg[ CC2420_MANOR ];
+  AGCCTRL = Spi.Reg[ CC2420_AGCCTRL ];
+  RXFIFO_REGISTER = Spi.Reg[ CC2420_RXFIFO ];
+  
+  // ram
+  IEEEADR = Spi.Ram[ CC2420_RAM_IEEEADR ];
+  PANID = Spi.Ram[ CC2420_RAM_PANID ];
+  SHORTADR = Spi.Ram[ CC2420_RAM_SHORTADR ];
+  TXFIFO_RAM = Spi.Ram[ CC2420_RAM_TXFIFO ];
+  RXFIFO_RAM = Spi.Ram[ CC2420_RAM_RXFIFO ];
+  KEY0 = Spi.Ram[ CC2420_RAM_KEY0 ];
+  KEY1 = Spi.Ram[ CC2420_RAM_KEY1 ];
+  SABUF = Spi.Ram[ CC2420_RAM_SABUF ];
+  TXNONCE = Spi.Ram[ CC2420_RAM_TXNONCE ];
+  RXNONCE = Spi.Ram[ CC2420_RAM_RXNONCE ];
+
+  // fifos
+  RXFIFO = Spi.Fifo[ CC2420_RXFIFO ];
+  TXFIFO = Spi.Fifo[ CC2420_TXFIFO ];
+
+}
+
diff -urN tos/chips/cc2420/spi/sim/CC2420SpiP.nc tos/chips/cc2420/spi/sim/CC2420SpiP.nc
--- tos/chips/cc2420/spi/sim/CC2420SpiP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/spi/sim/CC2420SpiP.nc	2010-04-24 13:16:12.393435556 -0600
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Roman Lim
+ * @author Razvan Musaloie-E.
+ * @author Jeonggil Ko
+ * @version $Revision: 1.4 $ $Date: 2008/06/23 20:25:15 $
+ */
+
+module CC2420SpiP @safe() {
+
+  provides {
+    interface ChipSpiResource;
+    interface Resource[ uint8_t id ];
+    interface CC2420Fifo as Fifo[ uint8_t id ];
+    interface CC2420Ram as Ram[ uint16_t id ];
+    interface CC2420Register as Reg[ uint8_t id ];
+    interface CC2420Strobe as Strobe[ uint8_t id ];
+  }
+  
+  uses {
+    interface Resource as SpiResource;
+    interface SpiByte;
+    interface SpiPacket;
+    interface State as WorkingState;
+    interface Leds;
+  }
+}
+
+implementation {
+
+  enum {
+    RESOURCE_COUNT = uniqueCount( "CC2420Spi.Resource" ),
+    NO_HOLDER = 0xFF,
+  };
+
+  /** WorkingStates */
+  enum {
+    S_IDLE,
+    S_BUSY,
+  };
+
+  /** Address to read/write on the CC2420, also maintains caller's client id */
+  norace uint16_t m_addr;
+  
+  /** Each bit represents a client ID that is requesting SPI bus access */
+  uint8_t m_requests = 0;
+  
+  /** The current client that owns the SPI bus */
+  uint8_t m_holder = NO_HOLDER;
+  
+  /** TRUE if it is safe to release the SPI bus after all users say ok */
+  bool release;
+  
+  /***************** Prototypes ****************/
+  error_t attemptRelease();
+  task void grant();
+  
+  /***************** ChipSpiResource Commands ****************/
+  /**
+   * Abort the release of the SPI bus.  This must be called only with the
+   * releasing() event
+   */
+  async command void ChipSpiResource.abortRelease() {
+    atomic release = FALSE;
+  }
+  
+  /**
+   * Release the SPI bus if there are no objections
+   */
+  async command error_t ChipSpiResource.attemptRelease() {
+    return attemptRelease();
+  }
+  
+  /***************** Resource Commands *****************/
+  async command error_t Resource.request[ uint8_t id ]() {
+        
+    atomic {
+      if ( call WorkingState.requestState(S_BUSY) == SUCCESS ) {
+        m_holder = id;
+        if(call SpiResource.isOwner()) {
+          post grant();
+          
+        } else {
+          call SpiResource.request();
+        }
+        
+      } else {
+        m_requests |= 1 << id;
+      }
+    }
+    return SUCCESS;
+  }
+  
+  async command error_t Resource.immediateRequest[ uint8_t id ]() {
+    error_t error;
+        
+    atomic {
+      if ( call WorkingState.requestState(S_BUSY) != SUCCESS ) {
+        return EBUSY;
+      }
+      
+      
+      if(call SpiResource.isOwner()) {
+        m_holder = id;
+        error = SUCCESS;
+      
+      } else if ((error = call SpiResource.immediateRequest()) == SUCCESS ) {
+        m_holder = id;
+        
+      } else {
+        call WorkingState.toIdle();
+      }
+    }
+    return error;
+  }
+
+  async command error_t Resource.release[ uint8_t id ]() {
+    uint8_t i;
+    atomic {
+      if ( m_holder != id ) {
+        return FAIL;
+      }
+
+      m_holder = NO_HOLDER;
+      if ( !m_requests ) {
+        call WorkingState.toIdle();
+        attemptRelease();
+        
+      } else {
+        for ( i = m_holder + 1; ; i++ ) {
+          i %= RESOURCE_COUNT;
+          
+          if ( m_requests & ( 1 << i ) ) {
+            m_holder = i;
+            m_requests &= ~( 1 << i );
+            post grant();
+            return SUCCESS;
+          }
+        }
+      }
+    }
+    
+    return SUCCESS;
+  }
+  
+  async command uint8_t Resource.isOwner[ uint8_t id ]() {
+    atomic return (m_holder == id);
+  }
+
+
+  /***************** SpiResource Events ****************/
+  event void SpiResource.granted() {
+    post grant();
+  }
+  
+  /***************** Fifo Commands ****************/
+  async command cc2420_status_t Fifo.beginRead[ uint8_t addr ]( uint8_t* data, 
+                                                                uint8_t len ) {
+    
+    cc2420_status_t status = 0;
+
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return status;
+      }
+    }
+    
+    m_addr = addr | 0x40;
+        
+    status = call SpiByte.write( m_addr );
+    dbg("CC2420", "%s: begin read, length is %d\n", __FUNCTION__, len);
+    call Fifo.continueRead[ addr ]( data, len );
+    
+    return status;
+    
+  }
+
+  async command error_t Fifo.continueRead[ uint8_t addr ]( uint8_t* data,
+                                                           uint8_t len ) {
+    dbg("CC2420", "%s: continue read, length is %d\n", __FUNCTION__, len);
+    return call SpiPacket.send( NULL, data, len );
+  }
+
+  async command cc2420_status_t Fifo.write[ uint8_t addr ]( uint8_t* data, 
+                                                            uint8_t len ) {
+
+    uint8_t status = 0;
+ 
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return status;
+      }
+    }
+    
+    m_addr = addr;
+
+    status = call SpiByte.write( m_addr );
+    call SpiPacket.send( data, NULL, len );
+
+    return status;
+
+  }
+
+  /***************** RAM Commands ****************/
+  async command cc2420_status_t Ram.read[ uint16_t addr ]( uint8_t offset,
+                                                           uint8_t* data, 
+                                                           uint8_t len ) {
+
+    cc2420_status_t status = 0;
+
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return status;
+      }
+    }
+    
+    addr += offset;
+
+    status = call SpiByte.write( addr | 0x80 );
+    call SpiByte.write( ( ( addr >> 1 ) & 0xC0 ) | 0x20 );
+    for ( ; len; len-- ) {
+      *data++ = call SpiByte.write( 0 );
+    }
+
+    return status;
+
+  }
+
+
+  async command cc2420_status_t Ram.write[ uint16_t addr ]( uint8_t offset,
+                                                            uint8_t* data, 
+                                                            uint8_t len ) {
+
+    cc2420_status_t status = 0;
+    uint8_t tmpLen = len;
+    uint8_t * COUNT(tmpLen) tmpData = (uint8_t * COUNT(tmpLen))data;
+
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return status;
+      }
+    }
+    
+    addr += offset;
+
+    status = call SpiByte.write( addr | 0x80 );
+    call SpiByte.write( ( addr >> 1 ) & 0xc0 );
+    for ( ; len; len-- ) {
+      call SpiByte.write( tmpData[tmpLen-len] );
+    }
+
+    return status;
+
+  }
+
+  /***************** Register Commands ****************/
+  async command cc2420_status_t Reg.read[ uint8_t addr ]( uint16_t* data ) {
+
+    cc2420_status_t status = 0;
+    
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return status;
+      }
+    }
+    
+    status = call SpiByte.write( addr | 0x40 );
+    *data = (uint16_t)call SpiByte.write( 0 ) << 8;
+    *data |= call SpiByte.write( 0 );
+    
+    return status;
+
+  }
+
+  async command cc2420_status_t Reg.write[ uint8_t addr ]( uint16_t data ) {
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return 0;
+      }
+    }
+    call SpiByte.write( addr );
+    call SpiByte.write( data >> 8 );
+    return call SpiByte.write( data & 0xff );
+  }
+
+  
+  /***************** Strobe Commands ****************/
+  async command cc2420_status_t Strobe.strobe[ uint8_t addr ]() {
+    atomic {
+      if(call WorkingState.isIdle()) {
+        return 0;
+      }
+    }
+    
+    return call SpiByte.write( addr );
+  }
+
+  /***************** SpiPacket Events ****************/
+  async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf, 
+                                       uint16_t len, error_t error ) {
+    if ( m_addr & 0x40 ) {
+      signal Fifo.readDone[ m_addr & ~0x40 ]( rx_buf, len, error );
+    } else {
+      signal Fifo.writeDone[ m_addr ]( tx_buf, len, error );
+    }
+  }
+  
+  /***************** Functions ****************/
+  error_t attemptRelease() {
+    if(m_requests > 0 
+        || m_holder != NO_HOLDER 
+        || !call WorkingState.isIdle()) {
+      return FAIL;
+    }
+    
+    atomic release = TRUE;
+    signal ChipSpiResource.releasing();
+    atomic {
+      if(release) {
+        call SpiResource.release();
+        return SUCCESS;
+      }
+    }
+    
+    return EBUSY;
+  }
+  
+  task void grant() {
+    uint8_t holder;
+    atomic { 
+      holder = m_holder;
+    }
+    signal Resource.granted[ holder ]();
+  }
+
+  /***************** Defaults ****************/
+  default event void Resource.granted[ uint8_t id ]() {
+  }
+
+  default async event void Fifo.readDone[ uint8_t addr ]( uint8_t* rx_buf, uint8_t rx_len, error_t error ) {
+  }
+  
+  default async event void Fifo.writeDone[ uint8_t addr ]( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
+  }
+
+  default async event void ChipSpiResource.releasing() {
+  }
+  
+}
diff -urN tos/chips/cc2420/transmit/sim/CC2420TransmitC.nc tos/chips/cc2420/transmit/sim/CC2420TransmitC.nc
--- tos/chips/cc2420/transmit/sim/CC2420TransmitC.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/transmit/sim/CC2420TransmitC.nc	2010-04-24 13:16:30.625435532 -0600
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation of the transmit path for the ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision: 1.3 $ $Date: 2009/08/14 20:33:43 $
+ */
+
+#include "IEEE802154.h"
+
+configuration CC2420TransmitC {
+
+  provides {
+    interface StdControl;
+    interface CC2420Transmit;
+    interface RadioBackoff;
+    interface ReceiveIndicator as EnergyIndicator;
+    interface ReceiveIndicator as ByteIndicator;
+  }
+}
+
+implementation {
+
+  components CC2420TransmitP;
+  StdControl = CC2420TransmitP;
+  CC2420Transmit = CC2420TransmitP;
+  RadioBackoff = CC2420TransmitP;
+  EnergyIndicator = CC2420TransmitP.EnergyIndicator;
+  ByteIndicator = CC2420TransmitP.ByteIndicator;
+
+  components MainC;
+  MainC.SoftwareInit -> CC2420TransmitP;
+  MainC.SoftwareInit -> Alarm;
+  
+  components AlarmMultiplexC as Alarm;
+  CC2420TransmitP.BackoffTimer -> Alarm;
+
+  components HplCC2420PinsC as Pins;
+  CC2420TransmitP.CCA -> Pins.CCA;
+  CC2420TransmitP.CSN -> Pins.CSN;
+  CC2420TransmitP.SFD -> Pins.SFD;
+
+  components HplCC2420InterruptsC as Interrupts;
+  CC2420TransmitP.TriggerFIFOP -> Interrupts.TriggerFIFOP;
+  CC2420TransmitP.CaptureSFD -> Interrupts.CaptureSFD;
+
+  components new CC2420SpiC() as Spi;
+  CC2420TransmitP.SpiResource -> Spi;
+  CC2420TransmitP.ChipSpiResource -> Spi;
+  CC2420TransmitP.SNOP        -> Spi.SNOP;
+  CC2420TransmitP.STXON       -> Spi.STXON;
+  CC2420TransmitP.STXONCCA    -> Spi.STXONCCA;
+  CC2420TransmitP.SFLUSHTX    -> Spi.SFLUSHTX;
+  CC2420TransmitP.TXCTRL      -> Spi.TXCTRL;
+  CC2420TransmitP.TXFIFO      -> Spi.TXFIFO;
+  CC2420TransmitP.TXFIFO_RAM  -> Spi.TXFIFO_RAM;
+  CC2420TransmitP.MDMCTRL1    -> Spi.MDMCTRL1;
+  CC2420TransmitP.SECCTRL0 -> Spi.SECCTRL0;
+  CC2420TransmitP.SECCTRL1 -> Spi.SECCTRL1;
+  CC2420TransmitP.STXENC -> Spi.STXENC;
+  CC2420TransmitP.TXNONCE -> Spi.TXNONCE;
+  CC2420TransmitP.KEY0 -> Spi.KEY0;
+  CC2420TransmitP.KEY1 -> Spi.KEY1;
+  
+  components CC2420ReceiveC;
+  CC2420TransmitP.CC2420Receive -> CC2420ReceiveC;
+  
+  components CC2420PacketC;
+  CC2420TransmitP.CC2420Packet -> CC2420PacketC;
+  CC2420TransmitP.CC2420PacketBody -> CC2420PacketC;
+  CC2420TransmitP.PacketTimeStamp -> CC2420PacketC;
+  CC2420TransmitP.PacketTimeSyncOffset -> CC2420PacketC;
+
+  components LedsC;
+  CC2420TransmitP.Leds -> LedsC;
+
+}
diff -urN tos/chips/cc2420/transmit/sim/CC2420TransmitP.nc tos/chips/cc2420/transmit/sim/CC2420TransmitP.nc
--- tos/chips/cc2420/transmit/sim/CC2420TransmitP.nc	1969-12-31 17:00:00.000000000 -0700
+++ tos/chips/cc2420/transmit/sim/CC2420TransmitP.nc	2010-04-24 13:16:30.625435532 -0600
@@ -0,0 +1,891 @@
+/* 
+ * Copyright (c) 2005-2006 Arch Rock Corporation 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Jung Il Choi Initial SACK implementation
+ * @author JeongGil Ko
+ * @author Razvan Musaloiu-E
+ * @version $Revision: 1.16 $ $Date: 2009/10/28 21:09:52 $
+ */
+
+#include "CC2420.h"
+#include "CC2420TimeSyncMessage.h"
+#include "crc.h"
+#include "message.h"
+
+module CC2420TransmitP @safe() {
+
+  provides interface Init;
+  provides interface StdControl;
+  provides interface CC2420Transmit as Send;
+  provides interface RadioBackoff;
+  provides interface ReceiveIndicator as EnergyIndicator;
+  provides interface ReceiveIndicator as ByteIndicator;
+  
+  uses interface Alarm<T32khz,uint32_t> as BackoffTimer;
+  uses interface CC2420Packet;
+  uses interface CC2420PacketBody;
+  uses interface PacketTimeStamp<T32khz,uint32_t>;
+  uses interface PacketTimeSyncOffset;
+  uses interface GpioCapture as CaptureSFD;
+#ifdef SIM_CC2420
+  uses interface TriggerInterrupt as TriggerFIFOP;
+#endif
+  uses interface GeneralIO as CCA;
+  uses interface GeneralIO as CSN;
+  uses interface GeneralIO as SFD;
+
+  uses interface Resource as SpiResource;
+  uses interface ChipSpiResource;
+  uses interface CC2420Fifo as TXFIFO;
+  uses interface CC2420Ram as TXFIFO_RAM;
+  uses interface CC2420Register as TXCTRL;
+  uses interface CC2420Strobe as SNOP;
+  uses interface CC2420Strobe as STXON;
+  uses interface CC2420Strobe as STXONCCA;
+  uses interface CC2420Strobe as SFLUSHTX;
+  uses interface CC2420Register as MDMCTRL1;
+
+  uses interface CC2420Strobe as STXENC;
+  uses interface CC2420Register as SECCTRL0;
+  uses interface CC2420Register as SECCTRL1;
+  uses interface CC2420Ram as KEY0;
+  uses interface CC2420Ram as KEY1;
+  uses interface CC2420Ram as TXNONCE;
+
+  uses interface CC2420Receive;
+  uses interface Leds;
+}
+
+implementation {
+
+  typedef enum {
+    S_STOPPED,
+    S_STARTED,
+    S_LOAD,
+    S_SAMPLE_CCA,
+    S_BEGIN_TRANSMIT,
+    S_SFD,
+    S_EFD,
+    S_ACK_WAIT,
+    S_CANCEL,
+  } cc2420_transmit_state_t;
+
+  // This specifies how many jiffies the stack should wait after a
+  // TXACTIVE to receive an SFD interrupt before assuming something is
+  // wrong and aborting the send. There seems to be a condition
+  // on the micaZ where the SFD interrupt is never handled.
+  enum {
+    CC2420_ABORT_PERIOD = 320
+  };
+
+#ifdef CC2420_HW_SECURITY
+  uint16_t startTime = 0;
+  norace uint8_t secCtrlMode = 0;
+  norace uint8_t nonceValue[16] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+  norace uint8_t skip;
+  norace uint16_t CTR_SECCTRL0, CTR_SECCTRL1;
+  uint8_t securityChecked = 0;
+  
+  void securityCheck();
+#endif
+  
+  norace message_t * ONE_NOK m_msg;
+  
+  norace bool m_cca;
+  
+  norace uint8_t m_tx_power;
+  
+  cc2420_transmit_state_t m_state = S_STOPPED;
+
+  bool m_receiving = FALSE;
+  
+  uint16_t m_prev_time;
+  
+  /** Byte reception/transmission indicator */
+  bool sfdHigh;
+  
+  /** Let the CC2420 driver keep a lock on the SPI while waiting for an ack */
+  bool abortSpiRelease;
+  
+  /** Total CCA checks that showed no activity before the NoAck LPL send */
+  norace int8_t totalCcaChecks;
+  
+  /** The initial backoff period */
+  norace uint16_t myInitialBackoff;
+  
+  /** The congestion backoff period */
+  norace uint16_t myCongestionBackoff;
+  
+
+  /***************** Prototypes ****************/
+  error_t send( message_t * ONE p_msg, bool cca );
+  error_t resend( bool cca );
+  void loadTXFIFO();
+  void attemptSend();
+  void congestionBackoff();
+  error_t acquireSpiResource();
+  error_t releaseSpiResource();
+  void signalDone( error_t err );
+  
+  
+  /***************** Init Commands *****************/
+  command error_t Init.init() {
+    call CCA.makeInput();
+    call CSN.makeOutput();
+    call SFD.makeInput();
+    return SUCCESS;
+  }
+
+  /***************** StdControl Commands ****************/
+  command error_t StdControl.start() {
+    atomic {
+      call CaptureSFD.captureRisingEdge();
+      m_state = S_STARTED;
+      m_receiving = FALSE;
+      abortSpiRelease = FALSE;
+      m_tx_power = 0;
+    }
+    return SUCCESS;
+  }
+
+  command error_t StdControl.stop() {
+    atomic {
+      m_state = S_STOPPED;
+      call BackoffTimer.stop();
+      call CaptureSFD.disable();
+      call SpiResource.release();  // REMOVE
+      call CSN.set();
+    }
+    return SUCCESS;
+  }
+
+
+  /**************** Send Commands ****************/
+  async command error_t Send.send( message_t* ONE p_msg, bool useCca ) {
+    return send( p_msg, useCca );
+  }
+
+  async command error_t Send.resend(bool useCca) {
+    return resend( useCca );
+  }
+
+  async command error_t Send.cancel() {
+    atomic {
+      switch( m_state ) {
+      case S_LOAD:
+      case S_SAMPLE_CCA:
+      case S_BEGIN_TRANSMIT:
+        m_state = S_CANCEL;
+        break;
+        
+      default:
+        // cancel not allowed while radio is busy transmitting
+        return FAIL;
+      }
+    }
+
+    return SUCCESS;
+  }
+
+  async command error_t Send.modify( uint8_t offset, uint8_t* buf, 
+                                     uint8_t len ) {
+    call CSN.clr();
+    call TXFIFO_RAM.write( offset, buf, len );
+    call CSN.set();
+    return SUCCESS;
+  }
+  
+  /***************** Indicator Commands ****************/
+  command bool EnergyIndicator.isReceiving() {
+    return !(call CCA.get());
+  }
+  
+  command bool ByteIndicator.isReceiving() {
+    bool high;
+    atomic high = sfdHigh;
+    return high;
+  }
+  
+
+  /***************** RadioBackoff Commands ****************/
+  /**
+   * Must be called within a requestInitialBackoff event
+   * @param backoffTime the amount of time in some unspecified units to backoff
+   */
+  async command void RadioBackoff.setInitialBackoff(uint16_t backoffTime) {
+    myInitialBackoff = backoffTime + 1;
+  }
+  
+  /**
+   * Must be called within a requestCongestionBackoff event
+   * @param backoffTime the amount of time in some unspecified units to backoff
+   */
+  async command void RadioBackoff.setCongestionBackoff(uint16_t backoffTime) {
+    myCongestionBackoff = backoffTime + 1;
+  }
+  
+  async command void RadioBackoff.setCca(bool useCca) {
+  }
+  
+  
+  inline uint32_t getTime32(uint16_t timet)
+  {
+    uint32_t recent_time=call BackoffTimer.getNow();
+    return recent_time + (int16_t)(timet - recent_time);
+  }
+
+  /**
+   * The CaptureSFD event is actually an interrupt from the capture pin
+   * which is connected to timing circuitry and timer modules.  This
+   * type of interrupt allows us to see what time (being some relative value)
+   * the event occurred, and lets us accurately timestamp our packets.  This
+   * allows higher levels in our system to synchronize with other nodes.
+   *
+   * Because the SFD events can occur so quickly, and the interrupts go
+   * in both directions, we set up the interrupt but check the SFD pin to
+   * determine if that interrupt condition has already been met - meaning,
+   * we should fall through and continue executing code where that interrupt
+   * would have picked up and executed had our microcontroller been fast enough.
+   */
+  async event void CaptureSFD.captured( uint16_t timet ) {
+    uint32_t time32;
+    uint8_t sfd_state = 0;
+    atomic {
+      time32 = getTime32(timet);
+      switch( m_state ) {
+        
+      case S_SFD:
+        m_state = S_EFD;
+        sfdHigh = TRUE;
+        // in case we got stuck in the receive SFD interrupts, we can reset
+        // the state here since we know that we are not receiving anymore
+        m_receiving = FALSE;
+        call CaptureSFD.captureFallingEdge();
+        call PacketTimeStamp.set(m_msg, time32);
+        if (call PacketTimeSyncOffset.isSet(m_msg)) {
+           uint8_t absOffset = sizeof(message_header_t)-sizeof(cc2420_header_t)+call PacketTimeSyncOffset.get(m_msg);
+           timesync_radio_t *timesync = (timesync_radio_t *)((nx_uint8_t*)m_msg+absOffset);
+           // set timesync event time as the offset between the event time and the SFD interrupt time (TEP  133)
+           *timesync  -= time32;
+           call CSN.clr();
+           call TXFIFO_RAM.write( absOffset, (uint8_t*)timesync, sizeof(timesync_radio_t) );
+           call CSN.set();
+           //restoring the event time to the original value
+           *timesync  += time32;
+        }
+
+        if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
+          // This is an ack packet, don't release the chip's SPI bus lock.
+          abortSpiRelease = TRUE;
+        }
+        releaseSpiResource();
+        call BackoffTimer.stop();
+
+        if ( call SFD.get() ) {
+          break;
+        }
+        /** Fall Through because the next interrupt was already received */
+
+      case S_EFD:
+        sfdHigh = FALSE;
+        call CaptureSFD.captureRisingEdge();
+        
+        if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
+          m_state = S_ACK_WAIT;
+          call BackoffTimer.start( CC2420_ACK_WAIT_DELAY );
+        } else {
+          signalDone(SUCCESS);
+        }
+        
+        if ( !call SFD.get() ) {
+          break;
+        }
+        /** Fall Through because the next interrupt was already received */
+        
+      default:
+        /* this is the SFD for received messages */
+        if ( !m_receiving && sfdHigh == FALSE ) {
+          sfdHigh = TRUE;
+          call CaptureSFD.captureFallingEdge();
+          // safe the SFD pin status for later use
+          sfd_state = call SFD.get();
+          call CC2420Receive.sfd( time32 );
+          m_receiving = TRUE;
+          m_prev_time = timet;
+          if ( call SFD.get() ) {
+            // wait for the next interrupt before moving on
+            return;
+          }
+          // if SFD.get() = 0, then an other interrupt happened since we
+          // reconfigured CaptureSFD! Fall through
+        }
+        
+        if ( sfdHigh == TRUE ) {
+          sfdHigh = FALSE;
+          call CaptureSFD.captureRisingEdge();
+          m_receiving = FALSE;
+          /* if sfd_state is 1, then we fell through, but at the time of
+           * saving the time stamp the SFD was still high. Thus, the timestamp
+           * is valid.
+           * if the sfd_state is 0, then either we fell through and SFD
+           * was low while we safed the time stamp, or we didn't fall through.
+           * Thus, we check for the time between the two interrupts.
+           * FIXME: Why 10 tics? Seams like some magic number...
+           */
+          if ((sfd_state == 0) && (timet - m_prev_time < 10) ) {
+            call CC2420Receive.sfd_dropped();
+            if (m_msg)
+              call PacketTimeStamp.clear(m_msg);
+          }
+          break;
+        }
+      }
+    }
+  }
+
+  /***************** ChipSpiResource Events ****************/
+  async event void ChipSpiResource.releasing() {
+    if(abortSpiRelease) {
+      call ChipSpiResource.abortRelease();
+    }
+  }
+  
+  
+  /***************** CC2420Receive Events ****************/
+  /**
+   * If the packet we just received was an ack that we were expecting,
+   * our send is complete.
+   */
+  async event void CC2420Receive.receive( uint8_t type, message_t* ack_msg ) {
+    cc2420_header_t* ack_header;
+    cc2420_header_t* msg_header;
+    cc2420_metadata_t* msg_metadata;
+    uint8_t* ack_buf;
+    uint8_t length;
+
+    if ( type == IEEE154_TYPE_ACK && m_msg) {
+      ack_header = call CC2420PacketBody.getHeader( ack_msg );
+      msg_header = call CC2420PacketBody.getHeader( m_msg );
+      
+      if ( m_state == S_ACK_WAIT && msg_header->dsn == ack_header->dsn ) {
+        call BackoffTimer.stop();
+        
+        msg_metadata = call CC2420PacketBody.getMetadata( m_msg );
+        ack_buf = (uint8_t *) ack_header;
+        length = ack_header->length;
+        
+        msg_metadata->ack = TRUE;
+        msg_metadata->rssi = ack_buf[ length - 1 ];
+        msg_metadata->lqi = ack_buf[ length ] & 0x7f;
+        signalDone(SUCCESS);
+      }
+    }
+  }
+
+  /***************** SpiResource Events ****************/
+  event void SpiResource.granted() {
+    uint8_t cur_state;
+
+    atomic {
+      cur_state = m_state;
+    }
+
+    switch( cur_state ) {
+    case S_LOAD:
+      loadTXFIFO();
+      break;
+      
+    case S_BEGIN_TRANSMIT:
+      attemptSend();
+      break;
+      
+    case S_CANCEL:
+      call CSN.clr();
+      call SFLUSHTX.strobe();
+      call CSN.set();
+      releaseSpiResource();
+      atomic {
+        m_state = S_STARTED;
+      }
+      signal Send.sendDone( m_msg, ECANCEL );
+      break;
+      
+    default:
+      releaseSpiResource();
+      break;
+    }
+  }
+  
+  /***************** TXFIFO Events ****************/
+  /**
+   * The TXFIFO is used to load packets into the transmit buffer on the
+   * chip
+   */
+  async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len,
+                                     error_t error ) {
+
+    call CSN.set();
+    if ( m_state == S_CANCEL ) {
+      atomic {
+        call CSN.clr();
+        call SFLUSHTX.strobe();
+        call CSN.set();
+      }
+      releaseSpiResource();
+      m_state = S_STARTED;
+      signal Send.sendDone( m_msg, ECANCEL );
+      
+    } else if ( !m_cca ) {
+      atomic {
+        m_state = S_BEGIN_TRANSMIT;
+      }
+      dbg("CC2420", "%s, write done!\n", __FUNCTION__);
+      attemptSend();
+      
+    } else {
+      releaseSpiResource();
+      atomic {
+        m_state = S_SAMPLE_CCA;
+      }
+      
+      signal RadioBackoff.requestInitialBackoff(m_msg);
+      call BackoffTimer.start(myInitialBackoff);
+    }
+  }
+
+  
+  async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, 
+      error_t error ) {
+  }
+  
+  
+  /***************** Timer Events ****************/
+  /**
+   * The backoff timer is mainly used to wait for a moment before trying
+   * to send a packet again. But we also use it to timeout the wait for
+   * an acknowledgement, and timeout the wait for an SFD interrupt when
+   * we should have gotten one.
+   */
+  async event void BackoffTimer.fired() {
+    atomic {
+      switch( m_state ) {
+        
+      case S_SAMPLE_CCA : 
+        // sample CCA and wait a little longer if free, just in case we
+        // sampled during the ack turn-around window
+        if ( call CCA.get() ) {
+          m_state = S_BEGIN_TRANSMIT;
+          call BackoffTimer.start( CC2420_TIME_ACK_TURNAROUND );
+          
+        } else {
+          congestionBackoff();
+        }
+        break;
+        
+      case S_BEGIN_TRANSMIT:
+      case S_CANCEL:
+        if ( acquireSpiResource() == SUCCESS ) {
+          attemptSend();
+        }
+        break;
+        
+      case S_ACK_WAIT:
+        signalDone( SUCCESS );
+        break;
+
+      case S_SFD:
+        // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD
+        // jiffies. Assume something is wrong.
+        call SFLUSHTX.strobe();
+        call CaptureSFD.captureRisingEdge();
+        releaseSpiResource();
+        signalDone( ERETRY );
+        break;
+
+      default:
+        break;
+      }
+    }
+  }
+
+  TRUSTEDBLOCK void output_message(message_t* ONE msg) {
+     // header part
+     int i;
+     uint8_t* start = (uint8_t*)msg;
+
+     printf("Header is: \n");
+     for(i = 0; i<sizeof(message_header_t); i++) {
+        printf("%x  ", *(start+i));
+     }
+     printf("end!\n");
+
+     printf("Body is: \n");
+     for(; i<TOSH_DATA_LENGTH; i++) {
+        printf("%x  ", *(start+i));
+     }
+     printf("end!\n");
+
+     printf("Footer is: \n");
+     for(; i<sizeof(message_footer_t); i++) {
+        printf("%x  ", *(start+i));
+     }
+     printf("end!\n");
+
+     printf("Metadata is: \n");
+     for(; i<sizeof(message_metadata_t); i++) {
+        printf("%x  ", *(start+i));
+     }
+     printf("end!\n");
+  }
+      
+  /***************** Functions ****************/
+  /**
+   * Set up a message to be sent. First load it into the outbound tx buffer
+   * on the chip, then attempt to send it.
+   * @param *p_msg Pointer to the message that needs to be sent
+   * @param cca TRUE if this transmit should use clear channel assessment
+   */
+  error_t send( message_t* ONE p_msg, bool cca ) {
+    atomic {
+      if (m_state == S_CANCEL) {
+        return ECANCEL;
+      }
+      
+      if ( m_state != S_STARTED ) {
+        return FAIL;
+      }
+      
+#ifdef CC2420_HW_SECURITY
+      securityChecked = 0;
+#endif
+      m_state = S_LOAD;
+      m_cca = cca;
+      m_msg = p_msg;
+      totalCcaChecks = 0;
+    }
+    output_message(p_msg);
+     
+    if ( acquireSpiResource() == SUCCESS ) {
+#ifdef SIM_CC2420
+      if(call TriggerFIFOP.enableIntr()) 
+	 dbg("CC2420", "After acquiring the spi source, it is right time to enable the receive interrupts of neighboring motes!\n");
+#endif
+      loadTXFIFO();
+    }
+
+    return SUCCESS;
+  }
+  
+  /**
+   * Resend a packet that already exists in the outbound tx buffer on the
+   * chip
+   * @param cca TRUE if this transmit should use clear channel assessment
+   */
+  error_t resend( bool cca ) {
+
+    atomic {
+      if (m_state == S_CANCEL) {
+        return ECANCEL;
+      }
+      
+      if ( m_state != S_STARTED ) {
+        return FAIL;
+      }
+      
+      m_cca = cca;
+      m_state = cca ? S_SAMPLE_CCA : S_BEGIN_TRANSMIT;
+      totalCcaChecks = 0;
+    }
+    
+    if(m_cca) {
+      signal RadioBackoff.requestInitialBackoff(m_msg);
+      call BackoffTimer.start( myInitialBackoff );
+      
+    } else if ( acquireSpiResource() == SUCCESS ) {
+      attemptSend();
+    }
+    
+    return SUCCESS;
+  }
+#ifdef CC2420_HW_SECURITY
+
+  task void waitTask(){
+    call Leds.led2Toggle();
+    if(SECURITYLOCK == 1){
+      post waitTask();
+    }else{
+      securityCheck();
+    }
+  }
+
+  void securityCheck(){
+
+    cc2420_header_t* msg_header;
+    cc2420_status_t status;
+    security_header_t* secHdr;
+    uint8_t mode;
+    uint8_t key;
+    uint8_t micLength;
+
+    msg_header = call CC2420PacketBody.getHeader( m_msg );
+
+    if(!(msg_header->fcf & (1 << IEEE154_FCF_SECURITY_ENABLED))){
+      // Security is not used for this packet
+      // Make sure to set mode to 0 and the others to the default values
+      CTR_SECCTRL0 = ((0 << CC2420_SECCTRL0_SEC_MODE) |
+		      (1 << CC2420_SECCTRL0_SEC_M) |
+		      (1 << CC2420_SECCTRL0_SEC_TXKEYSEL) |
+		      (1 << CC2420_SECCTRL0_SEC_CBC_HEAD)) ;
+      
+      call CSN.clr();
+      call SECCTRL0.write(CTR_SECCTRL0);
+      call CSN.set();
+
+      return;
+    }
+
+    if(SECURITYLOCK == 1){
+      post waitTask();
+    }else {
+      //Will perform encryption lock registers
+      atomic SECURITYLOCK = 1;
+
+      secHdr = (security_header_t*) &msg_header->secHdr;
+      memcpy(&nonceValue[3], &(secHdr->frameCounter), 4);
+
+      skip = secHdr->reserved;
+      key = secHdr->keyID[0]; // For now this is the only key selection mode.
+
+      if (secHdr->secLevel == NO_SEC){
+	mode = CC2420_NO_SEC;
+	micLength = 4;
+      }else if (secHdr->secLevel == CBC_MAC_4){
+	mode = CC2420_CBC_MAC;
+	micLength = 4;
+      }else if (secHdr->secLevel == CBC_MAC_8){
+	mode = CC2420_CBC_MAC;
+	micLength = 8;
+      }else if (secHdr->secLevel == CBC_MAC_16){
+	mode = CC2420_CBC_MAC;
+	micLength = 16;
+      }else if (secHdr->secLevel == CTR){
+	mode = CC2420_CTR;
+	micLength = 4;
+      }else if (secHdr->secLevel == CCM_4){
+	mode = CC2420_CCM;
+	micLength = 4;
+      }else if (secHdr->secLevel == CCM_8){
+	mode = CC2420_CCM;
+	micLength = 8;
+      }else if (secHdr->secLevel == CCM_16){
+	mode = CC2420_CCM;
+	micLength = 16;
+      }else{
+	return;
+      }
+
+      CTR_SECCTRL0 = ((mode << CC2420_SECCTRL0_SEC_MODE) |
+		      ((micLength-2)/2 << CC2420_SECCTRL0_SEC_M) |
+		      (key << CC2420_SECCTRL0_SEC_TXKEYSEL) |
+		      (1 << CC2420_SECCTRL0_SEC_CBC_HEAD)) ;
+#ifndef TFRAMES_ENABLED
+      CTR_SECCTRL1 = (skip+11+sizeof(security_header_t)+((skip+11+sizeof(security_header_t))<<8));
+#else
+      CTR_SECCTRL1 = (skip+10+sizeof(security_header_t)+((skip+10+sizeof(security_header_t))<<8));
+#endif
+
+      call CSN.clr();
+      call SECCTRL0.write(CTR_SECCTRL0);
+      call CSN.set();
+
+      call CSN.clr();
+      call SECCTRL1.write(CTR_SECCTRL1);
+      call CSN.set();
+
+      call CSN.clr();
+      call TXNONCE.write(0, nonceValue, 16);
+      call CSN.set();
+
+      call CSN.clr();
+      status = call SNOP.strobe();
+      call CSN.set();
+
+      while(status & CC2420_STATUS_ENC_BUSY){
+	call CSN.clr();
+	status = call SNOP.strobe();
+	call CSN.set();
+      }
+      
+      // Inline security will be activated by STXON or STXONCCA strobes
+
+      atomic SECURITYLOCK = 0;
+
+    }
+  }
+#endif
+
+  /**
+   * Attempt to send the packet we have loaded into the tx buffer on 
+   * the radio chip.  The STXONCCA will send the packet immediately if
+   * the channel is clear.  If we're not concerned about whether or not
+   * the channel is clear (i.e. m_cca == FALSE), then STXON will send the
+   * packet without checking for a clear channel.
+   *
+   * If the packet didn't get sent, then congestion == TRUE.  In that case,
+   * we reset the backoff timer and try again in a moment.
+   *
+   * If the packet got sent, we should expect an SFD interrupt to take
+   * over, signifying the packet is getting sent.
+   * 
+   * If security is enabled, STXONCCA or STXON will perform inline security
+   * options before transmitting the packet.
+   */
+  void attemptSend() {
+    uint8_t status;
+    bool congestion = TRUE;
+    dbg("CC2420", "Keep on sending!\n");
+
+    atomic {
+      if (m_state == S_CANCEL) {
+        call SFLUSHTX.strobe();
+        releaseSpiResource();
+        call CSN.set();
+        m_state = S_STARTED;
+        signal Send.sendDone( m_msg, ECANCEL );
+        return;
+      }
+#ifdef CC2420_HW_SECURITY
+      if(securityChecked != 1){
+	securityCheck();
+      }
+      securityChecked = 1;
+#endif
+      call CSN.clr();
+      status = m_cca ? call STXONCCA.strobe() : call STXON.strobe();
+      if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) {
+        status = call SNOP.strobe();
+        if ( status & CC2420_STATUS_TX_ACTIVE ) {
+          congestion = FALSE;
+        }
+      }
+
+      m_state = congestion ? S_SAMPLE_CCA : S_SFD;
+      call CSN.set();
+    }
+
+    if ( congestion ) {
+      totalCcaChecks = 0;
+      releaseSpiResource();
+      congestionBackoff();
+    } else {
+      call BackoffTimer.start(CC2420_ABORT_PERIOD);
+    }
+  }
+  
+  
+  /**  
+   * Congestion Backoff
+   */
+  void congestionBackoff() {
+    atomic {
+      signal RadioBackoff.requestCongestionBackoff(m_msg);
+      call BackoffTimer.start(myCongestionBackoff);
+    }
+  }
+  
+  error_t acquireSpiResource() {
+    error_t error = call SpiResource.immediateRequest();
+    if ( error != SUCCESS ) {
+      call SpiResource.request();
+    }
+    return error;
+  }
+
+  error_t releaseSpiResource() {
+    call SpiResource.release();
+    return SUCCESS;
+  }
+
+
+  /** 
+   * Setup the packet transmission power and load the tx fifo buffer on
+   * the chip with our outbound packet.  
+   *
+   * Warning: the tx_power metadata might not be initialized and
+   * could be a value other than 0 on boot.  Verification is needed here
+   * to make sure the value won't overstep its bounds in the TXCTRL register
+   * and is transmitting at max power by default.
+   *
+   * It should be possible to manually calculate the packet's CRC here and
+   * tack it onto the end of the header + payload when loading into the TXFIFO,
+   * so the continuous modulation low power listening strategy will continually
+   * deliver valid packets.  This would increase receive reliability for
+   * mobile nodes and lossy connections.  The crcByte() function should use
+   * the same CRC polynomial as the CC2420's AUTOCRC functionality.
+   */
+  void loadTXFIFO() {
+    cc2420_header_t* header = call CC2420PacketBody.getHeader( m_msg );
+    uint8_t tx_power = (call CC2420PacketBody.getMetadata( m_msg ))->tx_power;
+
+    if ( !tx_power ) {
+      tx_power = CC2420_DEF_RFPOWER;
+    }
+    
+    call CSN.clr();
+    
+    if ( m_tx_power != tx_power ) {
+      call TXCTRL.write( ( 2 << CC2420_TXCTRL_TXMIXBUF_CUR ) |
+                         ( 3 << CC2420_TXCTRL_PA_CURRENT ) |
+                         ( 1 << CC2420_TXCTRL_RESERVED ) |
+                         ( (tx_power & 0x1F) << CC2420_TXCTRL_PA_LEVEL ) );
+    }
+    
+    m_tx_power = tx_power;
+    
+    {
+      uint8_t tmpLen __DEPUTY_UNUSED__ = header->length - 1;
+      dbg("CC2420", "The header length is %d\n", header->length);
+      call TXFIFO.write(TCAST(uint8_t * COUNT(tmpLen), header), header->length - 1);
+    }
+  }
+  
+  void signalDone( error_t err ) {
+    atomic m_state = S_STARTED;
+    abortSpiRelease = FALSE;
+    call ChipSpiResource.attemptRelease();
+    signal Send.sendDone( m_msg, err );
+  }
+
+}
+
