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

📄 delugepatchp.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>
 */

#include "imgNum2volumeId.h"

module DelugePatchP
{
  provides interface DelugePatch[uint8_t client];
  uses {
    interface BlockRead[uint8_t volumeId];
    interface BlockWrite[uint8_t volumeId];
    interface StorageMap[uint8_t volumeId];
    event void storageReady();
  }
}

implementation
{
  enum {
    S_READ_IDENT,
    S_READY,
    S_BUSY,
    S_READ_PATCH_CMD,
    S_READ_PATCH_DATA, 
    S_READ_PATCH_COPY,
    S_WRITE_PATCH,
  };

  DelugeIdent ident;
  DelugePatchCmd patch;

  uint8_t patchData[MAX_PATCH_DATA_SIZE];

  uint8_t state;
  uint8_t currentClient;

  uint16_t patchNumLinesRead;
  uint16_t patchNumLines;

  uint32_t patchByteAddr;  
  uint8_t patchVolume;
  uint8_t patchImageIdx;
  uint8_t patchPage;

  uint32_t dstByteAddr;  
  uint8_t srcVolume;
  uint8_t srcImageIdx;
  uint8_t srcPage;

  uint32_t dstByteAddr;  
  uint8_t dstVolume;
  uint8_t dstImageIdx;
  uint8_t dstPage;


  void setStorageReady()
  {
    signal storageReady();
    state = S_READY;
  }

  void notifySuccess() 
  {
    signal DelugePatch.decodePatchDone[currentClient](
            patchImageIdx, srcImageIdx, dstImageIdx, SUCCESS);
    setStorageReady();
  }

  void notifyFailure(error_t error)
  {
    signal DelugePatch.decodePatchDone[currentClient](
            patchImageIdx, srcImageIdx, dstImageIdx, error);
    setStorageReady();
  }

  command error_t DelugePatch.decodePatch[uint8_t client](uint8_t imgNumPatch,
                                                          uint8_t imgNumSrc,
                                                          uint8_t imgNumDst)
  {
    patchImageIdx = imgNumPatch;
    patchVolume   = _imgNum2volumeId[patchImageIdx];
    srcImageIdx   = imgNumSrc;
    srcVolume     = _imgNum2volumeId[srcImageIdx];
    dstImageIdx   = imgNumDst;
    dstVolume     = _imgNum2volumeId[dstImageIdx];

    // First, read the DelugeIdent section.
    if (patchImageIdx < DELUGE_NUM_VOLUMES) {
      state = S_READ_IDENT;
      call BlockRead.read[patchVolume](0, &ident, sizeof(ident));
    } else {
      signal storageReady();
      state = S_READY;
    }

    return SUCCESS;
  }

  event void BlockRead.readDone[uint8_t imgNum](
    storage_addr_t addr, void* buf, storage_len_t len, error_t error)
  {
    switch (state) {
    case S_BUSY:
      notifyFailure(error);
      break;
    // Read the DelugeIdent structure into ident.
    // If it is valid, ident.userhash contains
    // number of patch command lines.
    // Initialize patchByteAddr to the beginning of
    // the patch commands.
    case S_READ_IDENT:
      if (error == SUCCESS) {
        if (ident.uidhash != DELUGE_INVALID_UID) {
          patchNumLines = ident.userhash;
          state = S_READ_PATCH_CMD;
          patchByteAddr = DELUGE_IDENT_SIZE + DELUGE_CRC_BLOCK_SIZE; 
          call BlockRead.read[patchVolume](patchByteAddr, &patch, sizeof(patch)); 
          break;
        } 
      }
      notifyFailure(error);
      break;
    // Read a patch command.
    // If successful, check it is UPLOAD or COPY.
    // For an UPLOAD commandy
    //   increment the number of patch lines read,
    //   increase patchByteAddr by PATCH_LINE_SIZE,
    //   and read the patch data.
    // For a COPY command,
    //   increment the number of patch lines read,
    //   increase patchByteAddr by PATCH_LINE_SIZE,
    //   and read data from the source volume.
    case S_READ_PATCH_CMD:
      if (error == SUCCESS) {
        if (patch.cmd == PATCH_CMD_UPLOAD) { 
          patchNumLinesRead++;
          patchByteAddr += PATCH_LINE_SIZE;  // read the next line of patch
          state = S_READ_PATCH_DATA;
          call BlockRead.read[patchVolume](patchByteAddr, patchData, patch.data_length);
          break;
        }
        else if (patch.cmd == PATCH_CMD_COPY) { 
          patchNumLinesRead++; 
          patchByteAddr += PATCH_LINE_SIZE;  // read the next line of patch
          state = S_READ_PATCH_COPY;
          call BlockRead.read[srcVolume](patch.src_offset, patchData, patch.data_length);
          break;
        }
      }
      notifyFailure(error);
      break;
    // When the patch data of PATCH_UPLOAD is ready,
    // increase patchByteAddr ceiling(len / PATCH_LINE_SIZE) * PATCH_LINE_SIZE,
    // and  write it into the destination volume.  
    case S_READ_PATCH_DATA:
      if (error == SUCCESS) {
        state = S_WRITE_PATCH;
        patchByteAddr += ((len + PATCH_LINE_SIZE - 1) / PATCH_LINE_SIZE * PATCH_LINE_SIZE); 
        call BlockWrite.write[dstVolume](patch.dst_offset, buf, len);
        break;
      }
      notifyFailure(error);
      break;
    // When the source data of PATCH_COPY is ready,
    // write it into the destination volume.
    case S_READ_PATCH_COPY:
      if (error == SUCCESS) {
        state = S_WRITE_PATCH;
        call BlockWrite.write[dstVolume](patch.dst_offset, buf, len);
        break;
      }
      notifyFailure(error);
      break;
    }
  }

  event void BlockWrite.writeDone[uint8_t imgNum](
    storage_addr_t addr, void* buf, storage_len_t len, error_t error) 
  {
    switch (state) {
    case S_WRITE_PATCH:
      if (error == SUCCESS) {
        // When more patch commands remaining, read the next one.
        if (patchNumLinesRead < patchNumLines) {
          state = S_READ_PATCH_CMD;
          call BlockRead.read[patchVolume](patchByteAddr, &patch, sizeof(patch)); 
        }
        else {
          notifySuccess();
        }
        break;
      }
      notifyFailure(error);
      break;
    }
  }

  event void BlockWrite.eraseDone[uint8_t imgNum](error_t error)
  {
    switch (state) {
    case S_READY:
      signal BlockWrite.eraseDone[imgNum](error);
      break;
    }
  }

  default command error_t BlockWrite.write[uint8_t imgNum](
    storage_addr_t addr, void* buf, storage_len_t len) { return FAIL; }
  default command error_t BlockRead.read[uint8_t imgNum](
    storage_addr_t addr, void* buf, storage_len_t len) { return FAIL; }
  default command error_t BlockRead.computeCrc[uint8_t imgNum](
    storage_addr_t addr, storage_len_t len, uint16_t crc) { return FAIL; }
  event void BlockRead.computeCrcDone[uint8_t imgNum](
    storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error) {}
  event void BlockWrite.syncDone[uint8_t imgNum](error_t error) {}
  default command error_t BlockWrite.erase[uint8_t imgNum]() { return FAIL; }
  default event void storageReady() {}
  default event void DelugePatch.decodePatchDone[uint8_t client](
    uint8_t imgNumPatch, uint8_t imgNumSrc, uint8_t imgNumDst, error_t error) {}

}

⌨️ 快捷键说明

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