nx_uint16_t sourceAddr;
nx_object_id_t objid;
nx_page_num_t pgNum;
- nx_uint8_t requestedPkts[DELUGE_PKT_BITVEC_SIZE];
+ nx_uint8_t requestedPkts[DELUGET2_PKT_BITVEC_SIZE];
} DelugeReqMsg;
typedef nx_struct DelugeDataMsg {
nx_object_id_t objid;
nx_page_num_t pgNum;
nx_uint8_t pktNum;
- nx_uint8_t data[DELUGE_PKT_PAYLOAD_SIZE];
+ nx_uint8_t data[DELUGET2_PKT_PAYLOAD_SIZE];
} DelugeDataMsg;
#endif
typedef nx_uint8_t nx_page_num_t;
enum {
- DELUGE_PKT_PAYLOAD_SIZE = TOSH_DATA_LENGTH - sizeof(nx_object_id_t) - sizeof(nx_page_num_t) - sizeof(nx_uint8_t),
- DELUGE_BYTES_PER_PAGE = 1024,
- DELUGE_PKTS_PER_PAGE = ((DELUGE_BYTES_PER_PAGE - 1) / DELUGE_PKT_PAYLOAD_SIZE) + 1,
-
+ DELUGET2_PKT_PAYLOAD_SIZE = TOSH_DATA_LENGTH - sizeof(nx_object_id_t) - sizeof(nx_page_num_t) - sizeof(nx_uint8_t),
+ DELUGET2_BYTES_PER_PAGE = 1024,
+ DELUGET2_PKTS_PER_PAGE = ((DELUGET2_BYTES_PER_PAGE - 1) / DELUGET2_PKT_PAYLOAD_SIZE) + 1,
+ DELUGET2_PKT_BITVEC_SIZE = (((DELUGET2_PKTS_PER_PAGE - 1) / 8) + 1),
+
+ DELUGE_PKT_PAYLOAD_SIZE = 23,
+ DELUGE_PKTS_PER_PAGE = 48,
+ DELUGE_BYTES_PER_PAGE = (DELUGE_PKTS_PER_PAGE*DELUGE_PKT_PAYLOAD_SIZE),
+
DELUGE_VERSION = 2,
DELUGE_MAX_ADV_PERIOD_LOG2 = 22,
DELUGE_NUM_NEWDATA_ADVS_REQUIRED = 2,
DELUGE_INVALID_ADDR = (0x7fffffffL),
DELUGE_MAX_REQ_DELAY = (0x1L << (DELUGE_MIN_ADV_PERIOD_LOG2 - 1)),
DELUGE_NACK_TIMEOUT = (DELUGE_MAX_REQ_DELAY >> 0x1),
- DELUGE_PKT_BITVEC_SIZE = (((DELUGE_PKTS_PER_PAGE - 1) / 8) + 1),
DELUGE_MAX_IMAGE_SIZE = (128L * 1024L),
DELUGE_MAX_PAGES = 128,
DELUGE_CRC_SIZE = sizeof(uint16_t),
implementation
{
// send/receive page buffers, and state variables for buffers
- uint8_t pktsToSend[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to send
- uint8_t pktsToReceive[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to receive
+ uint8_t pktsToSend[DELUGET2_PKT_BITVEC_SIZE]; // bit vec of packets to send
+ uint8_t pktsToReceive[DELUGET2_PKT_BITVEC_SIZE]; // bit vec of packets to receive
DelugeDataMsg rxQueue[DELUGE_QSIZE];
uint8_t head, size;
// send req message
else {
uint32_t i;
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pReqMsg->requestedPkts[i] = pktsToReceive[i];
}
//memcpy(pReqMsg->requestedPkts, pktsToReceive, DELUGE_PKT_BITVEC_SIZE);
storage_addr_t calcOffset(page_num_t pgNum, uint8_t pktNum)
{
- return (storage_addr_t)pgNum * (storage_addr_t)DELUGE_BYTES_PER_PAGE
- + (uint16_t)pktNum * (uint16_t)DELUGE_PKT_PAYLOAD_SIZE;
+ return (storage_addr_t)pgNum * (storage_addr_t)DELUGET2_BYTES_PER_PAGE
+ + (uint16_t)pktNum * (uint16_t)DELUGET2_PKT_PAYLOAD_SIZE;
//+ DELUGE_METADATA_SIZE;
}
pDataMsg->pktNum = 0;
}
- if (call BitVecUtils.indexOf(&nextPkt, pDataMsg->pktNum, pktsToSend, DELUGE_PKTS_PER_PAGE) != SUCCESS) {
+ if (call BitVecUtils.indexOf(&nextPkt, pDataMsg->pktNum, pktsToSend, DELUGET2_PKTS_PER_PAGE) != SUCCESS) {
// no more packets to send
//dbg(DBG_USR1, "DELUGE: SEND_DONE\n");
changeState(S_IDLE);
} else {
pDataMsg->pktNum = nextPkt;
- if (call BlockRead.read[imgNum](calcOffset(pageToSend, nextPkt), pDataMsg->data, DELUGE_PKT_PAYLOAD_SIZE) != SUCCESS) {
+ if (call BlockRead.read[imgNum](calcOffset(pageToSend, nextPkt), pDataMsg->data, DELUGET2_PKT_PAYLOAD_SIZE) != SUCCESS) {
call Timer.startOneShot(DELUGE_FAILED_SEND_DELAY);
}
}
if (objid < objToSend || (objid == objToSend && pgNum < pageToSend)) {
uint32_t i;
changeState(S_IDLE);
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pktsToSend[i] = 0x00;
}
//memset(pktsToSend, 0x00, DELUGE_PKT_BITVEC_SIZE);
void writeData()
{
if(call BlockWrite.write[imgNum](calcOffset(rxQueue[head].pgNum, rxQueue[head].pktNum),
- rxQueue[head].data, DELUGE_PKT_PAYLOAD_SIZE) != SUCCESS) {
+ rxQueue[head].data, DELUGET2_PKT_PAYLOAD_SIZE) != SUCCESS) {
size = 0;
}
}
workingObjid = DELUGE_INVALID_OBJID;
workingPgNum = DELUGE_INVALID_PGNUM;
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pktsToReceive[i] = 0x00;
}
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pktsToSend[i] = 0x00;
}
//memset(pktsToReceive, 0x00, DELUGE_PKT_BITVEC_SIZE);
workingObjid = new_objid;
workingPgNum = new_pgNum;
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pktsToReceive[i] = 0xFF;
}
//memset(pktsToReceive, (nx_uint8_t)0xff, DELUGE_PKT_BITVEC_SIZE);
&& objid == objToSend
&& pgNum == pageToSend)) {
// take union of packet bit vectors
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pktsToSend[i] |= rxReqMsg->requestedPkts[i];
}
}
// failed to write
if (error != SUCCESS) {
uint32_t i;
- for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) {
+ for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) {
pktsToReceive[i] = 0xFF;
}
size = 0;
head = (head + 1) % DELUGE_QSIZE;
size--;
- if (call BitVecUtils.indexOf(&tmp, 0, pktsToReceive, DELUGE_PKTS_PER_PAGE) != SUCCESS) {
+ if (call BitVecUtils.indexOf(&tmp, 0, pktsToReceive, DELUGET2_PKTS_PER_PAGE) != SUCCESS) {
// For collecting stats
//call StatsCollector.endRecvPageTransTime(publisher_addr);
dbg("Deluge", "%.3f 115 116 116 117 115 2 %d\n", ((float)((sim_time() * 1000) / sim_ticks_per_sec())) / 1000, publisher_addr);
interface DelugeStorage[uint8_t img_num];
interface DelugeMetadata;
- interface Notify<uint8_t>;
+ interface Notify<uint8_t> as ReadyNotify;
}
}
DelugeStorageP.Leds -> LedsC;
DelugeStorageP.Boot -> MainC;
- Notify = DelugeStorageP.Notify;
+ ReadyNotify = DelugeStorageP.ReadyNotify;
}
*/
#include "Deluge.h"
+#include "DelugePageTransfer.h"
module DelugeStorageP
{
interface DelugeStorage[uint8_t img_num];
interface DelugeMetadata;
- interface Notify<uint8_t>;
+ interface Notify<uint8_t> as ReadyNotify;
}
}
implementation
{
enum {
- S_INIT,
+ S_READ_META,
+ S_READ_CRC,
+ S_CRC,
S_READY,
};
- uint8_t state = S_INIT;
- uint8_t last_init_img_num = 0;
+ uint8_t state;
+ uint8_t current_image;
+ uint8_t current_page;
+ uint16_t current_crc;
DelugeImgDesc imgDesc[DELUGE_NUM_VOLUMES];
+ void nextImage()
+ {
+ if (current_image < DELUGE_NUM_VOLUMES) {
+ state = S_READ_META;
+ call SubBlockRead.read[current_image](0, &(imgDesc[current_image]), sizeof(DelugeImgDesc));
+ } else {
+ signal ReadyNotify.notify(SUCCESS);
+ state = S_READY;
+ }
+ }
+
+ uint32_t calcCrcAddr()
+ {
+ return DELUGE_METADATA_SIZE + current_page * sizeof(uint16_t);
+ }
+
+ uint32_t calcPageAddr()
+ {
+ return DELUGE_METADATA_SIZE + current_page * DELUGE_BYTES_PER_PAGE;
+ }
+
event void Boot.booted()
{
uint32_t i;
imgDesc[i].size = 0;
}
- // Reads image descriptions
- state = S_INIT;
- if (DELUGE_NUM_VOLUMES > 0) {
- call SubBlockRead.read[last_init_img_num](0, &(imgDesc[last_init_img_num]), sizeof(DelugeImgDesc));
- }
+ // We are going to iterate over all the images and verify their
+ // integrity. For each image we first read the metadata to find
+ // the number of pages and then iterate over all of them, compute
+ // the CRC and check it against the corresponding value from the CRCs
+ // block.
+ state = S_READ_META;
+ current_image = 0;
+ nextImage();
}
command DelugeImgDesc* DelugeMetadata.getImgDesc(imgnum_t imgNum)
// BlockRead events
event void SubBlockRead.readDone[uint8_t img_num](storage_addr_t addr, void* buf, storage_len_t len, error_t error)
{
- if (state == S_READY) {
+ switch (state) {
+ case S_READY:
signal BlockRead.readDone[img_num](addr, buf, len, error);
- } else {
- // Continues reading image descriptions
+ break;
+ case S_READ_META:
if (error == SUCCESS) {
- last_init_img_num++;
- if (last_init_img_num >= DELUGE_NUM_VOLUMES) {
- signal Notify.notify(SUCCESS);
- state = S_READY;
- } else {
- call SubBlockRead.read[last_init_img_num](0, &(imgDesc[last_init_img_num]), sizeof(DelugeImgDesc));
- }
+ if (imgDesc[current_image].uid != DELUGE_INVALID_UID) {
+ current_page = 0;
+ state = S_READ_CRC;
+ call SubBlockRead.read[current_image](calcCrcAddr(), ¤t_crc, sizeof(current_crc));
+ } else {
+ current_image++;
+ nextImage();
+ }
+ }
+ break;
+ case S_READ_CRC:
+ state = S_CRC;
+ if (current_page == 0) {
+ call SubBlockRead.computeCrc[current_image](calcPageAddr() + DELUGE_CRC_BLOCK_SIZE,
+ DELUGE_BYTES_PER_PAGE - DELUGE_CRC_BLOCK_SIZE, 0);
+ } else {
+ call SubBlockRead.computeCrc[current_image](calcPageAddr(), DELUGE_BYTES_PER_PAGE, 0);
}
+ break;
}
}
event void SubBlockRead.computeCrcDone[uint8_t img_num](storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error)
{
- signal BlockRead.computeCrcDone[img_num](addr, len, crc, error);
+ switch (state) {
+ case S_READY:
+ signal BlockRead.computeCrcDone[img_num](addr, len, crc, error);
+ break;
+ case S_CRC:
+ if (crc != current_crc) {
+ // invalidate the image by erasing it
+ call SubBlockWrite.erase[current_image]();
+ } else {
+ current_page++;
+ if (current_page < imgDesc[current_image].numPgs) {
+ state = S_READ_CRC;
+ call SubBlockRead.read[current_image](calcCrcAddr(), ¤t_crc, sizeof(current_crc));
+ } else {
+ current_image++;
+ nextImage();
+ }
+ }
+ break;
+ }
}
// SubBlockWrite commands
imgDesc[img_num].reserved = 0;
imgDesc[img_num].size = 0;
}
-
- signal BlockWrite.eraseDone[img_num](error);
+
+ switch (state) {
+ case S_READY:
+ signal BlockWrite.eraseDone[img_num](error);
+ break;
+ case S_CRC:
+ current_image++;
+ nextImage();
+ break;
+ }
}
event void SubBlockWrite.syncDone[uint8_t img_num](error_t error)
default command error_t SubBlockRead.computeCrc[uint8_t img_num](storage_addr_t addr, storage_len_t len, uint16_t crc) { return FAIL; }
default command storage_len_t SubBlockRead.getSize[uint8_t img_num]() { return 0; }
- command error_t Notify.enable() { return SUCCESS; }
- command error_t Notify.disable() { return SUCCESS; }
+ command error_t ReadyNotify.enable() { return SUCCESS; }
+ command error_t ReadyNotify.disable() { return SUCCESS; }
#if defined(PLATFORM_TELOSB)
default command storage_addr_t StorageMap.getPhysicalAddress[uint8_t img_num](storage_addr_t addr) { return 0xFFFFFFFF; }
state = S_INITIALIZING_PUB;
curObjDesc.objid = new_objid;
- curObjDesc.numPgs = ((new_size - 1) / DELUGE_BYTES_PER_PAGE) + 1; // Number of pages to transmit
+ curObjDesc.numPgs = ((new_size - 1) / DELUGET2_BYTES_PER_PAGE) + 1; // Number of pages to transmit
curObjDesc.numPgsComplete = curObjDesc.numPgs; // Publisher doesn't really care about this
curObjDesc.crc = call Crc.crc16(&curObjDesc, sizeof(object_id_t) + sizeof(page_num_t));
void cont_receive() {
state = S_INITIALIZING_RECV;
curObjDesc.objid = cont_receive_new_objid;
- curObjDesc.numPgs = ((cont_receive_new_size - 1) / DELUGE_BYTES_PER_PAGE) + 1; // Number of pages to receive
+ curObjDesc.numPgs = ((cont_receive_new_size - 1) / DELUGET2_BYTES_PER_PAGE) + 1; // Number of pages to receive
curObjDesc.numPgsComplete = 0;
curObjDesc.crc = call Crc.crc16(&curObjDesc, sizeof(object_id_t) + sizeof(page_num_t));