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

📄 smacm.nc

📁 tinyos最新版
💻 NC
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 2002 the University of Southern 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 and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN 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 SOUTHERN CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * THE UNIVERSITY OF SOUTHERN 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 SOUTHERN CALIFORNIA HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR * MODIFICATIONS. * * Authors:	Wei Ye, Honghui Chen * * This module implements Sensor-MAC (S-MAC) * http://www.isi.edu/scadds/papers/smac_infocom.pdf * * It has the following functions. *  1) Low-duty-cycle operation on radio -- periodic listen and sleep *     Option to disable sleep cycles *  2) Broadcast only uses CSMA *  3) Many features for unicast *     - RTS/CTS for hidden terminal problem *     - fragmentation support for a long message *       A long message is divided (by upper layer) into multiple fragments. *       The RTS/CTS reserves the medium for the entire message. *       ACK is used for each fragment for immediate error recovery. *     - Node goes to sleep when its neighbors are talking to other nodes. */includes uartDebug;module SMACM{   provides {      interface StdControl as MACControl;      interface MACComm;      interface LinkState;      interface MACTest;      interface MACPerformance;      interface MACReport;   }   uses {      interface StdControl as PhyControl;      interface RadioState;      interface CarrierSense;      interface PhyComm;      interface Random;      interface ClockSMAC as Clock;      interface TimeStamp;      interface PowerManagement;   }}implementation{#include "SMACMsg.h"#include "PhyConst.h"#include "SMACConst.h"#include "smacEvents.h"//#define SMAC_DEBUG//#define SMAC_PERFORMANCE/* Internal S-MAC parameters * Do NOT change them unless for tuning S-MAC * User adjustable parameters are in SMACConst.h *-------------------------- * SLOTTIME: time of each slot in contention window, in ms. It should be large *   enough to receive the whole start symbol. * DIFS: DCF interframe space (from 802.11), in ms. It is used at the beginning *   of each contention window. It's the minmum time to wait to start a new  *   transmission. * SIFS: short interframe space (from 802.11), in ms. It is used before sending *   an CTS or ACK packet. It takes care of the processing delay of each pkt. * TX_PKT_DONE_TIME: maximum time waiting for the packet TX done signal, in ms. * SYNC_CW: number of slots in the sync contention window, must be 2^n - 1  * DATA_CW: number of slots in the data contention window, must be 2^n - 1 * GUARDTIME: guard time at the end of each listen interval, in ms. * SYNC_PERIOD: period to send a sync pkt, in ms. * UPDATE_NEIGHB_PERIOD: period to update neighbor list, is n times of *    SYNC_PERIOD. It is used in low duty cycle mode. If there is no SYNC pkts *    from a node within this period, it will be removed from neighbor list. * DATA_ACTIVE_PERIOD (ms): This is only used in fully active mode to update  *    neighbor list. Since there is no SYNC pkts, data pkts are used to measure  *    if a neighbor is active recently. */#define DIFS 10#define SIFS 5#define EIFS 50#define TX_PKT_DONE_TIME 2000#define SLOTTIME 1#define SYNC_CW 15#define DATA_CW 31#define GUARDTIME 5#define SYNC_PERIOD 10000#define UPDATE_NEIGHB_PERIOD 12#define DATA_ACTIVE_PERIOD 600000// hardware clock resolution in ms#define CLOCK_RES 1   /* MAC states   *-------------   * SLEEP: radio is turned off, can't Tx or Rx   * IDLE: radio in idle mode, will go to Rx if start symbol is deteded.   *   Can start Tx in this state   * CARR_SENSE: carrier sense. Do it before initiate a Tx   * TX_PKT: transmitting packet   * BACKOFF - medium is busy, and cannot Tx   * WAIT_CTS - just sent RTS, and is waiting for CTS   * WAIT_DATA - just sent CTS, and is waiting for DATA   * WAIT_ACK - just sent DATA, and is waiting for ACK   * TX_NEXT_FRAG - just send one fragment, waiting to tx next fragment   */   enum {      SLEEP,      IDLE,      CARR_SENSE,      TX_PKT,      BACKOFF,      WAIT_CTS,      WAIT_DATA,      WAIT_ACK,      TX_NEXT_FRAG,      DATA_SENSE1,      DATA_SENSE2   };   // radio states   enum { RADIO_SLEEP, RADIO_IDLE, RADIO_RX, RADIO_TX };   // how to send a pkt: broadcast or unicast   enum { BCAST_DATA, SEND_SYNC, SEND_RTS, SEND_CTS, SEND_DATA, SEND_ACK };   // MAC packet types   enum { DATA_PKT, RTS_PKT, CTS_PKT, ACK_PKT, SYNC_PKT };   // how to enter sleep mode   enum { TRY, FORCE };   // data type definitions   // note: pkt formats are defined in tos/include/smac_msg.h   typedef struct {      uint8_t numNodes;  // number of nodes on this schedule      char txSync;   // flag indicating need to send sync      char txData;   // flag indicating need to send data      char chkSched; // flag indicating need to check numNodes      uint16_t counter;  // tick counter   } SchedTable;   typedef struct {      char state;      uint16_t nodeId;      uint8_t schedId;      uint8_t active; //flag indicating the node is active recently      uint8_t txSeqNo; // Tx sequence no of unicast packets to a node      uint8_t rxSeqNo; // Rx sequence no of unicast packets from a node   } NeighbList;   // state variables   char state;			// MAC state   char srchNeighb;    // flag to keep listening for finding possible neighbors   char schedListen;   // flag indicating the time of scheduled listen   char updateNeighbList;  // flag indicating need to update neighbor list   uint8_t numNeighb;  // number of known neighbors   NeighbList neighbList[SMAC_MAX_NUM_NEIGHB]; // neighbor list   uint8_t numSched;  // number of different schedules   SchedTable schedTab[SMAC_MAX_NUM_SCHED];   // schedule table   char radioState;  // radio state   char schedState;  // schedule state: first, second schedule...      // timing variables   uint32_t clockTime;   // clock time in mili-second   uint16_t syncTime;    // time of listen/contention interval for sync pkt   uint16_t dataTime;    // time of listen/contention interval for data pkt   uint16_t listenTime;  // time of listening interval   uint16_t sleepTime;   // time of sleeping interval    uint16_t period;      // period of my schedule =listenTime + sleepTime   uint16_t timeToTxSync; // timer for sending SYNC packets to all schedules   uint8_t numSyncPrd;   // number of SYNC peroids, for dependent timers   uint16_t durDataPkt;  // duration (tx time needed) of data packet    uint16_t durCtrlPkt;  // duration (tx time needed) of control packet   uint16_t durSyncPkt;  // duration (tx time needed) of sync packet   uint16_t timeWaitCtrl; // time to wait for a control packet   uint16_t nav;	     // network allocation vector. nav>0 -> medium busy   uint16_t neighbNav;   // track neighbors' NAV while I'm sending/receiving   uint16_t geneTime;    // generic timer   uint8_t neighbListTime;  // timer for track nodes activity in neighbor list   uint8_t txDelay;      // timer for carrier sense   uint16_t adapTime;    // timer for adaptive listen   uint8_t retryTime;    // number of retries in unicast#ifdef SMAC_NO_SLEEP_CYCLE   uint32_t dataActiveTime; // timer for updating neighbor list#endif      // Variables for Tx   char txRequest;     // if I have accept a tx request;   char howToSend;     // what action to take for tx   uint16_t sendAddr;   // node that I'm sending data to   uint8_t dataSched;  // current schedule I'm talking to   uint8_t syncSched;  // current schedule I'm talking to   uint8_t numRetry;   // number of RTS tries for a data pkt   uint8_t numExtend;  // number of Tx time extensions when ACK timeout   uint8_t numSyncTx;  // number of times to send a SYNC (multiple schedules)   uint8_t numBcast;   // number of times to broadcast a pkt (multiple scheds)   uint8_t txFragAll;  // number of fragments in this transmission   uint8_t txFragCount; // number of transmitted fragments   uint8_t txPktLen;   // length of data pkt to be transmitted   uint8_t syncSeqNo;  // Tx sequence number for SYNC packets   uint8_t bcastSeqNo; // Tx sequence number for broadcast data packets   MACHeader* dataPkt; // pointer to tx data pkt, only access MAC header   MACCtrlPkt ctrlPkt; // MAC control packet   MACSyncPkt syncPkt; // MAC sync packet      // Variables for Rx   uint16_t recvAddr;  // node that I'm receiving data from   uint8_t rxFragAll;  // number of fragments to be received in a msg   uint8_t lastRxFrag; // fragment no of last received fragment   // Variables for link state measurement   uint8_t numTx1Msg;  // number of Tx on a msg, including reTx on frags   uint8_t numRx1Msg;  // number of Rx on a msg, including duplicated frags   uint8_t numTxFragOld; // number of Tx on a single fragment#ifdef SMAC_REPORT	uint32_t crcErr;	uint32_t lenErr;	uint32_t retx;	uint32_t ctrlPkts;#endif#ifdef SMAC_DEBUG   char numLenErr;   char numCrcErr;   char numSlpPkt;   char numCTStimeout;   char numDATAtimeout;   char numACKtimeout;   char numSleeps;   char numWakeups;   char syncDiff1;  // debug time difference in received SYNC pkt   char syncDiff2;  // time difference bigger than GUARDTIME#endif#ifdef SMAC_PERFORMANCE   char cntRadioTime;   RadioTime radioTime;#endif// update my NAV#define UPDATE_NAV(duration) { \	if (nav < duration) nav = duration; \}// track my neighbors' NAV#define TRACK_NAV(duration) { \	if (neighbNav < duration) neighbNav = duration; \}   // function prototypes   result_t getNodeIdx(uint16_t nodeAddr, uint8_t* nodeIdx, uint8_t* emptyIdx);   void sleep(char manner);   void wakeup();   void setMySched(MACSyncPkt* packet, uint16_t refTime);   void update_neighbList();   void checkMySched();   void check_schedFlag();   void update_schedTab_neighbList();   void handleRTS(void* packet);   void handleCTS(void* packet);   void* handleDATA(void* packet);   void handleACK(void* packet);   void handleSYNC(void* packet);   void startBcast();   void sendRTS();   void sendCTS();   void sendDATA();   void sendACK();   void sendSYNC();   void tryToSend();   void tryToResend(uint8_t delay);   void txMsgDone();   command result_t MACControl.init()   {      uint8_t i;            // initialize constants      durCtrlPkt = (PRE_PKT_BYTES + sizeof(MACCtrlPkt) * ENCODE_RATIO)                        * 8 / BANDWIDTH + 1;      durSyncPkt = (PRE_PKT_BYTES + sizeof(MACSyncPkt) * ENCODE_RATIO)                        * 8 / BANDWIDTH + 1;      syncTime = DIFS + SLOTTIME * SYNC_CW + durSyncPkt + GUARDTIME;      // added time for overhearing CTS so that can do adaptive listen      dataTime = DIFS + SLOTTIME * DATA_CW + durCtrlPkt +                      PROC_DELAY + SIFS + durCtrlPkt + GUARDTIME;      listenTime = syncTime + dataTime;      period = listenTime * 100 / SMAC_DUTY_CYCLE + 1;      sleepTime = period - listenTime;      // time to wait for CTS or ACK      timeWaitCtrl = PROC_DELAY + SIFS + durCtrlPkt + PROC_DELAY;      // initialize state variables      state = IDLE;      radioState = RADIO_IDLE;      // initialize neighbor list      numNeighb = 0;  // number of known neighbors      neighbListTime = 0;      updateNeighbList = 0;      for (i = 0; i < SMAC_MAX_NUM_NEIGHB; i++) {         neighbList[i].state = 0;  // invalid or dead      }      // initialize schedule table      for (i = 0; i < SMAC_MAX_NUM_SCHED; i++) {         schedTab[i].numNodes = 0;      }	#ifndef SMAC_NO_SLEEP_CYCLE      // choose a tentative schedule, but don't broadcast until      // listening for a whole SYNC_PERIOD.      schedState = 1;  // this is my first schedule      numSched = 1;      schedTab[0].numNodes = 1;  // I'm the only one on this schedule      schedTab[0].txData = 0;      schedTab[0].txSync = 0;      schedTab[0].chkSched = 0;       schedTab[0].counter = listenTime;      // Don't go to sleep for the first SYNC period.      srchNeighb = 1;      numSyncPrd = 1;      schedListen = 1;#ifdef SMAC_SLAVE_SCHED      // don't broadcast my schedule, and keeps listening for an existing one      timeToTxSync = 0;#else      timeToTxSync = SYNC_PERIOD; // set timer to broadcast my schedule#endif // SMAC_SLAVE_SCHED#endif // SMAC_NO_SLEEP_CYCLE      // initialize timing variables      clockTime = 0;      nav = 0;      neighbNav = 0;      txDelay = 0;      adapTime = 0;#ifdef SMAC_NO_SLEEP_CYCLE      retryTime = 0;#endif	      // initialize Tx variables      txRequest = 0;      syncSeqNo = 0;      bcastSeqNo = 0;            // fill in fixed portion of control packet      ctrlPkt.fromAddr = TOS_LOCAL_ADDRESS;      // fill in fixed portion of sync packet      syncPkt.fromAddr = TOS_LOCAL_ADDRESS;      syncPkt.type = SYNC_PKT << 4;      syncPkt.state = schedState;#ifdef SMAC_DEBUG      numLenErr = 0;      numCrcErr = 0;      numCTStimeout = 0;      numDATAtimeout = 0;      numACKtimeout = 0;      numSleeps = 0;      numWakeups = 0;      syncDiff1 = 100;  // initialize to a big value to easily see its change      syncDiff2 = 100;#endif#ifdef SMAC_PERFORMANCE

⌨️ 快捷键说明

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