Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

smac.h

Go to the documentation of this file.
00001 // Copyright (c) 2000 by the University of Southern California
00002 // All rights reserved.
00003 //
00004 // Permission to use, copy, modify, and distribute this software and its
00005 // documentation in source and binary forms for non-commercial purposes
00006 // and without fee is hereby granted, provided that the above copyright
00007 // notice appear in all copies and that both the copyright notice and
00008 // this permission notice appear in supporting documentation. and that
00009 // any documentation, advertising materials, and other materials related
00010 // to such distribution and use acknowledge that the software was
00011 // developed by the University of Southern California, Information
00012 // Sciences Institute.  The name of the University may not be used to
00013 // endorse or promote products derived from this software without
00014 // specific prior written permission.
00015 //
00016 // THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
00017 // the suitability of this software for any purpose.  THIS SOFTWARE IS
00018 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
00019 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 //
00022 // Other copyrights might apply to parts of this software and are so
00023 // noted when applicable.
00024 
00025 // smac is designed and developed by Wei Ye (SCADDS/ISI)
00026 // and is ported into ns by Padma Haldar, June'02.
00027 
00028 // This module implements Sensor-MAC
00029 //  See http://www.isi.edu/scadds/papers/smac_infocom.pdf for details
00030 //
00031 // It has the following functions.
00032 //  1) Both virtual and physical carrier sense
00033 //  2) RTS/CTS for hidden terminal problem
00034 //  3) Backoff and retry
00035 //  4) Broadcast packets are sent directly without using RTS/CTS/ACK.
00036 //  5) A long unicast message is divided into multiple TOS_MSG (by upper
00037 //     layer). The RTS/CTS reserves the medium for the entire message.
00038 //     ACK is used for each TOS_MSG for immediate error recovery.
00039 //  6) Node goes to sleep when its neighbor is communicating with another
00040 //     node.
00041 //  7) Each node follows a periodic listen/sleep schedule
00042 //  8) At bootup time each node listens for a fixed SYNCPERIOD and then
00043 //     tries to send out a sync packet. It suppresses sending out of sync pkt 
00044 //     if it happens to receive a sync pkt from a neighbor and follows the 
00045 //     neighbor's schedule. 
00046 // 
00047 
00048 #ifndef NS_SMAC
00049 #define NS_SMAC
00050 
00051 #include "mac.h"
00052 #include "mac-802_11.h"
00053 #include "cmu-trace.h"
00054 #include "random.h"
00055 #include "timer-handler.h"
00056 
00057 /* User-adjustable MAC parameters
00058  *--------------------------------
00059  * The default values can be overriden in Each application's Makefile
00060  * SMAC_MAX_NUM_NEIGHB: maximum number of neighbors.
00061  * SMAC_MAX_NUM_SCHED: maximum number of different schedules.
00062  * SMAC_DUTY_CYCLE: duty cycle in percentage. It controls the length of sleep 
00063  *   interval.
00064  * SMAC_RETRY_LIMIT: maximum number of RTS retries for sending a single message.
00065  * SMAC_EXTEND_LIMIT: maximum number of times to extend Tx time when ACK timeout
00066      happens.
00067  */
00068 
00069 #ifndef SMAC_MAX_NUM_NEIGHBORS
00070 #define SMAC_MAX_NUM_NEIGHBORS 20
00071 #endif
00072 
00073 #ifndef SMAC_MAX_NUM_SCHEDULES
00074 #define SMAC_MAX_NUM_SCHEDULES 4
00075 #endif
00076 
00077 #ifndef SMAC_DUTY_CYCLE
00078 #define SMAC_DUTY_CYCLE 10
00079 #endif
00080 
00081 #ifndef SMAC_RETRY_LIMIT
00082 #define SMAC_RETRY_LIMIT 5
00083 #endif
00084 
00085 #ifndef SMAC_EXTEND_LIMIT
00086 #define SMAC_EXTEND_LIMIT 5
00087 #endif
00088 
00089 
00090 /* Internal MAC parameters
00091  *--------------------------
00092  * Do NOT change them unless for tuning S-MAC
00093  * SYNC_CW: number of slots in the sync contention window, must be 2^n - 1 
00094  * DATA_CW: number of slots in the data contention window, must be 2^n - 1
00095  * SYNC_PERIOD: period to send a sync pkt, in cycles.
00096  */
00097 
00098 #define SYNC_CW 31
00099 #define DATA_CW 63
00100 #define SYNCPERIOD 10
00101 #define SYNCPKTTIME 3         // an adhoc value used for now later shld converge with durSyncPkt_
00102 
00103 /* Physical layer parameters
00104  *---------------------------
00105  * Based on the parameters from PHY_RADIO and RADIO_CONTROL
00106  * CLOCK_RES: clock resolution in ms. 
00107  * BANDWIDTH: bandwidth (bit rate) in kbps. Not directly used.
00108  * PRE_PKT_BYTES: number of extra bytes transmitted before each pkt. It equals
00109  *   preamble + start symbol + sync bytes.
00110  * ENCODE_RATIO: output/input ratio of the number of bytes of the encoding
00111  *  scheme. In Manchester encoding, 1-byte input generates 2-byte output.
00112  * PROC_DELAY: processing delay of each packet in physical and MAC layer, in ms
00113  */
00114 
00115 #define CLOCKRES 1       // clock resolution is 1ms
00116 #define BANDWIDTH 20      // kbps =>CHANGE BYTE_TX_TIME WHENEVER BANDWIDTH CHANGES
00117 //#define BYTE_TX_TIME 4/10 // 0.4 ms to tx one byte => changes when bandwidth does
00118 #define PRE_PKT_BYTES 5
00119 #define ENCODE_RATIO 2   /* Manchester encoding has 2x overhead */
00120 #define PROC_DELAY 1
00121 
00122 
00123 
00124 // Note everything is in clockticks (CLOCKRES in ms) for tinyOS
00125 // so we need to convert that to sec for ns
00126 #define CLKTICK2SEC(x)  ((x) * (CLOCKRES / 1.0e3))
00127 #define SEC2CLKTICK(x)  ((x) / (CLOCKRES / 1.0e3))
00128 
00129 
00130 // MAC states
00131 #define SLEEP 0         // radio is turned off, can't Tx or Rx
00132 #define IDLE 1          // radio in Rx mode, and can start Tx
00133 //#define CHOOSE_SCHED 2  // node in boot-up phase, needs to choose a schedule
00134 #define CR_SENSE 2      // medium is free, do it before initiate a Tx
00135 //#define BACKOFF 3       // medium is busy, and cannot Tx
00136 #define WAIT_CTS 3      // sent RTS, waiting for CTS
00137 #define WAIT_DATA 4     // sent CTS, waiting for DATA
00138 #define WAIT_ACK 5      // sent DATA, waiting for ACK
00139 #define WAIT_NEXTFRAG 6 // send one fragment, waiting for next from upper layer
00140 
00141 
00142 // how to send the pkt: broadcast or unicast
00143 #define BCASTSYNC 0
00144 #define BCASTDATA 1
00145 #define UNICAST 2
00146 
00147 // Types of pkt
00148 #define DATA_PKT 0
00149 #define RTS_PKT 1
00150 #define CTS_PKT 2
00151 #define ACK_PKT 3
00152 #define SYNC_PKT 4
00153 
00154 
00155 // radio states for performance measurement
00156 #define RADIO_SLP 0  // radio off
00157 #define RADIO_IDLE 1 // radio idle
00158 #define RADIO_RX 2   // recv'ing mode
00159 #define RADIO_TX 3   // transmitting mode
00160 
00161 
00162 
00163 
00164 /*  sizeof smac datapkt hdr and smac control and sync packets  */
00165 /*  have been hardcoded here to mirror the values in TINY_OS implementation */
00166 /*  The following is the pkt format definitions for tiny_os implementation */
00167 /*  of smac : */
00168 
00169 /*  typedef struct MAC_CTRLPKT_VALS{ */
00170 /*  unsigned char length; */
00171 /*  char type; */
00172 /*  short addr; */
00173 /*  unsigned char group; */
00174 /*  short srcAddr; */
00175 /*  unsigned char duration; */
00176 /*  short crc; */
00177 /*  }; */
00178 
00179 /*  typedef struct MAC_SYNCPKT_VALS{ */
00180 /*  unsigned char length; */
00181 /*  char type; */
00182 /*  short srcAddr; */
00183 /*  short syncNode; */
00184 /*  unsigned char sleepTime;  // my next sleep time from now */
00185 /*  short crc; */
00186 /*  };  */
00187 
00188 /*  struct MSG_VALS{ */
00189 /*  unsigned char length; */
00190 /*  char type; */
00191 /*  short addr; */
00192 /*  unsigned char group; */
00193 /*  short srcAddr; */
00194 /*  unsigned char duration; */
00195 /*  char data[DATA_LENGTH]; */
00196 /*  short crc; */
00197 /*  }; */
00198 
00199 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00200 
00201 #define SIZEOF_SMAC_DATAPKT 50  // hdr(10) + payload - fixed size pkts
00202 #define SIZEOF_SMAC_CTRLPKT 10
00203 #define SIZEOF_SMAC_SYNCPKT 9  
00204 
00205 
00206 // Following are the ns definitions of the smac frames
00207 //SYNC PKT 
00208 struct smac_sync_frame { 
00209   int type; 
00210   int length; 
00211   int srcAddr;
00212   //int dstAddr;
00213   int syncNode; 
00214   double sleepTime;  // my next sleep time from now */
00215   int crc; 
00216 }; 
00217 
00218 // RTS, CTS, ACK
00219 struct smac_control_frame {
00220   int type;
00221   int length;
00222   int dstAddr;
00223   int srcAddr;
00224   double duration;
00225   int crc;
00226 };
00227 
00228 // DATA 
00229 struct hdr_smac {
00230   int type;
00231   int length;
00232   int dstAddr;
00233   int srcAddr;
00234   double duration;
00235   //char data[DATA_LENGTH];
00236   int crc;
00237 };
00238 
00239 // Used by smac when in sync mode
00240 struct SchedTable { 
00241   int txSync;  // flag indicating need to send sync 
00242   int txData;  // flag indicating need to send data 
00243   int numPeriods; // count for number of periods 
00244 }; 
00245 
00246 struct NeighbList { 
00247   int nodeId; 
00248   int schedId; 
00249 }; 
00250 
00251 class SMAC;
00252 
00253 // Timers used in smac
00254 class SmacTimer : public TimerHandler {
00255  public:
00256   SmacTimer(SMAC *a) : TimerHandler() {a_ = a; }
00257   virtual void expire(Event *e) = 0 ;
00258   int busy() ;
00259  protected:
00260   SMAC *a_;
00261 };
00262 
00263 // Generic timer used for sync, CTS and ACK timeouts
00264 class SmacGeneTimer : public SmacTimer {
00265  public:
00266   SmacGeneTimer(SMAC *a) : SmacTimer(a) {}
00267   void expire(Event *e);
00268 };
00269 
00270 // Receive timer for receiving pkts
00271 class SmacRecvTimer : public SmacTimer {
00272  public:
00273   SmacRecvTimer(SMAC *a) : SmacTimer(a) { stime_ = rtime_ = 0; }
00274   void sched(double duration);
00275   void expire(Event *e);
00276   double timeToExpire();
00277  protected:
00278   double stime_;
00279   double rtime_;
00280 };
00281 
00282 // Send timer
00283 class SmacSendTimer : public SmacTimer {
00284  public:
00285   SmacSendTimer(SMAC *a) : SmacTimer(a) {}
00286   void expire(Event *e);
00287 };
00288 
00289 // Nav- indicating if medium is busy or not
00290 class SmacNavTimer : public SmacTimer {
00291  public:
00292   SmacNavTimer(SMAC *a) : SmacTimer(a) {}
00293   void expire(Event *e);
00294 };
00295 
00296 // Neighbor nav - if neighbor is busy or not
00297 // used for data timeout
00298 class SmacNeighNavTimer : public SmacTimer {
00299  public:
00300   SmacNeighNavTimer(SMAC *a) : SmacTimer(a) { stime_ = rtime_ = 0; }
00301   void sched(double duration);
00302   void expire(Event *e);
00303   double timeToExpire();
00304  protected:
00305   double stime_;
00306   double rtime_;
00307 };
00308 
00309 // carrier sense timer
00310 class SmacCsTimer : public SmacTimer {
00311  public:
00312   SmacCsTimer(SMAC *a) : SmacTimer(a) {}
00313   void expire(Event *e);
00314   void checkToCancel();
00315 };
00316 
00317 // synchronisation timer, regulates the sleep/wakeup cycles
00318 class SmacCounterTimer : public SmacTimer { 
00319  public:  
00320   friend class SMAC;
00321   SmacCounterTimer(SMAC *a, int i) : SmacTimer(a) {index_ = i;}
00322   void sched(double t);
00323   void expire(Event *e); 
00324   double timeToSleep();
00325  protected:
00326   int index_;
00327   int value_;
00328   int syncTime_;
00329   int dataTime_;
00330   int listenTime_;
00331   int sleepTime_;
00332   int cycleTime_;
00333   double tts_;
00334   double stime_;
00335 }; 
00336 
00337 
00338 // The smac class
00339 class SMAC : public Mac {
00340   
00341   friend class SmacGeneTimer;
00342   friend class SmacRecvTimer;
00343   friend class SmacSendTimer;
00344   friend class SmacNavTimer;
00345   friend class SmacNeighNavTimer;
00346   friend class SmacCsTimer; 
00347   friend class SmacCounterTimer;
00348 
00349  public:
00350   SMAC(void);
00351   ~SMAC() { 
00352     for (int i=0; i< SMAC_MAX_NUM_SCHEDULES; i++) {
00353       delete mhCounter_[i];
00354     }
00355   }
00356   void recv(Packet *p, Handler *h);
00357 
00358  protected:
00359   
00360   // functions for handling timers
00361   void handleGeneTimer();
00362   void handleRecvTimer();
00363   void handleSendTimer();
00364   void handleNavTimer();
00365   void handleNeighNavTimer();
00366   void handleCsTimer();
00367   //void handleChkSendTimer();
00368   void handleCounterTimer(int i);
00369 
00370   // Internal MAC parameters
00371   double slotTime_;
00372   double slotTime_sec_;
00373   double difs_;
00374   double sifs_;
00375   double eifs_;
00376   double guardTime_;
00377   double byte_tx_time_;
00378   
00379  private:
00380   // functions for node schedule folowing sleep-wakeup cycles
00381   void setMySched(Packet *syncpkt);
00382   void sleep();
00383   void wakeup();
00384 
00385   // functions for handling incoming packets
00386   
00387   void rxMsgDone(Packet* p);
00388   //void rxFragDone(Packet *p);  no frag for now
00389 
00390   void handleRTS(Packet *p);
00391   void handleCTS(Packet *p);
00392   void handleDATA(Packet *p);
00393   void handleACK(Packet *p);
00394   void handleSYNC(Packet *p);
00395 
00396   // functions for handling outgoing packets
00397   
00398   // check for pending data pkt to be tx'ed
00399   // when smac is not following SYNC (sleep-wakeup) cycles.
00400   int checkToSend();               // check if can send, start cs 
00401 
00402   bool chkRadio();         // checks radiostate
00403   void transmit(Packet *p);         // actually transmits packet
00404 
00405   bool sendMsg(Packet *p, Handler *h);
00406   bool bcastMsg(Packet *p);
00407   bool unicastMsg(int n, Packet *p);
00408   //int sendMoreFrag(Packet *p);
00409   
00410   void txMsgDone();
00411   // void txFragDone();
00412 
00413   int startBcast();
00414   int startUcast();
00415   
00416   bool sendRTS();
00417   bool sendCTS(double duration);
00418   bool sendDATA();
00419   bool sendACK(double duration);
00420   bool sendSYNC();
00421 
00422   void sentRTS(Packet *p);
00423   void sentCTS(Packet *p);
00424   void sentDATA(Packet *p);
00425   void sentACK(Packet *p);
00426   void sentSYNC(Packet *p);
00427   
00428   // Misc functions
00429   void collision(Packet *p);
00430   void capture(Packet *p);
00431   double txtime(Packet *p);
00432   
00433   void updateNav(double duration);
00434   void updateNeighNav(double duration);
00435 
00436   void mac_log(Packet *p) {
00437     logtarget_->recv(p, (Handler*) 0);
00438   }
00439   
00440   void discard(Packet *p, const char* why);
00441   int drop_RTS(Packet *p, const char* why);
00442   int drop_CTS(Packet *p, const char* why);
00443   int drop_DATA(Packet *p, const char* why);
00444   int drop_SYNC(Packet *p, const char* why);
00445 
00446   // smac methods to set dst, src and hdr_type in pkt hdrs
00447   inline int hdr_dst(char* hdr, int dst = -2) {
00448     struct hdr_smac *sh = (struct hdr_smac *) hdr;
00449     if (dst > -2)
00450       sh->dstAddr = dst;
00451     return sh->dstAddr;
00452   }
00453   inline int hdr_src(char* hdr, int src = -2) {
00454     struct hdr_smac *sh = (struct hdr_smac *) hdr;
00455     if (src > -2)
00456       sh->srcAddr = src;
00457     return sh->srcAddr;
00458   }
00459   inline int hdr_type(char *hdr, u_int16_t type = 0) {
00460     struct hdr_smac *sh = (struct hdr_smac *) hdr;
00461     if (type)
00462       sh->type = type;
00463     return sh->type;
00464   }
00465   
00466   // SMAC internal variables
00467   
00468   NsObject*       logtarget_;
00469   
00470   // Internal states
00471   int  state_;                   // MAC state
00472   int  radioState_;              // state of radio, rx, tx or sleep
00473   int tx_active_;                
00474   int mac_collision_;            
00475   
00476   int sendAddr_;                // node to send data to
00477   int recvAddr_;                // node to receive data from
00478   
00479   double  nav_;         // network allocation vector. nav>0 -> medium busy
00480   double  neighNav_;      // track neighbors' NAV while I'm sending/receiving
00481   
00482   // SMAC Timers
00483   SmacNavTimer          mhNav_;         // NAV timer medium is free or not
00484   SmacNeighNavTimer     mhNeighNav_;    // neighbor NAV timer for data timeout
00485   SmacSendTimer         mhSend_;        // incoming packets
00486   SmacRecvTimer         mhRecv_;        // outgoing packets
00487   SmacGeneTimer         mhGene_;        // generic timer used sync/CTS/ACK timeout
00488   SmacCsTimer           mhCS_;          // carrier sense timer
00489   
00490   // array of countertimer, one for each schedule
00491   // counter tracking node's sleep/awake cycle
00492   SmacCounterTimer      *mhCounter_[SMAC_MAX_NUM_SCHEDULES];  
00493 
00494 
00495   int numRetry_;        // number of tries for a data pkt
00496   int numExtend_;      // number of extensions on Tx time when frags are lost
00497   //int numFrags_;       // number of fragments in this transmission
00498   //int succFrags_;      // number of successfully transmitted fragments
00499   int lastRxFrag_;     // keep track of last data fragment recvd to prevent duplicate data
00500 
00501   int howToSend_;               // broadcast or unicast
00502   
00503   double durSyncPkt_;     // duration of sync packet
00504   double durDataPkt_;     // duration of data packet XXX caveat fixed packet size
00505   double durCtrlPkt_;     // duration of control packet
00506   double timeWaitCtrl_;   // set timer to wait for a control packet
00507   
00508   struct SchedTable schedTab_[SMAC_MAX_NUM_SCHEDULES];   // schedule table
00509   struct NeighbList neighbList_[SMAC_MAX_NUM_NEIGHBORS]; // neighbor list
00510 
00511   int mySyncNode_;                                 // nodeid of my synchronizer
00512   
00513   int currSched_;      // current schedule I'm talking to
00514   int numSched_;       // number of different schedules
00515   int numNeighb_;      // number of known neighbors
00516   int numBcast_;       // number of times needed to broadcast a packet
00517   
00518   Packet *dataPkt_;             // outgoing data packet
00519   Packet *pktRx_;               // buffer for incoming pkt
00520   Packet *pktTx_;               // buffer for outgoing pkt
00521 
00522   // flag to check pending data pkt for tx
00523   // when smac is not following SYNC (sleep-wakeup) cycles.
00524   int txData_ ;
00525 
00526   int syncFlag_;  // is set to 1 when SMAC uses sleep-wakeup cycle
00527 
00528   // sleep-wakeup cycle times
00529   int syncTime_;
00530   int dataTime_;
00531   int listenTime_;
00532   int sleepTime_;
00533   int cycleTime_;
00534 
00535  protected:
00536   int command(int argc, const char*const* argv);
00537   virtual int initialized() { 
00538     return (netif_ && uptarget_ && downtarget_); 
00539   }
00540 };
00541 
00542 
00543 #endif //NS_SMAC

Generated on Tue Apr 20 12:14:32 2004 for NS2.26SourcesOriginal by doxygen 1.3.3