]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - apps/AntiTheft/Nodes/AntiTheftC.nc
antitheft demo app
[tinyos-2.x.git] / apps / AntiTheft / Nodes / AntiTheftC.nc
diff --git a/apps/AntiTheft/Nodes/AntiTheftC.nc b/apps/AntiTheft/Nodes/AntiTheftC.nc
new file mode 100644 (file)
index 0000000..e1babb3
--- /dev/null
@@ -0,0 +1,161 @@
+module AntiTheftC
+{
+  uses {
+    interface Timer<TMilli> as Check;
+    interface Read<uint16_t>;
+    interface ReadStream<uint16_t>;
+    interface Leds;
+    interface Boot;
+    interface Mts300Sounder;
+    interface DisseminationValue<settings_t> as SettingsValue;
+    interface Send as AlertRoot;
+    interface StdControl as CollectionControl;
+    interface SplitControl as RadioControl;
+    interface LowPowerListening;
+    interface AMSend as TheftSend;
+    interface Receive as TheftReceive;
+  }
+}
+implementation
+{
+  enum {
+    DARK_THRESHOLD = 200,
+    WARNING_TIME = 3,
+    ACCEL_SAMPLES = 10
+  };
+
+  settings_t settings;
+  message_t alertMsg, theftMsg;
+  uint16_t ledTime;
+  uint16_t accelSamples[ACCEL_SAMPLES];
+
+  void errorLed() {
+    ledTime = WARNING_TIME;
+    call Leds.led2On();
+  }
+
+  void settingsLed() {
+    ledTime = WARNING_TIME;
+    call Leds.led1On();
+  }
+
+  void theftLed() {
+    ledTime = WARNING_TIME;
+    call Leds.led0On();
+  }
+
+  void updateLeds() {
+    if (ledTime && !--ledTime)
+      {
+       call Leds.led0Off();
+       call Leds.led1Off();
+       call Leds.led2Off();
+      }
+  }
+
+  void check(error_t ok) {
+    if (ok != SUCCESS)
+      errorLed();
+  }
+
+  void theft() {
+    if (settings.alert & ALERT_LEDS)
+      theftLed();
+    if (settings.alert & ALERT_SOUND)
+      call Mts300Sounder.beep(100);
+    if (settings.alert & ALERT_RADIO)
+      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));
+      }
+  }
+
+  event void AlertRoot.sendDone(message_t *msg, error_t ok) { }
+  event void TheftSend.sendDone(message_t *msg, error_t ok) { }
+
+  event message_t *TheftReceive.receive(message_t* msg, void* payload, uint8_t len) {
+    theftLed();
+    return msg;
+  }
+  
+  void resetTimer() {
+    call Check.startPeriodic(settings.checkInterval);
+  }
+  
+  event void Boot.booted() {
+    errorLed();
+    settings.alert = DEFAULT_ALERT;
+    settings.detect = DEFAULT_DETECT;
+
+    call Check.startPeriodic(DEFAULT_CHECK_INTERVAL);
+    call RadioControl.start();
+  }
+
+  event void RadioControl.startDone(error_t ok) {
+    if (ok == SUCCESS)
+      {
+       call CollectionControl.start();
+       call LowPowerListening.setLocalDutyCycle(200);
+      }
+    else
+      errorLed();
+  }
+
+  event void RadioControl.stopDone(error_t ok) { }
+
+  event void SettingsValue.changed() {
+    const settings_t *newSettings = call SettingsValue.get();
+
+    settingsLed();
+    settings = *newSettings;
+    call Check.startPeriodic(newSettings->checkInterval);
+  }
+
+  event void Check.fired() {
+    updateLeds();
+
+    if (settings.detect & DETECT_DARK)
+      call Read.read();
+    if (settings.detect & DETECT_ACCEL)
+      {
+       call ReadStream.postBuffer(accelSamples, ACCEL_SAMPLES);
+       call ReadStream.read(10000);
+      }
+  }
+
+  event void Read.readDone(error_t ok, uint16_t val) {
+    if (ok == SUCCESS && val < DARK_THRESHOLD)
+      theft();
+  }
+
+  task void checkAcceleration() {
+    uint8_t i;
+    uint16_t avg;
+    uint32_t var;
+
+    for (avg = 0, i = 0; i < ACCEL_SAMPLES; i++)
+      avg += accelSamples[i];
+    avg /= ACCEL_SAMPLES;
+
+    for (var = 0, i = 0; i < ACCEL_SAMPLES; i++)
+      {
+       int16_t diff = accelSamples[i] - avg;
+       var += diff * diff;
+      }
+
+    if (var > 4 * ACCEL_SAMPLES)
+      theft();
+  }
+
+  event void ReadStream.readDone(error_t ok, uint32_t usActualPeriod) {
+    if (ok == SUCCESS)
+      post checkAcceleration();
+    else
+      errorLed();
+  }
+
+  event void ReadStream.bufferDone(error_t ok, uint16_t *buf, uint16_t count) { }
+}