mvirus.nc

来自「tinyos最新版」· NC 代码 · 共 644 行 · 第 1/2 页

NC
644
字号
/*									tab:4 * * * "Copyright (c) 2000-2004 The Regents of the University  of California.   * 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 following two paragraphs and the author appear in all * copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, * UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * *//*									tab:4 *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By *  downloading, copying, installing or using the software you agree to *  this license.  If you do not agree to this license, do not download, *  install, copy or use the software. * *  Intel Open Source License  * *  Copyright (c) 2004 Intel Corporation  *  All rights reserved.  *  Redistribution and use in source and binary forms, with or without *  modification, are permitted provided that the following conditions are *  met: *  *	Redistributions of source code must retain the above copyright *  notice, this list of conditions and the following disclaimer. *	Redistributions in binary form must reproduce the above copyright *  notice, this list of conditions and the following disclaimer in the *  documentation and/or other materials provided with the distribution. *      Neither the name of the Intel Corporation nor the names of its *  contributors may be used to endorse or promote products derived from *  this software without specific prior written permission. *   *  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 INTEL OR ITS *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *  PROFITS; OR BUSINESS INTERRUPTION) 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. *  *  *//* * Authors:   Philip Levis * History:   July 21, 2002 *	      * *//** * @author Philip Levis */includes Mate;module MVirus {  provides interface StdControl;  provides interface MateVirus as Virus;  uses {    interface MateError;    interface MateEngineControl as EngineControl;        interface Timer as VersionTimer;    interface ReceiveMsg as VersionReceive;    interface SendMsg as VersionSend;    interface Timer as CapsuleTimer;    interface ReceiveMsg as CapsuleChunkReceive;    interface Receive as CapsuleChunkRouteReceive;    interface Intercept as CapsuleChunkRouteIntercept;        interface SendMsg as CapsuleChunkSend;    interface ReceiveMsg as CapsuleStatusReceive;    interface SendMsg as CapsuleStatusSend;        interface Random as Random;    interface StdControl as SubControl;  }}implementation {  typedef enum {    MVIRUS_MAINTAIN,    // Everything seems to be in order: default state    MVIRUS_REQUEST,     // Somebody has something newer: receive capsules    MVIRUS_RESPOND,     // Somebody has something older: send capsules  } MVirusState;  MateCapsule* capsules[MATE_CAPSULE_NUM];  MateTrickleTimer versionTimer;  MateTrickleTimer capsuleTimer;  MVirusState state;  uint8_t currentCapsule;  // If we're exchanging1 a capsule, which one  b_capsule_version currentVersion; // If we need a capsule, what version  uint8_t needBitmask[MVIRUS_BITMASK_SIZE];    bool sendBusy;  bool capsuleBusy;    TOS_Msg sendMessage;  TOS_MsgPtr sendPtr;  void sendCapsulePacket();  void sendVersionPacket();  void printNeedBitmask() {#ifdef PLATFORM_PC    int i;    dbg(DBG_USR3, "\tneedBitmask: ");    for (i = 0; i < MVIRUS_BITMASK_ENTRIES; i++) {      dbg_clear(DBG_USR3, "%s", (needBitmask[i/8] & (0x80 >> (i % 8)))? "1":"0");    }    dbg_clear(DBG_USR3, "\n");#endif  }    uint8_t bitEntry(uint8_t* mask, uint8_t which) {    return (mask[which >> 3] & (1 << (7 - (which & 7))));  }    /* Select a new threshold, in the range [interval/2,interval], and     clear out temporary state. */  void newCounter(MateTrickleTimer* timer) {    timer->elapsed = 0;    timer->threshold = timer->interval / 2;    timer->threshold += call Random.rand() % (timer->interval / 2);    dbg(DBG_USR3, "MVirus: Picking new counter %i in range [%i,%i].\n", (int)timer->threshold, (int)timer->interval/2, (int)timer->interval);    timer->numHeard = 0;  }  void decayNeedField() {    int i;    dbg(DBG_USR3, "MVirus: Decaying need field.\n");    printNeedBitmask();    for (i = 0; i < MVIRUS_BITMASK_SIZE; i++) {      needBitmask[i] &= (uint8_t)(call Random.rand());    }    printNeedBitmask();  }  void clearInvalidBits() {    int i;    uint8_t neededBits;    uint16_t size = sizeof(MateCapsule) - MATE_PGMSIZE + capsules[currentCapsule]->codeLen;    dbg(DBG_USR3, "MVirus: Total size of capsule is %i-%i+%i = %i (%i).\n", (int)sizeof(MateCapsule), (int)MATE_PGMSIZE, (int)capsules[currentCapsule]->codeLen, (int)(size), (int)MVIRUS_CHUNK_SIZE);    size += (MVIRUS_CHUNK_SIZE - 1);    size /= MVIRUS_CHUNK_SIZE;    neededBits = size;    dbg(DBG_USR3, "MVirus: Clearing need bits for caspule %i.%i. (%i)\n", (int)currentCapsule, (int)currentVersion, (int)size);    printNeedBitmask();    if (neededBits & 7) {      uint8_t mask = (0x80 >> ((neededBits & 7) - 1));      mask -= 1;      mask = ~mask;      needBitmask[neededBits / 8] &= mask;      neededBits -= neededBits & 7;      neededBits += 8;    }    for (i = neededBits / 8; i < MVIRUS_BITMASK_SIZE; i++) {      needBitmask[i]  = 0;    }    printNeedBitmask();  }  void removeNeededBit(uint16_t bit) {    uint8_t mask = (1 << (7 - (bit & 7)));    dbg(DBG_USR3, "MVirus: clear mask for %i: %hhx -> %hhx\n", bit/8, mask, ~mask);    mask = ~mask;    needBitmask[bit / 8] &= mask;  }    command result_t StdControl.init() {    call SubControl.init();    call Random.init();        state = MVIRUS_MAINTAIN;    currentCapsule = MATE_CAPSULE_INVALID;    memset(needBitmask, 0, MVIRUS_BITMASK_SIZE);    // Initialize (but do not start) the timers    versionTimer.interval = MVIRUS_VERSION_TAU_MAX;    capsuleTimer.interval = MVIRUS_CAPSULE_TAU;    newCounter(&versionTimer);    newCounter(&capsuleTimer);        sendPtr = (TOS_MsgPtr)&sendMessage;        dbg(DBG_USR3, "MVirus: Initialized:\n\tchunk size=%i; bitmask size=%i\n", (int)MVIRUS_CHUNK_SIZE, (int)MVIRUS_BITMASK_SIZE);    dbg(DBG_USR3, "\tversion constants: quantum=%i;tau_l=%i;tau_h=%i;k=%i\n", (int)MVIRUS_VERSION_TIMER, (int)MVIRUS_VERSION_TAU_MIN, (int)MVIRUS_VERSION_TAU_MAX, (int)MVIRUS_VERSION_REDUNDANCY);    dbg(DBG_USR3, "\tcapsule constants: quantum=%i;tau=%i;repeat=%i;k=%i.\n", (int)MVIRUS_CAPSULE_TIMER, (int)MVIRUS_CAPSULE_TAU, (int)MVIRUS_CAPSULE_REPEAT, (int)MVIRUS_CAPSULE_REDUNDANCY);    sendBusy = FALSE;    capsuleBusy = FALSE;        return SUCCESS;  }  command result_t StdControl.start() {    call SubControl.start();    dbg(DBG_USR3, "MVirus started.\n");    call VersionTimer.start(TIMER_REPEAT, MVIRUS_VERSION_TIMER);    dbg(DBG_USR3, "MVirus version timer started.\n");    return SUCCESS;  }  command result_t Virus.registerCapsule(uint8_t id, MateCapsule* capsule) {    capsules[id] = capsule;    return SUCCESS;  }      command result_t StdControl.stop() {    call VersionTimer.stop();    call CapsuleTimer.stop();    dbg(DBG_USR3, "MVirus stopped.\n");    return call SubControl.stop();  }  void toRequestState(uint8_t capsuleNum, b_capsule_version version) {    dbg(DBG_USR3, "MVirus: Moving to request state, capsule %i version %i.\n", (int)capsuleNum, (int)version);    state = MVIRUS_REQUEST;    currentCapsule = capsuleNum;    currentVersion = version;    memset(needBitmask, 0xff, MVIRUS_BITMASK_SIZE);        versionTimer.interval = MVIRUS_VERSION_TAU_MIN;    newCounter(&versionTimer);    call VersionTimer.stop();    call VersionTimer.start(TIMER_REPEAT, MVIRUS_VERSION_TIMER);  }  void toResponseState(uint8_t capsuleNum) {    dbg(DBG_USR3, "MVirus: Moving to response state, capsule %i version %i.\n", (int)capsuleNum, (int)capsules[capsuleNum]->version);    state = MVIRUS_RESPOND;    currentCapsule = capsuleNum;        newCounter(&capsuleTimer);    call CapsuleTimer.stop();    call CapsuleTimer.start(TIMER_REPEAT, MVIRUS_CAPSULE_TIMER);  }  void toMaintainState() {    dbg(DBG_USR3, "MVirus: Moving to maintain state, capsule %i version %i.\n");    state = MVIRUS_MAINTAIN;    call CapsuleTimer.stop();  }      task void versionTimerTask() {    versionTimer.elapsed++;    if (versionTimer.elapsed == versionTimer.threshold) {      if (versionTimer.numHeard < MVIRUS_VERSION_REDUNDANCY) {	dbg(DBG_USR3, "MVirus: Sending version packet @%s\n", currentTime());	sendVersionPacket();      }    }    else if (versionTimer.elapsed >= versionTimer.interval) {      dbg(DBG_USR3, "MVirus: Version tau elapsed, picking new t.\n");      versionTimer.interval *= 2;      if (versionTimer.interval > MVIRUS_VERSION_TAU_MAX) {	versionTimer.interval = MVIRUS_VERSION_TAU_MAX;      }      newCounter(&versionTimer);    }    else {      // do nothing    }  }  task void capsuleTimerTask() {    capsuleTimer.elapsed++;    if (capsuleTimer.elapsed == capsuleTimer.threshold) {      if (capsuleTimer.numHeard < MVIRUS_CAPSULE_REDUNDANCY) {	dbg(DBG_USR3, "MVirus: Sending capsule packet @%s.\n", currentTime());	sendCapsulePacket();	capsuleTimer.numHeard++;      }    }    else if (capsuleTimer.elapsed >= capsuleTimer.interval) {      newCounter(&capsuleTimer);      decayNeedField();    }    else {      // do nothing    }  }  int8_t getRandomChunkIndex(uint8_t capsule) {    uint8_t idx;    uint8_t count = 0;    uint16_t size = sizeof(MateCapsule);    dbg(DBG_USR3, "MVirus: Get random chunk index from\n");    printNeedBitmask();    size -= (MATE_PGMSIZE - capsules[capsule]->codeLen);

⌨️ 快捷键说明

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