📄 delugepatchp.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 + -