delugem.nc

来自「tinyos最新版」· NC 代码 · 共 418 行

NC
418
字号
// $Id: DelugeM.nc,v 1.50 2004/08/30 22:10:46 jwhui Exp $/*									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." * *//** * Manages advertisements of image data and communication to update * metadata. Also notifies <code>DelugePageTransfer</code> of nodes to * request data from. * * @author Jonathan Hui <jwhui@cs.berkeley.edu> */includes crc;module DelugeM {  provides {    interface StdControl;  }  uses {    interface BitVecUtils;    interface DelugeMetadata as Metadata;    interface DelugePageTransfer as PageTransfer;    interface InternalFlash as IFlash;    interface Leds;    interface NetProg;    interface Random;    interface ReceiveMsg as ReceiveAdvMsg;    interface SendMsg as SendAdvMsg;    interface SharedMsgBuf;    interface StdControl as MetadataControl;    interface StdControl as PageTransferControl;    interface StdControl as SubControl;    interface Timer;#ifdef DELUGE_DBG    interface DelugeDbg;#endif  }}implementation {  // state variables  uint8_t   state;                     // general state of protocol  uint8_t   newDataAdvsRequired;       // number of advertisment to send before requesting more data  uint8_t   overheardAdvs;             // counter of many advertisment before advertising  int16_t   globalVNum;  uint8_t   runningImgNum;  uint8_t   advPeriodLog2;  int8_t    diffAdvOrReboot;  enum {    S_DISABLED,    S_ADV,    S_TRANSFERRING,  };  void switchState(uint8_t _state);  void startTimer() {    uint32_t delay;    call Timer.stop();    delay = 0x1 << advPeriodLog2;    delay += call Random.rand() & (delay-1);    call Timer.start(TIMER_ONE_SHOT, delay);  }  void startTimerHalf() {    uint32_t delay;    call Timer.stop();    delay = 0x1 << (DELUGE_MIN_ADV_PERIOD_LOG2-1);    delay = DELUGE_MIN_DELAY + (call Random.rand() & (delay-1));    call Timer.start(TIMER_ONE_SHOT, delay);  }  command result_t StdControl.init() {    result_t result = call SubControl.init();        // initialize state variables#ifndef PLATFORM_PC    call IFlash.read((uint16_t*)IFLASH_GVNUM_ADDR, &globalVNum, sizeof(globalVNum));#endif        switchState(S_DISABLED);    call Leds.init();        result = rcombine(call MetadataControl.init(), result);    result = rcombine(call PageTransferControl.init(), result);        return result;  }    command result_t StdControl.start() {        result_t result = call SubControl.start();        if (state != S_DISABLED)      return SUCCESS;    runningImgNum = call NetProg.getExecutingImgNum();    switchState(S_ADV);    overheardAdvs = 0;    if (call Metadata.isReady()) {      call PageTransferControl.start();      startTimer();    }        return result;      }  command result_t StdControl.stop() {    switchState(S_DISABLED);    return call PageTransferControl.stop();  }  uint16_t calcAdvCrc(DelugeAdvMsg* pAdvMsg) {    uint8_t* tmp = (uint8_t*)pAdvMsg;    uint16_t crc = 0;    uint8_t  i;    for ( i = 0; i < sizeof(DelugeAdvMsg)-sizeof(uint16_t); i++ )      crc = crcByte(crc, tmp[i]);    return crc;  }  void fillAdvMsg(DelugeAdvMsg* pAdvMsg) {    pAdvMsg->sourceAddr = TOS_LOCAL_ADDRESS;    pAdvMsg->globalVNum = globalVNum;    pAdvMsg->runningImgNum = runningImgNum;    if (call Metadata.isReady()) {      pAdvMsg->type = DELUGE_ADV_NORMAL;            call Metadata.getImgSummaries(pAdvMsg->imgSummaries);        }    else {      pAdvMsg->type = DELUGE_ADV_NOT_READY;    }    pAdvMsg->crc = calcAdvCrc(pAdvMsg);  }  event result_t Metadata.ready(result_t result) {    dbg(DBG_USR1, "DELUGE: START(vNum=%d)\n", call Metadata.getVNum(0));    dbg(DBG_USR2, "DELUGE: @%lld START(vNum=%d,numPgs=%d,delay=%d)\n", 	tos_state.tos_time, call Metadata.getVNum(0), call Metadata.getNumPgs(0),	NODE_0_STARTUP_DELAY);    if (state != S_DISABLED) {      // start advertising      call PageTransferControl.start();      startTimer();    }        return SUCCESS;      }    event result_t Timer.fired() {    bool sentAdv = FALSE;    call Leds.greenToggle();    if (call Metadata.getNextIncompleteImage() == DELUGE_INVALID_IMGNUM)      call Leds.redOn();    else      call Leds.redOff();    // don't do anything if disabled    if (state != S_ADV)      return SUCCESS;    if (diffAdvOrReboot < 0) {      if (++diffAdvOrReboot == 0) {#ifndef PLATFORM_PC	call IFlash.write((uint16_t*)IFLASH_GVNUM_ADDR, &globalVNum, sizeof(globalVNum));	call NetProg.programImgAndReboot(runningImgNum); // SHOULD NOT RETURN!	// XXX: WHAT DO WE DO HERE?#endif      }    }    else {      call Leds.yellowOff();    }    if (newDataAdvsRequired)      newDataAdvsRequired--;        if (diffAdvOrReboot)      advPeriodLog2 = (DELUGE_MIN_ADV_PERIOD_LOG2-1);    else if (newDataAdvsRequired == 0) {      advPeriodLog2++;      if (advPeriodLog2 > (DELUGE_MAX_ADV_PERIOD_LOG2-1))	advPeriodLog2 = DELUGE_MAX_ADV_PERIOD_LOG2-1;    }    if (diffAdvOrReboot > 0)      diffAdvOrReboot--;    if (overheardAdvs < DELUGE_MAX_OVERHEARD_ADVS 	&& !call SharedMsgBuf.isLocked()) {      TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();      fillAdvMsg((DelugeAdvMsg*)pMsgBuf->data);      if (call SendAdvMsg.send(TOS_BCAST_ADDR, sizeof(DelugeAdvMsg), pMsgBuf) == SUCCESS) {	call SharedMsgBuf.lock();	sentAdv = TRUE;      }    }    overheardAdvs = 0;    if (sentAdv) {      uint32_t delay = (uint32_t)0x1 << (uint32_t)(advPeriodLog2+1);      call Timer.start(TIMER_ONE_SHOT, delay);    }    else {      startTimer();    }          return SUCCESS;  }  event TOS_MsgPtr ReceiveAdvMsg.receive(TOS_MsgPtr pMsg) {    TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();    DelugeAdvMsg *rxAdvMsg = (DelugeAdvMsg*)pMsg->data;        if (calcAdvCrc(rxAdvMsg) != rxAdvMsg->crc)      return pMsg;#ifdef DELUGE_DBG    call DelugeDbg.rxAdvMsg();#endif//    dbg(DBG_USR1, "DELUGE: Received ADV_MSG(source=%d,vnum=%d,numPgsComplete=%d)\n",//	rxAdvMsg->sourceAddr, rxAdvMsg->summary.vNum, rxAdvMsg->summary.numPgsComplete);    if (rxAdvMsg->type == DELUGE_ADV_PC) {      if ((rxAdvMsg->globalVNum == DELUGE_INVALID_VNUM	   && rxAdvMsg->runningImgNum == DELUGE_INVALID_IMGNUM)	  || call Metadata.isImgSummariesEqual(rxAdvMsg->imgSummaries)) {	// query over UART, send an ADV back	if (!call SharedMsgBuf.isLocked()) {	  fillAdvMsg((DelugeAdvMsg*)pMsgBuf->data);	  if (call SendAdvMsg.send(rxAdvMsg->sourceAddr, sizeof(DelugeAdvMsg), pMsgBuf) 	      == SUCCESS) {	    call SharedMsgBuf.lock();	  }	}	return pMsg;      }    }    // don't do anything if disabled or if waiting to reboot    if (state == S_DISABLED || diffAdvOrReboot < 0)      return pMsg;    if (rxAdvMsg->type != DELUGE_ADV_PC) {      if (rxAdvMsg->globalVNum == globalVNum	  && rxAdvMsg->runningImgNum == runningImgNum	  && call Metadata.isImgSummariesEqual(rxAdvMsg->imgSummaries)) {	// record number of similar advs	overheardAdvs++;      }      else {	// reduce advertisement period if a different adv is received	if (advPeriodLog2 != (DELUGE_MIN_ADV_PERIOD_LOG2-1)	    && state == S_ADV) {	  startTimer();	}	if (diffAdvOrReboot >= 0)	  diffAdvOrReboot = DELUGE_NUM_MIN_ADV_PERIODS;      }    }    if (call Metadata.setImgSummaries(rxAdvMsg->imgSummaries) == SUCCESS) {      // there is a newer version to match, have to update metadata      call Timer.stop();      call PageTransferControl.stop();    }    else if (call Metadata.canProvideData(rxAdvMsg->imgSummaries)) {      if (!newDataAdvsRequired)	call PageTransfer.setNewSource(rxAdvMsg->sourceAddr);    }        if ((rxAdvMsg->globalVNum - globalVNum) > 0	&& rxAdvMsg->globalVNum != DELUGE_INVALID_VNUM	&& call Metadata.isValidTOSApp(rxAdvMsg->runningImgNum)) {            call Leds.yellowOn();      advPeriodLog2 = DELUGE_MIN_ADV_PERIOD_LOG2-1;      globalVNum = rxAdvMsg->globalVNum;      runningImgNum = rxAdvMsg->runningImgNum;      diffAdvOrReboot = -4;      overheardAdvs = 0;      startTimer();    }    return pMsg;  }  event result_t Metadata.applyPageDiffDone(result_t result) {    // don't do anything if disabled    if (state == S_DISABLED)      return SUCCESS;    // reset state to advertising    switchState(S_ADV);    overheardAdvs = 0;        startTimerHalf();    // reset and enable page transfers    call PageTransferControl.start();    return SUCCESS;  }  event result_t PageTransfer.transferBegin() {    if (state == S_DISABLED)      return SUCCESS;    switchState(S_TRANSFERRING);    dbg(DBG_USR1, "DELUGE: STATE(TRANSFER_BEGIN)\n");    call Timer.stop();    return SUCCESS;  }  event result_t PageTransfer.transferDone() {    if (state == S_DISABLED)      return SUCCESS;    switchState(S_ADV);    dbg(DBG_USR1, "DELUGE: STATE(ADV)\n");    //startTimer();    call Timer.start(TIMER_ONE_SHOT, 0x1 << advPeriodLog2);    return SUCCESS;  }  event result_t SendAdvMsg.sendDone(TOS_MsgPtr pMsg, result_t success) {#ifdef DELUGE_DBG    call DelugeDbg.txAdvMsg();#endif    call SharedMsgBuf.unlock();    return SUCCESS;  }  event result_t PageTransfer.receivedNewData() {    overheardAdvs = 0;    newDataAdvsRequired = DELUGE_NUM_NEWDATA_ADVS_REQUIRED;    if (state == S_ADV)      startTimerHalf();    return SUCCESS;  }  event result_t PageTransfer.overheardOlderData() {    newDataAdvsRequired = DELUGE_NUM_NEWDATA_ADVS_REQUIRED;    if (diffAdvOrReboot >= 0)      diffAdvOrReboot = DELUGE_NUM_MIN_ADV_PERIODS;    return SUCCESS;  }  void switchState(uint8_t _state) {    if (diffAdvOrReboot >= 0)      diffAdvOrReboot = DELUGE_NUM_MIN_ADV_PERIODS;    state = _state;  }}

⌨️ 快捷键说明

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