#include "Timer.h"
#include "MultihopOscilloscope.h"
-module MultihopOscilloscopeC {
+module MultihopOscilloscopeC @safe(){
uses {
// Interfaces for initialization:
interface Boot;
interface CollectionPacket;
interface RootControl;
+ interface Queue<message_t *> as UARTQueue;
+ interface Pool<message_t> as UARTMessagePool;
+
// Miscalleny:
interface Timer<TMilli>;
interface Read<uint16_t>;
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)
}
static void startTimer() {
+ if (call Timer.isRunning()) call Timer.stop();
call Timer.startPeriodic(local.interval);
reading = 0;
}
//
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;
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.
//
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;
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() {