From 09c23fb9b147a4c6de48c812976eb74cd42a6718 Mon Sep 17 00:00:00 2001 From: xuanthanh18 Date: Sat, 22 Aug 2009 08:24:06 +0000 Subject: [PATCH] *** empty log message *** --- tos/lib/net/dhv/AMDhvC.nc | 46 ++ tos/lib/net/dhv/AMDhvP.nc | 158 +++++++ tos/lib/net/dhv/Dhv.h | 123 ++++++ tos/lib/net/dhv/DhvDataC.nc | 44 ++ tos/lib/net/dhv/DhvDataP.nc | 127 ++++++ tos/lib/net/dhv/DhvHSumC.nc | 29 ++ tos/lib/net/dhv/DhvHSumP.nc | 86 ++++ tos/lib/net/dhv/DhvLogicC.nc | 84 ++++ tos/lib/net/dhv/DhvLogicP.nc | 402 ++++++++++++++++++ tos/lib/net/dhv/DhvSummaryC.nc | 32 ++ tos/lib/net/dhv/DhvSummaryP.nc | 76 ++++ tos/lib/net/dhv/DhvTrickleMilliC.nc | 62 +++ tos/lib/net/dhv/DhvTrickleMilliP.nc | 120 ++++++ tos/lib/net/dhv/DhvVBitC.nc | 35 ++ tos/lib/net/dhv/DhvVBitP.nc | 218 ++++++++++ tos/lib/net/dhv/DhvVectorC.nc | 35 ++ tos/lib/net/dhv/DhvVectorP.nc | 163 +++++++ tos/lib/net/dhv/DhvVersionC.nc | 29 ++ tos/lib/net/dhv/DhvVersionP.nc | 321 ++++++++++++++ tos/lib/net/dhv/DisseminationC.nc | 11 + tos/lib/net/dhv/DisseminatorC.nc | 77 ++++ tos/lib/net/dhv/DisseminatorP.nc | 109 +++++ tos/lib/net/dhv/README | 29 ++ tos/lib/net/dhv/interfaces/DhvCache.nc | 12 + tos/lib/net/dhv/interfaces/DhvDecision.nc | 6 + tos/lib/net/dhv/interfaces/DhvEstimates.nc | 15 + tos/lib/net/dhv/interfaces/DhvHelp.nc | 15 + tos/lib/net/dhv/interfaces/DhvLogic.nc | 9 + tos/lib/net/dhv/interfaces/DhvNeighbour.nc | 5 + tos/lib/net/dhv/interfaces/DhvReceive.nc | 4 + tos/lib/net/dhv/interfaces/DhvSend.nc | 6 + tos/lib/net/dhv/interfaces/DhvStateLogic.nc | 12 + tos/lib/net/dhv/interfaces/DhvTrickleTimer.nc | 90 ++++ tos/lib/net/dhv/interfaces/DhvVersion.nc | 7 + 34 files changed, 2597 insertions(+) create mode 100755 tos/lib/net/dhv/AMDhvC.nc create mode 100755 tos/lib/net/dhv/AMDhvP.nc create mode 100755 tos/lib/net/dhv/Dhv.h create mode 100755 tos/lib/net/dhv/DhvDataC.nc create mode 100755 tos/lib/net/dhv/DhvDataP.nc create mode 100755 tos/lib/net/dhv/DhvHSumC.nc create mode 100755 tos/lib/net/dhv/DhvHSumP.nc create mode 100755 tos/lib/net/dhv/DhvLogicC.nc create mode 100755 tos/lib/net/dhv/DhvLogicP.nc create mode 100755 tos/lib/net/dhv/DhvSummaryC.nc create mode 100755 tos/lib/net/dhv/DhvSummaryP.nc create mode 100755 tos/lib/net/dhv/DhvTrickleMilliC.nc create mode 100755 tos/lib/net/dhv/DhvTrickleMilliP.nc create mode 100755 tos/lib/net/dhv/DhvVBitC.nc create mode 100755 tos/lib/net/dhv/DhvVBitP.nc create mode 100755 tos/lib/net/dhv/DhvVectorC.nc create mode 100755 tos/lib/net/dhv/DhvVectorP.nc create mode 100755 tos/lib/net/dhv/DhvVersionC.nc create mode 100755 tos/lib/net/dhv/DhvVersionP.nc create mode 100755 tos/lib/net/dhv/DisseminationC.nc create mode 100755 tos/lib/net/dhv/DisseminatorC.nc create mode 100755 tos/lib/net/dhv/DisseminatorP.nc create mode 100755 tos/lib/net/dhv/README create mode 100755 tos/lib/net/dhv/interfaces/DhvCache.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvDecision.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvEstimates.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvHelp.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvLogic.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvNeighbour.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvReceive.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvSend.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvStateLogic.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvTrickleTimer.nc create mode 100755 tos/lib/net/dhv/interfaces/DhvVersion.nc diff --git a/tos/lib/net/dhv/AMDhvC.nc b/tos/lib/net/dhv/AMDhvC.nc new file mode 100755 index 00000000..ffa47b15 --- /dev/null +++ b/tos/lib/net/dhv/AMDhvC.nc @@ -0,0 +1,46 @@ +/** + * 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 + +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; + +} diff --git a/tos/lib/net/dhv/AMDhvP.nc b/tos/lib/net/dhv/AMDhvP.nc new file mode 100755 index 00000000..22d275de --- /dev/null +++ b/tos/lib/net/dhv/AMDhvP.nc @@ -0,0 +1,158 @@ +/** + * 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; + } +} diff --git a/tos/lib/net/dhv/Dhv.h b/tos/lib/net/dhv/Dhv.h new file mode 100755 index 00000000..8731f79d --- /dev/null +++ b/tos/lib/net/dhv/Dhv.h @@ -0,0 +1,123 @@ +/** + * 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 diff --git a/tos/lib/net/dhv/DhvDataC.nc b/tos/lib/net/dhv/DhvDataC.nc new file mode 100755 index 00000000..6b0d15b0 --- /dev/null +++ b/tos/lib/net/dhv/DhvDataC.nc @@ -0,0 +1,44 @@ +/** +* 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_key_t key]; + uses interface DisseminationValue[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; +} diff --git a/tos/lib/net/dhv/DhvDataP.nc b/tos/lib/net/dhv/DhvDataP.nc new file mode 100755 index 00000000..b1259dba --- /dev/null +++ b/tos/lib/net/dhv/DhvDataP.nc @@ -0,0 +1,127 @@ +/** + * 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 + +module DhvDataP { + provides interface DhvDecision; + + uses interface DhvSend as DataSend; + uses interface DhvReceive as DataReceive; + + uses interface DisseminationUpdate[dhv_key_t key]; + uses interface DisseminationValue[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) { } + +} diff --git a/tos/lib/net/dhv/DhvHSumC.nc b/tos/lib/net/dhv/DhvHSumC.nc new file mode 100755 index 00000000..6b98086f --- /dev/null +++ b/tos/lib/net/dhv/DhvHSumC.nc @@ -0,0 +1,29 @@ +/** + * 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; +} diff --git a/tos/lib/net/dhv/DhvHSumP.nc b/tos/lib/net/dhv/DhvHSumP.nc new file mode 100755 index 00000000..451f4423 --- /dev/null +++ b/tos/lib/net/dhv/DhvHSumP.nc @@ -0,0 +1,86 @@ +/** + * 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 + +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); + } + } +} diff --git a/tos/lib/net/dhv/DhvLogicC.nc b/tos/lib/net/dhv/DhvLogicC.nc new file mode 100755 index 00000000..b349bdfe --- /dev/null +++ b/tos/lib/net/dhv/DhvLogicC.nc @@ -0,0 +1,84 @@ +/** + * 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 + +configuration DhvLogicC { + provides interface DisseminationUpdate[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; +} diff --git a/tos/lib/net/dhv/DhvLogicP.nc b/tos/lib/net/dhv/DhvLogicP.nc new file mode 100755 index 00000000..de9d3caf --- /dev/null +++ b/tos/lib/net/dhv/DhvLogicP.nc @@ -0,0 +1,402 @@ +/** + * 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 + +module DhvLogicP { + provides interface DisseminationUpdate[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 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; + } +} diff --git a/tos/lib/net/dhv/DhvSummaryC.nc b/tos/lib/net/dhv/DhvSummaryC.nc new file mode 100755 index 00000000..0cece24d --- /dev/null +++ b/tos/lib/net/dhv/DhvSummaryC.nc @@ -0,0 +1,32 @@ +/** + * 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; +} diff --git a/tos/lib/net/dhv/DhvSummaryP.nc b/tos/lib/net/dhv/DhvSummaryP.nc new file mode 100755 index 00000000..0902f13a --- /dev/null +++ b/tos/lib/net/dhv/DhvSummaryP.nc @@ -0,0 +1,76 @@ +/** + * 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 + +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"); + } + } +} diff --git a/tos/lib/net/dhv/DhvTrickleMilliC.nc b/tos/lib/net/dhv/DhvTrickleMilliC.nc new file mode 100755 index 00000000..1ae0291d --- /dev/null +++ b/tos/lib/net/dhv/DhvTrickleMilliC.nc @@ -0,0 +1,62 @@ +// $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; +} + + diff --git a/tos/lib/net/dhv/DhvTrickleMilliP.nc b/tos/lib/net/dhv/DhvTrickleMilliP.nc new file mode 100755 index 00000000..ab25c3ca --- /dev/null +++ b/tos/lib/net/dhv/DhvTrickleMilliP.nc @@ -0,0 +1,120 @@ +// $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 +#include + +module DhvTrickleMilliP { + provides { + interface Init; + interface DhvTrickleTimer as TrickleTimer; + } + uses { + interface Timer as PeriodicIntervalTimer; + interface Timer 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(); + } +} + + diff --git a/tos/lib/net/dhv/DhvVBitC.nc b/tos/lib/net/dhv/DhvVBitC.nc new file mode 100755 index 00000000..cdec7ee8 --- /dev/null +++ b/tos/lib/net/dhv/DhvVBitC.nc @@ -0,0 +1,35 @@ +/** + * 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; +} diff --git a/tos/lib/net/dhv/DhvVBitP.nc b/tos/lib/net/dhv/DhvVBitP.nc new file mode 100755 index 00000000..07579c29 --- /dev/null +++ b/tos/lib/net/dhv/DhvVBitP.nc @@ -0,0 +1,218 @@ +/** + * 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 + +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"); + } + } + } +} diff --git a/tos/lib/net/dhv/DhvVectorC.nc b/tos/lib/net/dhv/DhvVectorC.nc new file mode 100755 index 00000000..7f14e558 --- /dev/null +++ b/tos/lib/net/dhv/DhvVectorC.nc @@ -0,0 +1,35 @@ +/** + * 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; + +} diff --git a/tos/lib/net/dhv/DhvVectorP.nc b/tos/lib/net/dhv/DhvVectorP.nc new file mode 100755 index 00000000..9a3b5870 --- /dev/null +++ b/tos/lib/net/dhv/DhvVectorP.nc @@ -0,0 +1,163 @@ +/** + * 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 + +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); + } + } + } + } +} diff --git a/tos/lib/net/dhv/DhvVersionC.nc b/tos/lib/net/dhv/DhvVersionC.nc new file mode 100755 index 00000000..7b7f320d --- /dev/null +++ b/tos/lib/net/dhv/DhvVersionC.nc @@ -0,0 +1,29 @@ +/** + * 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 + +configuration DhvVersionC { + provides interface DhvHelp; + provides interface DisseminationUpdate[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; +} diff --git a/tos/lib/net/dhv/DhvVersionP.nc b/tos/lib/net/dhv/DhvVersionP.nc new file mode 100755 index 00000000..cc89a2f9 --- /dev/null +++ b/tos/lib/net/dhv/DhvVersionP.nc @@ -0,0 +1,321 @@ +/** + * 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_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; + } + +} diff --git a/tos/lib/net/dhv/DisseminationC.nc b/tos/lib/net/dhv/DisseminationC.nc new file mode 100755 index 00000000..989eca94 --- /dev/null +++ b/tos/lib/net/dhv/DisseminationC.nc @@ -0,0 +1,11 @@ + +#include + +configuration DisseminationC { + provides interface StdControl; +} + +implementation { + components DhvLogicC; + StdControl = DhvLogicC; +} diff --git a/tos/lib/net/dhv/DisseminatorC.nc b/tos/lib/net/dhv/DisseminatorC.nc new file mode 100755 index 00000000..d546f80b --- /dev/null +++ b/tos/lib/net/dhv/DisseminatorC.nc @@ -0,0 +1,77 @@ +#include + +/* + * 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 + * @version $Revision$ $Date$ + */ + +generic configuration DisseminatorC(typedef t, dhv_key_t key) { + provides interface DisseminationValue; + provides interface DisseminationUpdate; +} +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; +} diff --git a/tos/lib/net/dhv/DisseminatorP.nc b/tos/lib/net/dhv/DisseminatorP.nc new file mode 100755 index 00000000..6ecec982 --- /dev/null +++ b/tos/lib/net/dhv/DisseminatorP.nc @@ -0,0 +1,109 @@ +/* + * 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 + * @version $Revision$ $Date$ + */ + +generic module DisseminatorP(typedef t, dhv_key_t key) { + provides interface DisseminationValue as AppDisseminationValue; + provides interface DisseminationUpdate as AppDisseminationUpdate; + provides interface DisseminationUpdate as DataDisseminationUpdate; + provides interface DisseminationValue as DataDisseminationValue; + + provides interface Init; + + uses interface DisseminationUpdate 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() { } + +} diff --git a/tos/lib/net/dhv/README b/tos/lib/net/dhv/README new file mode 100755 index 00000000..b465e6cf --- /dev/null +++ b/tos/lib/net/dhv/README @@ -0,0 +1,29 @@ + +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 + diff --git a/tos/lib/net/dhv/interfaces/DhvCache.nc b/tos/lib/net/dhv/interfaces/DhvCache.nc new file mode 100755 index 00000000..973ca190 --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvCache.nc @@ -0,0 +1,12 @@ +#include + +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(); +} + diff --git a/tos/lib/net/dhv/interfaces/DhvDecision.nc b/tos/lib/net/dhv/interfaces/DhvDecision.nc new file mode 100755 index 00000000..8580760c --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvDecision.nc @@ -0,0 +1,6 @@ + +interface DhvDecision { + command uint8_t getCommRate(); + command void resetCommRate(); + command error_t send(); +} diff --git a/tos/lib/net/dhv/interfaces/DhvEstimates.nc b/tos/lib/net/dhv/interfaces/DhvEstimates.nc new file mode 100755 index 00000000..9143677d --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvEstimates.nc @@ -0,0 +1,15 @@ + +#include + +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); +} diff --git a/tos/lib/net/dhv/interfaces/DhvHelp.nc b/tos/lib/net/dhv/interfaces/DhvHelp.nc new file mode 100755 index 00000000..806ebabd --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvHelp.nc @@ -0,0 +1,15 @@ + +#include + +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); +} diff --git a/tos/lib/net/dhv/interfaces/DhvLogic.nc b/tos/lib/net/dhv/interfaces/DhvLogic.nc new file mode 100755 index 00000000..dc57e2c0 --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvLogic.nc @@ -0,0 +1,9 @@ +#include + +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(); +} diff --git a/tos/lib/net/dhv/interfaces/DhvNeighbour.nc b/tos/lib/net/dhv/interfaces/DhvNeighbour.nc new file mode 100755 index 00000000..b8ea315d --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvNeighbour.nc @@ -0,0 +1,5 @@ +#include +interface DhvNeighbour{ + command uint8_t getNeighbourCount(); + command void addNeighbour(uint8_t nodeId); +} diff --git a/tos/lib/net/dhv/interfaces/DhvReceive.nc b/tos/lib/net/dhv/interfaces/DhvReceive.nc new file mode 100755 index 00000000..ebaeeb10 --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvReceive.nc @@ -0,0 +1,4 @@ + +interface DhvReceive { + event void receive(void* payload, uint8_t len); +} diff --git a/tos/lib/net/dhv/interfaces/DhvSend.nc b/tos/lib/net/dhv/interfaces/DhvSend.nc new file mode 100755 index 00000000..9fef6fbe --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvSend.nc @@ -0,0 +1,6 @@ + +interface DhvSend { + command error_t send(uint8_t len); + command void* getPayloadPtr(); + command uint8_t maxPayloadLength(); +} diff --git a/tos/lib/net/dhv/interfaces/DhvStateLogic.nc b/tos/lib/net/dhv/interfaces/DhvStateLogic.nc new file mode 100755 index 00000000..9d2e71c2 --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvStateLogic.nc @@ -0,0 +1,12 @@ +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(); +} diff --git a/tos/lib/net/dhv/interfaces/DhvTrickleTimer.nc b/tos/lib/net/dhv/interfaces/DhvTrickleTimer.nc new file mode 100755 index 00000000..322bc4f4 --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvTrickleTimer.nc @@ -0,0 +1,90 @@ +// $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 incrementCounter 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 reset before + * start. + * + * @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(); +} diff --git a/tos/lib/net/dhv/interfaces/DhvVersion.nc b/tos/lib/net/dhv/interfaces/DhvVersion.nc new file mode 100755 index 00000000..b2b36843 --- /dev/null +++ b/tos/lib/net/dhv/interfaces/DhvVersion.nc @@ -0,0 +1,7 @@ + +#include + +interface DhvVersion { + command void setVersion(); + command void incVersion(); +} -- 2.39.2