]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/Deluge/DelugeP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / lib / net / Deluge / DelugeP.nc
index 81020484e06fc9f0fe626c7a1e240810a646e376..e5dc2efa62722082bf6d277096b649c26e086ec8 100644 (file)
 */
 
 /**
- * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
  * @author Razvan Musaloiu-E. <razvanm@cs.jhu.edu>
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
  */
 
 module DelugeP
 {
   uses {
+    interface Boot;
     interface Leds;
-    interface Notify<uint8_t> as StorageReadyNotify;
-    interface DisseminationUpdate<DelugeDissemination>;
-    interface DisseminationValue<DelugeDissemination>;
-    interface StdControl as StdControlDissemination;
-    interface DelugeMetadata;
+    interface DisseminationValue<DelugeCmd>;
+    interface StdControl as DisseminationStdControl;
     interface ObjectTransfer;
-    interface NetProg;
-    interface InternalFlash as IFlash;
     interface SplitControl as RadioSplitControl;
-    
-#ifdef DELUGE_BASESTATION
-    interface Notify<uint8_t> as ReprogNotify;
-#endif
+    interface NetProg;
+    interface StorageMap[uint8_t volumeId];
+    interface DelugeMetadata;
+    interface DelugeVolumeManager;
+    interface Resource;
+  }
+  provides {
+    event void storageReady();
+    command void stop();
   }
 }
 
 implementation
 {
-  uint8_t img_num;
-  
-  /**
-   * Starts the radio
-   */
-  event void StorageReadyNotify.notify(uint8_t val)
+  enum {
+    S_IDLE,
+    S_PUB,
+    S_RECV
+  };
+
+  DelugeCmd lastCmd;
+  uint8_t state = S_IDLE;
+
+  event void storageReady()
   {
     call RadioSplitControl.start();
   }
 
-#ifdef DELUGE_BASESTATION
-  /**
-   * Starts disseminating image information
-   */
-  event void ReprogNotify.notify(uint8_t new_img_num)
+  event void Boot.booted()
   {
-    DelugeDissemination delugeDis;
-    DelugeImgDesc *imgDesc;
-    
-    imgDesc = call DelugeMetadata.getImgDesc(new_img_num);
-    if (imgDesc->uid != DELUGE_INVALID_UID) {
-      call ObjectTransfer.stop();
-      call Leds.led0Toggle();
-      img_num = new_img_num;
-      
-      delugeDis.uid = imgDesc->uid;
-      delugeDis.vNum = imgDesc->vNum;
-      delugeDis.imgNum = imgDesc->imgNum;
-      delugeDis.size = imgDesc->size;
-      
-      call DisseminationUpdate.change(&delugeDis);   // Disseminates image information
-      call ObjectTransfer.publish(delugeDis.uid,
-                                  delugeDis.size,
-                                  delugeDis.imgNum);   // Prepares to publish image data
+    lastCmd.uidhash = DELUGE_INVALID_UID;
+  }
+
+  event void RadioSplitControl.startDone(error_t error)
+  {
+    if (error == SUCCESS) {
+      call DisseminationStdControl.start();
     }
   }
-#endif
 
-  /**
-   * Receives a disseminated message. If the message contains information about a
-   * newer image, then we should grab this image from the network
-   */
-  event void DisseminationValue.changed()
+  command void stop()
   {
-    const DelugeDissemination *delugeDis = call DisseminationValue.get();
-    DelugeImgDesc *imgDesc = call DelugeMetadata.getImgDesc(delugeDis->imgNum);
-    
-    if (imgDesc->uid == delugeDis->uid) {
-      if (imgDesc->vNum < delugeDis->vNum) {
-        img_num = delugeDis->imgNum;   // Note which image number to boot
-        call ObjectTransfer.receive(delugeDis->uid, delugeDis->size, delugeDis->imgNum);
-      }
+    call Resource.release();
+    if (state == S_RECV) {
+//      printf("erase %d\n", lastCmd.imgNum);
+      call DelugeVolumeManager.erase(lastCmd.imgNum);
+    }
+    call ObjectTransfer.stop();
+    state = S_IDLE;
+  }
+
+  task void taskRequest()
+  {
+    signal Resource.granted();
+  }
+  
+  void request()
+  {
+    if (call Resource.isOwner()) {
+      post taskRequest();
     } else {
-      img_num = delugeDis->imgNum;   // Note which image number to boot
-      call ObjectTransfer.receive(delugeDis->uid, delugeDis->size, delugeDis->imgNum);
+      call Resource.request();
     }
   }
 
-  /**
-   * Reboots and reprograms with the newly received image
-   */
+  event void DisseminationValue.changed()
+  {
+    const DelugeCmd *cmd = call DisseminationValue.get();
+//    printf("cmd: %d uidhash: 0x%lx imgNum: %d size: %u\n", cmd->type, cmd->uidhash, cmd->imgNum, cmd->size);
+    switch (cmd->type) {
+    case DELUGE_CMD_STOP:
+      call stop();
+      break;
+    case DELUGE_CMD_ONLY_DISSEMINATE:
+    case DELUGE_CMD_DISSEMINATE_AND_REPROGRAM:
+      if (state == S_RECV) {
+       if (cmd->uidhash == lastCmd.uidhash) {
+         if (cmd->imgNum == lastCmd.imgNum) {
+           // Same uidhash, same imgNum, only cmd should be
+           // different.  That will be properly updated by the last
+           // statement from this function.
+           break;
+         }
+       }
+       call stop();
+      }
+      if (cmd->uidhash != IDENT_UIDHASH) {
+       call DelugeMetadata.read(cmd->imgNum);
+      } else {
+       state = S_PUB;
+       request();
+      }
+      break;
+    }
+    lastCmd = *cmd;
+//    printf("lastCmd: %d uidhash: 0x%lx\n", lastCmd.type, lastCmd.uidhash);
+  }
+  
   event void ObjectTransfer.receiveDone(error_t error)
   {
-    call ObjectTransfer.stop();
+    call Leds.set(LEDS_LED1 | LEDS_LED2);
+    state = S_IDLE;
+    
     if (error == SUCCESS) {
-      call NetProg.programImgAndReboot(img_num);
+      switch (lastCmd.type) {
+      case DELUGE_CMD_ONLY_DISSEMINATE:
+       state = S_PUB;
+       request();
+       break;
+      case DELUGE_CMD_DISSEMINATE_AND_REPROGRAM:
+       call NetProg.programImageAndReboot(call StorageMap.getPhysicalAddress[lastCmd.imgNum](0));
+       break;
+      }
+    } else {
+      call DelugeVolumeManager.erase(lastCmd.imgNum);
     }
   }
 
-  /**
-   * Prepares to publish the image that was just reprogrammed
-   */
-  event void RadioSplitControl.startDone(error_t error)
+  event void DelugeMetadata.readDone(uint8_t imgNum, DelugeIdent* ident, error_t error)
   {
-    if (error == SUCCESS) {
-      // Start publishing the current image
-      DelugeImgDesc *imgDesc;
-      DelugeNodeDesc nodeDesc;
-      call IFlash.read((uint8_t*)IFLASH_NODE_DESC_ADDR,
-                       &nodeDesc,
-                       sizeof(DelugeNodeDesc));   // Reads which image was just reprogrammed
-      imgDesc = call DelugeMetadata.getImgDesc(nodeDesc.imgNum);
-      if (nodeDesc.uid == imgDesc->uid && imgDesc->uid != DELUGE_INVALID_UID) {
-        call ObjectTransfer.publish(imgDesc->uid, imgDesc->size, imgDesc->imgNum);
+//    printf("readDone 0x%lx imgNum: %d size: %lu\n", lastCmd.uidhash, lastCmd.imgNum, lastCmd.size);
+    if (ident->uidhash == lastCmd.uidhash) {
+      if (lastCmd.type == DELUGE_CMD_DISSEMINATE_AND_REPROGRAM) {
+       call NetProg.programImageAndReboot(call StorageMap.getPhysicalAddress[imgNum](0));
+      } else {
+       // We already have the image so we'll go ahead and start publishing.
+       state = S_PUB;
+       request();
       }
-            
-      call StdControlDissemination.start();
+    } else {
+      state = S_RECV;
+      request();
     }
   }
-  
+
+  event void Resource.granted()
+  {
+    switch (state) {
+    case S_PUB:
+//      printf("start pub 0x%lx imgNum: %d size: %u\n", lastCmd.uidhash, lastCmd.imgNum, lastCmd.size);
+      call ObjectTransfer.publish(lastCmd.uidhash, lastCmd.size, lastCmd.imgNum);
+      break;
+    case S_RECV:
+      call ObjectTransfer.receive(lastCmd.uidhash, lastCmd.size, lastCmd.imgNum);
+      break;
+    }
+  }
+
+  event void DelugeVolumeManager.eraseDone(uint8_t imgNum) {}
   event void RadioSplitControl.stopDone(error_t error) {}
+  default async void command Leds.set(uint8_t val) {}
 }