delugepagetransferm.nc
来自「tinyos最新版」· NC 代码 · 共 661 行 · 第 1/2 页
NC
661 行
// $Id: DelugePageTransferM.nc,v 1.28 2004/08/28 19:50:59 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." * *//** * Handles the transfer of individual data pages between neighboring * nodes. * * @author Jonathan Hui <jwhui@cs.berkeley.edu> */module DelugePageTransferM { provides { interface DelugePageTransfer as PageTransfer; interface StdControl; } uses { interface BitVecUtils; interface DelugeImgStableStore as StableStore; interface DelugeMetadata as Metadata; interface Random; interface ReceiveMsg as ReceiveDataMsg; interface ReceiveMsg as ReceiveReqMsg; interface Leds; interface SendMsg as SendDataMsg; interface SendMsg as SendReqMsg; interface SharedMsgBuf; interface StdControl as SubControl; interface Timer as ReqTimer;#ifdef DELUGE_DBG interface DelugeDbg;#endif }}implementation { typedef struct { uint16_t dataSourceAddr; uint8_t numReqTriesLeft; bool suppressReq; } RxState; typedef struct { uint8_t imgToSend; uint8_t pgToSend; } TxState; typedef struct { union { RxState rx; TxState tx; }; } RxTxState; typedef struct { uint8_t pktNum; uint8_t data[DELUGE_PKT_PAYLOAD_SIZE]; } DataQEntry; // Data Write Queue DataQEntry dataQ[DELUGE_DATA_Q_SIZE]; uint8_t dataQHead, dataQLen; // send/receive page buffers, and state variables for buffers uint8_t pktsToSend[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to send uint8_t pktsToReceive[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to receive // state variables uint8_t state; RxTxState vars; enum { S_DISABLED, S_IDLE, S_SENDING, S_TX_LOCKING, S_RECEIVING, S_RX_LOCKING, }; void changeState(uint8_t _state); void setupDataMsg(); command result_t StdControl.init() { result_t result = call SubControl.init(); // initialize state variables changeState(S_DISABLED); return result; } command result_t StdControl.start() { result_t result = call SubControl.start(); // get ready to receive next page dataQHead = dataQLen = 0; memset(pktsToReceive, 0xff, DELUGE_PKT_BITVEC_SIZE); // enable receives and sends changeState(S_IDLE); return result; } command result_t StdControl.stop() { // disable receives and sends changeState(S_DISABLED); return SUCCESS; } command result_t PageTransfer.setNewSource(uint16_t sourceAddr) { if (call Metadata.getNextIncompleteImage() == DELUGE_INVALID_IMGNUM) return FAIL; if (state == S_IDLE) { // currently idle, so request data from source changeState(S_RX_LOCKING); vars.rx.dataSourceAddr = sourceAddr; vars.rx.suppressReq = FALSE; // randomize request to prevent collision call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_MIN_DELAY + call Random.rand() % DELUGE_MAX_REQ_DELAY); } return SUCCESS; } task void retrySetupDataMsg() { setupDataMsg(); } uint32_t calcOffset(pgnum_t pgNum, uint8_t pktNum) { return (uint32_t)pgNum*(uint32_t)DELUGE_BYTES_PER_PAGE + (uint32_t)pktNum*(uint32_t)DELUGE_PKT_PAYLOAD_SIZE; } void setupDataMsg() { TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf(); DelugeDataMsg* pDataMsg = (DelugeDataMsg*)(pMsgBuf->data); uint32_t offset; uint16_t length; uint16_t nextPkt; result_t result; if (state != S_SENDING && state != S_TX_LOCKING) return; if (state == S_TX_LOCKING) { if (call SharedMsgBuf.lock() == FAIL) { post retrySetupDataMsg(); return; } changeState(S_SENDING); pDataMsg->vNum = call Metadata.getVNum(vars.tx.imgToSend); pDataMsg->imgNum = vars.tx.imgToSend; pDataMsg->pgNum = vars.tx.pgToSend; pDataMsg->pktNum = 0; } if (pDataMsg->pktNum < DELUGE_PKTS_PER_PAGE) { if (!call BitVecUtils.indexOf(&nextPkt, pDataMsg->pktNum, pktsToSend, DELUGE_PKTS_PER_PAGE) && !call BitVecUtils.indexOf(&nextPkt, 0, pktsToSend, DELUGE_PKTS_PER_PAGE)) { // no more packets to send dbg(DBG_USR1, "DELUGE: SEND_DONE\n"); changeState(S_IDLE); return; } pDataMsg->pktNum = (uint8_t)nextPkt; length = DELUGE_PKT_PAYLOAD_SIZE; if (pDataMsg->pktNum == DELUGE_PKTS_PER_PAGE - 1) length -= 2; offset = calcOffset(pDataMsg->pgNum, pDataMsg->pktNum); result = call StableStore.getImgData(pDataMsg->imgNum, offset, pDataMsg->data, length); } else { result = call StableStore.getPageCrc(pDataMsg->imgNum, pDataMsg->pgNum, &(pDataMsg->data[DELUGE_PKT_PAYLOAD_SIZE-2])); } if (result == FAIL) post retrySetupDataMsg(); } event result_t ReqTimer.fired() { TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf(); DelugeReqMsg* pReqMsg = (DelugeReqMsg*)(pMsgBuf->data); if (state != S_RECEIVING && state != S_RX_LOCKING) return SUCCESS; if (state == S_RX_LOCKING) { if (call SharedMsgBuf.lock() == FAIL) { call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_FAILED_SEND_DELAY); return SUCCESS; } // update address of source node changeState(S_RECEIVING); pReqMsg->dest = vars.rx.dataSourceAddr; vars.rx.numReqTriesLeft = DELUGE_MAX_NUM_REQ_TRIES; pReqMsg->imgNum = call Metadata.getNextIncompleteImage(); pReqMsg->pgNum = call Metadata.getNextIncompletePage(); pReqMsg->vNum = call Metadata.getVNum(pReqMsg->imgNum); memcpy(pReqMsg->requestedPkts, pktsToReceive, DELUGE_PKT_BITVEC_SIZE); } if (vars.rx.suppressReq) { // suppress request call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_NACK_TIMEOUT + call Random.rand() % DELUGE_NACK_TIMEOUT); vars.rx.suppressReq = FALSE; return SUCCESS; } if (vars.rx.numReqTriesLeft == 0) { // tried too many times, give up changeState(S_IDLE); return SUCCESS; } { uint16_t dest = (pReqMsg->dest == TOS_UART_ADDR) ? TOS_UART_ADDR : TOS_BCAST_ADDR; if (call SendReqMsg.send(dest, sizeof(DelugeReqMsg), pMsgBuf) == SUCCESS) { vars.rx.numReqTriesLeft--; } else { // send failed, wait a bit and try again call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_FAILED_SEND_DELAY); } } return SUCCESS; } event TOS_MsgPtr ReceiveReqMsg.receive(TOS_MsgPtr pMsg) { DelugeReqMsg *rxReqMsg = (DelugeReqMsg*)(pMsg->data); uint8_t imgNum, tmpImgNum; pgnum_t pgNum, tmpPgNum; int i;#ifdef DELUGE_DBG call DelugeDbg.rxReqMsg();#endif if (state == S_DISABLED) return pMsg; imgNum = call Metadata.getNextIncompleteImage(); pgNum = call Metadata.getNextIncompletePage(); if (state == S_SENDING || state == S_TX_LOCKING) { tmpImgNum = vars.tx.imgToSend; tmpPgNum = vars.tx.pgToSend; } else { tmpImgNum = imgNum; tmpPgNum = pgNum; } if (rxReqMsg->imgNum < tmpImgNum || (rxReqMsg->imgNum == tmpImgNum && (rxReqMsg->vNum - call Metadata.getVNum(tmpImgNum) > 0 || (rxReqMsg->vNum == call Metadata.getVNum(tmpImgNum) && rxReqMsg->pgNum < tmpPgNum)))) { if (state == S_IDLE) signal PageTransfer.overheardOlderData(); else if (state == S_SENDING || state == S_TX_LOCKING) { changeState(S_IDLE); memset(pktsToSend, 0x0, DELUGE_PKT_BITVEC_SIZE); } } if (rxReqMsg->dest != TOS_LOCAL_ADDRESS) { if ((state == S_RECEIVING || state == S_RX_LOCKING) && rxReqMsg->imgNum == imgNum && rxReqMsg->vNum == call Metadata.getVNum(imgNum) && rxReqMsg->pgNum <= pgNum) { // suppress next request since similar request has been overheard vars.rx.suppressReq = TRUE; } return pMsg; } if (rxReqMsg->pgNum >= call Metadata.getNumPgsComplete(rxReqMsg->imgNum) || rxReqMsg->vNum != call Metadata.getVNum(rxReqMsg->imgNum)) { // don't have this page, ignore request return pMsg; } if (state == S_IDLE || ((state == S_SENDING || state == S_TX_LOCKING) && rxReqMsg->imgNum == vars.tx.imgToSend && rxReqMsg->vNum == call Metadata.getVNum(vars.tx.imgToSend) && rxReqMsg->pgNum == vars.tx.pgToSend)) { // take union of packet bit vectors
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?