]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Reorganizing directory: enabling LPL, 32khz clock for certain platforms. Patches...
authorkusy <kusy>
Thu, 16 Jul 2009 06:59:38 +0000 (06:59 +0000)
committerkusy <kusy>
Thu, 16 Jul 2009 06:59:38 +0000 (06:59 +0000)
20 files changed:
apps/tests/TestFtsp/Ftsp/FtspDataAnalyzer.m [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/FtspDataLogger.java [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/FtspDataLogger.py [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/Makefile [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/README.MATLAB.txt [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/README.txt [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/TestFtsp.h [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/TestFtspAppC.nc [new file with mode: 0755]
apps/tests/TestFtsp/Ftsp/TestFtspC.nc [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/FtspDataLogger.py [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/Makefile [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/README [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/TestFtsp.h [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/TestFtspAppC.nc [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/TestFtspC.nc [new file with mode: 0755]
apps/tests/TestFtsp/FtspLpl/TestFtspMsg.py [new file with mode: 0755]
apps/tests/TestFtsp/FtspLplBeaconer/Makefile [new file with mode: 0755]
apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLeds.h [new file with mode: 0755]
apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLedsAppC.nc [new file with mode: 0755]
apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLedsC.nc [new file with mode: 0755]

diff --git a/apps/tests/TestFtsp/Ftsp/FtspDataAnalyzer.m b/apps/tests/TestFtsp/Ftsp/FtspDataAnalyzer.m
new file mode 100755 (executable)
index 0000000..94dda15
--- /dev/null
@@ -0,0 +1,60 @@
+%load file written out by FtspDataLogger.java class\r
+%arg0 - filename, e.g. '1205543689171.report'\r
+function FTSPDataAnalyzer(file, varargin)\r
+[c1 c2 c3 c4 c5]= textread(file, '%u %u %u %u %u', 'commentstyle', 'shell');\r
+data = [c2 c3 c4 c5]; %skipping the first column (java time)\r
+data1 = sortrows(sortrows(data,1),2);\r
+newdata = [];\r
+\r
+row=1;\r
+newrow=1;\r
+unsynced=0;\r
+while (row<=size(data1,1))\r
+\r
+    seqnum=data1(row,2);\r
+\r
+    data2=[];\r
+    row2=1;\r
+    tmprow1=row;\r
+    while (row <= size(data1,1) && data1(row,2)==seqnum)\r
+        if (data1(row,4)==0)\r
+            data2(row2,1)=data1(row,3);\r
+            row2= row2+ 1;\r
+        else\r
+            unsynced=unsynced+1;\r
+        end\r
+        row = row + 1;\r
+    end\r
+    \r
+    if (row2>1)\r
+        row2size=row2-1;\r
+        rcvdsize=row-tmprow1;\r
+        newdata(newrow,1) = seqnum;\r
+        newdata(newrow,2) = mad(data2(1:row2size,1));\r
+        newdata(newrow,3) = mean(data2(1:row2size,1));\r
+        newdata(newrow,4) = row2size/rcvdsize;\r
+        newrow = newrow + 1;\r
+    end\r
+end\r
+\r
+if (length(newdata)==0)\r
+    disp('no data found (at least one data point from a synchronized mote is required)!');\r
+else\r
+    newsize=newrow-1;\r
+    subplot(3,1,1);\r
+    plot(newdata(1:newsize,1),newdata(1:newsize,2));\r
+    title(sprintf('TimeSync Errors'));\r
+    subplot(3,1,2);\r
+    plot(newdata(1:newsize,1),newdata(1:newsize,3));\r
+    title(sprintf('Avg Glob Time'));\r
+    subplot(3,1,3);\r
+    plot(newdata(1:newsize,1),newdata(1:newsize,4),'b-');\r
+    title(sprintf('%% Synced Motes'));\r
+\r
+    disp(sprintf('total unsycned num %d (all %d)',unsynced,newsize));\r
+    disp(sprintf('avg %0.3f',mean(newdata(1:newsize,2))));\r
+    disp(sprintf('max %d',max(newdata(1:newsize,2))));\r
+    savedata = newdata(1:newsize,:);\r
+    save data.out savedata -ASCII;\r
+end\r
+    
\ No newline at end of file
diff --git a/apps/tests/TestFtsp/Ftsp/FtspDataLogger.java b/apps/tests/TestFtsp/Ftsp/FtspDataLogger.java
new file mode 100755 (executable)
index 0000000..168fa0f
--- /dev/null
@@ -0,0 +1,120 @@
+/*                  tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University  of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2007 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.
+ */
+
+
+/**
+ * @author Brano Kusy
+ */
+
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import net.tinyos.message.*;
+import net.tinyos.util.*;
+
+public class FtspDataLogger implements MessageListener {
+        public class RunWhenShuttingDown extends Thread {
+                public void run()
+                {
+                        System.out.println("Control-C caught. Shutting down...");
+                        if (outReport!=null)
+                        outReport.close();
+                }
+        }
+
+  MoteIF mote;    // For talking to the antitheft root node
+
+        void connect()
+        {
+                try {
+                        mote = new MoteIF(PrintStreamMessenger.err);
+                        mote.registerListener(new TestFtspMsg(), this);
+                        System.out.println("Connection ok!");
+                }
+                catch(Exception e) {
+                        e.printStackTrace();
+                        System.exit(2);
+                }
+        }
+        PrintStream outReport = null;
+
+        public FtspDataLogger() {
+                connect();
+                Runtime.getRuntime().addShutdownHook(new RunWhenShuttingDown());
+                String name=""+System.currentTimeMillis();
+                try
+                {
+                        outReport = new PrintStream(new FileOutputStream(name+".report"));
+                        outReport.println("#[JAVA_TIME] [NODE_ID] [SEQ_NUM] [GLOB_TIME] [IS_TIME_VALID]");
+                }
+                catch (Exception e)
+                {
+                        System.out.println("FtspDataLogger.FtspDataLogger(): "+e.toString());
+                }
+        }
+
+        public void writeReprot(TestFtspMsg tspr)
+        {
+                String foo = (System.currentTimeMillis()
+                               +" "+tspr.get_src_addr()+" "+tspr.get_counter()
+                        +" "+tspr.get_global_rx_timestamp()+" "+tspr.get_is_synced());
+                outReport.println(foo);
+                System.out.println(foo);
+                outReport.flush();
+        }
+
+        public void writeFullReprot(TestFtspMsg tspr)
+        {
+                String foo = (System.currentTimeMillis()
+                               +" "+tspr.get_src_addr()
+                        +" "+tspr.get_counter()
+                        +" "+tspr.get_local_rx_timestamp()
+                        +" "+tspr.get_global_rx_timestamp()
+                        +" "+tspr.get_skew_times_1000000()
+                        +" "+tspr.get_is_synced()
+                        +" "+tspr.get_ftsp_root_addr()
+                        +" "+tspr.get_ftsp_seq()
+                        +" "+tspr.get_ftsp_table_entries());
+                outReport.println(foo);
+                System.out.println(foo);
+                outReport.flush();
+        }
+
+        public void messageReceived(int dest_addr, Message msg)
+        {
+                if (msg instanceof TestFtspMsg)
+                        //writeFullReprot((TestFtspMsg)msg);
+                        writeReprot((TestFtspMsg)msg);
+        }
+
+        /* Just start the app... */
+        public static void main(String[] args)
+        {
+                new FtspDataLogger();
+        }
+}
\ No newline at end of file
diff --git a/apps/tests/TestFtsp/Ftsp/FtspDataLogger.py b/apps/tests/TestFtsp/Ftsp/FtspDataLogger.py
new file mode 100755 (executable)
index 0000000..0c5687b
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import sys, time
+import tos
+
+AM_TEST_FTSP_MSG = 137
+
+class FtspMsg(tos.Packet):
+    def __init__(self, packet = None):
+        tos.Packet.__init__(self,
+                            [('src_addr',            'int', 2),
+                             ('counter',             'int', 2),
+                             ('local_rx_timestamp',  'int', 4),
+                             ('global_rx_timestamp', 'int', 4),
+                             ('skew_times_1000000',  'int', 4),
+                             ('is_synced',           'int', 1),
+                             ('ftsp_root_addr',      'int', 2),
+                             ('ftsp_seq',            'int', 1),
+                             ('ftsp_table_entries',  'int', 2)],
+                            packet)
+
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p and p.type == AM_TEST_FTSP_MSG:
+        msg = FtspMsg(p.data)
+        print int(time.time()), msg.src_addr, msg.counter, msg.global_rx_timestamp, msg.is_synced
+        #print msg
diff --git a/apps/tests/TestFtsp/Ftsp/Makefile b/apps/tests/TestFtsp/Ftsp/Makefile
new file mode 100755 (executable)
index 0000000..25cb720
--- /dev/null
@@ -0,0 +1,17 @@
+BUILD_EXTRA_DEPS = FtspDataLogger.class
+CLEAN_EXTRA = *.class TestFtspMsg.java
+
+FtspDataLogger.class: TestFtspMsg.java
+       javac *.java
+
+TestFtspMsg.java: TestFtsp.h
+       mig java -target=$(PLATFORM) $(CFLAGS) -java-classname=TestFtspMsg TestFtsp.h test_ftsp_msg -o $@
+
+COMPONENT=TestFtspAppC
+
+PFLAGS += -DTIMESYNC_RATE=3
+#PFLAGS += -DTIMESYNC_DEBUG
+
+PFLAGS += -I$(TOSDIR)/lib/ftsp -I$(TOSDIR)/../apps/RadioCountToLeds
+
+include $(MAKERULES)
diff --git a/apps/tests/TestFtsp/Ftsp/README.MATLAB.txt b/apps/tests/TestFtsp/Ftsp/README.MATLAB.txt
new file mode 100755 (executable)
index 0000000..0535549
--- /dev/null
@@ -0,0 +1,46 @@
+FtspDataAnalyzer.m\r
+\r
+-------------------------------------------------------------------------------\r
+Author/Contact:\r
+---------------\r
+ Brano Kusy: branislav.kusy@gmail.com\r
+\r
+-------------------------------------------------------------------------------\r
+DESCRIPTION:\r
+------------\r
+\r
+FtspDataAnalyzer.m works with data logs collected by FtspDataLogger.java and\r
+calculates the maximum and average timesync error over time.\r
+\r
+-------------------------------------------------------------------------------\r
+STEP BY STEP GUIDE TO RUN OUR TEST SCENARIO:\r
+--------------------------------------------\r
+1. program and start motes as described in ./README.txt\r
+2. start SerialForwarder and FtspDataLogger.java as described in ./README.txt\r
+3. 'current_time.report' file (where current_time is a number) is created in ./\r
+   this file is updated with data in the real time\r
+4. let the experiment run for some time\r
+5. start matlab and enter (assuming your current_time was 1206126224593)\r
+    FTSPDataAnalyzer('1206126224593.report')\r
+    this will plot the mean absolute timesync error, global time, and number of\r
+    synced motes; this can be done while experiment is running\r
+6. Matlab also creates data.out file which contains data in the following format\r
+    #seqNum mean_abs_error global_time num_synced_motes\r
+    mean_abs_error is calculated as mean absolute deviation from the mean (mad)\r
+\r
+Simulating multi-hop:\r
+1. define TIMESYNC_DEBUG in the Makefile\r
+2. recompile and upload TestFTSP app to n motes with special NODE_IDs:\r
+     using 'make micaz reinstall.0xAB', nodes 0xAB and 0xCD can communicate\r
+     iff 2D grid coordinates (A,B) and (C,D) are neighbors in a 2D grid\r
\r
+-------------------------------------------------------------------------------\r
+EVALUATION:\r
+--------------------------------------------\r
+ - deployment setup: 11 nodes in a 5x3 grid using simulated multi-hop (4 points\r
+   were vacant as we only used 11 nodes). the max number of hops was 5.\r
+ - parameters: sync period 10sec, polling period 3 sec\r
+ - experiment length: 100 minutes\r
+ - results (1 jiffy is ~30.5 us)\r
+    1.53 jiffy avg error (~50us)\r
+    3.5 jiffy max error (~100us)
\ No newline at end of file
diff --git a/apps/tests/TestFtsp/Ftsp/README.txt b/apps/tests/TestFtsp/Ftsp/README.txt
new file mode 100755 (executable)
index 0000000..b011bc3
--- /dev/null
@@ -0,0 +1,93 @@
+TestFtsp
+
+-------------------------------------------------------------------------------
+Author/Contact:
+---------------
+ Brano Kusy: branislav.kusy@gmail.com
+ Janos Sallai: janos.sallai@vanderbilt.edu
+ Miklos Maroti: mmaroti@gmail.com
+
+-------------------------------------------------------------------------------
+DESCRIPTION:
+------------
+ The TestFtsp application tests the Flooding Time Synchronization Protocol
+ (FTSP) implementation. A network of motes programmed with TestFtsp run the
+ FTSP protocol to time synchronize, and sends to the base station the global
+ reception timestamps of messages broadcast by a dedicated beacon mote
+ programmed with RadioCountToLeds. Ideally, the global reception timestamps of
+ the same RadioCountToLeds message should agree for all TestFtsp motes (with a
+ small synchronization error).
+
+-------------------------------------------------------------------------------
+SUPPORTED PLATFORMS:
+--------------------------------------------
+ The supported platforms are micaz, telosb and iris.
+
+-------------------------------------------------------------------------------
+STEP BY STEP GUIDE TO RUN OUR TEST SCENARIO:
+--------------------------------------------
+ - program one mote with apps/RadioCountToLeds
+ - program multiple motes with TestFtsp
+ - program a mote with apps/BaseStation, leave it on the programming board
+ - turn on all the motes
+ - start the FtspDataLogger java application (type "java FtspDataLogger")
+
+-------------------------------------------------------------------------------
+REPORTED DATA:
+--------------
+ The most important reported data is the global time of arrival of the beacons.
+ The beacon msg arrives to all clients at the same time instant, thus reported
+ global times should be the same for all clients for the same sequence number.
+
+ Each message contains:
+ - the time of message reception by the java app [JAVA_TIME]
+ - the node ID of the mote that is sending this report [NODE_ID]
+ - the  sequence number of the RadioCountToLeds message that is increased
+   for each new polling msg [SEQ_NUM]
+ - the global time when the polling message arrived [GLOB_TIME]
+ - a result_t value indicating if the timestamp is valid [IS_TIME_VALID]
+   (a result_t of 0 denotes a valid timestamp)
+
+If the application is running correctly, then the output should show
+reports from the different FTSP nodes with valid timestamps and similar
+global time values. For example, this is a trace with two FTSP nodes,
+with IDs 1 and 5:
+
+1214516486569 1 10916 433709 0
+1214516486569 5 10916 433709 0
+1214516486809 5 10917 433964 0
+1214516486809 1 10917 433963 0
+1214516487045 5 10918 434210 0
+1214516487053 1 10918 434210 0
+1214516487285 1 10919 434454 0
+1214516487293 5 10919 434455 0
+
+One way to test if FTSP is operating correctly is to turn off one of
+the FTSP nodes. For a short time, that node's global times will differ
+significantly and its valid flag will not be 0. For example, this
+is what it looks like when node 1 in the earlier trace is reset:
+
+1214516490953 5 10934 438208 0
+1214516491201 5 10935 438460 0
+1214516491441 5 10936 438712 0
+1214516491685 5 10937 438964 0
+1214516492169 5 10939 439455 0
+1214516492417 1 10940 243 1
+1214516492421 5 10940 439706 0
+1214516492665 5 10941 439960 0
+1214516492669 1 10941 497 1
+1214516492905 5 10942 440213 0
+...
+1214516497541 1 10961 5495 1
+1214516497549 5 10961 444958 0
+1214516497793 1 10962 5747 1
+1214516498025 1 10963 445456 0
+1214516498033 5 10963 445455 0
+1214516498277 5 10964 445705 0
+1214516498285 1 10964 445707 0
+1214516498521 1 10965 445964 0
+
+This output is also saved in a file named 'current_timestamp.report'.
+'.report' files can be used with the FtspDataAnalyzer.m Matlab
+application. Mean absolute timesync error, global time, and % of
+synced motes will be plotted.
diff --git a/apps/tests/TestFtsp/Ftsp/TestFtsp.h b/apps/tests/TestFtsp/Ftsp/TestFtsp.h
new file mode 100755 (executable)
index 0000000..cc241ab
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2002, 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, Brano Kusy (kusy@isis.vanderbilt.edu)
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ */
+
+#ifndef TEST_FTSP_H
+#define TEST_FTSP_H
+
+typedef nx_struct test_ftsp_msg
+{
+  nx_uint16_t    src_addr;
+  nx_uint16_t    counter;
+  nx_uint32_t    local_rx_timestamp;
+  nx_uint32_t    global_rx_timestamp;
+  nx_int32_t     skew_times_1000000;
+  nx_uint8_t     is_synced;
+  nx_uint16_t    ftsp_root_addr;
+  nx_uint8_t     ftsp_seq;
+  nx_uint8_t     ftsp_table_entries;
+} test_ftsp_msg_t;
+
+enum
+{
+       AM_TEST_FTSP_MSG = 137
+};
+
+#endif
diff --git a/apps/tests/TestFtsp/Ftsp/TestFtspAppC.nc b/apps/tests/TestFtsp/Ftsp/TestFtspAppC.nc
new file mode 100755 (executable)
index 0000000..d30adcd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2002, 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, Brano Kusy (kusy@isis.vanderbilt.edu)
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ */
+
+#include "TestFtsp.h"
+#include "RadioCountToLeds.h"
+
+configuration TestFtspAppC {
+}
+
+implementation {
+  components MainC, TimeSyncC;
+
+  MainC.SoftwareInit -> TimeSyncC;
+  TimeSyncC.Boot -> MainC;
+
+  components TestFtspC as App;
+  App.Boot -> MainC;
+
+  components ActiveMessageC;
+  App.RadioControl -> ActiveMessageC;
+  App.Receive -> ActiveMessageC.Receive[AM_RADIO_COUNT_MSG];
+  App.AMSend -> ActiveMessageC.AMSend[AM_TEST_FTSP_MSG];
+  App.Packet -> ActiveMessageC;
+  App.PacketTimeStamp -> ActiveMessageC;
+
+  components LedsC;
+
+  App.GlobalTime -> TimeSyncC;
+  App.TimeSyncInfo -> TimeSyncC;
+  App.Leds -> LedsC;
+
+}
diff --git a/apps/tests/TestFtsp/Ftsp/TestFtspC.nc b/apps/tests/TestFtsp/Ftsp/TestFtspC.nc
new file mode 100755 (executable)
index 0000000..304da1b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2002, 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, Brano Kusy (kusy@isis.vanderbilt.edu)
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ */
+
+#include "TestFtsp.h"
+#include "RadioCountToLeds.h"
+
+module TestFtspC
+{
+    uses
+    {
+        interface GlobalTime<TMilli>;
+        interface TimeSyncInfo;
+        interface Receive;
+        interface AMSend;
+        interface Packet;
+        interface Leds;
+        interface PacketTimeStamp<TMilli,uint32_t>;
+        interface Boot;
+        interface SplitControl as RadioControl;
+    }
+}
+
+implementation
+{
+    message_t msg;
+    bool locked = FALSE;
+
+    event void Boot.booted() {
+        call RadioControl.start();
+    }
+
+    event message_t* Receive.receive(message_t* msgPtr, void* payload, uint8_t len)
+    {
+        call Leds.led0Toggle();
+        if (!locked && call PacketTimeStamp.isValid(msgPtr)) {
+            radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(msgPtr, sizeof(radio_count_msg_t));
+            test_ftsp_msg_t* report = (test_ftsp_msg_t*)call Packet.getPayload(&msg, sizeof(test_ftsp_msg_t));
+
+            uint32_t rxTimestamp = call PacketTimeStamp.timestamp(msgPtr);
+
+            report->src_addr = TOS_NODE_ID;
+            report->counter = rcm->counter;
+            report->local_rx_timestamp = rxTimestamp;
+            report->is_synced = call GlobalTime.local2Global(&rxTimestamp);
+            report->global_rx_timestamp = rxTimestamp;
+            report->skew_times_1000000 = (uint32_t)call TimeSyncInfo.getSkew()*1000000UL;
+            report->ftsp_root_addr = call TimeSyncInfo.getRootID();
+            report->ftsp_seq = call TimeSyncInfo.getSeqNum();
+            report->ftsp_table_entries = call TimeSyncInfo.getNumEntries();
+
+            if (call AMSend.send(AM_BROADCAST_ADDR, &msg, sizeof(test_ftsp_msg_t)) == SUCCESS) {
+              locked = TRUE;
+            }
+        }
+
+        return msgPtr;
+    }
+
+    event void AMSend.sendDone(message_t* ptr, error_t success) {
+        locked = FALSE;
+        return;
+    }
+
+    event void RadioControl.startDone(error_t err) {}
+    event void RadioControl.stopDone(error_t error){}
+}
diff --git a/apps/tests/TestFtsp/FtspLpl/FtspDataLogger.py b/apps/tests/TestFtsp/FtspLpl/FtspDataLogger.py
new file mode 100755 (executable)
index 0000000..0c5687b
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import sys, time
+import tos
+
+AM_TEST_FTSP_MSG = 137
+
+class FtspMsg(tos.Packet):
+    def __init__(self, packet = None):
+        tos.Packet.__init__(self,
+                            [('src_addr',            'int', 2),
+                             ('counter',             'int', 2),
+                             ('local_rx_timestamp',  'int', 4),
+                             ('global_rx_timestamp', 'int', 4),
+                             ('skew_times_1000000',  'int', 4),
+                             ('is_synced',           'int', 1),
+                             ('ftsp_root_addr',      'int', 2),
+                             ('ftsp_seq',            'int', 1),
+                             ('ftsp_table_entries',  'int', 2)],
+                            packet)
+
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p and p.type == AM_TEST_FTSP_MSG:
+        msg = FtspMsg(p.data)
+        print int(time.time()), msg.src_addr, msg.counter, msg.global_rx_timestamp, msg.is_synced
+        #print msg
diff --git a/apps/tests/TestFtsp/FtspLpl/Makefile b/apps/tests/TestFtsp/FtspLpl/Makefile
new file mode 100755 (executable)
index 0000000..9962988
--- /dev/null
@@ -0,0 +1,16 @@
+SENSORBOARD=quantoplus
+
+COMPONENT=TestFtspAppC
+
+PFLAGS += -DTIMESYNC_RATE=10
+#PFLAGS += -DTIMESYNC_DEBUG
+#PFLAGS += -DCC2420_CHANNEL=26
+CFLAGS += -DTOSH_DATA_LENGTH=50
+#CFLAGS += -DCOUNT_LOG
+
+PFLAGS += -I$(TOSDIR)/lib/ftsp -I$(TOSDIR)/../apps/RadioCountToLeds -I$(TOSDIR)/lib/printf
+
+CFLAGS += -DLPL_INTERVAL=200
+CFLAGS += -DLOW_POWER_LISTENING
+
+include $(MAKERULES)
diff --git a/apps/tests/TestFtsp/FtspLpl/README b/apps/tests/TestFtsp/FtspLpl/README
new file mode 100755 (executable)
index 0000000..24c080c
--- /dev/null
@@ -0,0 +1,31 @@
+First, program several nodes with this TestFtsp application. In addition,
+you will need one TinyOS Basestation that listens for messages, and one
+beacon node. Program the beacon node with the RadioCountToLed application
+from the TestFtsp32kLplBeaconer directory. This is a special modification of
+the RadioCountToLed code which allows to evaluate a duty-cycled ftsp
+network. The regular RadioCountToLed code doesn't work, since a LPL
+broadcast message gets transmitted more than just once. Thus, there is a
+disambiguity in which precise broadcast message was actually timestamped by
+the TestFtsp application. The modifications take care of this by using the
+TimeSyncAMSend interface and setting an arbitrary event time. Thus, on
+reception, the TestFtsp code can account for this delayed send.
+
+To evaluate the synchronization precision, use the FtspDataLogger.py
+application. First, you will need a serial forwarder that connects to the
+BaseStation node. Then, run the python application like this:
+python FtspDataLogger.py sf@localhost:9002
+
+You should now see messages coming in, one per line. The first value is the
+current time as a unix timestamp. The last line is a binary value indicating
+if there was some missed data, and thus the values are not good (indicated
+by a 1), or if all the nodes are synchronized and we received a value for
+each and every one of them (indicated by a 0).
+
+Note!!!!!
+- the basestation should also define
+    CFLAGS += -DTOSH_DATA_LENGTH=50
+    in the makefile. Else, the reports will not fit into 1 tinyos message, and
+    they will get silently dropped.
+- 32k timesync only works for certain platforms (those that provide 32khz
+    counter), if your platform does not support the counter, LPL still works,
+    but you need to use TMilli timesync
diff --git a/apps/tests/TestFtsp/FtspLpl/TestFtsp.h b/apps/tests/TestFtsp/FtspLpl/TestFtsp.h
new file mode 100755 (executable)
index 0000000..57cd25c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2002, 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, Brano Kusy (kusy@isis.vanderbilt.edu)
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ */
+
+#ifndef TEST_FTSP_H
+#define TEST_FTSP_H
+
+typedef nx_struct test_ftsp_msg
+{
+  nx_uint16_t    src_addr;
+  nx_uint16_t    counter;
+  nx_uint32_t    local_rx_timestamp;
+  nx_uint32_t    global_rx_timestamp;
+  nx_int32_t     skew_times_1000000;
+  nx_float       skew;
+  nx_uint8_t     is_synced;
+  nx_uint16_t    ftsp_root_addr;
+  nx_uint8_t     ftsp_seq;
+  nx_uint8_t     ftsp_table_entries;
+  nx_uint32_t    localAverage;
+  nx_int32_t     offsetAverage;
+} test_ftsp_msg_t;
+
+enum
+{
+       AM_TEST_FTSP_MSG = 137
+};
+
+#endif
diff --git a/apps/tests/TestFtsp/FtspLpl/TestFtspAppC.nc b/apps/tests/TestFtsp/FtspLpl/TestFtspAppC.nc
new file mode 100755 (executable)
index 0000000..fbb7540
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2002, 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, Brano Kusy (kusy@isis.vanderbilt.edu)
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ * Adapted for LPL: 6/16/09 by Thomas Schmid (thomas.schmid@ucla.edu)
+ */
+
+#include "TestFtsp.h"
+#include "RadioCountToLeds.h"
+
+configuration TestFtspAppC {
+}
+
+implementation {
+  components MainC, TimeSync32kC;
+
+  MainC.SoftwareInit -> TimeSync32kC;
+  TimeSync32kC.Boot -> MainC;
+
+  components TestFtspC as App;
+  App.Boot -> MainC;
+
+  components ActiveMessageC;
+  components TimeSyncMessageC;
+  App.RadioControl -> ActiveMessageC;
+  App.Receive -> TimeSyncMessageC.Receive[AM_RADIO_COUNT_MSG];
+  App.TimeSyncPacket -> TimeSyncMessageC;
+  App.AMSend -> ActiveMessageC.AMSend[AM_TEST_FTSP_MSG];
+  App.Packet -> ActiveMessageC;
+  App.PacketTimeStamp -> ActiveMessageC;
+
+  components RandomC;
+  App.Random -> RandomC;
+
+  components new TimerMilliC() as Timer0;
+  App.RandomTimer -> Timer0;
+
+  components LedsC;
+
+  App.GlobalTime -> TimeSync32kC;
+  App.TimeSyncInfo -> TimeSync32kC;
+  App.Leds -> LedsC;
+
+#ifdef LOW_POWER_LISTENING
+  components CC2420ActiveMessageC;
+  App.LowPowerListening -> CC2420ActiveMessageC;
+#endif
+
+}
diff --git a/apps/tests/TestFtsp/FtspLpl/TestFtspC.nc b/apps/tests/TestFtsp/FtspLpl/TestFtspC.nc
new file mode 100755 (executable)
index 0000000..ed8f504
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2002, 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, Brano Kusy (kusy@isis.vanderbilt.edu)
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ * Ported for LPL: Thomas Schmid (thomas.schmid@ucla.edu)
+ */
+
+#include "TestFtsp.h"
+#include "RadioCountToLeds.h"
+
+module TestFtspC
+{
+    uses
+    {
+        interface GlobalTime<T32khz>;
+        interface TimeSyncInfo;
+        interface Receive;
+        interface AMSend;
+        interface Packet;
+        interface Leds;
+        interface PacketTimeStamp<T32khz,uint32_t>;
+        interface Boot;
+        interface SplitControl as RadioControl;
+        interface Timer<TMilli> as RandomTimer;
+        interface Random;
+
+        interface TimeSyncPacket<T32khz,uint32_t>;
+
+#ifdef LOW_POWER_LISTENING
+        interface LowPowerListening;
+#endif
+
+    }
+}
+
+implementation
+{
+    enum {
+        ACT_TESTFTSP = 0x11,
+    };
+
+    message_t msg;
+    bool locked = FALSE;
+    test_ftsp_msg_t* report;
+
+    event void Boot.booted() {
+        call RadioControl.start();
+    }
+
+    event message_t* Receive.receive(message_t* msgPtr, void* payload, uint8_t len)
+    {
+        if (!(call PacketTimeStamp.isValid(msgPtr))){
+            call Leds.led1Toggle();
+        }
+        if (!locked && call PacketTimeStamp.isValid(msgPtr)) {
+            radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(msgPtr, sizeof(radio_count_msg_t));
+            if(call TimeSyncPacket.isValid(msgPtr)) {
+                uint32_t rxTimestamp = call TimeSyncPacket.eventTime(msgPtr);
+                report = (test_ftsp_msg_t*)call Packet.getPayload(&msg, sizeof(test_ftsp_msg_t));
+
+                report->src_addr = TOS_NODE_ID;
+                report->counter = rcm->counter;
+                report->local_rx_timestamp = rxTimestamp;
+                report->is_synced = call GlobalTime.local2Global(&rxTimestamp);
+                report->global_rx_timestamp = rxTimestamp;
+                report->skew_times_1000000 = (uint32_t)call TimeSyncInfo.getSkew()*1000000UL;
+                report->skew = call TimeSyncInfo.getSkew();
+                report->ftsp_root_addr = call TimeSyncInfo.getRootID();
+                report->ftsp_seq = call TimeSyncInfo.getSeqNum();
+                report->ftsp_table_entries = call TimeSyncInfo.getNumEntries();
+                report->localAverage = call TimeSyncInfo.getSyncPoint();
+                report->offsetAverage = call TimeSyncInfo.getOffset();
+
+                locked = TRUE;
+                call RandomTimer.startOneShot(call Random.rand16() % (64));
+            }
+        }
+
+        return msgPtr;
+    }
+
+    event void RandomTimer.fired()
+    {
+#ifdef LOW_POWER_LISTENING
+        call LowPowerListening.setRxSleepInterval(&msg, LPL_INTERVAL);
+#endif
+        if(locked && (call AMSend.send(4000, &msg, sizeof(test_ftsp_msg_t)) == SUCCESS)){
+            call Leds.led2On();
+        } else {
+            locked = FALSE;
+        }
+    }
+
+    event void AMSend.sendDone(message_t* ptr, error_t success) {
+        locked = FALSE;
+        call Leds.led2Off();
+        return;
+    }
+
+    event void RadioControl.startDone(error_t err) {
+#ifdef LOW_POWER_LISTENING
+        call LowPowerListening.setLocalSleepInterval(LPL_INTERVAL);
+#endif
+    }
+    event void RadioControl.stopDone(error_t error){}
+}
diff --git a/apps/tests/TestFtsp/FtspLpl/TestFtspMsg.py b/apps/tests/TestFtsp/FtspLpl/TestFtspMsg.py
new file mode 100755 (executable)
index 0000000..0223c4d
--- /dev/null
@@ -0,0 +1,744 @@
+#
+# This class is automatically generated by mig. DO NOT EDIT THIS FILE.
+# This class implements a Python interface to the 'TestFtspMsg'
+# message type.
+#
+
+import tinyos.message.Message
+
+# The default size of this message type in bytes.
+DEFAULT_MESSAGE_SIZE = 33
+
+# The Active Message type associated with this message.
+AM_TYPE = 137
+
+class TestFtspMsg(tinyos.message.Message.Message):
+    # Create a new TestFtspMsg of size 33.
+    def __init__(self, data="", addr=None, gid=None, base_offset=0, data_length=33):
+        tinyos.message.Message.Message.__init__(self, data, addr, gid, base_offset, data_length)
+        self.amTypeSet(AM_TYPE)
+
+    # Get AM_TYPE
+    def get_amType(cls):
+        return AM_TYPE
+
+    get_amType = classmethod(get_amType)
+
+    #
+    # Return a String representation of this message. Includes the
+    # message type name and the non-indexed field values.
+    #
+    def __str__(self):
+        s = "Message <TestFtspMsg> \n"
+        try:
+            s += "  [src_addr=0x%x]\n" % (self.get_src_addr())
+        except:
+            pass
+        try:
+            s += "  [counter=0x%x]\n" % (self.get_counter())
+        except:
+            pass
+        try:
+            s += "  [local_rx_timestamp=0x%x]\n" % (self.get_local_rx_timestamp())
+        except:
+            pass
+        try:
+            s += "  [global_rx_timestamp=0x%x]\n" % (self.get_global_rx_timestamp())
+        except:
+            pass
+        try:
+            s += "  [skew_times_1000000=0x%x]\n" % (self.get_skew_times_1000000())
+        except:
+            pass
+        try:
+            s += "  [skew=0x%x]\n" % (self.get_skew())
+        except:
+            pass
+        try:
+            s += "  [is_synced=0x%x]\n" % (self.get_is_synced())
+        except:
+            pass
+        try:
+            s += "  [ftsp_root_addr=0x%x]\n" % (self.get_ftsp_root_addr())
+        except:
+            pass
+        try:
+            s += "  [ftsp_seq=0x%x]\n" % (self.get_ftsp_seq())
+        except:
+            pass
+        try:
+            s += "  [ftsp_table_entries=0x%x]\n" % (self.get_ftsp_table_entries())
+        except:
+            pass
+        try:
+            s += "  [localAverage=0x%x]\n" % (self.get_localAverage())
+        except:
+            pass
+        try:
+            s += "  [offsetAverage=0x%x]\n" % (self.get_offsetAverage())
+        except:
+            pass
+        return s
+
+    # Message-type-specific access methods appear below.
+
+    #
+    # Accessor methods for field: src_addr
+    #   Field type: int
+    #   Offset (bits): 0
+    #   Size (bits): 16
+    #
+
+    #
+    # Return whether the field 'src_addr' is signed (False).
+    #
+    def isSigned_src_addr(self):
+        return False
+
+    #
+    # Return whether the field 'src_addr' is an array (False).
+    #
+    def isArray_src_addr(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'src_addr'
+    #
+    def offset_src_addr(self):
+        return (0 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'src_addr'
+    #
+    def offsetBits_src_addr(self):
+        return 0
+
+    #
+    # Return the value (as a int) of the field 'src_addr'
+    #
+    def get_src_addr(self):
+        return self.getUIntElement(self.offsetBits_src_addr(), 16, 1)
+
+    #
+    # Set the value of the field 'src_addr'
+    #
+    def set_src_addr(self, value):
+        self.setUIntElement(self.offsetBits_src_addr(), 16, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'src_addr'
+    #
+    def size_src_addr(self):
+        return (16 / 8)
+
+    #
+    # Return the size, in bits, of the field 'src_addr'
+    #
+    def sizeBits_src_addr(self):
+        return 16
+
+    #
+    # Accessor methods for field: counter
+    #   Field type: int
+    #   Offset (bits): 16
+    #   Size (bits): 16
+    #
+
+    #
+    # Return whether the field 'counter' is signed (False).
+    #
+    def isSigned_counter(self):
+        return False
+
+    #
+    # Return whether the field 'counter' is an array (False).
+    #
+    def isArray_counter(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'counter'
+    #
+    def offset_counter(self):
+        return (16 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'counter'
+    #
+    def offsetBits_counter(self):
+        return 16
+
+    #
+    # Return the value (as a int) of the field 'counter'
+    #
+    def get_counter(self):
+        return self.getUIntElement(self.offsetBits_counter(), 16, 1)
+
+    #
+    # Set the value of the field 'counter'
+    #
+    def set_counter(self, value):
+        self.setUIntElement(self.offsetBits_counter(), 16, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'counter'
+    #
+    def size_counter(self):
+        return (16 / 8)
+
+    #
+    # Return the size, in bits, of the field 'counter'
+    #
+    def sizeBits_counter(self):
+        return 16
+
+    #
+    # Accessor methods for field: local_rx_timestamp
+    #   Field type: long
+    #   Offset (bits): 32
+    #   Size (bits): 32
+    #
+
+    #
+    # Return whether the field 'local_rx_timestamp' is signed (False).
+    #
+    def isSigned_local_rx_timestamp(self):
+        return False
+
+    #
+    # Return whether the field 'local_rx_timestamp' is an array (False).
+    #
+    def isArray_local_rx_timestamp(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'local_rx_timestamp'
+    #
+    def offset_local_rx_timestamp(self):
+        return (32 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'local_rx_timestamp'
+    #
+    def offsetBits_local_rx_timestamp(self):
+        return 32
+
+    #
+    # Return the value (as a long) of the field 'local_rx_timestamp'
+    #
+    def get_local_rx_timestamp(self):
+        return self.getUIntElement(self.offsetBits_local_rx_timestamp(), 32, 1)
+
+    #
+    # Set the value of the field 'local_rx_timestamp'
+    #
+    def set_local_rx_timestamp(self, value):
+        self.setUIntElement(self.offsetBits_local_rx_timestamp(), 32, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'local_rx_timestamp'
+    #
+    def size_local_rx_timestamp(self):
+        return (32 / 8)
+
+    #
+    # Return the size, in bits, of the field 'local_rx_timestamp'
+    #
+    def sizeBits_local_rx_timestamp(self):
+        return 32
+
+    #
+    # Accessor methods for field: global_rx_timestamp
+    #   Field type: long
+    #   Offset (bits): 64
+    #   Size (bits): 32
+    #
+
+    #
+    # Return whether the field 'global_rx_timestamp' is signed (False).
+    #
+    def isSigned_global_rx_timestamp(self):
+        return False
+
+    #
+    # Return whether the field 'global_rx_timestamp' is an array (False).
+    #
+    def isArray_global_rx_timestamp(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'global_rx_timestamp'
+    #
+    def offset_global_rx_timestamp(self):
+        return (64 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'global_rx_timestamp'
+    #
+    def offsetBits_global_rx_timestamp(self):
+        return 64
+
+    #
+    # Return the value (as a long) of the field 'global_rx_timestamp'
+    #
+    def get_global_rx_timestamp(self):
+        return self.getUIntElement(self.offsetBits_global_rx_timestamp(), 32, 1)
+
+    #
+    # Set the value of the field 'global_rx_timestamp'
+    #
+    def set_global_rx_timestamp(self, value):
+        self.setUIntElement(self.offsetBits_global_rx_timestamp(), 32, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'global_rx_timestamp'
+    #
+    def size_global_rx_timestamp(self):
+        return (32 / 8)
+
+    #
+    # Return the size, in bits, of the field 'global_rx_timestamp'
+    #
+    def sizeBits_global_rx_timestamp(self):
+        return 32
+
+    #
+    # Accessor methods for field: skew_times_1000000
+    #   Field type: int
+    #   Offset (bits): 96
+    #   Size (bits): 32
+    #
+
+    #
+    # Return whether the field 'skew_times_1000000' is signed (False).
+    #
+    def isSigned_skew_times_1000000(self):
+        return False
+
+    #
+    # Return whether the field 'skew_times_1000000' is an array (False).
+    #
+    def isArray_skew_times_1000000(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'skew_times_1000000'
+    #
+    def offset_skew_times_1000000(self):
+        return (96 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'skew_times_1000000'
+    #
+    def offsetBits_skew_times_1000000(self):
+        return 96
+
+    #
+    # Return the value (as a int) of the field 'skew_times_1000000'
+    #
+    def get_skew_times_1000000(self):
+        return self.getSIntElement(self.offsetBits_skew_times_1000000(), 32, 1)
+
+    #
+    # Set the value of the field 'skew_times_1000000'
+    #
+    def set_skew_times_1000000(self, value):
+        self.setSIntElement(self.offsetBits_skew_times_1000000(), 32, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'skew_times_1000000'
+    #
+    def size_skew_times_1000000(self):
+        return (32 / 8)
+
+    #
+    # Return the size, in bits, of the field 'skew_times_1000000'
+    #
+    def sizeBits_skew_times_1000000(self):
+        return 32
+
+    #
+    # Accessor methods for field: skew
+    #   Field type: int
+    #   Offset (bits): 128
+    #   Size (bits): 32
+    #
+
+    #
+    # Return whether the field 'skew' is signed (False).
+    #
+    def isSigned_skew(self):
+        return False
+
+    #
+    # Return whether the field 'skew' is an array (False).
+    #
+    def isArray_skew(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'skew'
+    #
+    def offset_skew(self):
+        return (128 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'skew'
+    #
+    def offsetBits_skew(self):
+        return 128
+
+    #
+    # Return the value (as a int) of the field 'skew'
+    #
+    def get_skew(self):
+        return self.getFloatElement(self.offsetBits_skew(), 32, 0)
+
+    #
+    # Set the value of the field 'skew'
+    #
+    def set_skew(self, value):
+        self.setSIntElement(self.offsetBits_skew(), 32, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'skew'
+    #
+    def size_skew(self):
+        return (32 / 8)
+
+    #
+    # Return the size, in bits, of the field 'skew'
+    #
+    def sizeBits_skew(self):
+        return 32
+
+    #
+    # Accessor methods for field: is_synced
+    #   Field type: short
+    #   Offset (bits): 160
+    #   Size (bits): 8
+    #
+
+    #
+    # Return whether the field 'is_synced' is signed (False).
+    #
+    def isSigned_is_synced(self):
+        return False
+
+    #
+    # Return whether the field 'is_synced' is an array (False).
+    #
+    def isArray_is_synced(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'is_synced'
+    #
+    def offset_is_synced(self):
+        return (160 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'is_synced'
+    #
+    def offsetBits_is_synced(self):
+        return 160
+
+    #
+    # Return the value (as a short) of the field 'is_synced'
+    #
+    def get_is_synced(self):
+        return self.getUIntElement(self.offsetBits_is_synced(), 8, 1)
+
+    #
+    # Set the value of the field 'is_synced'
+    #
+    def set_is_synced(self, value):
+        self.setUIntElement(self.offsetBits_is_synced(), 8, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'is_synced'
+    #
+    def size_is_synced(self):
+        return (8 / 8)
+
+    #
+    # Return the size, in bits, of the field 'is_synced'
+    #
+    def sizeBits_is_synced(self):
+        return 8
+
+    #
+    # Accessor methods for field: ftsp_root_addr
+    #   Field type: int
+    #   Offset (bits): 168
+    #   Size (bits): 16
+    #
+
+    #
+    # Return whether the field 'ftsp_root_addr' is signed (False).
+    #
+    def isSigned_ftsp_root_addr(self):
+        return False
+
+    #
+    # Return whether the field 'ftsp_root_addr' is an array (False).
+    #
+    def isArray_ftsp_root_addr(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'ftsp_root_addr'
+    #
+    def offset_ftsp_root_addr(self):
+        return (168 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'ftsp_root_addr'
+    #
+    def offsetBits_ftsp_root_addr(self):
+        return 168
+
+    #
+    # Return the value (as a int) of the field 'ftsp_root_addr'
+    #
+    def get_ftsp_root_addr(self):
+        return self.getUIntElement(self.offsetBits_ftsp_root_addr(), 16, 1)
+
+    #
+    # Set the value of the field 'ftsp_root_addr'
+    #
+    def set_ftsp_root_addr(self, value):
+        self.setUIntElement(self.offsetBits_ftsp_root_addr(), 16, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'ftsp_root_addr'
+    #
+    def size_ftsp_root_addr(self):
+        return (16 / 8)
+
+    #
+    # Return the size, in bits, of the field 'ftsp_root_addr'
+    #
+    def sizeBits_ftsp_root_addr(self):
+        return 16
+
+    #
+    # Accessor methods for field: ftsp_seq
+    #   Field type: short
+    #   Offset (bits): 184
+    #   Size (bits): 8
+    #
+
+    #
+    # Return whether the field 'ftsp_seq' is signed (False).
+    #
+    def isSigned_ftsp_seq(self):
+        return False
+
+    #
+    # Return whether the field 'ftsp_seq' is an array (False).
+    #
+    def isArray_ftsp_seq(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'ftsp_seq'
+    #
+    def offset_ftsp_seq(self):
+        return (184 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'ftsp_seq'
+    #
+    def offsetBits_ftsp_seq(self):
+        return 184
+
+    #
+    # Return the value (as a short) of the field 'ftsp_seq'
+    #
+    def get_ftsp_seq(self):
+        return self.getUIntElement(self.offsetBits_ftsp_seq(), 8, 1)
+
+    #
+    # Set the value of the field 'ftsp_seq'
+    #
+    def set_ftsp_seq(self, value):
+        self.setUIntElement(self.offsetBits_ftsp_seq(), 8, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'ftsp_seq'
+    #
+    def size_ftsp_seq(self):
+        return (8 / 8)
+
+    #
+    # Return the size, in bits, of the field 'ftsp_seq'
+    #
+    def sizeBits_ftsp_seq(self):
+        return 8
+
+    #
+    # Accessor methods for field: ftsp_table_entries
+    #   Field type: short
+    #   Offset (bits): 192
+    #   Size (bits): 8
+    #
+
+    #
+    # Return whether the field 'ftsp_table_entries' is signed (False).
+    #
+    def isSigned_ftsp_table_entries(self):
+        return False
+
+    #
+    # Return whether the field 'ftsp_table_entries' is an array (False).
+    #
+    def isArray_ftsp_table_entries(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'ftsp_table_entries'
+    #
+    def offset_ftsp_table_entries(self):
+        return (192 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'ftsp_table_entries'
+    #
+    def offsetBits_ftsp_table_entries(self):
+        return 192
+
+    #
+    # Return the value (as a short) of the field 'ftsp_table_entries'
+    #
+    def get_ftsp_table_entries(self):
+        return self.getUIntElement(self.offsetBits_ftsp_table_entries(), 8, 1)
+
+    #
+    # Set the value of the field 'ftsp_table_entries'
+    #
+    def set_ftsp_table_entries(self, value):
+        self.setUIntElement(self.offsetBits_ftsp_table_entries(), 8, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'ftsp_table_entries'
+    #
+    def size_ftsp_table_entries(self):
+        return (8 / 8)
+
+    #
+    # Return the size, in bits, of the field 'ftsp_table_entries'
+    #
+    def sizeBits_ftsp_table_entries(self):
+        return 8
+
+    #
+    # Accessor methods for field: localAverage
+    #   Field type: long
+    #   Offset (bits): 200
+    #   Size (bits): 32
+    #
+
+    #
+    # Return whether the field 'localAverage' is signed (False).
+    #
+    def isSigned_localAverage(self):
+        return False
+
+    #
+    # Return whether the field 'localAverage' is an array (False).
+    #
+    def isArray_localAverage(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'localAverage'
+    #
+    def offset_localAverage(self):
+        return (200 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'localAverage'
+    #
+    def offsetBits_localAverage(self):
+        return 200
+
+    #
+    # Return the value (as a long) of the field 'localAverage'
+    #
+    def get_localAverage(self):
+        return self.getUIntElement(self.offsetBits_localAverage(), 32, 1)
+
+    #
+    # Set the value of the field 'localAverage'
+    #
+    def set_localAverage(self, value):
+        self.setUIntElement(self.offsetBits_localAverage(), 32, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'localAverage'
+    #
+    def size_localAverage(self):
+        return (32 / 8)
+
+    #
+    # Return the size, in bits, of the field 'localAverage'
+    #
+    def sizeBits_localAverage(self):
+        return 32
+
+    #
+    # Accessor methods for field: offsetAverage
+    #   Field type: int
+    #   Offset (bits): 232
+    #   Size (bits): 32
+    #
+
+    #
+    # Return whether the field 'offsetAverage' is signed (False).
+    #
+    def isSigned_offsetAverage(self):
+        return False
+
+    #
+    # Return whether the field 'offsetAverage' is an array (False).
+    #
+    def isArray_offsetAverage(self):
+        return False
+
+    #
+    # Return the offset (in bytes) of the field 'offsetAverage'
+    #
+    def offset_offsetAverage(self):
+        return (232 / 8)
+
+    #
+    # Return the offset (in bits) of the field 'offsetAverage'
+    #
+    def offsetBits_offsetAverage(self):
+        return 232
+
+    #
+    # Return the value (as a int) of the field 'offsetAverage'
+    #
+    def get_offsetAverage(self):
+        return self.getSIntElement(self.offsetBits_offsetAverage(), 32, 1)
+
+    #
+    # Set the value of the field 'offsetAverage'
+    #
+    def set_offsetAverage(self, value):
+        self.setSIntElement(self.offsetBits_offsetAverage(), 32, value, 1)
+
+    #
+    # Return the size, in bytes, of the field 'offsetAverage'
+    #
+    def size_offsetAverage(self):
+        return (32 / 8)
+
+    #
+    # Return the size, in bits, of the field 'offsetAverage'
+    #
+    def sizeBits_offsetAverage(self):
+        return 32
+
diff --git a/apps/tests/TestFtsp/FtspLplBeaconer/Makefile b/apps/tests/TestFtsp/FtspLplBeaconer/Makefile
new file mode 100755 (executable)
index 0000000..a935c01
--- /dev/null
@@ -0,0 +1,7 @@
+COMPONENT=RadioCountToLedsAppC
+
+CFLAGS += -DLPL_INTERVAL=200
+CFLAGS += -DLOW_POWER_LISTENING
+
+include $(MAKERULES)
+
diff --git a/apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLeds.h b/apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLeds.h
new file mode 100755 (executable)
index 0000000..8d29f3f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * "Copyright (c) 2004-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."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+#ifndef RADIO_COUNT_TO_LEDS_H
+#define RADIO_COUNT_TO_LEDS_H
+
+typedef nx_struct radio_count_msg {
+  nx_uint16_t counter;
+} radio_count_msg_t;
+
+enum {
+  AM_RADIO_COUNT_MSG = 6,
+};
+
+#endif
diff --git a/apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLedsAppC.nc b/apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLedsAppC.nc
new file mode 100755 (executable)
index 0000000..13f3667
--- /dev/null
@@ -0,0 +1,74 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "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."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+#include "RadioCountToLeds.h"
+#include "Timer.h"
+
+/**
+ * Configuration for the RadioCountToLeds application. RadioCountToLeds 
+ * maintains a 4Hz counter, broadcasting its value in an AM packet 
+ * every time it gets updated. A RadioCountToLeds node that hears a counter 
+ * displays the bottom three bits on its LEDs. This application is a useful 
+ * test to show that basic AM communication and timers work.
+ *
+ * @author Philip Levis
+ * @date   June 6 2005
+ */
+
+configuration RadioCountToLedsAppC {}
+implementation {
+  components MainC, new RadioCountToLedsC(T32khz) as App, LedsC;
+  components new AMReceiverC(AM_RADIO_COUNT_MSG);
+  components new TimerMilliC();
+  components TimeSyncMessageC as ActiveMessageC;
+  
+  App.Boot -> MainC.Boot;
+  
+  App.Receive -> AMReceiverC;
+  App.AMSend -> ActiveMessageC.TimeSyncAMSend32khz[AM_RADIO_COUNT_MSG];
+  App.AMControl -> ActiveMessageC;
+  App.Leds -> LedsC;
+  App.MilliTimer -> TimerMilliC;
+  App.Packet -> ActiveMessageC;
+
+  components Counter32khz32C, new CounterToLocalTimeC(T32khz) as LocalTime32khzC;
+  LocalTime32khzC.Counter -> Counter32khz32C;
+  App.LocalTime     -> LocalTime32khzC;
+
+
+#ifdef LOW_POWER_LISTENING
+  components CC2420ActiveMessageC;
+  App.LowPowerListening -> CC2420ActiveMessageC;
+#endif
+
+}
+
+
diff --git a/apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLedsC.nc b/apps/tests/TestFtsp/FtspLplBeaconer/RadioCountToLedsC.nc
new file mode 100755 (executable)
index 0000000..436c4ed
--- /dev/null
@@ -0,0 +1,148 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "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."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+#include "Timer.h"
+#include "RadioCountToLeds.h"
+/**
+ * Implementation of the RadioCountToLeds application. RadioCountToLeds 
+ * maintains a 4Hz counter, broadcasting its value in an AM packet 
+ * every time it gets updated. A RadioCountToLeds node that hears a counter 
+ * displays the bottom three bits on its LEDs. This application is a useful 
+ * test to show that basic AM communication and timers work.
+ *
+ * @author Philip Levis
+ * @date   June 6 2005
+ */
+
+generic module RadioCountToLedsC(typedef precision_tag) @safe() {
+  uses {
+    interface Leds;
+    interface Boot;
+    interface Receive;
+    interface TimeSyncAMSend<precision_tag,uint32_t> as AMSend;
+    interface Timer<TMilli> as MilliTimer;
+    interface SplitControl as AMControl;
+    interface Packet;
+
+    interface LocalTime<precision_tag> as LocalTime;
+
+
+#ifdef LOW_POWER_LISTENING
+    interface LowPowerListening;
+#endif
+
+  }
+}
+implementation {
+
+  message_t packet;
+
+  bool locked;
+  uint16_t counter = 0;
+  
+  event void Boot.booted() {
+    call AMControl.start();
+  }
+
+  event void AMControl.startDone(error_t err) {
+    if (err == SUCCESS) {
+      call MilliTimer.startPeriodic(2*1024);
+    }
+    else {
+      call AMControl.start();
+    }
+  }
+
+  event void AMControl.stopDone(error_t err) {
+    // do nothing
+  }
+  
+  event void MilliTimer.fired() {
+      uint32_t time = call LocalTime.get();
+    counter++;
+    dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);
+    if (locked) {
+      return;
+    }
+    else {
+      radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t));
+      if (rcm == NULL) {
+       return;
+      }
+
+      rcm->counter = counter;
+#ifdef LOW_POWER_LISTENING
+      call LowPowerListening.setRxSleepInterval(&packet, LPL_INTERVAL);
+#endif
+      
+      if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t), time) == SUCCESS) {
+       dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n", counter); 
+       locked = TRUE;
+      }
+    }
+  }
+
+  event message_t* Receive.receive(message_t* bufPtr, 
+                                  void* payload, uint8_t len) {
+    dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
+    if (len != sizeof(radio_count_msg_t)) {return bufPtr;}
+    else {
+      radio_count_msg_t* rcm = (radio_count_msg_t*)payload;
+      if (rcm->counter & 0x1) {
+       call Leds.led0On();
+      }
+      else {
+       call Leds.led0Off();
+      }
+      if (rcm->counter & 0x2) {
+       call Leds.led1On();
+      }
+      else {
+       call Leds.led1Off();
+      }
+      if (rcm->counter & 0x4) {
+       call Leds.led2On();
+      }
+      else {
+       call Leds.led2Off();
+      }
+      return bufPtr;
+    }
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
+    if (&packet == bufPtr) {
+      locked = FALSE;
+    }
+  }
+
+}