--- /dev/null
+COMPONENT=TestNetworkLplAppC
+
+CFLAGS += -DLOW_POWER_LISTENING
+CFLAGS += -DLPL_DEF_LOCAL_WAKEUP=512
+CFLAGS += -DLPL_DEF_REMOTE_WAKEUP=512
+CFLAGS += -DDELAY_AFTER_RECEIVE=20
+
+# CFLAGS += -DCC2420_DEF_CHANNEL=12
+CFLAGS += -I.
+CFLAGS += -I../TestNetwork
+
+CFLAGS += -I$(TOSDIR)/lib/net \
+ -I$(TOSDIR)/lib/net/drip \
+ -I$(TOSDIR)/lib/net/4bitle \
+ -I$(TOSDIR)/lib/net/ctp -DNO_DEBUG
+
+TFLAGS += -I$(TOSDIR)/../apps/tests/TestDissemination \
+ -I$(TOSDIR)/../support/sdk/c \
+ -I$(TOSDIR)/types \
+ -I.
+
+LIBMOTE = $(TOSDIR)/../support/sdk/c/libmote.a
+#BUILD_EXTRA_DEPS += tn-injector #tn-listener
+LISTEN_OBJS = collection_msg.o test_network_msg.o tn-listener.o $(LIBMOTE)
+INJECT_OBJS = set_rate_msg.o tn-injector.o collection_debug_msg.o $(LIBMOTE)
+
+# arguments: output filename stem, input filename, struct name
+define mig_templ
+MIGFILES += $(1).c $(1).h $(1).java $(1).o
+$(1).c:
+ mig -o $(1).h c -target=$$(PLATFORM) $$(CFLAGS) $$(TFLAGS) $(2) $(3)
+$(1).java:
+ mig -o $(1).java java -target=$$(PLATFORM) $$(CFLAGS) $$(TFLAGS) $(2) $(3)
+endef
+
+$(eval $(call mig_templ,test_network_msg,TestNetwork.h,TestNetworkMsg))
+$(eval $(call mig_templ,set_rate_msg,$(TOSDIR)/lib/net/DisseminationEngine.h,dissemination_message))
+$(eval $(call mig_templ,collection_debug_msg,$(TOSDIR)/lib/net/collection/CollectionDebugMsg.h,CollectionDebugMsg))
+
+%.o: %.c
+ gcc -v $(TFLAGS) $(CFLAGS) -c -o $@ $<
+
+tn-listener: $(LISTEN_OBJS)
+ gcc -v $(TFLAGS) $(CFLAGS) -o $@ $(LISTEN_OBJS)
+
+tn-injector: $(INJECT_OBJS)
+ gcc -v $(TFLAGS) $(CFLAGS) -o $@ $(INJECT_OBJS)
+
+#tn-listener.o: tn-listener.c
+# gcc $(TFLAGS) $(CFLAGS) -c -o $@ $<
+
+tn-injector.o: tn-injector.c test_network_msg.c
+ gcc $(TFLAGS) $(CFLAGS) -c -o $@ $<
+
+#test_network_msg.c:
+# mig -o test_network_msg.h c -target=$(PLATFORM) $(CFLAGS) $(TFLAGS) TestNetwork.h TestNetworkMsg
+
+#set_rate_msg.c:
+# mig -o set_rate_msg.h c -target=$(PLATFORM) $(CFLAGS) $(TFLAGS) $(TOSDIR)/lib/net/DisseminationEngine.h dissemination_message
+
+#set_rate_msg.o: set_rate_msg.c
+# gcc $(CFLAGS) $(TFLAGS) -c -o $@ $<
+
+#test_network_msg.o: test_network_msg.c
+# gcc $(CFLAGS) $(TFLAGS) -c -o $@ $<
+
+#collection_msg.c:
+# mig -o collection_msg.h c -target=$(PLATFORM) $(CFLAGS) $(TFLAGS) $(TOSDIR)/lib/net/collection/ForwardingEngine.h collection_header
+
+include $(MAKERULES)
+
+migclean:
+ rm -rf $(MIGFILES)
--- /dev/null
+/**
+ * TestNetworkLplC exercises the basic networking layers, collection and
+ * dissemination. The application samples DemoSensorC at a basic rate
+ * and sends packets up a collection tree. The rate is configurable
+ * through dissemination.
+ *
+ * See TEP118: Dissemination, TEP 119: Collection, and TEP 123: The
+ * Collection Tree Protocol for details.
+ *
+ * @author Philip Levis
+ * @version $Revision$ $Date$
+ */
+#include "TestNetwork.h"
+#include "Ctp.h"
+
+configuration TestNetworkLplAppC {}
+implementation {
+ components TestNetworkLplC, MainC, LedsC, ActiveMessageC;
+ components DisseminationC;
+ components new DisseminatorC(uint32_t, SAMPLE_RATE_KEY) as Object32C;
+ components CollectionC as Collector;
+ components new CollectionSenderC(CL_TEST);
+ components new TimerMilliC();
+ components new DemoSensorC();
+ components new SerialAMSenderC(CL_TEST);
+ components SerialActiveMessageC;
+#ifndef NO_DEBUG
+ components new SerialAMSenderC(AM_COLLECTION_DEBUG) as UARTSender;
+ components UARTDebugSenderP as DebugSender;
+#endif
+ components RandomC;
+ components new QueueC(message_t*, 12);
+ components new PoolC(message_t, 12);
+
+ TestNetworkLplC.Boot -> MainC;
+ TestNetworkLplC.RadioControl -> ActiveMessageC;
+ TestNetworkLplC.SerialControl -> SerialActiveMessageC;
+ TestNetworkLplC.RoutingControl -> Collector;
+ TestNetworkLplC.DisseminationControl -> DisseminationC;
+ TestNetworkLplC.Leds -> LedsC;
+ TestNetworkLplC.Timer -> TimerMilliC;
+ TestNetworkLplC.DisseminationPeriod -> Object32C;
+ TestNetworkLplC.Send -> CollectionSenderC;
+ TestNetworkLplC.ReadSensor -> DemoSensorC;
+ TestNetworkLplC.RootControl -> Collector;
+ TestNetworkLplC.Receive -> Collector.Receive[CL_TEST];
+ TestNetworkLplC.UARTSend -> SerialAMSenderC.AMSend;
+ TestNetworkLplC.CollectionPacket -> Collector;
+ TestNetworkLplC.CtpInfo -> Collector;
+ TestNetworkLplC.CtpCongestion -> Collector;
+ TestNetworkLplC.Random -> RandomC;
+ TestNetworkLplC.Pool -> PoolC;
+ TestNetworkLplC.Queue -> QueueC;
+ TestNetworkLplC.RadioPacket -> ActiveMessageC;
+ TestNetworkLplC.LowPowerListening -> ActiveMessageC;
+
+#ifndef NO_DEBUG
+ components new PoolC(message_t, 10) as DebugMessagePool;
+ components new QueueC(message_t*, 10) as DebugSendQueue;
+ DebugSender.Boot -> MainC;
+ DebugSender.UARTSend -> UARTSender;
+ DebugSender.MessagePool -> DebugMessagePool;
+ DebugSender.SendQueue -> DebugSendQueue;
+ Collector.CollectionDebug -> DebugSender;
+ TestNetworkLplC.CollectionDebug -> DebugSender;
+#endif
+ TestNetworkLplC.AMPacket -> ActiveMessageC;
+}
--- /dev/null
+/**
+ * TestNetworkC exercises the basic networking layers, collection and
+ * dissemination. The application samples DemoSensorC at a basic rate
+ * and sends packets up a collection tree. The rate is configurable
+ * through dissemination. The default send rate is every 10s.
+ *
+ * See TEP118: Dissemination and TEP 119: Collection for details.
+ *
+ * @author Philip Levis
+ * @version $Revision$ $Date$
+ */
+
+#include <Timer.h>
+#include "TestNetwork.h"
+#include "CtpDebugMsg.h"
+
+module TestNetworkLplC {
+ uses interface Boot;
+ uses interface SplitControl as RadioControl;
+ uses interface SplitControl as SerialControl;
+ uses interface StdControl as RoutingControl;
+ uses interface StdControl as DisseminationControl;
+ uses interface DisseminationValue<uint32_t> as DisseminationPeriod;
+ uses interface Send;
+ uses interface Leds;
+ uses interface Read<uint16_t> as ReadSensor;
+ uses interface Timer<TMilli>;
+ uses interface RootControl;
+ uses interface Receive;
+ uses interface AMSend as UARTSend;
+ uses interface CollectionPacket;
+ uses interface CtpInfo;
+ uses interface CtpCongestion;
+ uses interface Random;
+ uses interface Queue<message_t*>;
+ uses interface Pool<message_t>;
+ uses interface CollectionDebug;
+ uses interface AMPacket;
+ uses interface Packet as RadioPacket;
+ uses interface LowPowerListening;
+}
+implementation {
+ task void uartEchoTask();
+ message_t packet;
+ message_t uartpacket;
+ message_t* recvPtr = &uartpacket;
+ uint8_t msglen;
+ bool sendBusy = FALSE;
+ bool uartbusy = FALSE;
+ bool firstTimer = TRUE;
+ uint16_t seqno;
+ enum {
+ SEND_INTERVAL = 60*1024U,
+ };
+
+ event void ReadSensor.readDone(error_t err, uint16_t val) { }
+
+ event void Boot.booted() {
+ call SerialControl.start();
+ }
+ event void SerialControl.startDone(error_t err) {
+ if (TOS_NODE_ID % 500 == 0) {
+ call LowPowerListening.setLocalWakeupInterval(0);
+ }
+ call RadioControl.start();
+ }
+ event void RadioControl.startDone(error_t err) {
+ if (err != SUCCESS) {
+ call RadioControl.start();
+ }
+ else {
+ //call DisseminationControl.start();
+ call RoutingControl.start();
+ if (TOS_NODE_ID % 500 == 0) {
+ call RootControl.setRoot();
+ }
+ seqno = 0;
+ call Timer.startOneShot(call Random.rand32() % SEND_INTERVAL);
+ }
+ }
+
+ event void RadioControl.stopDone(error_t err) {}
+ event void SerialControl.stopDone(error_t err) {}
+
+ void failedSend() {
+ dbg("App", "%s: Send failed.\n", __FUNCTION__);
+ call CollectionDebug.logEvent(NET_C_DBG_1);
+ }
+
+
+ void sendMessage() {
+ TestNetworkMsg* msg = (TestNetworkMsg*)call Send.getPayload(&packet, sizeof(TestNetworkMsg));
+ uint16_t metric;
+ am_addr_t parent = 0;
+
+ call CtpInfo.getParent(&parent);
+ call CtpInfo.getEtx(&metric);
+
+ msg->source = TOS_NODE_ID;
+ msg->seqno = seqno;
+ msg->data = 0xCAFE;
+ msg->parent = parent;
+ msg->hopcount = 0;
+ msg->metric = metric;
+
+ if (call Send.send(&packet, sizeof(TestNetworkMsg)) != SUCCESS) {
+ failedSend();
+ call Leds.led0On();
+ dbg("TestNetworkC", "%s: Transmission failed.\n", __FUNCTION__);
+ }
+ else {
+ sendBusy = TRUE;
+ seqno++;
+ dbg("TestNetworkC", "%s: Transmission succeeded.\n", __FUNCTION__);
+ }
+ }
+
+
+ event void Timer.fired() {
+ uint32_t nextInt;
+ call Leds.led0Toggle();
+ dbg("TestNetworkC", "TestNetworkC: Timer fired.\n");
+ nextInt = call Random.rand32() % SEND_INTERVAL;
+ nextInt += SEND_INTERVAL >> 1;
+ call Timer.startOneShot(nextInt);
+ if (!sendBusy)
+ sendMessage();
+ }
+
+ event void Send.sendDone(message_t* m, error_t err) {
+ if (err != SUCCESS) {
+ // call Leds.led0On();
+ }
+ sendBusy = FALSE;
+ dbg("TestNetworkC", "Send completed.\n");
+ }
+
+ event void DisseminationPeriod.changed() {
+ const uint32_t* newVal = call DisseminationPeriod.get();
+ call Timer.stop();
+ call Timer.startPeriodic(*newVal);
+ }
+
+ event message_t*
+ Receive.receive(message_t* msg, void* payload, uint8_t len) {
+ dbg("TestNetworkC", "Received packet at %s from node %hhu.\n", sim_time_string(), call CollectionPacket.getOrigin(msg));
+ call Leds.led1Toggle();
+ if (!call Pool.size() <= (TEST_NETWORK_QUEUE_SIZE < 4)? 1:3) {
+ // call CtpCongestion.setClientCongested(TRUE);
+ }
+ if (!call Pool.empty() && call Queue.size() < call Queue.maxSize()) {
+ message_t* tmp = call Pool.get();
+ call Queue.enqueue(msg);
+ if (!uartbusy) {
+ post uartEchoTask();
+ }
+ return tmp;
+ }
+ return msg;
+ }
+
+ task void uartEchoTask() {
+ dbg("Traffic", "Sending packet to UART.\n");
+ if (call Queue.empty()) {
+ return;
+ }
+ else if (!uartbusy) {
+ message_t* msg = call Queue.dequeue();
+ dbg("Traffic", "Sending packet to UART.\n");
+ if (call UARTSend.send(0xffff, msg, call RadioPacket.payloadLength(msg)) == SUCCESS) {
+ uartbusy = TRUE;
+ }
+ else {
+ call CollectionDebug.logEventMsg(NET_C_DBG_2,
+ call CollectionPacket.getSequenceNumber(msg),
+ call CollectionPacket.getOrigin(msg),
+ call AMPacket.destination(msg));
+ }
+ }
+ }
+
+ event void UARTSend.sendDone(message_t *msg, error_t error) {
+ dbg("Traffic", "UART send done.\n");
+ uartbusy = FALSE;
+ call Pool.put(msg);
+ if (!call Queue.empty()) {
+ post uartEchoTask();
+ }
+ else {
+ // call CtpCongestion.setClientCongested(FALSE);
+ }
+ }
+
+ /* Default implementations for CollectionDebug calls.
+ * These allow CollectionDebug not to be wired to anything if debugging
+ * is not desired. */
+
+ default command error_t CollectionDebug.logEvent(uint8_t type) {
+ return SUCCESS;
+ }
+ default command error_t CollectionDebug.logEventSimple(uint8_t type, uint16_t arg) {
+ return SUCCESS;
+ }
+ default command error_t CollectionDebug.logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3) {
+ return SUCCESS;
+ }
+ default command error_t CollectionDebug.logEventMsg(uint8_t type, uint16_t msg, am_addr_t origin, am_addr_t node) {
+ return SUCCESS;
+ }
+ default command error_t CollectionDebug.logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t metric) {
+ return SUCCESS;
+ }
+
+}
--- /dev/null
+#!/usr/bin/env python
+
+import sys, time
+import tos
+
+class Test(tos.Packet):
+ def __init__(self, payload = None):
+ tos.Packet.__init__(self,
+ [('source', 'int', 2),
+ ('seqno', 'int', 2),
+ ('parent', 'int', 2),
+ ('metric', 'int', 2),
+ ('data', 'int', 2),
+ ('hopcount', 'int', 1),
+ ('sendCount','int', 2),
+ ('sendSuccessCount','int', 2)],
+ payload)
+
+class CtpData(tos.Packet):
+ def __init__(self, payload = None):
+ tos.Packet.__init__(self,
+ [('options', 'int', 1),
+ ('thl', 'int', 1),
+ ('etx', 'int', 2),
+ ('origin', 'int', 2),
+ ('originSeqNo', 'int', 1),
+ ('collectionId','int', 1),
+ ('data', 'blob', None)],
+ payload)
+
+if len(sys.argv) < 2:
+ print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+ sys.exit()
+
+#s = tos.Serial(sys.argv[1], int(sys.argv[2]), debug=False)
+am = tos.AM()
+
+while True:
+ p = am.read()
+ if p:
+ if p.type == 238:
+ ts = "%.4f" % time.time()
+ ctp = CtpData(p.data)
+ test = Test(ctp.data)
+ print ts, '\t', ctp
+ print ts, '\t', test
+ else:
+ print p
+