--- /dev/null
+/**
+ * Active Message Configuration.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Took the source code from Dip
+ **/
+
+#include <Dhv.h>
+
+configuration AMDhvC {
+ provides interface DhvSend;
+ provides interface DhvReceive as DataReceive;
+ provides interface DhvReceive as VectorReceive;
+ provides interface DhvReceive as SummaryReceive;
+ provides interface DhvReceive as DhvVBitReceive;
+ provides interface DhvReceive as DhvHSumReceive;
+}
+
+implementation {
+ components AMDhvP;
+ components new AMSenderC(AM_DHV) as SendC;
+ components new AMReceiverC(AM_DHV) as ReceiveC;
+
+ AMDhvP.NetAMSend -> SendC.AMSend;
+ AMDhvP.NetReceive -> ReceiveC.Receive;
+
+ components MainC;
+ MainC.SoftwareInit -> AMDhvP.Init;
+ AMDhvP.Boot -> MainC;
+
+ components ActiveMessageC;
+ AMDhvP.AMSplitControl -> ActiveMessageC;
+
+ DhvSend = AMDhvP.DhvSend;
+ DataReceive = AMDhvP.DhvDataReceive;
+ VectorReceive = AMDhvP.DhvVectorReceive;
+ SummaryReceive = AMDhvP.DhvSummaryReceive;
+ DhvVBitReceive = AMDhvP.DhvVBitReceive;
+ DhvHSumReceive = AMDhvP.DhvHSumReceive;
+
+}
--- /dev/null
+/**
+ * Active Message Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type and renamed the instances to distinguish from DIP.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+module AMDhvP {
+ provides interface Init;
+ provides interface DhvSend;
+ provides interface DhvReceive as DhvDataReceive;
+ provides interface DhvReceive as DhvVectorReceive;
+ provides interface DhvReceive as DhvSummaryReceive;
+ provides interface DhvReceive as DhvHSumReceive;
+ provides interface DhvReceive as DhvVBitReceive;
+
+ uses interface AMSend as NetAMSend;
+ uses interface Receive as NetReceive;
+ uses interface SplitControl as AMSplitControl;
+ uses interface Boot;
+}
+
+implementation {
+ message_t am_msg;
+ uint32_t send_count;
+ bool busy;
+
+ event void Boot.booted() {
+ send_count = 0;
+ call AMSplitControl.start();
+ }
+
+ event void AMSplitControl.startDone(error_t err) {
+ if(err != SUCCESS) {
+ call AMSplitControl.start();
+ return;
+ }
+ dbg("AMDhvP", "ActiveMessageC started!\n");
+ }
+
+ event void AMSplitControl.stopDone(error_t err) { }
+
+ command error_t Init.init() {
+ busy = FALSE;
+ return SUCCESS;
+ }
+
+ command error_t DhvSend.send(uint8_t len) {
+ error_t err;
+ dhv_msg_t* dmsg;
+ uint8_t type;
+
+ dmsg = (dhv_msg_t *) (&am_msg)->data;
+ type = dmsg->type;
+
+ send_count = send_count + 1;
+
+ switch(type){
+ case ID_DHV_SUMMARY:
+ dbg("AMDhvP", "Sending SUMMARY : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ case ID_DHV_VBIT:
+ dbg("AMDhvP", "Sending VBIT : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ case ID_DHV_HSUM:
+ dbg("AMDhvP", "Sending HSUM : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ case ID_DHV_VECTOR:
+ dbg("AMDhvP", "Sending VECTOR : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ case ID_DHV_VECTOR_REQ:
+ dbg("AMDhvP", "Sending VECTOR_REQ : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ case ID_DHV_DATA:
+ dbg("AMDhvP", "Sending DATA : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ default :
+ dbg("AMDhvP", "Sending UNKNOWN : length %d count %d at %s \n", len, send_count, sim_time_string());
+ break;
+ }
+ err = call NetAMSend.send(AM_BROADCAST_ADDR, &am_msg, len);
+
+ if(err == SUCCESS) {
+ busy = TRUE;
+ }else{
+ dbg("AMDhvP", "Send failed \n");
+ }
+
+ return err;
+ }
+
+ command void* DhvSend.getPayloadPtr() {
+ // returns NULL if message is busy
+ if(busy) {
+ return NULL;
+ }
+ return call NetAMSend.getPayload(&am_msg, 0);
+ }
+
+ command uint8_t DhvSend.maxPayloadLength() {
+ return call NetAMSend.maxPayloadLength();
+ }
+
+ event void NetAMSend.sendDone(message_t* msg, error_t err) {
+ //dbg("AMDhvP", "Data send successfully in the air\n");
+ if(msg == &am_msg) {
+ busy = FALSE;
+ }
+ }
+
+ event message_t* NetReceive.receive(message_t* msg, void* payload,
+ uint8_t len) {
+ dhv_msg_t* dmsg;
+ uint8_t type;
+
+ dmsg = (dhv_msg_t*) payload;
+ type = dmsg->type;
+ switch(type) {
+ case ID_DHV_DATA:
+
+ dbg("AMDhvPReceive", "Receive DATA : length %d at %s \n",len, sim_time_string() );
+ signal DhvDataReceive.receive(dmsg->content, len);
+ break;
+ case ID_DHV_VECTOR:
+
+ dbg("AMDhvPReceive", "Receive VECTOR : length %d at %s \n",len, sim_time_string() );
+ signal DhvVectorReceive.receive(dmsg, len);
+ break;
+ case ID_DHV_SUMMARY:
+
+ dbg("AMDhvPReceive", "Receive SUMMARY : length %d at %s \n", len, sim_time_string() );
+ signal DhvSummaryReceive.receive(dmsg->content, len);
+ break;
+ case ID_DHV_HSUM:
+ dbg("AMDhvPReceive", "Receive HSUM length %d at %s \n", len, sim_time_string());
+ signal DhvHSumReceive.receive(dmsg->content, len);
+ break;
+ case ID_DHV_VBIT:
+
+ dbg("AMDhvPReceive", "Receive VBIT : length %d at %s \n", len, sim_time_string());
+ signal DhvVBitReceive.receive(dmsg->content, len);
+ break;
+
+ case ID_DHV_VECTOR_REQ:
+
+ dbg("AMDhvPReceive", "Receive VECTOR_REQ : length %d at %s \n", len, sim_time_string());
+ signal DhvVectorReceive.receive(dmsg, len);
+ break;
+ }
+ return msg;
+ }
+}
--- /dev/null
+/**
+ * DHV header file.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV packet type and renamed the variable
+ * @modified 8/28/2008 Take the source code from Dip
+ **/
+
+
+#ifndef __DHV_H__
+#define __DHV_H__
+
+#define DHV_TAU_LOW (1024L)
+#define DHV_TAU_HIGH (65535L)
+
+#define UQ_DHV unique("DHV")
+#define UQCOUNT_DHV uniqueCount("DHV")
+
+#define DHV_UNKNOWN_VERSION 0xFFFFFFFF
+#define DHV_UNKNOWN_INDEX 0xFFFF
+#define DHV_VERSION_LENGTH 4
+
+#define VBIT_LENGTH 8
+
+enum {
+ AM_DHV_TEST_MSG = 0xAB
+};
+
+
+typedef enum {
+ ID_DHV_INVALID = 0x0,
+ ID_DHV_SUMMARY = 0x1,
+ ID_DHV_VECTOR = 0x2,
+ ID_DHV_DATA = 0x3,
+ ID_DHV_HSUM = 0x4,
+ ID_DHV_VBIT = 0x5,
+ ID_DHV_VECTOR_REQ = 0x6
+} dhv_msgid_t;
+
+//status indicator : no action, ads, request
+enum{
+ ID_DHV_NO = 0x0,
+ ID_DHV_ADS = 0x1,
+ ID_DHV_REQ = 0x2
+};
+
+enum {
+ AM_DHV = 0x62,
+ AM_DHV_DATA_MSG = 0x62, // For MIG tool
+ AM_DHV_MSG = 0x62, // For MIG tool
+ AM_DHV_DATA = 0x62 // For MIG tool
+};
+
+typedef uint16_t dhv_key_t;
+typedef uint16_t dhv_index_t;
+typedef nx_uint16_t nx_dhv_key_t;
+typedef uint32_t dhv_version_t;
+typedef nx_uint32_t nx_dhv_version_t;
+typedef uint8_t dhv_estimate_t;
+typedef dhv_index_t dhv_hashlen_t;
+
+typedef nx_struct dhv_msg {
+ nx_uint8_t type;
+ nx_uint8_t content[0];
+} dhv_msg_t;
+
+typedef nx_struct dhv_data_msg {
+ nx_dhv_key_t key;
+ nx_dhv_version_t version;
+ nx_uint8_t size;
+ nx_uint8_t data[0];
+} dhv_data_msg_t;
+
+typedef nx_struct dhv_vector_msg {
+ nx_uint8_t unitLen;
+ nx_uint32_t vector[0];
+} dhv_vector_msg_t;
+
+typedef nx_struct dhv_summary_msg {
+ //nx_uint8_t unitLen;
+ nx_uint32_t salt;
+ nx_uint32_t info;
+} dhv_summary_msg_t;
+
+typedef nx_struct dhv_hsum_msg{
+ nx_uint32_t salt;
+ nx_uint32_t info;
+ nx_uint32_t checksum;
+} dhv_hsum_msg_t;
+
+typedef nx_struct dhv_vbit_msg{
+ nx_uint8_t numKey;
+ nx_uint8_t bindex;
+ nx_uint8_t vindex;
+ nx_uint32_t salt;
+ nx_uint32_t info; //include hash into vbit message
+ nx_uint8_t vbit[0];
+}dhv_vbit_msg_t;
+
+typedef nx_struct dhv_data {
+ nx_uint8_t data[16];
+} dhv_data_t;
+
+
+typedef nx_struct dhv_test_msg {
+ nx_uint16_t id;
+ nx_uint8_t count;
+ nx_uint8_t isOk;
+} dhv_test_msg_t;
+
+
+/* TUNABLE PARAMETERS */
+#define DHV_SUMMARY_VALUES_PER_PACKET 2
+#define DHV_VECTOR_VALUES_PER_PACKET 2
+
+#define DHV_SUMMARY_ENTRIES_PER_PACKET (DHV_SUMMARY_VALUES_PER_PACKET * 3)
+#define DHV_VECTOR_ENTRIES_PER_PACKET (DHV_VECTOR_VALUES_PER_PACKET * 2)
+#endif
--- /dev/null
+/**
+* DHV header file.
+*
+* Define the interfaces and components.
+*
+* @author Thanh Dang
+* @author Seungweon Park
+*
+* @modified 1/3/2009 Added meaningful documentation.
+* @modified 8/28/2008 Defined DHV packet type and renamed the variable
+* @modified 8/28/2008 Take the source code from Dip
+**/
+
+
+
+configuration DhvDataC {
+ provides interface DhvDecision;
+
+ uses interface DhvSend as DataSend;
+ uses interface DhvReceive as DataReceive;
+
+ uses interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
+ uses interface DisseminationValue<dhv_data_t>[dhv_key_t key];
+
+ uses interface DhvLogic as DataLogic;
+ uses interface DhvLogic as VectorLogic;
+
+ uses interface DhvHelp;
+}
+
+implementation {
+ components DhvDataP;
+ DhvDecision = DhvDataP;
+ DataSend = DhvDataP;
+ DataReceive = DhvDataP;
+ DisseminationUpdate = DhvDataP;
+ DisseminationValue = DhvDataP;
+ DhvHelp = DhvDataP;
+ DataLogic = DhvDataP.DataLogic;
+ VectorLogic = DhvDataP.VectorLogic;
+
+ components LedsC;
+ DhvDataP.Leds -> LedsC;
+}
--- /dev/null
+/**
+ * DHV DATA Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+
+#include <Dhv.h>
+
+module DhvDataP {
+ provides interface DhvDecision;
+
+ uses interface DhvSend as DataSend;
+ uses interface DhvReceive as DataReceive;
+
+ uses interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
+ uses interface DisseminationValue<dhv_data_t>[dhv_key_t key];
+ uses interface DhvLogic as DataLogic;
+ uses interface DhvLogic as VectorLogic;
+
+ uses interface DhvHelp;
+ uses interface Leds;
+}
+
+implementation {
+ uint8_t commRate = 0;
+
+ command uint8_t DhvDecision.getCommRate() {
+ return commRate;
+ }
+
+ command void DhvDecision.resetCommRate() {
+ commRate = 0;
+ }
+
+ command error_t DhvDecision.send() {
+ dhv_key_t key;
+ uint8_t i;
+ dhv_version_t ver;
+ dhv_msg_t* dmsg;
+ dhv_data_msg_t* ddmsg;
+ const dhv_data_t* data;
+ error_t status;
+
+ status = FAIL;
+ //get the associated key of the data needed to send
+ i = call DataLogic.nextItem();
+ if(i == UQCOUNT_DHV){
+ return FAIL;
+ }
+ key = call DhvHelp.indexToKey(i);
+ ver = call DhvHelp.keyToVersion(key);
+ data = call DisseminationValue.get[key]();
+ dmsg = (dhv_msg_t*) call DataSend.getPayloadPtr();
+ if(dmsg == NULL) {
+ return FAIL;
+ }
+ ddmsg = (dhv_data_msg_t*) dmsg->content;
+ dmsg->type = ID_DHV_DATA;
+ ddmsg->key = key;
+ ddmsg->version = ver;
+ ddmsg->size = sizeof(dhv_data_t);
+ memcpy(ddmsg->data, data, sizeof(dhv_data_t));
+
+ dbg("DhvDataP", "Data sent with index %d key %x and version %08x\n",i, key, ver);
+ status = call DataSend.send(sizeof(dhv_data_msg_t) + sizeof(dhv_msg_t) + sizeof(dhv_data_t));
+ if(status == SUCCESS){
+ call DataLogic.unsetItem(key);
+ }
+
+ return status;
+ }
+
+ event void DataReceive.receive(void* payload, uint8_t len) {
+ dhv_key_t key;
+ dhv_version_t myVer;
+ dhv_version_t msgVer;
+ dhv_data_msg_t* ddmsg;
+
+ commRate = commRate + 1;
+ ddmsg = (dhv_data_msg_t*) payload;
+ key = ddmsg->key;
+ msgVer = ddmsg->version;
+ myVer = call DhvHelp.keyToVersion(key);
+ dbg("DhvDataP", "Data rcved with key %x and version %08x\n", key, msgVer);
+
+ // TODO: handle the invalid versions
+ if(myVer < msgVer) {
+ dbg("DhvDataP", "new version\n");
+ call DisseminationUpdate.change[key]((dhv_data_t*)ddmsg->data);
+ call DhvHelp.setVersion(key, msgVer);
+ call DataLogic.setItem(key);
+ call VectorLogic.setItem(key);
+ //set bindex to 0
+ }
+ else if (myVer > msgVer) {
+ dbg("DhvDataP", "Old version\n");
+ //report older key to dhvlogic to set data item to send
+ //reset timer
+ call DataLogic.setItem(key);
+ call VectorLogic.setItem(key);
+
+ }
+ else {
+ dbg("DhvDataP", "Same version\n");
+ //keep quite
+ call DataLogic.unsetItem(key);
+ call VectorLogic.unsetItem(key);
+ //set bindex to 0
+ }
+ }
+
+ event void DisseminationValue.changed[dhv_key_t key]() { }
+
+ default command const dhv_data_t* DisseminationValue.get[dhv_key_t key]() {
+ return NULL;
+ }
+
+ default command void DisseminationUpdate.change[dhv_key_t key](dhv_data_t* val) { }
+
+}
--- /dev/null
+/**
+ * DHV Horizontal Summary Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ **/
+
+configuration DhvHSumC{
+ provides interface DhvDecision;
+
+ uses interface DhvSend as HSumSend;
+ uses interface DhvReceive as HSumReceive;
+ uses interface DhvStateLogic as VBitLogic;
+ uses interface DhvHelp;
+}
+
+implementation{
+ components DhvHSumP, RandomC;
+ DhvDecision = DhvHSumP;
+ HSumSend = DhvHSumP;
+ HSumReceive = DhvHSumP;
+ VBitLogic = DhvHSumP;
+ DhvHelp = DhvHSumP;
+ DhvHSumP.Random -> RandomC;
+}
--- /dev/null
+/**
+ * DHV Horizontal Summary Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ **/
+
+#include<Dhv.h>
+
+module DhvHSumP{
+ provides interface DhvDecision;
+
+ uses interface DhvSend as HSumSend;
+ uses interface DhvReceive as HSumReceive;
+ uses interface DhvStateLogic as VBitLogic;
+ uses interface DhvHelp;
+ uses interface Random;
+}
+
+implementation{
+ uint8_t commRate;
+
+ command uint8_t DhvDecision.getCommRate(){
+ return commRate;
+ }
+ command void DhvDecision.resetCommRate(){
+ commRate = 0;
+ }
+ command error_t DhvDecision.send(){
+ dhv_hsum_msg_t* dhsmsg;
+ dhv_msg_t* dmsg;
+ uint32_t salt;
+ error_t sendResult;
+
+ dmsg = call HSumSend.getPayloadPtr();
+ dmsg->type = ID_DHV_HSUM;
+ dhsmsg = (dhv_hsum_msg_t*) dmsg->content;
+
+ //add the hash value
+ salt = call Random.rand32();
+ dhsmsg->info = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
+ dhsmsg->salt = salt;
+ dhsmsg->checksum = call DhvHelp.getHSum();
+
+ sendResult = call HSumSend.send(sizeof(dhv_msg_t) + sizeof(dhv_hsum_msg_t));
+ if(sendResult == SUCCESS){
+ call VBitLogic.unsetHSumStatus();
+ }
+ return sendResult;
+ }
+
+ event void HSumReceive.receive(void* payload, uint8_t len){
+ dhv_hsum_msg_t * rcv_dhmsg;
+ int32_t local_checksum;
+ int32_t rcv_checksum;
+ int32_t xor_checksum;
+ int32_t salt;
+ int32_t rcv_hash;
+ int32_t local_hash;
+
+ rcv_dhmsg = (dhv_hsum_msg_t*) payload;
+
+ rcv_checksum = rcv_dhmsg->checksum;
+ local_checksum = call DhvHelp.getHSum();
+ xor_checksum = rcv_checksum^local_checksum;
+ dbg("DhvHSumP", " xor_checksum 0x%08x 0x%08x 0x%08x \n",rcv_checksum, local_checksum, xor_checksum);
+ if(xor_checksum == 0){
+ //check for the hash
+ rcv_hash = rcv_dhmsg->info;
+ salt = rcv_dhmsg->salt;
+ local_hash = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
+ if(rcv_hash == local_hash) {
+ call VBitLogic.setSameSummary();
+ }else{
+ call VBitLogic.setVBitState(1);
+ }
+ }else{
+ dbg("DhvHSumP"," detect a difference in checksum \n" );
+ call VBitLogic.setVBitState(xor_checksum);
+ }
+ }
+}
--- /dev/null
+/**
+ * DHV Logic Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+#include <Dhv.h>
+
+configuration DhvLogicC {
+ provides interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
+ provides interface DhvLogic as DataLogic;
+ provides interface DhvLogic as VectorLogic;
+ provides interface DhvStateLogic;
+ provides interface StdControl;
+}
+
+implementation {
+ components DhvLogicP;
+ DisseminationUpdate = DhvLogicP;
+ StdControl = DhvLogicP;
+ DataLogic = DhvLogicP.DataLogic;
+ VectorLogic= DhvLogicP.VectorLogic;
+ DhvStateLogic = DhvLogicP;
+
+ components MainC;
+ MainC.SoftwareInit -> DhvLogicP;
+ DhvLogicP.Boot -> MainC;
+
+ components DhvTrickleMilliC;
+ DhvLogicP.DhvTrickleTimer -> DhvTrickleMilliC;
+
+ components DhvVersionC;
+ DhvLogicP.VersionUpdate -> DhvVersionC;
+ DhvLogicP.DhvHelp -> DhvVersionC;
+ DhvLogicP.DhvDataCache -> DhvVersionC.DataCache;
+ DhvLogicP.DhvVectorCache -> DhvVersionC.VectorCache;
+
+ components AMDhvC;
+
+ components DhvDataC;
+ DhvLogicP.DhvDataDecision -> DhvDataC;
+ DhvDataC.DataSend -> AMDhvC.DhvSend;
+ DhvDataC.DataReceive -> AMDhvC.DataReceive;
+ DhvDataC.DhvHelp -> DhvVersionC;
+ DhvDataC.DataLogic -> DhvLogicP.DataLogic;
+ DhvDataC.VectorLogic -> DhvLogicP.VectorLogic;
+
+ components DhvVectorC;
+ DhvLogicP.DhvVectorDecision -> DhvVectorC;
+ DhvVectorC.VectorSend -> AMDhvC.DhvSend;
+ DhvVectorC.VectorReceive -> AMDhvC.VectorReceive;
+ DhvVectorC.DhvHelp -> DhvVersionC;
+ DhvVectorC.VectorLogic -> DhvLogicP.VectorLogic;
+ DhvVectorC.DataLogic -> DhvLogicP.DataLogic;
+
+ components DhvSummaryC;
+ DhvLogicP.DhvSummaryDecision -> DhvSummaryC;
+ DhvSummaryC.SummarySend -> AMDhvC.DhvSend;
+ DhvSummaryC.SummaryReceive -> AMDhvC.SummaryReceive;
+ DhvSummaryC.DhvHelp -> DhvVersionC;
+ DhvSummaryC.StateLogic -> DhvLogicP.DhvStateLogic;
+
+ components DhvVBitC;
+ DhvLogicP.DhvVBitDecision -> DhvVBitC;
+ DhvVBitC.VBitSend -> AMDhvC.DhvSend;
+ DhvVBitC.VBitReceive -> AMDhvC.DhvVBitReceive;
+ DhvVBitC.DhvHelp -> DhvVersionC;
+ DhvVBitC.VectorLogic -> DhvLogicP.VectorLogic;
+ DhvVBitC.VBitLogic -> DhvLogicP.DhvStateLogic;
+
+ components DhvHSumC;
+ DhvHSumC.VBitLogic -> DhvLogicP.DhvStateLogic;
+ DhvHSumC.DhvHelp -> DhvVersionC;
+ DhvHSumC.HSumSend -> AMDhvC.DhvSend;
+ DhvHSumC.HSumReceive-> AMDhvC.DhvHSumReceive;
+ DhvLogicP.DhvHSumDecision -> DhvHSumC;
+}
--- /dev/null
+/**
+ * DHV Logic Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+#include <Dhv.h>
+
+module DhvLogicP {
+ provides interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
+
+ provides interface Init;
+ provides interface StdControl;
+ provides interface DhvLogic as VectorLogic;
+ provides interface DhvLogic as DataLogic;
+ provides interface DhvStateLogic;
+
+ uses interface Boot;
+ uses interface DhvTrickleTimer;
+ uses interface DisseminationUpdate<dhv_data_t> as VersionUpdate[dhv_key_t key];
+
+ uses interface DhvDecision as DhvDataDecision;
+ uses interface DhvDecision as DhvVectorDecision;
+ uses interface DhvDecision as DhvSummaryDecision;
+ uses interface DhvDecision as DhvVBitDecision;
+ uses interface DhvDecision as DhvHSumDecision;
+
+ uses interface DhvCache as DhvDataCache;
+ uses interface DhvCache as DhvVectorCache;
+ uses interface DhvHelp;
+
+}
+
+implementation {
+ uint32_t windowSize;
+ uint8_t sendDecision();
+ uint8_t getState();
+ uint32_t bitIndex;
+ uint8_t hsum_status;
+ uint32_t diffHash;
+
+ command error_t Init.init() {
+ windowSize = DHV_TAU_LOW;
+ dbg("DhvLogicP","DHV ready\n");
+ return SUCCESS;
+ }
+
+ event void Boot.booted() {
+ hsum_status = 0;
+ bitIndex = 0;
+ }
+
+ command error_t StdControl.start() {
+ return call DhvTrickleTimer.start();
+ }
+
+ command error_t StdControl.stop() {
+ call DhvTrickleTimer.stop();
+ return SUCCESS;
+ }
+
+
+ /*Logic operation on the vector */
+ command error_t VectorLogic.setItem(dhv_key_t key){
+ call DhvVectorCache.addItem(key);
+ call DhvTrickleTimer.reset();
+ return SUCCESS;
+ }
+
+ command error_t VectorLogic.setReqItem(dhv_key_t key){
+ call DhvVectorCache.addReqItem(key);
+ call DhvTrickleTimer.reset();
+ return SUCCESS;
+ }
+
+ command error_t VectorLogic.unsetItem(dhv_key_t key){
+ call DhvVectorCache.removeItem(key);
+ call DhvStateLogic.setVBitState(0);
+ return SUCCESS;
+ }
+
+ command uint8_t * VectorLogic.allItem(){
+ return call DhvVectorCache.allItem();
+ }
+
+ command uint8_t VectorLogic.nextItem(){
+ return call DhvVectorCache.nextItem();
+ }
+
+ /*logic operations on the data*/
+ command error_t DataLogic.setItem(dhv_key_t key){
+ call DhvDataCache.addItem( key);
+ call DhvTrickleTimer.reset();
+ return SUCCESS;
+ }
+
+ command error_t DataLogic.setReqItem(dhv_key_t key){
+ call DhvDataCache.addReqItem( key);
+ call DhvTrickleTimer.reset();
+ return SUCCESS;
+ }
+
+ command error_t DataLogic.unsetItem(dhv_key_t key){
+ call DhvDataCache.removeItem(key);
+ call DhvStateLogic.setVBitState(0);
+ return SUCCESS;
+ }
+
+ command uint8_t* DataLogic.allItem(){
+ return call DhvDataCache.allItem();
+ }
+
+ command uint8_t DataLogic.nextItem(){
+ return call DhvDataCache.nextItem();
+ }
+
+ /*logic operation for the summary and vbit*/
+ command void DhvStateLogic.setHSumStatus(){
+ hsum_status = 1;
+ call DhvTrickleTimer.reset();
+ }
+
+ command void DhvStateLogic.unsetHSumStatus(){
+ hsum_status = 0;
+ }
+
+ command uint8_t DhvStateLogic.getHSumStatus(){
+ return hsum_status;
+ }
+
+ command void DhvStateLogic.setDiffSummary(){
+ if(bitIndex == 0){
+ bitIndex=1;
+ }
+
+ call DhvTrickleTimer.reset();
+ }
+
+ command void DhvStateLogic.setSameSummary(){
+ bitIndex = 0;
+ hsum_status = 0;
+ //reset all the vector and data status to avoid flooding
+ call DhvDataCache.removeAll();
+ call DhvVectorCache.removeAll();
+
+ }
+
+ command void DhvStateLogic.setVBitState(uint32_t state){
+ bitIndex = state;
+ if(state != 0){
+ call DhvTrickleTimer.reset();
+ }
+ }
+
+ command uint32_t DhvStateLogic.getVBitState(){
+ return bitIndex;
+ }
+
+ //unset one bit at index location
+ command void DhvStateLogic.unsetVBitIndex(uint8_t dindex){
+ uint32_t mask;
+ mask = 1;
+
+ mask = mask << (dindex-1);
+ dbg("TempDebug", "TempDebug: Before mask dindex bitIndex %d %d %d\n", mask, dindex, bitIndex);
+ if((bitIndex & mask) != 0){
+ bitIndex = bitIndex^mask;
+ }
+ dbg("TempDebug", "TempDebug: After bitIndex %d\n", bitIndex);
+ }
+
+ command void DhvStateLogic.setVBitIndex(uint8_t dindex){
+ uint32_t mask;
+ mask = 1;
+ mask = mask << (dindex-1);
+
+ bitIndex = bitIndex | mask;
+
+ call DhvTrickleTimer.reset();
+}
+
+//get the non-zero bit index to extract the vertical bits.
+command uint8_t DhvStateLogic.getVBitIndex(){
+
+ uint32_t mask;
+ uint8_t i;
+ uint32_t xor;
+
+ if(bitIndex == 0){
+ return 0;
+ }else
+ {
+ mask = 1;
+ for(i = 1; i <= 32; i++){
+ xor = bitIndex & mask;
+
+ dbg("TempDebug", "TempDebug: %d %d %d %d \n", i, bitIndex, mask, xor);
+ if(xor != 0){
+ return i;
+ }
+ mask = mask << 1;
+ }
+ return 0;
+ }
+}
+
+
+
+ command void DisseminationUpdate.change[dhv_key_t key](dhv_data_t* val) {
+
+ dbg("DhvLogicP","App notified key %x is new\n", key);
+
+ //update data: actual reprogramming job
+ call VersionUpdate.change[key](val);
+
+ //set data
+ call DhvDataCache.addItem(key);
+
+ //set to advertise its version
+ call DhvVectorCache.addItem(key);
+
+ //reset bindex
+ call DhvStateLogic.setVBitState(0);
+
+ dbg("DhvLogicP","Reset bindex to 0\n");
+ //reset timer
+ call DhvTrickleTimer.reset();
+ }
+
+ event uint32_t DhvTrickleTimer.requestWindowSize() {
+ //TODO: consider if this is neccessary
+ uint8_t decision;
+
+ decision = sendDecision();
+
+ if(decision == ID_DHV_SUMMARY){
+ windowSize = windowSize << 1;
+ if(windowSize > DHV_TAU_HIGH){
+ windowSize = DHV_TAU_HIGH;
+ }
+ }else{
+ if(decision != ID_DHV_INVALID){
+ windowSize = DHV_TAU_LOW;
+ }
+ }
+
+ /*if(decision == ID_DHV_DATA){
+ windowSize = DHV_TAU_LOW;
+ }else{
+ if(decision == ID_DHV_VBIT){
+ windowSize = DHV_TAU_LOW;
+ }else{
+ windowSize = windowSize << 1;
+ if(windowSize > DHV_TAU_HIGH){
+ windowSize = DHV_TAU_HIGH;
+ }
+ }
+ }
+ */
+ dbg("DhvLogicP", "Time window size requested, give %u : send decision %d \n", windowSize, decision);
+ return windowSize;
+ }
+
+ event void DhvTrickleTimer.fired() {
+ uint8_t decision;
+
+ dbg("DhvLogicP","Trickle Timer fired!\n");
+
+ decision = sendDecision();
+
+ switch(decision) {
+ case ID_DHV_INVALID:
+ dbg("DhvLogicP", "Decision to SUPPRESS\n");
+ break;
+ case ID_DHV_SUMMARY:
+ dbg("DhvLogicP", "Decision to SUMMARY\n");
+ call DhvSummaryDecision.send();
+ break;
+ case ID_DHV_VECTOR:
+ dbg("DhvLogicP", "Decision to VECTOR\n");
+ call DhvVectorDecision.send();
+ break;
+ case ID_DHV_DATA:
+ dbg("DhvLogicP", "Decision to DATA\n");
+ call DhvDataDecision.send();
+ break;
+ case ID_DHV_VBIT:
+ dbg("DhvLogicP", "Decision to VSUM\n");
+ call DhvVBitDecision.send();
+ break;
+ case ID_DHV_HSUM:
+ dbg("DhvLogicP", "Decision to HSUM\n");
+ call DhvHSumDecision.send();
+ break;
+ }
+ call DhvDataDecision.resetCommRate();
+ call DhvVectorDecision.resetCommRate();
+ call DhvSummaryDecision.resetCommRate();
+ call DhvVBitDecision.resetCommRate();
+ call DhvHSumDecision.resetCommRate();
+
+ //set bitstate to zero
+ call DhvStateLogic.setVBitState(0);
+ }
+
+
+ uint8_t getState() {
+ bool hasItemToSend;
+ uint32_t bindex;
+
+ hasItemToSend = FALSE;
+
+ hasItemToSend = call DhvDataCache.hasItemToSend();
+ if(hasItemToSend){
+ dbg("DhvLogicP", "has data to send? %u \n", hasItemToSend);
+ return ID_DHV_DATA;
+ }else{
+ hasItemToSend = call DhvVectorCache.hasItemToSend();
+ dbg("DhvLogicP", "has vector to send? %u \n", hasItemToSend);
+ if(hasItemToSend){
+ return ID_DHV_VECTOR;
+ }else{
+ bindex = call DhvStateLogic.getVBitState();
+ dbg("DhvLogicP", "send decision bindex %d \n", bindex);
+
+ if(bindex != 0){
+ return ID_DHV_VBIT;
+ }else{
+ if(hsum_status != 0){
+ return ID_DHV_HSUM;
+ }else {
+ return ID_DHV_SUMMARY;
+ }
+ }
+ }
+ }
+ }
+
+
+ uint8_t sendDecision() {
+
+ bool hasItemToSend;
+ uint32_t bindex;
+ uint8_t dataCommRate;
+ uint8_t vectorCommRate;
+ uint8_t summaryCommRate;
+ uint8_t vbitCommRate;
+ uint8_t hsumCommRate;
+
+ dataCommRate = call DhvDataDecision.getCommRate();
+ vectorCommRate = call DhvVectorDecision.getCommRate();
+ summaryCommRate = call DhvSummaryDecision.getCommRate();
+ vbitCommRate = call DhvVBitDecision.getCommRate();
+ hsumCommRate = call DhvHSumDecision.getCommRate();
+
+ hasItemToSend = FALSE;
+ hasItemToSend = call DhvDataCache.hasItemToSend();
+ if(hasItemToSend){
+ dbg("DhvLogicP", "has data to send? %u \n", hasItemToSend);
+ return ID_DHV_DATA;
+ }
+
+ bindex = call DhvStateLogic.getVBitState();
+ dbg("DhvLogicP", "send decision bindex %d \n", bindex);
+
+ if(bindex != 0){
+ return ID_DHV_VBIT;
+ }
+
+ if(hsum_status != 0){
+ return ID_DHV_HSUM;
+ }
+
+ if(dataCommRate > 1) {
+ dbg("DhvLogicP", "Heard data\n");
+ return ID_DHV_INVALID;
+ }
+
+
+ hasItemToSend = call DhvVectorCache.hasItemToSend();
+ dbg("DhvLogicP", "has vector to send? %u \n", hasItemToSend);
+
+ if(hasItemToSend){
+ return ID_DHV_VECTOR;
+ }
+
+ // didn't send or hear data at this point
+ if(vectorCommRate + summaryCommRate + vbitCommRate > 1) {
+ dbg("DhvLogicP", "Heard an advertisement\n");
+ return ID_DHV_INVALID;
+ }
+
+ return ID_DHV_SUMMARY;
+ }
+}
--- /dev/null
+/**
+ * DHV Summary Message Configuration.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+configuration DhvSummaryC {
+ provides interface DhvDecision;
+
+ uses interface DhvSend as SummarySend;
+ uses interface DhvReceive as SummaryReceive;
+ uses interface DhvStateLogic as StateLogic;
+ uses interface DhvHelp;
+}
+
+implementation {
+ components DhvSummaryP;
+ DhvDecision = DhvSummaryP;
+ SummarySend = DhvSummaryP;
+ SummaryReceive = DhvSummaryP;
+ StateLogic = DhvSummaryP;
+ DhvHelp = DhvSummaryP;
+ components RandomC;
+ DhvSummaryP.Random -> RandomC;
+}
--- /dev/null
+/**
+ * DHV Summary Message Implementation.
+ *
+ * Define the interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV interfaces type.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+#include <Dhv.h>
+
+module DhvSummaryP {
+ provides interface DhvDecision;
+
+ uses interface DhvSend as SummarySend;
+ uses interface DhvReceive as SummaryReceive;
+ uses interface DhvHelp;
+ uses interface Random;
+ uses interface DhvStateLogic as StateLogic;
+}
+
+implementation {
+ uint32_t computeHash(dhv_index_t left, dhv_index_t right,
+ dhv_version_t* basedata, uint32_t salt);
+ uint8_t commRate;
+
+ command uint8_t DhvDecision.getCommRate() {
+ return commRate;
+ }
+
+ command void DhvDecision.resetCommRate() {
+ commRate = 0;
+ }
+
+ command error_t DhvDecision.send() {
+ uint32_t salt;
+ dhv_msg_t* dmsg;
+ dhv_summary_msg_t* dsmsg;
+
+ dmsg = (dhv_msg_t*) call SummarySend.getPayloadPtr();
+ dmsg->type = ID_DHV_SUMMARY;
+ dsmsg = (dhv_summary_msg_t*) dmsg->content;
+
+ salt = call Random.rand32();
+ dsmsg->info = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
+ dsmsg->salt = salt;
+
+ dbg("DhvSummaryP", "Hash Entry: %08x \n", dsmsg->info);
+ return call SummarySend.send(sizeof(dhv_msg_t) + sizeof(dhv_summary_msg_t));
+ }
+
+ event void SummaryReceive.receive(void* payload, uint8_t len) {
+ dhv_summary_msg_t* dsmsg;
+ uint32_t salt, myHash;
+
+ commRate = commRate + 1;
+
+ dsmsg = (dhv_summary_msg_t*) payload;
+ salt = dsmsg->salt;
+
+ myHash = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
+ if(myHash != dsmsg->info) {
+ //call StateLogic.setDiffSummary();
+ call StateLogic.setHSumStatus();
+ dbg("DhvSummaryP", "Hashes don't match\n");
+ }
+ else {
+ call StateLogic.setSameSummary();
+ dbg("DhvSummaryP", "Hashes match\n");
+ }
+ }
+}
--- /dev/null
+// $Id$
+/*
+ * "Copyright (c) 2006 Stanford University. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ *
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/*
+ * Configuration that encapsulates the trickle timer implementation to
+ * its needed services and initialization. For details on the working
+ * of the parameters, please refer to Levis et al., "A Self-Regulating
+ * Algorithm for Code Maintenance and Propagation in Wireless Sensor
+ * Networks," NSDI 2004.
+ *
+ * @param l Lower bound of the time period in seconds.
+ * @param h Upper bound of the time period in seconds.
+ * @param k Redundancy constant.
+ * @param count How many timers to provide.
+ *
+ * @author Philip Levis
+ * @author Gilman Tolle
+ * @date Jan 7 2006
+ */
+
+
+configuration DhvTrickleMilliC {
+ provides interface DhvTrickleTimer as TrickleTimer;
+}
+implementation {
+ components DhvTrickleMilliP as TrickleP;
+ components MainC, RandomC;
+ components new TimerMilliC() as PeriodicIntervalTimer;
+ components new TimerMilliC() as SingleEventTimer;
+ components LedsC;
+ TrickleTimer = TrickleP;
+
+ TrickleP.PeriodicIntervalTimer -> PeriodicIntervalTimer;
+ TrickleP.SingleEventTimer -> SingleEventTimer;
+ TrickleP.Random -> RandomC;
+
+ TrickleP.Leds -> LedsC;
+ MainC.SoftwareInit -> TrickleP;
+}
+
+
--- /dev/null
+// $Id$
+/*
+ * "Copyright (c) 2006 Stanford University. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ *
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/*
+ * Module that provides a service instance of trickle timers. For
+ * details on the working of the parameters, please refer to Levis et
+ * al., "A Self-Regulating Algorithm for Code Maintenance and
+ * Propagation in Wireless Sensor Networks," NSDI 2004.
+ *
+ * @param l Lower bound of the time period in seconds.
+ * @param h Upper bound of the time period in seconds.
+ * @param k Redundancy constant.
+ * @param count How many timers to provide.
+ *
+ * @author Philip Levis
+ * @author Gilman Tolle
+ * @date Jan 7 2006
+ */
+
+#include <Timer.h>
+#include <Dhv.h>
+
+module DhvTrickleMilliP {
+ provides {
+ interface Init;
+ interface DhvTrickleTimer as TrickleTimer;
+ }
+ uses {
+ interface Timer<TMilli> as PeriodicIntervalTimer;
+ interface Timer<TMilli> as SingleEventTimer;
+ interface Random;
+ interface Leds;
+ }
+}
+implementation {
+
+ uint32_t period;
+
+ command error_t Init.init() {
+ period = DHV_TAU_HIGH;
+ return SUCCESS;
+ }
+
+ /**
+ * Start a trickle timer. Reset the counter to 0.
+ */
+ command error_t TrickleTimer.start() {
+ call PeriodicIntervalTimer.startOneShot(period);
+ dbg("DhvTrickleMilliP",
+ "Starting trickle timer @ %s\n", sim_time_string());
+ return SUCCESS;
+ }
+
+ /**
+ * Stop the trickle timer. This call sets the timer period to H.
+ */
+ command void TrickleTimer.stop() {
+ call PeriodicIntervalTimer.stop();
+ dbg("DhvTrickleMilliP",
+ "Stopping trickle timer @ %s\n", sim_time_string());
+ }
+
+ /**
+ * Reset the timer period to L. If called while the timer is running,
+ * then a new interval (of length L) begins immediately.
+ */
+ command void TrickleTimer.reset() {
+ period = DHV_TAU_LOW;
+ call PeriodicIntervalTimer.stop();
+ call PeriodicIntervalTimer.startOneShot(period);
+ dbg("DhvTrickleMilliP",
+ "Resetting trickle timer @ %s\n", sim_time_string());
+ }
+
+ command void TrickleTimer.maxInterval() {
+ period = DHV_TAU_HIGH;
+ }
+
+ /**
+ * The trickle timer has fired. Signaled if C > K.
+ */
+ event void PeriodicIntervalTimer.fired() {
+ uint32_t dtfire;
+
+ dtfire = (call Random.rand16() % (period / 2)) + (period / 2);
+ dbg("DhvTrickleMilliP", "Scheduling Trickle event with %u\n", dtfire);
+ call SingleEventTimer.startOneShot(dtfire);
+ period = signal TrickleTimer.requestWindowSize();
+ call PeriodicIntervalTimer.startOneShot(period);
+ //call Leds.led0Toggle();
+ }
+
+ event void SingleEventTimer.fired() {
+ dbg("Trickle", "Firing Trickle Event Timer\n");
+ signal TrickleTimer.fired();
+ }
+}
+
+
--- /dev/null
+/**
+ * DHV Virtual Bits Check Configuration
+ *
+ * Define interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV modules.
+ **/
+
+configuration DhvVBitC{
+ provides interface DhvDecision;
+
+ uses interface DhvSend as VBitSend;
+ uses interface DhvReceive as VBitReceive;
+ uses interface DhvStateLogic as VBitLogic;
+ uses interface DhvLogic as VectorLogic;
+ uses interface DhvHelp;
+}
+
+implementation{
+
+ components DhvVBitP;
+ DhvDecision = DhvVBitP;
+ VBitSend = DhvVBitP;
+ VBitReceive = DhvVBitP;
+ VBitLogic = DhvVBitP;
+ VectorLogic = DhvVBitP;
+ DhvHelp = DhvVBitP;
+
+ components RandomC;
+ DhvVBitP.Random -> RandomC;
+}
--- /dev/null
+/**
+ * DHV Virtual Bits Check Configuration
+ *
+ * Define interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV modules.
+ **/
+
+#include<Dhv.h>
+
+module DhvVBitP{
+ provides interface DhvDecision;
+
+ uses interface DhvSend as VBitSend;
+ uses interface DhvReceive as VBitReceive;
+ uses interface DhvStateLogic as VBitLogic;
+ uses interface DhvLogic as VectorLogic;
+ uses interface DhvHelp;
+ uses interface Random;
+}
+
+implementation{
+ uint8_t commRate;
+
+ command uint8_t DhvDecision.getCommRate()
+ {
+ return commRate;
+ }
+
+ command void DhvDecision.resetCommRate(){
+ commRate = 0;
+ }
+
+
+ /*construct a vector of bits and send it*/
+ command error_t DhvDecision.send(){
+ uint8_t bindex;
+ uint8_t vbit_size;
+ uint8_t msg_size;
+ uint8_t numMsg;
+ uint8_t maxDataLength;
+ uint8_t i, j;
+ dhv_msg_t* dmsg;
+ dhv_vbit_msg_t* dvbmsg;
+ uint8_t *versionPtr;
+ error_t sendResult;
+ uint32_t salt;
+
+ maxDataLength = TOSH_DATA_LENGTH - 11;
+ sendResult = FAIL;
+
+ if(UQCOUNT_DHV != 0)
+ {
+ vbit_size = ((uint8_t)(UQCOUNT_DHV-1)/VBIT_LENGTH) + 1;
+ numMsg = (vbit_size -1)/maxDataLength + 1;
+ }else
+ {
+ vbit_size = 0;
+ numMsg = 0;
+ }
+
+ bindex = call VBitLogic.getVBitIndex();
+
+ //return if 0
+ if(bindex == 0){
+ dbg("DhvVBitP", "Error: no vbit to send \n");
+ }
+
+
+ dmsg = call VBitSend.getPayloadPtr();
+ dmsg->type = ID_DHV_VBIT;
+ dvbmsg = (dhv_vbit_msg_t*) dmsg->content;
+ dvbmsg->bindex = bindex;
+
+ //put the hash into the message
+ salt = call Random.rand32();
+ dvbmsg->info = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
+ dvbmsg->salt = salt;
+
+ //put the vbit into the message
+ versionPtr = call DhvHelp.getVBits(bindex);
+
+ for(j = 0; j < numMsg; j++){//number of tos message_t
+ if(j == numMsg-1){
+ //last message
+ msg_size = vbit_size - j*maxDataLength;
+ }else{
+ msg_size = maxDataLength;
+ }
+
+ //TODO: need to get this right
+ dvbmsg->numKey = msg_size*8; //number of keys
+
+ for(i = 0; i < msg_size; i++){
+ dvbmsg->vindex = j;
+ dvbmsg->vbit[i] = versionPtr[j*maxDataLength + i];
+ dbg("DhvVBitP", "bindex %d vbit %d: 0x%02x 0x%02x \n",bindex, i, dvbmsg->vbit[i], versionPtr[i]);
+ }
+
+ dbg("DhvVBitP", "Sending vbit of index %d size %d \n", bindex, sizeof(dhv_msg_t) + sizeof(dhv_vbit_msg_t) + msg_size );
+
+ for(i = 0; i < msg_size; i++){
+ dbg("DhvVBitP", "vbit to send %d, 0x%02x \n", i, dvbmsg->vbit[i]);
+ }
+
+ //send the vbit out
+ sendResult = call VBitSend.send(sizeof(dhv_msg_t) + sizeof(dhv_vbit_msg_t) + vbit_size);
+ if(sendResult == SUCCESS){
+ //call VBitLogic.unsetVBitIndex(bindex);
+ call VBitLogic.setVBitState(0);
+ call VBitLogic.unsetHSumStatus();
+ }
+ }
+ return sendResult;
+ }
+
+
+ event void VBitReceive.receive(void* payload, uint8_t len){
+ dhv_vbit_msg_t * rcv_dvbmsg;
+ uint8_t bindex, vindex;
+ int i,j;
+ dhv_version_t version;
+ dhv_version_t mask;
+ uint8_t diffIndex;
+ dhv_key_t diffKey;
+ bool isDiff;
+ uint8_t vbit_size;
+ uint8_t* vbit;
+ uint32_t salt, myHash;
+ uint8_t maxDataLength;
+ uint8_t msg_size;
+ uint8_t numMsg;
+ uint32_t bitIndexValue;
+
+ isDiff = FALSE;
+ commRate = 1;
+
+ maxDataLength = TOSH_DATA_LENGTH - 11;
+ if(UQCOUNT_DHV != 0)
+ {
+ vbit_size = ((uint8_t)(UQCOUNT_DHV-1)/VBIT_LENGTH) + 1;
+ numMsg = (vbit_size -1)/maxDataLength + 1;
+
+ }else
+ {
+ vbit_size = 0;
+ numMsg = 0;
+ }
+
+ rcv_dvbmsg = (dhv_vbit_msg_t*) payload;
+ bindex = rcv_dvbmsg->bindex;
+ vindex = rcv_dvbmsg->vindex;
+
+ dbg("DhvVBitP", "Receive vbit of index %d numMsg %d vbit_size %d \n", bindex, numMsg, vbit_size );
+
+ //compare the hash first
+ salt = rcv_dvbmsg->salt;
+ myHash = call DhvHelp.computeHash(0, UQCOUNT_DHV, salt);
+
+ if(myHash == rcv_dvbmsg->info){
+ //some duplicates
+ dbg("DhvVBitP", "same summary\n");
+ call VBitLogic.setSameSummary();
+
+ }else{
+ vbit = call DhvHelp.getVBits(bindex);
+ if(vindex == numMsg-1){
+ msg_size = vbit_size - vindex*maxDataLength;
+ //dbg("DhvVBitP", "Last message vindex %d numMsg %d msg_size %d \n", vindex, numMsg, msg_size );
+ }else{
+ msg_size = maxDataLength;
+ //dbg("DhvVBitP", "Not last message %d\n", msg_size);
+ }
+
+ //compare with the rcv vbits
+ for(i = 0; i < msg_size; i++){
+ dbg("DhvVBitP", "numMsg %d bindex %d vbit %d vindex %d: msg_size %d local 0x%02x - rcv 0x%02x \n",numMsg, bindex, i, vindex, msg_size ,vbit[vindex*maxDataLength+i],rcv_dvbmsg->vbit[i]);
+ if(vbit[vindex*maxDataLength + i] != rcv_dvbmsg->vbit[i]){
+ version = rcv_dvbmsg->vbit[i]^vbit[vindex*maxDataLength + i];
+ mask = 1;
+ if(version != 0){
+ dbg("DhvVBitP", "There is a difference \n");
+ isDiff = TRUE;
+ for(j = 0; j < VBIT_LENGTH; j++){
+ if((version & mask) != 0){
+ diffIndex = (VBIT_LENGTH -j) + VBIT_LENGTH*i + vindex*maxDataLength - 1 ;
+ dbg("DhvVBitP", "Detect difference at %d, %d %d %d %d \n", diffIndex, i, j, vindex, maxDataLength);
+
+ diffKey = call DhvHelp.indexToKey(diffIndex);
+ call VectorLogic.setItem(diffKey);
+ }
+ mask = mask << 1;
+ }
+ }
+ }
+ }
+
+ //reset this bit
+ call VBitLogic.unsetVBitIndex(bindex);
+
+ if((isDiff == FALSE)){
+ bitIndexValue = call VBitLogic.getVBitState();
+ if(bitIndexValue == 0){
+ //tell DhvLogic to send the next bindex
+ bindex++;
+ dbg("DhvVBitP", "No Difference detected, move to bindex %d \n", bindex );
+ call VBitLogic.setVBitIndex(bindex);
+ }
+ }else{
+ dbg("DhvVBitP","difference detected, reset to 0 \n");
+ }
+ }
+ }
+}
--- /dev/null
+/**
+ * DHV Vector Message Configuration
+ *
+ * Define interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV modules.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+configuration DhvVectorC {
+ provides interface DhvDecision;
+
+ uses interface DhvSend as VectorSend;
+ uses interface DhvReceive as VectorReceive;
+ uses interface DhvLogic as VectorLogic;
+ uses interface DhvLogic as DataLogic;
+ uses interface DhvHelp;
+}
+
+implementation {
+ components DhvVectorP;
+ DhvDecision = DhvVectorP;
+ VectorSend = DhvVectorP;
+ VectorReceive = DhvVectorP;
+ DhvHelp = DhvVectorP;
+ VectorLogic = DhvVectorP.VectorLogic;
+ DataLogic = DhvVectorP.DataLogic;
+ components RandomC;
+ DhvVectorP.Random -> RandomC;
+
+}
--- /dev/null
+/**
+ * DHV Vector Message Configuration
+ *
+ * Define interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV modules.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+#include <Dhv.h>
+
+module DhvVectorP {
+ provides interface DhvDecision;
+
+ uses interface DhvSend as VectorSend;
+ uses interface DhvReceive as VectorReceive;
+ uses interface DhvLogic as VectorLogic;
+ uses interface DhvLogic as DataLogic;
+ uses interface DhvHelp;
+ uses interface Random;
+}
+
+implementation {
+ uint8_t commRate = 0;
+
+ int myComparator(const void* a, const void* b);
+
+ command uint8_t DhvDecision.getCommRate() {
+ return commRate;
+ }
+
+ command void DhvDecision.resetCommRate() {
+ commRate = 0;
+ }
+
+ command error_t DhvDecision.send() {
+ dhv_index_t i, j;
+ dhv_key_t sendkey;
+ bool* keyvector;
+ dhv_msg_t* dmsg;
+ dhv_vector_msg_t* dvmsg;
+ error_t status;
+
+ dbg("DhvVectorP", "prepare to send vector out \n");
+
+ dmsg = call VectorSend.getPayloadPtr();
+ if(dmsg == NULL) {
+ return FAIL;
+ }
+
+ keyvector = call VectorLogic.allItem();
+ dmsg->type = ID_DHV_VECTOR;
+ dvmsg = (dhv_vector_msg_t*) dmsg->content;
+
+ //dvmsg->unitLen = DHV_VECTOR_ENTRIES_PER_PACKET;
+
+ //TODO: need to check for concurrency in here
+ i = 0;
+ for(j = 0; j < UQCOUNT_DHV; j++){
+ if(keyvector[j] > ID_DHV_NO){
+ sendkey = call DhvHelp.indexToKey(j);
+
+ /*if(keyvector[j] == ID_DHV_REQ){
+ dbg("DhvVectorP", " keyvector %d == %d \n", keyvector[j], ID_DHV_REQ);
+ dmsg->type = ID_DHV_VECTOR_REQ;
+ }*/
+
+ if(i < DHV_VECTOR_ENTRIES_PER_PACKET) {
+ dvmsg->vector[i] = sendkey;
+ dvmsg->vector[i+1] = call DhvHelp.keyToVersion(sendkey);
+ dbg("DhvVectorP","diff vector 0x%08x 0x%08x %d %d \n",dvmsg->vector[i] , dvmsg->vector[i+1], j, keyvector[j]);
+ i = i + 2;
+ }else{ break; }
+ }
+ }
+
+ dvmsg->unitLen = i;
+
+ //TODO: need to fix
+ dbg("DhvVectorP", "Sending vector message out ...unitLen 0x%02x \n", dvmsg->unitLen);
+ status = call VectorSend.send(sizeof(dhv_msg_t) + sizeof(dhv_vector_msg_t) +
+ (i*sizeof(uint32_t)));
+
+ i = 0;
+ dbg("DhvVectorP","Send status %d vs FALSE %d \n", status, FALSE);
+
+ if(status == SUCCESS){dbg("DhvVectorP","status == SUCCESS\n");}
+ if(status == FAIL){dbg("DhvVectorP","status == FAIL\n");}
+
+ //TODO: need to check for actual send status here
+ if(TRUE)
+ {
+ dbg("DhvVectorP", "Send msg successfully \n");
+ for(j = 0; j < UQCOUNT_DHV; j++){
+ if(keyvector[j] > ID_DHV_NO){
+ sendkey = call DhvHelp.indexToKey(j);
+ if(i < DHV_VECTOR_ENTRIES_PER_PACKET) {
+ call VectorLogic.unsetItem(sendkey);
+ i = i + 2;
+ }else{
+ break;
+ }
+ }
+ }
+ }
+
+ dbg("DhvVectorP", "Sent vector message out ...unitLen %d \n", dvmsg->unitLen);
+ return SUCCESS;
+ }
+
+ /*TODO: a callback event to remove the sent vectors*/
+ event void VectorReceive.receive(void* payload, uint8_t len) {
+ dhv_vector_msg_t* dvmsg;
+ dhv_msg_t* dmsg;
+
+ uint8_t unitlen;
+ uint8_t i;
+ uint8_t type;
+ uint32_t vectorkey;
+ uint32_t vectorver;
+ uint32_t myver;
+
+ commRate = commRate + 1;
+
+ dmsg = (dhv_msg_t*) payload;
+ type = dmsg->type;
+
+ dvmsg = (dhv_vector_msg_t*) dmsg->content;
+ unitlen = dvmsg->unitLen;
+
+ dbg("DhvVectorP", "Receive vector msg len %u unitlen 0x%02x 0x%02x \n", len, unitlen, dvmsg->unitLen);
+
+ for(i = 0; i < unitlen; i += 2) {
+ vectorkey = dvmsg->vector[i];
+ vectorver = dvmsg->vector[i+1];
+ myver = call DhvHelp.keyToVersion(vectorkey);
+ dbg("DhvVectorP", "key 0x%08x version 0x%08x myver 0x%08x \n", vectorkey, vectorver, myver);
+ // TODO: handle the invalid versions
+ if(myver < vectorver) {
+ dbg("DhvVectorP", "I have an older version -> setReqItem \n");
+ call VectorLogic.setReqItem(vectorkey);
+ }
+ else if(myver > vectorver) {
+ dbg("DhvVectorP", "I have a newer version -> Data.setItem \n");
+ call DataLogic.setItem(vectorkey);
+ }
+ else{
+ if(type == ID_DHV_VECTOR_REQ){
+ dbg("DhvVectorP", "Request msg and I have that version -> Data.setItem \n");
+ call DataLogic.setItem(vectorkey);
+ }else{
+
+ dbg("DhvVectorP", "Request msg and I have the same version -> keep quite \n");
+ call VectorLogic.unsetItem(vectorkey);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+/**
+ * DHV Vector Message Configuration
+ *
+ * Define interfaces and components.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV modules.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+#include <Dhv.h>
+
+configuration DhvVersionC {
+ provides interface DhvHelp;
+ provides interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
+ provides interface DhvCache as DataCache;
+ provides interface DhvCache as VectorCache;
+}
+
+implementation {
+ components DhvVersionP;
+ DhvHelp = DhvVersionP;
+ DisseminationUpdate = DhvVersionP;
+ DataCache = DhvVersionP.DhvDataCache;
+ VectorCache = DhvVersionP.DhvVectorCache;
+}
--- /dev/null
+/**
+ * DHV Version Check Module
+ *
+ * Module checks version of the data item.
+ * details on the working of the parameters, please refer to Thanh Dang et al.,
+ * "DHV: A Code Consistency Maintenance Protocol for Multi-Hop Wireless Sensor
+ * Networks" EWSN 09.
+ *
+ * @author Thanh Dang
+ * @author Seungweon Park
+ *
+ * @modified 1/3/2009 Added meaningful documentation.
+ * @modified 8/28/2008 Defined DHV modules.
+ * @modified 8/28/2008 Took the source code from DIP.
+ **/
+
+module DhvVersionP {
+ provides interface DhvHelp;
+ provides interface DisseminationUpdate<dhv_data_t>[dhv_key_t key];
+ provides interface DhvCache as DhvDataCache;
+ provides interface DhvCache as DhvVectorCache;
+}
+
+implementation {
+
+ // keys are ordered from smallest to largest.
+ dhv_key_t keys[UQCOUNT_DHV];
+ dhv_version_t versions[UQCOUNT_DHV];
+ dhv_index_t count = 0;
+
+ //keep track of task
+ uint8_t data_to_send[UQCOUNT_DHV];
+ uint8_t vector_to_send[UQCOUNT_DHV];
+ uint8_t vbit[(UQCOUNT_DHV == 0)?0:((UQCOUNT_DHV-1)/VBIT_LENGTH +1)];
+
+/*utility for debugging purposes */
+ void printDataStatus()
+ {
+ dhv_index_t i;
+
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ dbg("DhvVersionP", "Data Status %d: %u \n",i, data_to_send[i]);
+ }
+ }
+
+
+ void printVectorStatus()
+ {
+ dhv_index_t i;
+
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ dbg("DhvVersionP", "T Vector Status %d: %u \n",i, vector_to_send[i]);
+ }
+ }
+
+
+ void printVersionStatus()
+ {
+ dhv_index_t i;
+
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ dbg("DhvVersionP", "Version Status %d: 0x%08x \n",i, versions[i]);
+ }
+ }
+
+
+ /*DhvDataCache interface implementation */
+ command void DhvDataCache.addItem(dhv_key_t key){
+ dhv_index_t i;
+
+ dbg("DhvVersionP", "Add Item to data vector key %d\n", i);
+ i = call DhvHelp.keyToIndex(key);
+ data_to_send[i] = ID_DHV_ADS;
+ printDataStatus();
+ }
+
+ command void DhvDataCache.addReqItem(dhv_key_t key){
+ dhv_index_t i;
+
+ dbg("DhvVersionP", "Add Req Item to data vector key %d\n", i);
+ i = call DhvHelp.keyToIndex(key);
+ data_to_send[i] = ID_DHV_REQ;
+ printDataStatus();
+ }
+
+ command void DhvDataCache.removeItem(dhv_key_t key){
+ dhv_index_t i;
+
+ i = call DhvHelp.keyToIndex(key);
+ data_to_send[i] = ID_DHV_NO;
+
+ dbg("DhvVersionP", "Remove Item from data vector key %d\n", i);
+ printDataStatus();
+ }
+
+ command bool DhvDataCache.hasItemToSend(){
+ dhv_index_t i;
+
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ if(data_to_send[i] > ID_DHV_NO){return TRUE;}
+ }
+ return FALSE;
+ }
+
+ command uint8_t* DhvDataCache.allItem(){
+ return data_to_send;
+ }
+
+ command uint8_t DhvDataCache.nextItem(){
+ dhv_index_t i;
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ if(data_to_send[i] > ID_DHV_NO ){
+ return i;
+ }
+ }
+ return UQCOUNT_DHV;
+ }
+
+ command void DhvDataCache.removeAll(){
+ dhv_index_t i;
+
+ for(i=0; i < UQCOUNT_DHV; i++){
+ data_to_send[i] = ID_DHV_NO;
+ }
+ }
+
+ /*vector cache */
+ command void DhvVectorCache.addItem(dhv_key_t key){
+ dhv_index_t i;
+
+ i = call DhvHelp.keyToIndex(key);
+ vector_to_send[i] = ID_DHV_ADS;
+
+ dbg("DhvVersionP", "Add Item to vector_to_send index %d\n", i);
+ printVectorStatus();
+ }
+
+ command void DhvVectorCache.addReqItem(dhv_key_t key){
+ dhv_index_t i;
+
+ i = call DhvHelp.keyToIndex(key);
+ vector_to_send[i] = ID_DHV_REQ;
+
+ dbg("DhvVersionP", "Add Item to vector_to_send index %d\n", i);
+ printVectorStatus();
+ }
+
+ command void DhvVectorCache.removeItem(dhv_key_t key){
+ dhv_index_t i;
+
+ i = call DhvHelp.keyToIndex(key);
+ vector_to_send[i] = ID_DHV_NO;
+
+ dbg("DhvVersionP", "Remove Item from vector_to_send index %d\n", i);
+ printVectorStatus();
+ }
+
+
+ command bool DhvVectorCache.hasItemToSend(){
+ dhv_index_t i;
+
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ if(vector_to_send[i] > ID_DHV_NO){return TRUE;}
+ }
+ return FALSE;
+ }
+
+ command uint8_t* DhvVectorCache.allItem(){
+ return vector_to_send;
+ }
+
+
+ command uint8_t DhvVectorCache.nextItem(){
+ dhv_index_t i;
+
+ for(i = 0; i < UQCOUNT_DHV; i++){
+ if(vector_to_send[i] > ID_DHV_NO){
+ return i;
+ }
+ }
+ return UQCOUNT_DHV;
+ }
+
+
+ command void DhvVectorCache.removeAll(){
+ dhv_index_t i;
+
+ for(i=0; i < UQCOUNT_DHV; i++){
+ vector_to_send[i] = ID_DHV_NO;
+ }
+ }
+
+
+ command void DhvHelp.registerKey(dhv_key_t key) {
+ keys[count] = key;
+ count = count + 1;
+ if(count == UQCOUNT_DHV) {
+ dbg("DhvVersionP","Key registration complete!\n");
+ }
+ //printVersionStatus();
+ }
+
+ command void DisseminationUpdate.change[dhv_key_t key](dhv_data_t* val) {
+ dhv_index_t i;
+ dhv_version_t ver;
+
+ dbg("DhvVersioP", "Updateing version for key %d \n", key);
+ i = call DhvHelp.keyToIndex(key);
+ ver = versions[i];
+ ver++;
+ versions[i] = ver;
+ printVersionStatus();
+ }
+
+ command dhv_index_t DhvHelp.keyToIndex(dhv_key_t key) {
+ dhv_index_t answer;
+ dhv_index_t i;
+
+ answer = DHV_UNKNOWN_INDEX;
+ // linear search for now since it's easier
+
+ for(i = 0; i < UQCOUNT_DHV; i++) {
+ if(keys[i] == key) {
+ answer = i;
+ break;
+ }
+ }
+ dbg("DhvVersionP", "Converting key %x to index %u\n", key, answer);
+ return answer;
+ }
+
+ command dhv_key_t DhvHelp.indexToKey(dhv_index_t ind) {
+ return keys[ind];
+ }
+
+ command dhv_version_t DhvHelp.keyToVersion(dhv_key_t key) {
+ dhv_index_t i;
+ i = call DhvHelp.keyToIndex(key);
+ return versions[i];
+ }
+
+ command void DhvHelp.setVersion(dhv_key_t key, dhv_version_t ver) {
+ dhv_index_t i;
+ i = call DhvHelp.keyToIndex(key);
+ versions[i] = ver;
+ dbg("DhvVersionP","Setting key %x at index %u to version 0x%08x\n", key, i, ver);
+ }
+
+ command dhv_version_t* DhvHelp.getAllVersions() {
+ return versions;
+ }
+
+ command uint32_t DhvHelp.computeHash(uint8_t left, uint8_t right, uint32_t salt) {
+ dhv_index_t i;
+ uint32_t hashValue = salt;
+ uint8_t *sequence;
+ if(right <= left) return 0;
+ sequence = ((uint8_t*) (versions + left));
+ for(i = 0; i <= (right-left-1)*sizeof(dhv_version_t); i++) {
+ hashValue += sequence[i];
+ hashValue += (hashValue << 10);
+ hashValue ^= (hashValue >> 6);
+ }
+ hashValue += (hashValue << 3);
+ hashValue ^= (hashValue >> 11);
+ hashValue += (hashValue << 15);
+ return hashValue;
+ }
+
+ command uint8_t* DhvHelp.getVBits(uint32_t bindex){
+ dhv_version_t version;
+ uint8_t cur_byte;
+ dhv_index_t i,j;
+
+
+ j = 0;
+ version = 0;
+ cur_byte = 0;
+
+ dbg("DhvVersionP", "getVBits at index %d \n", bindex);
+ printVersionStatus();
+
+ for(i = 1; i <= UQCOUNT_DHV; i++){
+ version = versions[i-1];
+ //dbg("DhvVersionP", "version %d 0x%08x \n", i, version);
+ version = (version >>(bindex-1)) << (DHV_VERSION_LENGTH*8-1) >> (j + 24); //get the bindex bit
+
+ //dbg("DhvVersionP", "shifted version 1 by %d : 0x%08x -> 0x%08x : %d \n", VBIT_LENGTH-1, versions[i-1], version, j);
+ cur_byte = cur_byte | version;
+ //dbg("DhvVersionP", "shifted version 2 0x%08x -> 0x%08x : %d cur_byte 0x%08x \n\n\n", versions[i-1], version, j, cur_byte);
+ j++;
+
+ if(j == VBIT_LENGTH){
+ //reset j
+ j = 0;
+ vbit[(i-1)/VBIT_LENGTH] = cur_byte;
+ dbg("DhvVersionP", "vertical bits %d 0x%02x 0x%02x \n", (i-1)/VBIT_LENGTH, cur_byte, vbit[(i-1)/VBIT_LENGTH]);
+ cur_byte = 0;
+ }
+ }
+
+ //debug
+ for(i= 0; i < sizeof(vbit); i++){
+ dbg("DhvVersionP", "vbit %d -> 0x%02x \n", i, vbit[i]);
+ }
+
+ return vbit;
+ }
+
+ command dhv_version_t DhvHelp.getHSum(){
+ dhv_version_t hsum;
+ dhv_index_t i;
+ hsum = versions[0];
+
+ for(i =1 ; i < UQCOUNT_DHV; i++){
+ hsum = hsum^versions[i];
+ }
+ return hsum;
+ }
+
+}
--- /dev/null
+
+#include <Dhv.h>
+
+configuration DisseminationC {
+ provides interface StdControl;
+}
+
+implementation {
+ components DhvLogicC;
+ StdControl = DhvLogicC;
+}
--- /dev/null
+#include <Dhv.h>
+
+/*
+ * Copyright (c) 2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ */
+
+/**
+ * The DisseminatorC component holds and synchronizes a single value
+ * of a chosen type, and identifies that value by a chosen 16-bit key.
+ * Different nodes should use the same key for the same value.
+ *
+ * See TEP118 - Dissemination for details.
+ *
+ * @param t the type of the object that will be disseminated
+ * @param key the 16-bit identifier of the disseminated object
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+generic configuration DisseminatorC(typedef t, dhv_key_t key) {
+ provides interface DisseminationValue<t>;
+ provides interface DisseminationUpdate<t>;
+}
+implementation {
+ enum {
+ JUST_NEED_COUNT = UQ_DHV
+ };
+
+ components new DisseminatorP(t, key);
+ DisseminationValue = DisseminatorP.AppDisseminationValue;
+ DisseminationUpdate = DisseminatorP.AppDisseminationUpdate;
+
+ components LedsC;
+ DisseminatorP.Leds -> LedsC;
+
+ components DhvLogicC;
+ DisseminatorP.DhvDisseminationUpdate -> DhvLogicC.DisseminationUpdate[key];
+
+ components DhvVersionC;
+ DisseminatorP.DhvHelp -> DhvVersionC;
+
+ components MainC;
+ MainC.SoftwareInit -> DisseminatorP;
+
+ components DhvDataC;
+ DhvDataC.DisseminationUpdate[key] -> DisseminatorP.DataDisseminationUpdate;
+ DhvDataC.DisseminationValue[key] -> DisseminatorP.DataDisseminationValue;
+}
--- /dev/null
+/*
+ * Copyright (c) 2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ */
+
+/**
+ * The DisseminatorP module holds and synchronizes a single value of a
+ * chosen type.
+ *
+ * See TEP118 - Dissemination for details.
+ *
+ * @param t the type of the object that will be disseminated
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+generic module DisseminatorP(typedef t, dhv_key_t key) {
+ provides interface DisseminationValue<t> as AppDisseminationValue;
+ provides interface DisseminationUpdate<t> as AppDisseminationUpdate;
+ provides interface DisseminationUpdate<dhv_data_t> as DataDisseminationUpdate;
+ provides interface DisseminationValue<dhv_data_t> as DataDisseminationValue;
+
+ provides interface Init;
+
+ uses interface DisseminationUpdate<dhv_data_t> as DhvDisseminationUpdate;
+ uses interface DhvHelp;
+ uses interface Leds;
+}
+implementation {
+ dhv_data_t valueCache;
+
+ task void signalNewData() {
+ signal AppDisseminationValue.changed();
+ }
+
+ command error_t Init.init() {
+ call DhvHelp.registerKey(key);
+ return SUCCESS;
+ }
+
+ // A sequence number is 32 bits. The top 16 bits are an incrementing
+ // counter, while the bottom 16 bits are a unique node identifier.
+ // But versions aren't stored here.
+
+ command const t* AppDisseminationValue.get() {
+ return (t*) &valueCache;
+ }
+
+ command void AppDisseminationValue.set( const t* val ) {
+ memcpy( &valueCache, val, sizeof(t) );
+ // must signal here instead of posting task to prevent race condition
+ signal AppDisseminationValue.changed();
+ }
+
+ command void AppDisseminationUpdate.change( t* newVal ) {
+ memcpy( &valueCache, newVal, sizeof(t) );
+ /* Increment the counter and append the local node ID later. */
+ /* DhvLogicC doesn't care what the data actually is,
+ it just wants the key, so we cast it recklessly */
+ call DhvDisseminationUpdate.change((dhv_data_t*)newVal);
+ post signalNewData();
+ }
+
+ command const dhv_data_t* DataDisseminationValue.get() {
+ return (dhv_data_t*) &valueCache;
+ }
+
+ command void DataDisseminationValue.set( const dhv_data_t* val ) { }
+
+ command void DataDisseminationUpdate.change( dhv_data_t* newVal ) {
+ memcpy( &valueCache, newVal, sizeof(dhv_data_t) );
+ // don't post the task, this came from the network
+ signal AppDisseminationValue.changed();
+ }
+
+
+ default event void AppDisseminationValue.changed() { }
+
+ default event void DataDisseminationValue.changed() { }
+
+}
--- /dev/null
+
+Title: Dhv
+Author: Thanh Dang, Seungweon Park
+------------------
+
+DHV is a code consistency maintenance protocol to ensure that every node
+in a network will eventually have the same code. DHV is based on the
+simple observation that if two code versions are different, their
+corresponding version numbers often differ in only a few least significant
+bits of their binary representation. DHV allows nodes to carefully select
+and transmit only necessary bit level information to detect a newer code version
+in the network. Detail of the protocol can be found here
+
+Thanh Dang, Nirupama Bulusu, Wu-chi Feng, and Seungweon Park,
+"DHV: A Code Consistent Maintenance Protocol for Wireless Sensor Networks.",
+In Proceedings of EWSN 2009, Cork, Ireland, Feb 2009.
+
+Usage:
+------
+
+To use include the following in your Makefile:
+
+CFLAGS += -I$(TOSDIR)/lib/net
+CFLAGS += -I$(TOSDIR)/lib/net/dhv
+CFLAGS += -I$(TOSDIR)/lib/net/dhv/interfaces
+
+* add a following line when use BaseStation
+CFLAGS += -DTOSH_DATA_LENGTH=32
+
--- /dev/null
+#include<Dhv.h>
+
+interface DhvCache{
+ command void addItem(dhv_key_t key);
+ command void addReqItem(dhv_key_t key);
+ command void removeItem(dhv_key_t key);
+ command bool hasItemToSend();
+ command uint8_t* allItem();
+ command uint8_t nextItem();
+ command void removeAll();
+}
+
--- /dev/null
+
+interface DhvDecision {
+ command uint8_t getCommRate();
+ command void resetCommRate();
+ command error_t send();
+}
--- /dev/null
+
+#include <Dhv.h>
+
+interface DhvEstimates {
+ command dhv_estimate_t* getEstimates();
+ command void decEstimateByIndex(dhv_index_t i);
+ command void decEstimateByKey(dhv_key_t key);
+ command dhv_hashlen_t estimateToHashlength(dhv_estimate_t est);
+ command dhv_estimate_t hashlengthToEstimate(dhv_hashlen_t len);
+ // special event to reset trickle timer too
+ command void setDataEstimate(dhv_key_t key);
+ command void setVectorEstimate(dhv_key_t key);
+ command void setSummaryEstimateByIndex(dhv_index_t ind,
+ dhv_estimate_t est);
+}
--- /dev/null
+
+#include <Dhv.h>
+
+interface DhvHelp {
+ command void registerKey(dhv_key_t key);
+
+ command dhv_index_t keyToIndex(dhv_key_t key);
+ command dhv_key_t indexToKey(dhv_index_t ind);
+ command dhv_version_t keyToVersion(dhv_key_t key);
+ command void setVersion(dhv_key_t key, dhv_version_t ver);
+ command dhv_version_t* getAllVersions();
+ command dhv_version_t getHSum();
+ command uint8_t* getVBits(uint32_t bindex);
+ command uint32_t computeHash(uint8_t left, uint8_t right,uint32_t salt);
+}
--- /dev/null
+#include<Dhv.h>
+
+interface DhvLogic{
+ command error_t setItem(dhv_key_t key);
+ command error_t setReqItem(dhv_key_t key);
+ command error_t unsetItem(dhv_key_t key);
+ command uint8_t nextItem();
+ command uint8_t * allItem();
+}
--- /dev/null
+#include<Dhv.h>
+interface DhvNeighbour{
+ command uint8_t getNeighbourCount();
+ command void addNeighbour(uint8_t nodeId);
+}
--- /dev/null
+
+interface DhvReceive {
+ event void receive(void* payload, uint8_t len);
+}
--- /dev/null
+
+interface DhvSend {
+ command error_t send(uint8_t len);
+ command void* getPayloadPtr();
+ command uint8_t maxPayloadLength();
+}
--- /dev/null
+interface DhvStateLogic{
+ command void setDiffSummary();
+ command void setSameSummary();
+ command uint32_t getVBitState();
+ command void setVBitState(uint32_t state);
+ command void unsetVBitIndex(uint8_t dindex);
+ command uint8_t getVBitIndex();
+ command void setVBitIndex(uint8_t dindex);
+ command void setHSumStatus();
+ command void unsetHSumStatus();
+ command uint8_t getHSumStatus();
+}
--- /dev/null
+// $Id$
+/*
+ * "Copyright (c) 2006 Stanford University. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ *
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/*
+ * A network trickle timer. A trickle timer has a period in the range
+ * [L, H]. After firing, the period is doubled, up to H. If the period
+ * is P, then the timer is scheduled to fire in the interval [0.5P, P]
+ * (the second half of a period). The period can be reset to L (the
+ * smallest period, and therefore the highest frequency).
+ *
+ * The timer may be suppressed. If a user of the interface has heard
+ * enough packets from other nodes that indicate its transmitting a
+ * packet would be unncessarily redundant, then the timer does not
+ * fire. The timer has a constant K and a counter C. If C >e; K, then
+ * the timer does not fire. When an interval ends, C is reset to 0.
+ * Calling <tt>incrementCounter</tt> increments C by one.
+ *
+ * For details, refer to Levis et al., "A Self-Regulating Algorithm
+ * for Code Maintenance and Propagation in Wireless Sensor Networks,"
+ * NSDI 2004. The component providing this interface defines the
+ * constants L, H, and K.
+ *
+ * @author Philip Levis
+ * @date Jan 7 2006
+ * @author Thanh Dang
+ * @date Aug 5 2009
+ */
+
+
+interface DhvTrickleTimer {
+
+ /**
+ * Start the trickle timer. At boot, the timer period is its maximum
+ * value (H). If a protocol requires starting at the minimum value
+ * (e.g., fast start), then it should call <tt>reset</tt> before
+ * <tt>start</tt>.
+ *
+ * @return error_t SUCCESS if the timer was started, EBUSY if it is already
+ * running, and FAIL otherwise.
+ */
+ command error_t start();
+
+ /**
+ * Stop the trickle timer. This call sets the timer period to H and
+ * C to 0.
+ */
+ command void stop();
+
+ /**
+ * Reset the timer period to L. If called while the timer is
+ * running, then a new interval (of length L) begins immediately.
+ */
+ command void reset();
+
+ /**
+ * The trickle timer has fired. Signaled if C > K.
+ */
+ event void fired();
+
+ /**
+ * Compute the window size based on Dip's estimates
+ */
+ event uint32_t requestWindowSize();
+
+ /**
+ * Resets the timer period to H.
+ */
+ command void maxInterval();
+}
--- /dev/null
+
+#include <Dhv.h>
+
+interface DhvVersion {
+ command void setVersion();
+ command void incVersion();
+}