]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - apps/AntiTheft/Nodes/AntiTheftC.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / apps / AntiTheft / Nodes / AntiTheftC.nc
index e1babb39aae95e01c23ddf6d364c6ff1e8592cc2..3d502a929713062d388d1dd524f5501483391feb 100644 (file)
@@ -1,3 +1,20 @@
+// $Id$
+/*
+ * Copyright (c) 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.
+ */
+/**
+ * Main code for the anti theft demo application.
+ *
+ * @author David Gay
+ */
+#include "antitheft.h"
+
 module AntiTheftC
 {
   uses {
@@ -10,6 +27,7 @@ module AntiTheftC
     interface DisseminationValue<settings_t> as SettingsValue;
     interface Send as AlertRoot;
     interface StdControl as CollectionControl;
+    interface StdControl as DisseminationControl;
     interface SplitControl as RadioControl;
     interface LowPowerListening;
     interface AMSend as TheftSend;
@@ -19,31 +37,45 @@ module AntiTheftC
 implementation
 {
   enum {
-    DARK_THRESHOLD = 200,
+    /* Threshold for considering mote in a dark place */
+    DARK_THRESHOLD = 600, 
+
+    /* Amount of time warning leds should stay on (in checkInterval counts) */
     WARNING_TIME = 3,
-    ACCEL_SAMPLES = 10
+
+    /* Number of acceleration samples to collect */
+    ACCEL_SAMPLES = 10,
+
+    /* Interval between acceleration samples (us) */
+    ACCEL_INTERVAL = 10000
   };
 
   settings_t settings;
   message_t alertMsg, theftMsg;
-  uint16_t ledTime;
+  uint16_t ledTime; /* Time left until leds switched off */
   uint16_t accelSamples[ACCEL_SAMPLES];
 
+  /********* LED handling **********/
+
+  /* Warn that some error occurred */
   void errorLed() {
     ledTime = WARNING_TIME;
     call Leds.led2On();
   }
 
+  /* Notify user that settings changed */
   void settingsLed() {
     ledTime = WARNING_TIME;
     call Leds.led1On();
   }
 
+  /* Turn on bright red light! (LED) */
   void theftLed() {
     ledTime = WARNING_TIME;
     call Leds.led0On();
   }
 
+  /* Time-out leds. Called every checkInterval */
   void updateLeds() {
     if (ledTime && !--ledTime)
       {
@@ -53,38 +85,49 @@ implementation
       }
   }
 
+  /* Check result code and report error if a problem occurred */
   void check(error_t ok) {
     if (ok != SUCCESS)
       errorLed();
   }
 
+  /* Report theft, based on current settings */
   void theft() {
     if (settings.alert & ALERT_LEDS)
       theftLed();
     if (settings.alert & ALERT_SOUND)
       call Mts300Sounder.beep(100);
     if (settings.alert & ALERT_RADIO)
+      /* A local broadcast with no payload */
       check(call TheftSend.send(AM_BROADCAST_ADDR, &theftMsg, 0));
     if (settings.alert & ALERT_ROOT)
       {
-       alert_t *newAlert = call AlertRoot.getPayload(&alertMsg);
-       newAlert->stolenId = TOS_NODE_ID;
-       check(call AlertRoot.send(&alertMsg, sizeof *newAlert));
+       /* Report the identity of this node, using the collection protocol */
+
+       /* Get the payload part of alertMsg and fill in our data */
+       alert_t *newAlert = call AlertRoot.getPayload(&alertMsg, sizeof(alert_t));
+       if (newAlert != NULL) {
+         newAlert->stolenId = TOS_NODE_ID;
+         /* and send it... */
+         check(call AlertRoot.send(&alertMsg, sizeof *newAlert));
+       }
       }
   }
 
+  /* We have nothing to do after messages are sent */
   event void AlertRoot.sendDone(message_t *msg, error_t ok) { }
   event void TheftSend.sendDone(message_t *msg, error_t ok) { }
 
+  /* We've received a theft alert from a neighbour. Turn on the theft warning
+     light! */
   event message_t *TheftReceive.receive(message_t* msg, void* payload, uint8_t len) {
     theftLed();
+    /* We don't need to hold on to the message buffer, so just return the
+       received buffer */
     return msg;
   }
   
-  void resetTimer() {
-    call Check.startPeriodic(settings.checkInterval);
-  }
-  
+  /* At boot time, start the periodic timer and the radio */
   event void Boot.booted() {
     errorLed();
     settings.alert = DEFAULT_ALERT;
@@ -94,11 +137,14 @@ implementation
     call RadioControl.start();
   }
 
+  /* Radio started. Now start the collection protocol and set the
+     wakeup interval for low-power-listening wakeup to half a second. */
   event void RadioControl.startDone(error_t ok) {
     if (ok == SUCCESS)
       {
+       call DisseminationControl.start();
        call CollectionControl.start();
-       call LowPowerListening.setLocalDutyCycle(200);
+       call LowPowerListening.setLocalWakeupInterval(512);
       }
     else
       errorLed();
@@ -106,36 +152,48 @@ implementation
 
   event void RadioControl.stopDone(error_t ok) { }
 
+  /* New settings received, update our local copy */
   event void SettingsValue.changed() {
     const settings_t *newSettings = call SettingsValue.get();
 
     settingsLed();
     settings = *newSettings;
+    /* Switch to the new check interval */
     call Check.startPeriodic(newSettings->checkInterval);
   }
 
+  /* Every check interval: update leds, check for theft based on current
+     settings */
   event void Check.fired() {
     updateLeds();
 
     if (settings.detect & DETECT_DARK)
-      call Read.read();
+      call Read.read(); /* Initiate light sensor read */
     if (settings.detect & DETECT_ACCEL)
       {
+       /* To sample acceleration, we first register our buffer
+          (postBuffer). Then we trigger sampling at the desired
+          interval (read) */
        call ReadStream.postBuffer(accelSamples, ACCEL_SAMPLES);
-       call ReadStream.read(10000);
+       call ReadStream.read(ACCEL_INTERVAL);
       }
   }
 
+  /* Light sample completed. Check if it indicates theft */
   event void Read.readDone(error_t ok, uint16_t val) {
     if (ok == SUCCESS && val < DARK_THRESHOLD)
-      theft();
+      theft(); /* ALERT! ALERT! */
   }
 
+  /* A deferred task to check the acceleration data and detect theft. */
   task void checkAcceleration() {
     uint8_t i;
     uint16_t avg;
     uint32_t var;
 
+    /* We check for theft by checking whether the variance of the sample
+       (in mysterious acceleration units) is > 4 */
+
     for (avg = 0, i = 0; i < ACCEL_SAMPLES; i++)
       avg += accelSamples[i];
     avg /= ACCEL_SAMPLES;
@@ -147,9 +205,12 @@ implementation
       }
 
     if (var > 4 * ACCEL_SAMPLES)
-      theft();
+      theft(); /* ALERT! ALERT! */
   }
 
+  /* The acceleration read completed. Post the task that will check for
+     theft. We defer this somewhat cpu-intensive computation to avoid
+     having the current task run for too long. */
   event void ReadStream.readDone(error_t ok, uint32_t usActualPeriod) {
     if (ok == SUCCESS)
       post checkAcceleration();
@@ -157,5 +218,7 @@ implementation
       errorLed();
   }
 
+  /* The current sampling buffer is full. If we were using several buffers,
+     we would switch between them here. */
   event void ReadStream.bufferDone(error_t ok, uint16_t *buf, uint16_t count) { }
 }