⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delugep.nc

📁 tinyos-2.x.rar
💻 NC
字号:
/* Copyright (c) 2007 Johns Hopkins 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 (updated) modification history and the author appear in
*  all copies of this source code.
*
*  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 COPYRIGHT HOLDERS OR CONTRIBUTORS
*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
*  OR PROFITS) 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.
*/

/**
 * @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 DisseminationValue<DelugeCmd>;
    interface StdControl as DisseminationStdControl;
    interface ObjectTransfer;
    interface SplitControl as RadioSplitControl;
    interface NetProg;
    interface StorageMap[uint8_t volumeId];
    interface DelugeMetadata;
    interface DelugeVolumeManager;
    interface Resource;
  }
  provides {
    event void storageReady();
    command void stop();
  }
}

implementation
{
  enum {
    S_IDLE,
    S_PUB,
    S_RECV
  };

  DelugeCmd lastCmd;
  uint8_t state = S_IDLE;

  event void storageReady()
  {
    call RadioSplitControl.start();
  }

  event void Boot.booted()
  {
    lastCmd.uidhash = DELUGE_INVALID_UID;
  }

  event void RadioSplitControl.startDone(error_t error)
  {
    if (error == SUCCESS) {
      call DisseminationStdControl.start();
    }
  }

  command void stop()
  {
    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 {
      call Resource.request();
    }
  }

  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 Leds.set(LEDS_LED1 | LEDS_LED2);
    state = S_IDLE;
    
    if (error == SUCCESS) {
      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);
    }
  }

  event void DelugeMetadata.readDone(uint8_t imgNum, DelugeIdent* ident, error_t error)
  {
//    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();
      }
    } 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) {}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -