]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerP.nc
Fix the Deluge rollback gesture and increase the total number of Deluge images to...
[tinyos-2.x.git] / tos / lib / net / Deluge / FlashVolumeManager / FlashVolumeManagerP.nc
index f31c71603a0ee55ca7a95fd4d28006dacbf66ea0..bf29d2b3bc273eaede1bf54402c11d6dbb922526 100644 (file)
 generic module FlashVolumeManagerP()
 {
 #ifdef DELUGE
-  provides interface Notify<uint8_t>;
+  provides {
+    interface Notify<uint8_t> as DissNotify;
+    interface Notify<uint8_t> as ReprogNotify;
+  }
 #endif
   uses {
     interface BlockRead[uint8_t img_num];
     interface BlockWrite[uint8_t img_num];
-    interface StorageMap[uint8_t img_num];
-    interface AMSend as SerialAMSender;
-    interface Receive as SerialAMReceiver;
-    interface Leds;
 #ifdef DELUGE
+    interface DelugeStorage[uint8_t img_num];
     interface NetProg;
     interface Timer<TMilli> as Timer;
 #endif
+    interface AMSend as SerialAMSender;
+    interface Receive as SerialAMReceiver;
+    interface Leds;
   }
 }
 
@@ -55,6 +58,7 @@ implementation
     S_READ,
     S_CRC,
     S_REPROG,
+    S_SYNC,
   };
   
   message_t serialMsg;
@@ -67,7 +71,10 @@ implementation
    */
   void sendReply(error_t error, storage_len_t len)
   {
-    SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg);
+    SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
+    if (srpkt == NULL) {
+      return;
+    }
     if (error == SUCCESS) {
       srpkt->error = SERIALMSG_SUCCESS;
     } else {
@@ -82,7 +89,10 @@ implementation
                                error_t error)
   {
     if (state == S_READ) {
-      SerialReplyPacket *serialMsg_payload = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg);
+      SerialReplyPacket *serialMsg_payload = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
+      if (serialMsg_payload == NULL) {
+       return;
+      }
       if (buf == serialMsg_payload->data) {
         state = S_IDLE;
         sendReply(error, len + sizeof(SerialReplyPacket));
@@ -99,7 +109,10 @@ implementation
       state = S_IDLE;
       
       if (error == SUCCESS) {
-        SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg);
+        SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
+       if (srpkt == NULL) {
+         return;
+       }
         srpkt->data[1] = crc & 0xFF;
         srpkt->data[0] = (crc >> 8) & 0xFF;
       }
@@ -121,13 +134,18 @@ implementation
   event void BlockWrite.eraseDone[uint8_t img_num](error_t error)
   {
     if (state == S_ERASE) {
+      call BlockWrite.sync[img_num]();
+    }
+  }
+  
+  event void BlockWrite.syncDone[uint8_t img_num](error_t error)
+  {
+    if (state == S_ERASE || state == S_SYNC) {
       state = S_IDLE;
       sendReply(error, sizeof(SerialReplyPacket));
     }
   }
   
-  event void BlockWrite.syncDone[uint8_t img_num](error_t error) {}
-  
   event void SerialAMSender.sendDone(message_t* msg, error_t error) {}
   
   event message_t* SerialAMReceiver.receive(message_t* msg, void* payload, uint8_t len)
@@ -135,48 +153,80 @@ implementation
     error_t error = SUCCESS;
     SerialReqPacket *srpkt = (SerialReqPacket *)payload;
     SerialReplyPacket *serialMsg_payload =
-                              (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg);
-    
-    switch (srpkt->msg_type) {
-      case SERIALMSG_ERASE:    // === Erases a volume ===
-        state = S_ERASE;
-        error = call BlockWrite.erase[srpkt->img_num]();
-        break;
-      case SERIALMSG_WRITE:    // === Writes to a volume ===
-        state = S_WRITE;
-        memcpy(buffer, srpkt->data, srpkt->len);
-        error = call BlockWrite.write[srpkt->img_num](srpkt->offset,
-                                                      buffer,
-                                                      srpkt->len);
+      (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
+    uint8_t img_num = 0xFF;
+
+    if (serialMsg_payload == NULL) {
+      return msg;
+    }
+    // Converts the image number that the user wants to the real image number
+    switch (srpkt->img_num) {
+      case 0:
+        img_num = VOLUME_GOLDENIMAGE;
         break;
-      case SERIALMSG_READ:     // === Reads a portion of a volume ===
-        state = S_READ;
-        error = call BlockRead.read[srpkt->img_num](srpkt->offset,
-                                                    serialMsg_payload->data,
-                                                    srpkt->len);
+      case 1:
+        img_num = VOLUME_DELUGE1;
         break;
-      case SERIALMSG_CRC:      // === Computes CRC over a portion of a volume ===
-        state = S_CRC;
-        error = call BlockRead.computeCrc[srpkt->img_num](srpkt->offset,
-                                                          srpkt->len, 0);
+      case 2:
+        img_num = VOLUME_DELUGE2;
         break;
-      case SERIALMSG_ADDR:     // === Gets the physical starting address of a volume ===
-       *(nx_uint32_t*)(&serialMsg_payload->data) =
-                             (uint32_t)call StorageMap.getPhysicalAddress[srpkt->img_num](0);
-       sendReply(SUCCESS, sizeof(SerialReplyPacket) + 4);
+      case 3:
+        img_num = VOLUME_DELUGE3;
         break;
-#ifdef DELUGE
-      case SERIALMSG_REPROG:   // === Reboots and reprograms ===
-        state = S_REPROG;
-        sendReply(SUCCESS, sizeof(SerialReplyPacket));
-        img_num_reboot = srpkt->img_num;
-       call Timer.startOneShot(1024);
-       break;
-      case SERIALMSG_DISS:     // === Starts disseminating a volume ===
-       signal Notify.notify(srpkt->img_num);   // Notifies Deluge to start disseminate
-       sendReply(SUCCESS, sizeof(SerialReplyPacket));
-       break;
-#endif
+    }
+    
+    if (img_num != 0xFF) {
+      switch (srpkt->msg_type) {
+        case SERIALMSG_ERASE:    // === Erases a volume ===
+          state = S_ERASE;
+          error = call BlockWrite.erase[img_num]();
+          break;
+        case SERIALMSG_WRITE:    // === Writes to a volume ===
+          state = S_WRITE;
+          memcpy(buffer, srpkt->data, srpkt->len);
+          error = call BlockWrite.write[img_num](srpkt->offset,
+                                                        buffer,
+                                                        srpkt->len);
+          break;
+        case SERIALMSG_READ:     // === Reads a portion of a volume ===
+          state = S_READ;
+          error = call BlockRead.read[img_num](srpkt->offset,
+                                                      serialMsg_payload->data,
+                                                      srpkt->len);
+          break;
+        case SERIALMSG_CRC:      // === Computes CRC over a portion of a volume ===
+          state = S_CRC;
+          error = call BlockRead.computeCrc[img_num](srpkt->offset,
+                                                            srpkt->len, 0);
+          break;
+        case SERIALMSG_SYNC:     // === Sync the flash ===
+          state = S_SYNC;
+          error = call BlockWrite.sync[img_num]();
+         break;
+  #ifdef DELUGE
+        case SERIALMSG_ADDR:     // === Gets the physical starting address of a volume ===
+          *(nx_uint32_t*)(&serialMsg_payload->data) =
+                                  (uint32_t)call DelugeStorage.getPhysicalAddress[img_num](0);
+          sendReply(SUCCESS, sizeof(SerialReplyPacket) + 4);
+          break;
+        case SERIALMSG_REPROG_BS:   // === Reprograms only the base station ===
+          state = S_REPROG;
+          sendReply(SUCCESS, sizeof(SerialReplyPacket));
+          img_num_reboot = img_num;
+          call Timer.startOneShot(1024);
+          break;
+        case SERIALMSG_DISS:     // === Starts disseminating a volume ===
+          signal DissNotify.notify(img_num);   // Notifies Deluge to start disseminate
+          sendReply(SUCCESS, sizeof(SerialReplyPacket));
+          break;
+        case SERIALMSG_REPROG:   // === Reprograms the network (except the base station) ===
+          signal ReprogNotify.notify(img_num);
+          sendReply(SUCCESS, sizeof(SerialReplyPacket));
+          break;
+  #endif
+      }
+    } else {
+      error = FAIL;
     }
     
     // If a split-phase operation fails when being requested, signals the failure now
@@ -195,8 +245,12 @@ implementation
     call NetProg.programImgAndReboot(img_num_reboot);
   }
   
-  command error_t Notify.enable() { return SUCCESS; }
-  command error_t Notify.disable() { return SUCCESS; }
+  command error_t DissNotify.enable() { return SUCCESS; }
+  command error_t DissNotify.disable() { return SUCCESS; }
+  command error_t ReprogNotify.enable() { return SUCCESS; }
+  command error_t ReprogNotify.disable() { return SUCCESS; }
+  
+  default command storage_addr_t DelugeStorage.getPhysicalAddress[uint8_t img_num](storage_addr_t addr) { return 0; }
 #endif
 
   default command error_t BlockWrite.write[uint8_t img_num](storage_addr_t addr, void* buf, storage_len_t len) { return FAIL; }
@@ -204,6 +258,4 @@ implementation
   default command error_t BlockWrite.sync[uint8_t img_num]() { return FAIL; }
   default command error_t BlockRead.read[uint8_t img_num](storage_addr_t addr, void* buf, storage_len_t len) { return FAIL; }
   default command error_t BlockRead.computeCrc[uint8_t img_num](storage_addr_t addr, storage_len_t len, uint16_t crc) { return FAIL; }
-
-  default command storage_addr_t StorageMap.getPhysicalAddress[uint8_t img_num](storage_addr_t addr) { return 0; }
 }