]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - apps/MultihopOscilloscope/MultihopOscilloscopeC.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / apps / MultihopOscilloscope / MultihopOscilloscopeC.nc
index 78e6a88470d225f9c0ea1dd3a45a37710045cdaf..5179b3500d46aa8a37c9c3ba2a40a0e1a22d8687 100644 (file)
@@ -19,7 +19,7 @@
 #include "Timer.h"
 #include "MultihopOscilloscope.h"
 
-module MultihopOscilloscopeC {
+module MultihopOscilloscopeC @safe(){
   uses {
     // Interfaces for initialization:
     interface Boot;
@@ -35,6 +35,9 @@ module MultihopOscilloscopeC {
     interface CollectionPacket;
     interface RootControl;
 
+    interface Queue<message_t *> as UARTQueue;
+    interface Pool<message_t> as UARTMessagePool;
+
     // Miscalleny:
     interface Timer<TMilli>;
     interface Read<uint16_t>;
@@ -74,6 +77,7 @@ implementation {
   event void Boot.booted() {
     local.interval = DEFAULT_INTERVAL;
     local.id = TOS_NODE_ID;
+    local.version = 0;
 
     // Beginning our initialization phases:
     if (call RadioControl.start() != SUCCESS)
@@ -106,6 +110,7 @@ implementation {
   }
 
   static void startTimer() {
+    if (call Timer.isRunning()) call Timer.stop();
     call Timer.startPeriodic(local.interval);
     reading = 0;
   }
@@ -120,18 +125,43 @@ implementation {
   //
   event message_t*
   Receive.receive(message_t* msg, void *payload, uint8_t len) {
+    oscilloscope_t* in = (oscilloscope_t*)payload;
+    oscilloscope_t* out;
     if (uartbusy == FALSE) {
-      oscilloscope_t* in = (oscilloscope_t*)payload;
-      oscilloscope_t* out = (oscilloscope_t*)call SerialSend.getPayload(&uartbuf);
-      if (len != sizeof(oscilloscope_t)) {
+      out = (oscilloscope_t*)call SerialSend.getPayload(&uartbuf, sizeof(oscilloscope_t));
+      if (len != sizeof(oscilloscope_t) || out == NULL) {
        return msg;
       }
       else {
        memcpy(out, in, sizeof(oscilloscope_t));
       }
-      uartbusy = TRUE;
       uartlen = sizeof(oscilloscope_t);
       post uartSendTask();
+    } else {
+      // The UART is busy; queue up messages and service them when the
+      // UART becomes free.
+      message_t *newmsg = call UARTMessagePool.get();
+      if (newmsg == NULL) {
+        // drop the message on the floor if we run out of queue space.
+        report_problem();
+        return msg;
+      }
+
+      //Serial port busy, so enqueue.
+      out = (oscilloscope_t*)call SerialSend.getPayload(newmsg, sizeof(oscilloscope_t));
+      if (out == NULL) {
+       return msg;
+      }
+      memcpy(out, in, sizeof(oscilloscope_t));
+
+      if (call UARTQueue.enqueue(newmsg) != SUCCESS) {
+        // drop the message on the floor and hang if we run out of
+        // queue space without running out of queue space first (this
+        // should not occur).
+        call UARTMessagePool.put(newmsg);
+        fatal_problem();
+        return msg;
+      }
     }
 
     return msg;
@@ -139,9 +169,31 @@ implementation {
 
   task void uartSendTask() {
     if (call SerialSend.send(0xffff, &uartbuf, uartlen) != SUCCESS) {
-      uartbusy = FALSE;
+      report_problem();
+    } else {
+      uartbusy = TRUE;
     }
   }
+
+  event void SerialSend.sendDone(message_t *msg, error_t error) {
+    uartbusy = FALSE;
+    if (call UARTQueue.empty() == FALSE) {
+      // We just finished a UART send, and the uart queue is
+      // non-empty.  Let's start a new one.
+      message_t *queuemsg = call UARTQueue.dequeue();
+      if (queuemsg == NULL) {
+        fatal_problem();
+        return;
+      }
+      memcpy(&uartbuf, queuemsg, sizeof(message_t));
+      if (call UARTMessagePool.put(queuemsg) != SUCCESS) {
+        fatal_problem();
+        return;
+      }
+      post uartSendTask();
+    }
+  }
+
   //
   // Overhearing other traffic in the network.
   //
@@ -175,7 +227,11 @@ implementation {
   event void Timer.fired() {
     if (reading == NREADINGS) {
       if (!sendbusy) {
-       oscilloscope_t *o = (oscilloscope_t *)call Send.getPayload(&sendbuf);
+       oscilloscope_t *o = (oscilloscope_t *)call Send.getPayload(&sendbuf, sizeof(oscilloscope_t));
+       if (o == NULL) {
+         fatal_problem();
+         return;
+       }
        memcpy(o, &local, sizeof(local));
        if (call Send.send(&sendbuf, sizeof(local)) == SUCCESS)
          sendbusy = TRUE;
@@ -212,9 +268,6 @@ implementation {
     local.readings[reading++] = data;
   }
 
-  event void SerialSend.sendDone(message_t *msg, error_t error) {
-    uartbusy = FALSE;
-  }
 
   // Use LEDs to report various status issues.
   static void fatal_problem() {