smac.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:78k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * smac.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: smac.cc,v 1.18 2005/12/10 17:57:13 liyuan Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. // smac is designed and developed by Wei Ye (SCADDS/ISI)
  46. // and is re-written for ns by Padma Haldar (CONSER/ISI).
  47. // Contributors: Yuan Li
  48. // This module implements Sensor-MAC
  49. //  http://www.isi.edu/scadds/papers/smac_report.pdf
  50. //
  51. // It has the following functions.
  52. //  1) Both virtual and physical carrier sense
  53. //  2) RTS/CTS for hidden terminal problem
  54. //  3) Backoff and retry
  55. //  4) Broadcast packets are sent directly without using RTS/CTS/ACK.
  56. //  5) A long unicast message is divided into multiple TOS_MSG (by upper
  57. //     layer). The RTS/CTS reserves the medium for the entire message.
  58. //     ACK is used for each TOS_MSG for immediate error recovery.
  59. //  6) Node goes to sleep when its neighbor is communicating with another
  60. //     node.
  61. //  7) Each node follows a periodic listen/sleep schedule
  62. //  8.1) At bootup time each node listens for a fixed SYNCPERIOD and then
  63. //     tries to send out a sync packet. It suppresses sending out of sync pkt
  64. //     if it happens to receive a sync pkt from a neighbor and follows the
  65. //     neighbor's schedule.
  66. //  8.2) Or a node can choose its own schecule instead of following others, the
  67. //       schedule start time is user configurable
  68. //  9) Neighbor Discovery: in order to prevent that two neighbors can not
  69. //     find each other due to following complete different schedules, each
  70. //     node periodically listen for a whole period of the SYNCPERIOD
  71. //  10) Duty cycle is user configurable
  72. //  New features including adaptive listen
  73. //   See http://www.isi.edu/~weiye/pub/smac_ton.pdf
  74.                                                                                                                                                            
  75. #include "wireless-phy.h"
  76. #include "smac.h"
  77. static class MacSmacClass : public TclClass {
  78. public:
  79.        MacSmacClass() : TclClass("Mac/SMAC") {}
  80. TclObject* create(int, const char*const*) {
  81. return (new SMAC());
  82. }
  83. } class_macSMAC;
  84. // Timers call on expiration
  85. int SmacTimer::busy()
  86. {
  87. if (status_ != TIMER_PENDING)
  88. return 0;
  89. else
  90. return 1;
  91. }
  92. #ifdef JOURNAL_PAPER
  93. void SmacUpdateNeighbTimer::expire(Event *e) {
  94.         a_->handleUpdateNeighbTimer();
  95. }
  96.                                                                                                                                                             
  97. void SmacAdaptiveListenTimer::expire(Event *e) {
  98.         a_->handleAdaptiveListenTimer();
  99. }
  100. #endif
  101. void SmacGeneTimer::expire(Event *e) {
  102. a_->handleGeneTimer();
  103. }
  104. void SmacRecvTimer::expire(Event *e) {
  105. stime_ = rtime_ = 0;
  106. a_->handleRecvTimer();
  107. }
  108. void SmacRecvTimer::sched(double time) {
  109. TimerHandler::sched(time);
  110. stime_ = Scheduler::instance().clock();
  111. rtime_ = time;
  112. }
  113. void SmacRecvTimer::resched(double time) {
  114. TimerHandler::resched(time);
  115. stime_ = Scheduler::instance().clock();
  116. rtime_ = time;
  117. }
  118. double SmacRecvTimer::timeToExpire() {
  119. return ((stime_ + rtime_) - Scheduler::instance().clock());
  120. }
  121. void SmacSendTimer::expire(Event *e) {
  122. a_->handleSendTimer();
  123. }
  124. void SmacNavTimer::expire(Event *e) {
  125. a_->handleNavTimer();
  126. }
  127. void SmacNeighNavTimer::sched(double time) {
  128. TimerHandler::sched(time);
  129. stime_ = Scheduler::instance().clock();
  130. rtime_ = time;
  131. }
  132. void SmacNeighNavTimer::expire(Event *e) {
  133. stime_ = rtime_ = 0;
  134. a_->handleNeighNavTimer();
  135. }
  136. double SmacNeighNavTimer::timeToExpire() {
  137. return ((stime_ + rtime_) - Scheduler::instance().clock());
  138. }
  139. void SmacCsTimer::expire(Event *e) {
  140. a_->handleCsTimer();
  141. }
  142. // if pending, cancel timer
  143. void SmacCsTimer::checkToCancel() {
  144. if (status_ == TIMER_PENDING)
  145. cancel();
  146. }
  147. // void SmacChkSendTimer::expire(Event *e) {
  148. //   a_->handleChkSendTimer();
  149. // }
  150. void SmacCounterTimer::sched(double time) {
  151. // the cycle timer assumes that all time shall be scheduled with time "left to sleep" 
  152. // and not the absolute time for a given state (sleep, sync or data). Thus inorder 
  153. // to schedule for a sleep state, need to schedule with aggregate time CYCLETIME 
  154. // (sleeptime+synctime+dadatime).
  155. // Similarly for sync state, schedule with listenTime_ (synctime+datattime)
  156. // This is implemented to be in step with the counter used in actual smac.
  157. tts_ = time; // time before it goes to sleep again
  158. stime_ = Scheduler::instance().clock();
  159.   
  160. if (time <= CLKTICK2SEC(cycleTime_) && time > CLKTICK2SEC(listenTime_)) { // in sleep state
  161. value_ = sleepTime_;
  162. if (status_ == TIMER_IDLE)
  163. TimerHandler::sched(time - CLKTICK2SEC(listenTime_)); 
  164. else
  165. TimerHandler::resched(time - CLKTICK2SEC(listenTime_)); 
  166.     
  167. } else if ( time <= CLKTICK2SEC(listenTime_) && time > CLKTICK2SEC(dataTime_)) { // in sync state
  168. value_ = syncTime_;
  169. if (status_ == TIMER_IDLE)
  170. TimerHandler::sched(time - CLKTICK2SEC(dataTime_)); 
  171. else
  172. TimerHandler::resched(time - CLKTICK2SEC(dataTime_)); 
  173.     
  174. } else { // in data state
  175. assert(time <= CLKTICK2SEC(dataTime_));
  176. value_ = dataTime_;
  177. if (status_ == TIMER_IDLE)
  178. TimerHandler::sched(time); 
  179. else
  180. TimerHandler::resched(time); 
  181.     
  182. }
  183. }
  184. double SmacCounterTimer::timeToSleep() {
  185. return ((stime_ + tts_) - Scheduler::instance().clock()) ;
  186. }
  187. void SmacCounterTimer::expire(Event *e) {
  188. tts_ = stime_ = 0;
  189. a_->handleCounterTimer(index_);
  190. }
  191. #ifdef JOURNAL_PAPER
  192. SMAC::SMAC() : Mac(), mhUpdateNeighb_(this),mhNav_(this), mhNeighNav_(this), mhSend_(this), mhRecv_(this), mhGene_(this), mhCS_(this), mhAdap_(this), syncFlag_(0) {
  193.         int i;
  194. #else
  195. SMAC::SMAC() : Mac(), mhNav_(this), mhNeighNav_(this), mhSend_(this), mhRecv_(this), mhGene_(this), mhCS_(this), syncFlag_(0) {
  196. #endif
  197. state_ = IDLE;
  198. radioState_ = RADIO_IDLE;
  199. tx_active_ = 0;
  200. mac_collision_ = 0;
  201.   
  202. sendAddr_ = -1;
  203. recvAddr_ = -1;
  204. nav_ = 0;
  205. neighNav_ = 0;
  206.   
  207. numRetry_ = 0;
  208. numExtend_ = 0;
  209. lastRxFrag_ = -3; // since -1, -2 and 0 could be valid pkt uid's
  210. //numFrags_ = 0;
  211. //succFrags_ = 0;
  212. #ifdef JOURNAL_PAPER
  213.         numFrags_ = 0;
  214.         succFrags_ = 0;
  215.         dataSched_ = 0;
  216.         syncSched_ = 0;
  217.                                                                                                                                                             
  218.         globalSchedule_ = 0; // Do not test global schedule
  219.         //globalSchedule_ = 1; // Test global schedule
  220.                                                                                                                                                             
  221.         updateNeighbList_ = 0;
  222.                                                                                                                                                             
  223.         sendSYNCFlag_ = 0;
  224.                                                                                                                                                             
  225.         sendAddr = -1;
  226.         adapSend_ = 0;
  227.         txRequest_ = 0;
  228.                                                                                                                                                             
  229.         adaptiveListen_ = 0;
  230. #endif
  231. dataPkt_ = 0;
  232. pktRx_ = 0;
  233. pktTx_ = 0;
  234. /* setup internal mac and physical parameters
  235.    ----------------------------------------------
  236.    byte_tx_time_: time to transmit a byte, in ms. Derived from bandwidth
  237.   
  238.    slotTime_: time of each slot in contention window. It should be large
  239.    enough to receive the whole start symbol but cannot be smaller than clock 
  240.    resolution. in msec
  241.   
  242.    slotTime_sec_: slottime in sec
  243.   
  244.    difs_: DCF interframe space (from 802.11), in ms. It is used at the beginning
  245.    of each contention window. It's the minmum time to wait to start a new 
  246.    transmission.
  247.   
  248.    sifs_: short interframe space (f
  249.    /rom 802.11), in ms. It is used before sending
  250.    an CTS or ACK packet. It takes care of the processing delay of each pkt.
  251.   
  252.    eifs_: Entended interfrane space (from 802.11) in ms. Used for backing off 
  253.    incase of a collision.
  254.    guardTime_: guard time at the end of each listen interval, in ms.
  255. */
  256. byte_tx_time_ = 8.0 / BANDWIDTH;
  257. double start_symbol = byte_tx_time_ * 2.5;  // time to tx 20 bits
  258. slotTime_ = CLOCKRES >= start_symbol ? CLOCKRES : start_symbol;  // in msec
  259. slotTime_sec_ = slotTime_ / 1.0e3;   // in sec
  260. difs_ = 10.0 * slotTime_;
  261. sifs_ = 5.0 * slotTime_;
  262. eifs_ = 50.0 * slotTime_;
  263. guardTime_ = 4.0 * slotTime_;
  264.   
  265. // calculate packet duration. Following equations assume 4b/6b coding.
  266. // All calculations yield in usec
  267. //durSyncPkt_ = ((SIZEOF_SMAC_SYNCPKT) * 12 + 18) / 1.0e4 ;
  268. durSyncPkt_ =  (PRE_PKT_BYTES + (SIZEOF_SMAC_SYNCPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
  269. durSyncPkt_ = CLKTICK2SEC(durSyncPkt_);
  270. //durDataPkt_ = ((SIZEOF_SMAC_DATAPKT) * 12 + 18) / 1.0e4 ;
  271. durDataPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_DATAPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
  272. durDataPkt_ = CLKTICK2SEC(durDataPkt_);
  273. //durCtrlPkt_ = ((SIZEOF_SMAC_CTRLPKT) * 12 + 18) / 1.0e4;
  274. durCtrlPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_CTRLPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
  275. durCtrlPkt_ = CLKTICK2SEC(durCtrlPkt_);
  276.   
  277. // time to wait for CTS or ACK
  278. //timeWaitCtrl_ = durCtrlPkt_ + CLKTICK2SEC(4) ;    // timeout time
  279. double delay = 2 * PROC_DELAY + sifs_;
  280. timeWaitCtrl_ = CLKTICK2SEC(delay) + durCtrlPkt_;    // timeout time
  281.   
  282. numSched_ = 0;
  283. numNeighb_ = 0;
  284. numSync_ = 1;  // perform neighbor discovery, do not go to sleep for the first SYNC period
  285. schedListen_ = 1;
  286. searchNeighb_ = 1;
  287. #ifdef JOURNAL_PAPER
  288.         schedState_ = 1;  // this is my first schedule
  289. // initialize neighbour table
  290.         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
  291. neighbList_[i].nodeId = 0;
  292. neighbList_[i].schedId = 0;
  293. neighbList_[i].active = 0;
  294.                 neighbList_[i].state = 0;
  295.         }
  296.                                                                                                                                                             
  297.         // initialize schedule table
  298.         for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
  299.                 schedTab_[i].numNodes = 0;
  300.                 schedTab_[i].syncNode = 0;
  301.         }
  302.                                                                                                                                                             
  303.                                                                                                                                                             
  304.         schedTab_[0].numNodes = 1;  // I'm the only one on this schedule
  305.         schedTab_[0].syncNode = index_;  // I'm the schedule initializer
  306.         schedTab_[0].txData = 0;
  307.         schedTab_[0].txSync = 0;
  308.         schedTab_[0].chkSched = 0;
  309. #endif
  310. Tcl& tcl = Tcl::instance();
  311. tcl.evalf("Mac/SMAC set syncFlag_");
  312. if (strcmp(tcl.result(), "0") != 0)  
  313. syncFlag_ = 1;              // syncflag is set; use sleep-wakeup cycle
  314. tcl.evalf("Mac/SMAC set selfConfigFlag_");
  315.         if (strcmp(tcl.result(), "0") != 0)
  316.                 selfConfigFlag_ = 1;              // autoflag is set; user can not configure the schedule start time
  317. // User can specify the duty cycle
  318. tcl.evalf("Mac/SMAC set dutyCycle_");
  319. if (strcmp(tcl.result(), "0") != 0){
  320.                 bind_bw("dutyCycle_", &dutyCycle_);
  321.                 //printf("dutyCyle=%fn", dutyCycle_);
  322. }
  323.         else {
  324. //                dutyCycle_ = SMAC_DUTY_CYCLE;
  325. }
  326. if (!syncFlag_)
  327. txData_ = 0;
  328.   
  329. else {
  330. // Calculate sync/data/sleeptime based on duty cycle
  331. // all time in ms
  332. syncTime_ = difs_ + slotTime_ * SYNC_CW + SEC2CLKTICK(durSyncPkt_) + guardTime_;
  333. #ifdef JOURNAL_PAPER
  334.                 // added time for overhearing CTS so that can do adaptive listen
  335.                 dataTime_ = difs_ + slotTime_ * DATA_CW + SEC2CLKTICK(durCtrlPkt_) + PROC_DELAY + sifs_ + SEC2CLKTICK(durCtrlPkt_) + guardTime_;
  336. #else
  337. dataTime_ = difs_ + slotTime_ * DATA_CW + SEC2CLKTICK(durCtrlPkt_) + guardTime_;
  338. #endif
  339. listenTime_ = syncTime_ + dataTime_;
  340. cycleTime_ = listenTime_ * 100 / dutyCycle_ + 1;
  341. sleepTime_ = cycleTime_ - listenTime_;
  342.     
  343. //printf("cycletime=%d, sleeptime=%d, listentime=%dn", cycleTime_, sleepTime_, listenTime_);
  344. for (int i=0; i< SMAC_MAX_NUM_SCHEDULES; i++) {
  345. mhCounter_[i] = new SmacCounterTimer(this, i);
  346. mhCounter_[i]->syncTime_ = syncTime_;
  347. mhCounter_[i]->dataTime_ = dataTime_;
  348. mhCounter_[i]->listenTime_ = listenTime_;
  349. mhCounter_[i]->sleepTime_ = sleepTime_;
  350. mhCounter_[i]->cycleTime_ = cycleTime_;
  351. }
  352. // printf("syncTime= %d, dataTime= %d, listentime = %d, sleepTime= %d, cycletime= %dn", syncTime_, dataTime_, listenTime_, sleepTime_, cycleTime_);
  353. // listen for a whole period to choose a schedule first
  354. //double cw = (Random::random() % SYNC_CW) * slotTime_sec_ ;
  355.   
  356. // The foll (higher) CW value allows neigh nodes to follow a single schedule
  357. // double w = (Random::random() % (SYNC_CW)) ;
  358. // double cw = w/10.0;
  359. double c = CLKTICK2SEC(listenTime_) + CLKTICK2SEC(sleepTime_);
  360. double s = SYNCPERIOD + 1;
  361. double t = c * s ;
  362. //mhGene_.sched(t + cw);
  363. if ( selfConfigFlag_ == 1) {
  364. #ifdef JOURNAL_PAPER
  365.                 adapTime_ = dataTime_;
  366.                 mhGene_.sched(t);
  367.                                                                                                                                                             
  368.                 //start setting timer for update neighbor list
  369.                 //printf("SMAC_UPDATE_NEIGHB_PERIOD: ............node %d %d at %.6fn", index_, SMAC_UPDATE_NEIGHB_PERIOD, Scheduler::instance().clock());
  370.                 mhUpdateNeighb_.sched(SMAC_UPDATE_NEIGHB_PERIOD);
  371.                 //dump();
  372. #else
  373. mhGene_.sched(t);
  374. #endif
  375. }
  376. }
  377. }
  378. void SMAC::setMySched(Packet *pkt) 
  379. {
  380. // set my schedule and put it into the first entry of schedule table
  381. state_ = IDLE;
  382. numSched_ = 1;
  383. schedTab_[0].numPeriods = 0;
  384. schedTab_[0].txData = 0;
  385. schedTab_[0].txSync = 1; // need to brdcast my schedule
  386.   
  387. if (pkt == 0) { // freely choose my schedule
  388. #ifdef JOURNAL_PAPER
  389.                 //printf("#############################################################n");
  390.                 //printf(" %d is choosing its own shedule %d n", index_, index_);
  391.                 //printf("#############################################################n");
  392.                 schedState_++;
  393.                 mhCounter_[0]->sched(CLKTICK2SEC(listenTime_+index_*10));
  394.                 schedTab_[0].syncNode = index_;
  395. #else
  396. mhCounter_[0]->sched(CLKTICK2SEC(listenTime_));
  397. #endif
  398. mySyncNode_ = index_; // myself
  399. currSched_ = 0;
  400. //sendSYNC();  
  401.     
  402. } else { // follow schedule in syncpkt
  403.     
  404. struct smac_sync_frame *pf = (struct smac_sync_frame *)pkt->access(hdr_mac::offset_);
  405. mhCounter_[0]->sched(pf->sleepTime);
  406. #ifdef JOURNAL_PAPER
  407.                 mySyncNode_ = pf->syncNode;
  408.                 //printf("#############################################################n");
  409.                 //printf("%d receives SYNC packet from %d and starts following shedule %d n", index_, pf->srcAddr, pf->syncNode);
  410.                 //printf("#############################################################n");
  411.                 schedTab_[0].numNodes++;  // 2 nodes on this schedule now
  412.                 schedTab_[0].syncNode = pf->syncNode;
  413.                 schedState_++;
  414.                                                                                                                                                             
  415.                 //add node in my neighbor list
  416.                 neighbList_[0].nodeId = pf->srcAddr;
  417.                 neighbList_[0].schedId = 0;
  418.                 neighbList_[0].active = 1;
  419.                 neighbList_[0].state = pf->state;
  420. #else
  421. mySyncNode_ = pf->srcAddr;    
  422. //add node in my neighbor list
  423. neighbList_[0].nodeId = mySyncNode_;
  424. neighbList_[0].schedId = 0;
  425. #endif
  426. numNeighb_ = 1;
  427. }
  428. }
  429. int SMAC::command(int argc, const char*const* argv)
  430. {
  431. if (argc == 3) {
  432. if (strcmp(argv[1], "log-target") == 0) {
  433. logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
  434. if(logtarget_ == 0)
  435. return TCL_ERROR;
  436. return TCL_OK;
  437. }
  438. else if ( selfConfigFlag_ != 1) {
  439. if (strcmp(argv[1], "schedule-start-time") == 0) {
  440.                         startTime_ = strtod(argv[2],NULL);
  441.                          // set up schedule
  442.                         state_ = IDLE;
  443.                          numSched_ = 1;
  444.                          schedTab_[0].numPeriods = SYNCPERIOD;
  445.                          schedTab_[0].txData = 0;
  446.                         schedTab_[0].txSync = 1; // need to brdcast my schedule
  447.                          // schedule starts up with listen time (sync+data)
  448.                          // need to caculate time to sleep
  449.                          startTime_ = startTime_ + listenTime_;
  450.                         if ( startTime_ >= cycleTime_ )
  451.                                  startTime_ = startTime_ - cycleTime_;
  452.                          mhCounter_[0]->sched(CLKTICK2SEC(startTime_));
  453.                          mySyncNode_ = index_; // myself
  454.                         currSched_ = 0;
  455.                          return TCL_OK;
  456.                  }
  457. }
  458. }
  459. return Mac::command(argc, argv);
  460. }
  461. #ifdef JOURNAL_PAPER
  462. void SMAC::adaptiveListen()
  463. {
  464.         // adaptively wake-up at the end of current transmission. Will try to
  465.         // send only if the buffered packet is unicast. Since my next-hop
  466.         // neighbor may not be aware of the Tx of my previous-hop neighbor,
  467.         // broadcast now is unreliable
  468.         //printf("adaptiveListen set AdaptiveTimer: node %d scheduletime: %f adapTime_: %d time:%.9f n", index_, mhCounter_[0]->value_, adapTime_, Scheduler::instance().clock());
  469.         mhAdap_.resched(CLKTICK2SEC(adapTime_)); // set timer to bring me back to sleep
  470.         adaptiveListen_ = 1;
  471.         if (state_ == SLEEP) {
  472.                 //printf("adaptiveListen wakeup: node %d scheduletime: %f time:%.9f n", index_, mhCounter_[0]->value_, Scheduler::instance().clock());
  473.                 wakeup();
  474.         }
  475.          else {
  476.         }
  477.                                                                                                                                                             
  478.         if ( schedTab_[0].txData == 1 && sendAddr == UNICAST_ADDR){
  479.                 adapSend_ = 1;
  480.                 checkToSend();
  481.         }
  482. }
  483. #endif
  484. // XXXX smac handler functions
  485. void SMAC::handleSendTimer() {
  486. assert(pktTx_);
  487.   
  488. struct hdr_smac *sh = HDR_SMAC(pktTx_);
  489.   
  490. // Packet tx is done so radio should go back to idle
  491. radioState_ = RADIO_IDLE;
  492. tx_active_ = 0;
  493.   
  494. switch(sh->type) {
  495.     
  496. case RTS_PKT:
  497. sentRTS(pktTx_);
  498. break;
  499. case CTS_PKT:
  500. sentCTS(pktTx_);
  501. break;
  502.     
  503. case DATA_PKT:
  504. sentDATA(pktTx_);
  505. break;
  506.   
  507. case ACK_PKT:
  508. sentACK(pktTx_);
  509. break;
  510. case SYNC_PKT:
  511. sentSYNC(pktTx_);
  512. break;
  513. default:
  514. fprintf(stderr, "unknown mac pkt type, %dn", sh->type);
  515. break;
  516. }
  517.   
  518. pktTx_ = 0;
  519. }
  520. void SMAC::handleRecvTimer() {
  521. assert(pktRx_);
  522.   
  523. struct hdr_cmn *ch = HDR_CMN(pktRx_);
  524. struct hdr_smac *sh = HDR_SMAC(pktRx_);
  525. if (state_ == SLEEP) {
  526. // Bug fixed here. a collision might happen just now, need to clear the mac_collision_ flag, otherwise the node won't receive any following packet
  527. if (mac_collision_) {
  528.                 discard(pktRx_, DROP_MAC_COLLISION);
  529.                  mac_collision_ = 0;
  530.                 updateNav(CLKTICK2SEC(eifs_));
  531.                 if (state_ == CR_SENSE)
  532.                          sleep(); // have to wait until next wakeup time
  533.                  else
  534.                          radioState_ = RADIO_IDLE;
  535.                 goto done;
  536.                 }
  537. discard(pktRx_, DROP_MAC_SLEEP);
  538. radioState_ = RADIO_SLP;
  539. goto done;
  540. }
  541.   
  542. // if the radio interface is tx'ing when this packet arrives
  543. // I would never have seen it and should do a silent discard 
  544.   
  545. if (radioState_ == RADIO_TX) {
  546. Packet::free(pktRx_);
  547. goto done;
  548. }
  549.   
  550. if (mac_collision_) {
  551. discard(pktRx_, DROP_MAC_COLLISION);
  552. mac_collision_ = 0;
  553. updateNav(CLKTICK2SEC(eifs_));
  554.     
  555. if (state_ == CR_SENSE) 
  556. sleep(); // have to wait until next wakeup time
  557. else 
  558. radioState_ = RADIO_IDLE;
  559.     
  560. goto done;
  561. }
  562.   
  563. if (ch->error()) {
  564. Packet::free(pktRx_);
  565. updateNav(CLKTICK2SEC(eifs_)); 
  566. if (state_ == CR_SENSE) 
  567. sleep();
  568. else 
  569. radioState_ = RADIO_IDLE;
  570.       
  571. goto done;
  572. }
  573.   
  574. // set radio from rx to idle again
  575. radioState_ = RADIO_IDLE;
  576. switch (sh->type) {
  577. case DATA_PKT:
  578. handleDATA(pktRx_);
  579. break;
  580. case RTS_PKT:
  581. handleRTS(pktRx_);
  582. Packet::free(pktRx_);
  583. break;
  584. case CTS_PKT:
  585. handleCTS(pktRx_);
  586. Packet::free(pktRx_);
  587. break;
  588. case ACK_PKT:
  589. handleACK(pktRx_);
  590. Packet::free(pktRx_);
  591. break;
  592. case SYNC_PKT:
  593. handleSYNC(pktRx_);
  594. Packet::free(pktRx_);
  595. break;
  596. default:
  597. fprintf(stderr, "Unknown smac pkt type, %dn", sh->type);
  598. break;
  599. }
  600.   
  601.  done:
  602. pktRx_ = 0;
  603.   
  604. }
  605. void SMAC::handleGeneTimer() 
  606. {
  607.   
  608. if (syncFlag_) {
  609. // still in choose-schedule state
  610. if (numSched_ == 0) {
  611. setMySched(0); // I'm the primary synchroniser
  612. return;
  613. }
  614. if (state_ == WAIT_CTS) {  // CTS timeout
  615. if (numRetry_ < SMAC_RETRY_LIMIT) {
  616. numRetry_++;
  617. // wait until receiver's next wakeup
  618. state_ = IDLE;
  619. #ifdef JOURNAL_PAPER
  620. //node tries to go to sleep if it needs to resend
  621.                  if( mhCounter_[0]->value_ == sleepTime_ )
  622.                          sleep();
  623. #endif
  624.  
  625. if (!syncFlag_)
  626. checkToSend();
  627.       
  628. } else {
  629. state_ = IDLE;
  630. Packet::free(dataPkt_);
  631. dataPkt_ = 0;
  632. numRetry_ = 0;
  633. //numFrags_ = 0;
  634. // signal upper layer about failure of tx 
  635. // txMsgFailed();
  636. txMsgDone();
  637.       
  638. }
  639.     
  640. } else if (state_ == WAIT_ACK) { // ack timeout
  641.     
  642. if (numExtend_ < SMAC_EXTEND_LIMIT) { // extend time
  643. printf("SMAC %d: no ACK received. Extend Tx time.n", index_);
  644. numExtend_++;
  645.       
  646. updateNeighNav(durDataPkt_ + durCtrlPkt_);
  647. //neighNav_ = (durDataPkt_ + durCtrlPkt_);
  648.       
  649. } else { // reached extension limit, can't extend time
  650. //numFrags_--;
  651.       
  652. }
  653. if (neighNav_ < (durDataPkt_ + durCtrlPkt_)) {
  654.       
  655. // used up reserved time, stop tx
  656.       
  657. discard(dataPkt_, DROP_MAC_RETRY_COUNT_EXCEEDED);
  658. dataPkt_ = 0;
  659. pktTx_ = 0;
  660. state_ = IDLE;
  661.       
  662. // signal upper layer the number of transmitted frags
  663. //txMsgFailed(succFrags); -> no frag for now
  664.       
  665. txMsgDone();
  666.       
  667. } else { // still have time
  668. // keep sending until use up remaining time
  669. sendDATA();
  670. }
  671. #ifdef JOURNAL_PAPER
  672.         } else if (state_ == DATA_SENSE1) {
  673.                 state_ = DATA_SENSE2;
  674.                 mhGene_.resched(timeWaitCtrl_);
  675.                                                                                                                                                             
  676.         } else if (state_ == DATA_SENSE2) {
  677.                 state_ = IDLE;
  678. //node tries to go to sleep if it does not hear CTS or DATA for others' connection
  679.                 if( mhCounter_[0]->value_ == sleepTime_ )
  680.                         sleep();
  681. #endif
  682. }
  683. }
  684. void SMAC::handleNavTimer() {
  685. // medium is now free
  686. nav_ = 0; // why have this variable?? probably not required use the timer instead
  687.   
  688. if (!syncFlag_) {
  689. if (state_ == SLEEP)
  690. wakeup();
  691. // try to send waiting data, if any
  692. checkToSend();
  693. #ifdef JOURNAL_PAPER
  694.         adaptiveListen();
  695. #endif
  696. }
  697. int SMAC::checkToSend() {
  698. #ifdef JOURNAL_PAPER
  699.         if (txRequest_ == 1 || syncFlag_) {
  700. #else
  701. if (txData_ == 1) {
  702. #endif
  703. assert(dataPkt_);
  704. struct hdr_smac *mh = HDR_SMAC(dataPkt_);
  705.     
  706. if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
  707. goto done;  // cannot send if radio is sending or recving
  708.     
  709. if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
  710. goto done; // cannot send if not in any of these states
  711.     
  712. if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
  713.     (state_ == SLEEP || state_ == IDLE)) {
  714.       
  715. if (state_ == SLEEP) wakeup();
  716.       
  717. if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
  718. howToSend_ = BCASTDATA;
  719. else
  720. howToSend_ = UNICAST;
  721.       
  722. state_ = CR_SENSE;
  723. #ifdef JOURNAL_PAPER
  724.                         adapSend_ = 0;
  725. //printf("adaptiveListen sendData: node %d scheduletime: %f time:%.9f n", index_, mhCounter_[0]->value_, Scheduler::instance().clock());
  726. #endif
  727.     
  728. // start cstimer
  729. double cw = (Random::random() % DATA_CW) * slotTime_sec_;
  730. mhCS_.sched(CLKTICK2SEC(difs_) + cw);
  731.       
  732. return 1;
  733.     
  734. } else {
  735. return 0;
  736. }
  737.     
  738. done:
  739. return 0;
  740.     
  741. } else {
  742. return 0;
  743. }
  744. }
  745. void SMAC::handleNeighNavTimer() {
  746.   
  747. // Timer to track my neighbor's NAV
  748. neighNav_ = 0;         // probably don't need to use this variable
  749.   
  750. if (state_ == WAIT_DATA) { // data timeout
  751. state_ = IDLE;
  752.     
  753. // signal upper layer that rx msg is done
  754. // didnot get any/all data
  755. rxMsgDone(0); 
  756. } else {
  757. if (!syncFlag_)
  758. checkToSend();
  759. }
  760. #ifdef JOURNAL_PAPER
  761.         adaptiveListen();
  762. #endif
  763. }
  764. void SMAC::handleCsTimer() {
  765.   
  766. // carrier sense successful
  767.   
  768. #ifdef MAC_DEBUG
  769. if (howToSend_ != BCASTSYNC && dataPkt_ == 0)
  770. numCSError++;
  771. #endif // MAC_DEBUG
  772.   
  773. switch(howToSend_) {
  774. case BCASTSYNC:
  775. if (sendSYNC())
  776. state_ = IDLE;
  777. break;
  778.     
  779. case BCASTDATA:
  780. startBcast();
  781. break;
  782.     
  783. case UNICAST:
  784. startUcast();
  785. break;
  786. }
  787. }
  788. void SMAC::handleCounterTimer(int id) {
  789.   
  790. //printf("MAC:%d,id:%d - time:%.9fn", index_,id,Scheduler::instance().clock());
  791. #ifdef JOURNAL_PAPER
  792.         if (schedTab_[id].numNodes > 0) {
  793. #endif
  794. if (mhCounter_[id]->value_ == sleepTime_) { //woken up from sleep
  795. // listentime starts now
  796. if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
  797. goto sched_1;  // cannot send if radio is sending or recving
  798.     
  799. if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
  800. goto sched_1;; // cannot send if not in any of these states
  801.     
  802. if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
  803.     (state_ == SLEEP || state_ == IDLE)) {
  804.     
  805. if (state_ == SLEEP &&
  806.     (id == 0 || schedTab_[id].txSync == 1)) {
  807. wakeup();
  808. }
  809. if (schedTab_[id].txSync == 1) {
  810. // start carrier sense for sending sync
  811. howToSend_ = BCASTSYNC;
  812. #ifdef JOURNAL_PAPER
  813. syncSched_ = id;
  814. #else
  815. currSched_ = id;
  816. #endif
  817. state_ = CR_SENSE;
  818. double cw = (Random::random() % SYNC_CW) * slotTime_sec_;
  819. mhCS_.sched(CLKTICK2SEC(difs_) + cw);
  820. }
  821. }
  822. // start to listen now
  823. sched_1:
  824. mhCounter_[id]->sched(CLKTICK2SEC(listenTime_));
  825.     
  826. } else if (mhCounter_[id]->value_ == syncTime_) { //synctime over
  827. // can start datatime now
  828.     
  829. if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
  830. goto sched_2;  // cannot send if radio is sending or recving
  831.     
  832. if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
  833. goto sched_2; // cannot send if not in any of these states
  834.     
  835. if (schedTab_[id].txData == 1 &&
  836.     (!(mhNav_.busy()) && !(mhNeighNav_.busy())) &&
  837.     (state_ == SLEEP || state_ == IDLE)) {
  838. // schedule sending data
  839.       
  840. if (state_ == SLEEP)
  841. wakeup();
  842.       
  843. struct hdr_smac *mh = (struct hdr_smac *)dataPkt_->access(hdr_mac::offset_);
  844. if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
  845. howToSend_ = BCASTDATA;
  846. else
  847. howToSend_ = UNICAST;
  848. #ifdef JOURNAL_PAPER
  849.                         dataSched_ = id;
  850. #else
  851. currSched_ = id;
  852. #endif
  853. state_ = CR_SENSE;
  854. // start cstimer
  855. double cw = (Random::random() % DATA_CW) * slotTime_sec_;
  856. mhCS_.sched(CLKTICK2SEC(difs_) + cw);
  857. }
  858. sched_2:
  859. mhCounter_[id]->sched(CLKTICK2SEC(dataTime_));
  860.     
  861. } else if (mhCounter_[id]->value_ == dataTime_) { //datatime over
  862. // check if in the middle of recving a pkt
  863. if (radioState_ == RADIO_RX)
  864. goto sched_3;
  865. #ifdef JOURNAL_PAPER    
  866. if (id == 0 && state_ == IDLE && searchNeighb_ ==0 && adaptiveListen_ ==0 )
  867. #else
  868. if (id == 0 && state_ == IDLE && searchNeighb_ ==0 )
  869. #endif
  870. sleep();
  871. sched_3:
  872. // now time to go to sleep
  873. mhCounter_[id]->sched(CLKTICK2SEC(cycleTime_));
  874.     
  875. // check if ready to send out sync 
  876. if (schedTab_[id].numPeriods > 0) {
  877. schedTab_[id].numPeriods--;
  878. if (schedTab_[id].numPeriods == 0) {
  879. schedTab_[id].txSync = 1; 
  880. // neighbor discovery
  881. if ( id == 0 ) {
  882. numSync_--;
  883. // printf("numSync_ %d: ............node %d at %.6fn", numSync_, index_,Scheduler::instance().clock());
  884. if ( numSync_ == 1 ) {
  885. searchNeighb_ = 1; // node will go to neighbor discovery period starting from the next frame
  886. //printf("Start Neighbor Discovery: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  887. }
  888. else if ( numSync_ == 0 ) {
  889. searchNeighb_  = 0;  // neighbor discovery period lasts exactly one SYNC period
  890. //printf("Ending Neighbor Discovery: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  891. if ( numNeighb_ == 0 ) {
  892. numSync_ = SRCH_CYCLES_SHORT;
  893. }
  894. else {
  895. numSync_ = SRCH_CYCLES_LONG;
  896. }
  897. }
  898. }
  899. }
  900. }
  901. }
  902. #ifdef JOURNAL_PAPER
  903.     }
  904. #endif
  905. }
  906. #ifdef JOURNAL_PAPER
  907. void SMAC::handleUpdateNeighbTimer() {
  908.         //printf("SMAC::handleUpdateNeighbTimer: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  909.         if (txRequest_ == 0) { // No data waiting to be transmitted
  910.                 txRequest_ = 1; // temporarily disable tx when updating
  911.                 update_myNeighbList();
  912.         } else {
  913.                 updateNeighbList_ = 1; // set flag to update when tx done
  914.         }
  915. }
  916.                                                                                                                                                             
  917. void SMAC::handleAdaptiveListenTimer() {
  918. //node tries to go to sleep after adaptive listen times out
  919.         adaptiveListen_ = 0;
  920.         if (state_ == IDLE && state_ != TX_PKT && mhCounter_[0]->value_ == sleepTime_)
  921.                 sleep();
  922. }
  923. #endif
  924. // recv function for mac layer
  925. void SMAC::recv(Packet *p, Handler *h) {
  926.                                                                                                                                                             
  927. struct hdr_cmn *ch = HDR_CMN(p);
  928. assert(initialized());
  929. // handle outgoing pkt
  930. if ( ch->direction() == hdr_cmn::DOWN) {
  931. sendMsg(p, h);
  932. return;
  933. }
  934. // handle incoming pkt
  935. // we have just recvd the first bit of a pkt on the network interface  
  936.   
  937. // if the interface is in tx mode it probably would not see this pkt
  938. if (radioState_ == RADIO_TX && ch->error() == 0) {
  939. assert(tx_active_);
  940. ch->error() = 1;
  941. pktRx_ = p;
  942. mhRecv_.resched(txtime(p));
  943. return;
  944. }
  945.   
  946. // cancel carrier sense timer and wait for entire pkt
  947. if (state_ == CR_SENSE) {
  948. //printf("Cancelling CS- node %dn", index_);
  949. // cancels only if timer is pending; smac could be in CR_SENSE with timer cancelled
  950. // incase it has already received a pkt and receiving again
  951. mhCS_.checkToCancel();
  952. }
  953.   
  954. // if the interface is already in process of recv'ing pkt
  955. if (radioState_ == RADIO_RX) {
  956. assert(pktRx_); 
  957. assert(mhRecv_.busy());
  958.     
  959. // if power of the incoming pkt is smaller than the power 
  960. // of the pkt currently being recvd by atleast the capture 
  961. // threshold then we ignore the new pkt.
  962.     
  963. if (pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) 
  964. capture(p);
  965. else
  966. collision(p);
  967.   
  968. else {
  969. if (mhRecv_.busy()) { // and radiostate != RADIO_RX
  970. assert(radioState_ == RADIO_SLP);
  971. // The radio interface was recv'ing a pkt when it went to sleep
  972. // should it postpone sleep till it finishes recving the pkt???
  973. mhRecv_.resched(txtime(p));
  974. } else
  975. mhRecv_.sched(txtime(p));
  976.     
  977. radioState_ = RADIO_RX;
  978. pktRx_ = p;
  979. }
  980. }
  981. void SMAC::capture(Packet *p) {
  982. // we update NAV for this pkt txtime
  983. updateNav(CLKTICK2SEC(eifs_) + txtime(p));
  984. Packet::free(p);
  985. }
  986. void SMAC::collision(Packet *p) {
  987. if (!mac_collision_)
  988. mac_collision_ = 1;
  989.   
  990. // since a collision has occured figure out which packet that caused 
  991. // the collision will "last" longer. Make this pkt pktRx_ and reset the
  992. // recv timer.
  993. if (txtime(p) > mhRecv_.timeToExpire()) {
  994. mhRecv_.resched(txtime(p));
  995. discard(pktRx_, DROP_MAC_COLLISION);
  996. // shouldn't we free pkt here ???
  997. pktRx_ = p;
  998. }
  999. else 
  1000. discard(p, DROP_MAC_COLLISION);
  1001. // shouldn't we free pkt here ???
  1002. }
  1003. void SMAC::discard(Packet *p, const char* why)
  1004. {
  1005. hdr_cmn *ch = HDR_CMN(p);
  1006. hdr_smac *sh = HDR_SMAC(p);
  1007.   
  1008. /* if the rcvd pkt contains errors, a real MAC layer couldn't
  1009.    necessarily read any data from it, so we just toss it now */
  1010. if(ch->error() != 0) {
  1011. Packet::free(p);
  1012. //p = 0;
  1013. return;
  1014. }
  1015. switch(sh->type) {
  1016.     
  1017. case RTS_PKT:
  1018. if (drop_RTS(p, why))
  1019. return;
  1020. break;
  1021.     
  1022. case CTS_PKT:
  1023. case ACK_PKT:
  1024. if (drop_CTS(p, why))
  1025. return;
  1026. break;
  1027.   
  1028. case DATA_PKT:
  1029. if (drop_DATA(p, why))
  1030. return;
  1031. break;
  1032. case SYNC_PKT:
  1033. if(drop_SYNC(p, why))
  1034. return;
  1035. break;
  1036. default:
  1037. fprintf(stderr, "invalid MAC type (%x)n", sh->type);
  1038. //trace_pkt(p);
  1039. exit(1);
  1040. }
  1041. Packet::free(p);
  1042. }
  1043. int SMAC::drop_RTS(Packet *p, const char* why) 
  1044. {
  1045. struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
  1046.   
  1047. if (cf->srcAddr == index_) {
  1048. drop(p, why);
  1049. return 1;
  1050. }
  1051. return 0;
  1052. }
  1053. int SMAC::drop_CTS(Packet *p, const char* why) 
  1054. {
  1055. struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
  1056. if (cf->dstAddr == index_) {
  1057. drop(p, why);
  1058. return 1;
  1059. }
  1060. return 0;
  1061. }
  1062. int SMAC::drop_DATA(Packet *p, const char* why) 
  1063. {
  1064. hdr_smac *sh = HDR_SMAC(p);
  1065. if ( (sh->dstAddr == index_) ||
  1066.      (sh->srcAddr == index_) ||
  1067.      ((u_int32_t)sh->dstAddr == MAC_BROADCAST)) {
  1068. drop(p, why);
  1069. return 1;
  1070. }
  1071. return 0;
  1072. }
  1073. int SMAC::drop_SYNC(Packet *p, const char* why) 
  1074. {
  1075. drop(p, why);
  1076. return 1;
  1077. }
  1078. #ifdef JOURNAL_PAPER
  1079. void SMAC::checkMySched()
  1080. {
  1081.         // check if I am the only one on schedTab[0]
  1082.         // if yes, should switch and follow the next available schedule
  1083.         // happens when an old node switches to a new schedule
  1084.         // and when I drop some inactive nodes from neighbor list(updating)
  1085.         int i, schedId;
  1086.         schedId = 0;
  1087.         if (schedTab_[0].numNodes == 1 && numSched_ > 1 && numNeighb_ > 0) {
  1088.                 for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) {
  1089.                         if (schedTab_[i].numNodes > 0) {  // switch to next available schedule
  1090.                                 //schedTab_[0].counter = schedTab[i].counter;
  1091.                                 schedTab_[0].numPeriods = 0;
  1092.                                 schedTab_[0].txSync = 1;
  1093.                                 schedTab_[0].txData = schedTab_[i].txData;
  1094.                                 schedTab_[0].syncNode = schedTab_[i].syncNode;
  1095.                                 schedTab_[0].numNodes = schedTab_[i].numNodes + 1;
  1096.                                 // delete this schedule
  1097.                                 schedTab_[i].numNodes = 0;
  1098.                                 numSched_--;
  1099.                                 schedId = i;
  1100.                                 break;
  1101.                         }
  1102.                 }
  1103.                 if (schedId > 0){
  1104.                         schedState_++;
  1105.                         // update my neighbor list which relative to this schedId
  1106.                         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
  1107.                                 if (neighbList_[i].state > 0 )
  1108.                                         if (neighbList_[i].schedId == schedId)
  1109.                                                 neighbList_[i].schedId = 0;
  1110.                         }
  1111.                 }
  1112.         }
  1113. }
  1114. // update_schedTab_neighbList() is executed whenever the transmission is done
  1115. void SMAC::update_schedTab_neighbList()
  1116. {
  1117.         //update schedTab and neighbList if flag is set
  1118.         //we should update the schedTab[].numNodes before we call checkMySched()
  1119.         //to ensure the next available schedule is correct
  1120.         check_schedFlag();
  1121.         if (updateNeighbList_ == 1) {
  1122.                 update_neighbList();
  1123.                 updateNeighbList_ = 0;
  1124.                 schedTab_[0].chkSched = 0;  //we already did checkMySched() in update_neighbList()
  1125.         } else if (schedTab_[0].chkSched == 1) {
  1126.                 checkMySched();
  1127.                 schedTab_[0].chkSched = 0;
  1128.         }
  1129. }
  1130.                                                                                                                                                             
  1131. //update_myNeighbList() is executed whenever the UpdateNeighb timer timesout
  1132. void SMAC::update_myNeighbList()
  1133. {
  1134.         //we should update the schedTab[].numNodes before we call checkMySched()
  1135.         //to ensure the next available schedule is correct
  1136.         check_schedFlag();
  1137.         update_neighbList();
  1138.         updateNeighbList_ = 0;
  1139.         schedTab_[0].chkSched = 0;  //we already did checkMySched() in update_neighbList()
  1140.         txRequest_ = 0;
  1141. }
  1142.                                                                                                                                                             
  1143. void SMAC::update_neighbList()
  1144. {
  1145.         // update neighbor list,
  1146.         // if the node is not active (moved away or died) for a certain time,
  1147.         // need to drop it from neighbor list
  1148.                                                                                                                                                             
  1149.         //printf("nupdate_neighbList:node %d at %.6f n", index_, Scheduler::instance().clock());
  1150.         int i, schedId;
  1151.         //dump();
  1152.         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
  1153.                 if (neighbList_[i].state > 0 ){
  1154.                         if (neighbList_[i].active != 1){ // this node is not active recently
  1155.                                 //printf("node %d lost a neighbor of node %d: ............at %.6fn", index_, neighbList_[i].nodeId, Scheduler::instance().clock());
  1156.                                 schedId = neighbList_[i].schedId;
  1157.                                 schedTab_[schedId].numNodes--;
  1158.                                 if (schedTab_[schedId].numNodes == 0)
  1159.                                         numSched_--;
  1160.                                 neighbList_[i].state = 0;
  1161.                                 numNeighb_--;
  1162.                         } else
  1163.                                 //printf("node %d has a neighbor of node %d: ............at %.6fn", index_, neighbList_[i].nodeId, Scheduler::instance().clock());
  1164.                         neighbList_[i].active = 0;
  1165.                 }
  1166.         }
  1167.         //printf("#####################################################n");
  1168.                                                                                                                                                             
  1169.         // maybe the inactive nodes were dropped from schedTab[0]
  1170.         // check if I am the only one on schedTab[0]
  1171.         // if yes, I should follow the next available schedule
  1172.         checkMySched();
  1173.         mhUpdateNeighb_.resched(SMAC_UPDATE_NEIGHB_PERIOD);
  1174. }
  1175. void SMAC::check_schedFlag()
  1176. {
  1177.         int i;
  1178.         // decrease the numNodes in the old schedule first
  1179.         for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) {
  1180.                 if (schedTab_[i].numNodes > 0 && schedTab_[i].chkSched == 1){
  1181.                         schedTab_[i].chkSched = 0;
  1182.                         schedTab_[i].numNodes--;
  1183.                         if (schedTab_[i].numNodes == 0)
  1184.                                 numSched_--;
  1185.                 }
  1186.         }
  1187. }
  1188. #endif
  1189. void SMAC::handleRTS(Packet *p) {
  1190. // internal handler for RTS
  1191. struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
  1192.   
  1193. if(cf->dstAddr == index_) {
  1194. if((state_ == IDLE || state_ == CR_SENSE) && nav_ == 0) {
  1195. recvAddr_ = cf->srcAddr; // remember sender's addr
  1196. #ifdef JOURNAL_PAPER
  1197.                         updateNeighNav(cf->duration);
  1198. #endif
  1199. if(sendCTS(cf->duration)) {
  1200. state_ = WAIT_DATA;
  1201. lastRxFrag_ = -3; //reset frag no 
  1202. }
  1203. }
  1204. } else { 
  1205. // pkt destined to another node
  1206. // don't go to sleep unless hear first data fragment
  1207. // so I know how long to sleep
  1208. if (state_ == CR_SENSE)
  1209. state_ = IDLE;
  1210. #ifdef JOURNAL_PAPER
  1211.                 updateNav(cf->duration);
  1212.                 state_ = DATA_SENSE1;
  1213.                 mhGene_.sched(timeWaitCtrl_);
  1214. #else
  1215. updateNav(durCtrlPkt_ + durDataPkt_);
  1216. #endif
  1217. }
  1218. }
  1219. void SMAC::handleCTS(Packet *p) {
  1220. // internal handler for CTS
  1221. struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
  1222. if(cf->dstAddr == index_) { // for me
  1223. if(state_ == WAIT_CTS && cf->srcAddr == sendAddr_) {
  1224. // cancel CTS timer
  1225. mhGene_.cancel();
  1226. if(sendDATA()) {
  1227. state_ = WAIT_ACK;
  1228. #ifndef JORNAL_PAPER
  1229. if (!syncFlag_)
  1230. txData_ = 0;
  1231. else
  1232. schedTab_[currSched_].txData = 0;
  1233. #endif
  1234. }
  1235. }
  1236. } else { // for others
  1237. updateNav(cf->duration);
  1238. #ifdef JOURNAL_PAPER
  1239.                 if(state_ == DATA_SENSE1 || state_ == DATA_SENSE2) { mhGene_.cancel();}
  1240.                 if(state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE1 || state_ == DATA_SENSE2)
  1241.                         sleep();
  1242. #else
  1243. if(state_ == IDLE || state_ == CR_SENSE)
  1244. sleep();
  1245. #endif
  1246. }
  1247. }
  1248. void SMAC::handleDATA(Packet *p) {
  1249. // internal handler for DATA packet
  1250. struct hdr_cmn *ch = HDR_CMN(p);
  1251. struct hdr_smac * sh = HDR_SMAC(p);
  1252.  
  1253. if((u_int32_t)sh->dstAddr == MAC_BROADCAST) { // brdcast pkt
  1254. state_ = IDLE;
  1255. // hand pkt over to higher layer
  1256. rxMsgDone(p);
  1257.     
  1258. } else if (sh->dstAddr == index_) { // unicast pkt
  1259. if(state_ == WAIT_DATA && sh->srcAddr == recvAddr_) {
  1260. // Should track neighbors' NAV, in case tx extended
  1261. updateNeighNav(sh->duration);
  1262. sendACK(sh->duration);
  1263. #ifdef JOURNAL_PAPER
  1264.                         if (sh->duration > durCtrlPkt_) { // wait for more frag
  1265.                                 rxFragDone(p);   //no frag for now
  1266.                                 state_ = WAIT_DATA;
  1267.                         } else {   // no more fragments
  1268.                          state_ = IDLE;
  1269.                                 rxMsgDone(p);
  1270.                         }
  1271. #else
  1272.       
  1273. //if (sh->duration > durCtrlPkt_) { // wait for more frag
  1274. //rxFragDone(p);   no frag for now
  1275. //state_ = IDLE;
  1276. //} else {   // no more fragments
  1277.       
  1278. state_ = IDLE;
  1279. if(lastRxFrag_ != ch->uid()) {
  1280. lastRxFrag_ = ch->uid();
  1281. rxMsgDone(p);
  1282. }
  1283. else {
  1284. printf("Recd duplicate data pkt at %d from %d! free pktn",index_,sh->srcAddr);
  1285. Packet::free(p);
  1286. if (!syncFlag_)
  1287. checkToSend();
  1288. }
  1289. #endif
  1290. } else if (state_ == IDLE || state_ == CR_SENSE ) {
  1291. printf("got data pkt in %d state XXX %dn", state_, index_);
  1292. //updateNav(sh->duration + 0.00001);  // incase I have a pkt to send
  1293. sendACK(sh->duration);
  1294. state_ = IDLE;
  1295. if(lastRxFrag_ != ch->uid()) {
  1296. lastRxFrag_ = ch->uid();
  1297. rxMsgDone(p);
  1298. }
  1299. else {
  1300. printf("Recd duplicate data pkt! free pktn");
  1301. Packet::free(p);
  1302. if (!syncFlag_)
  1303. checkToSend();
  1304. }
  1305. } else { // some other state
  1306. // not sure we can handle this
  1307. // so drop pkt
  1308. printf("Got data pkt in !WAIT_DATA/!CR_SENSE/!IDLE state(%d) XXX %dn", state_, index_);
  1309. printf("Dropping data pktn");
  1310. Packet::free(p);
  1311. }
  1312. } else { // unicast pkt destined to other node
  1313. updateNav(sh->duration);
  1314. Packet::free(p);
  1315. #ifdef JOURNAL_PAPER
  1316.                 if (state_ == DATA_SENSE2) { mhGene_.cancel();}
  1317.                 if (state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE2)
  1318.                         sleep();
  1319. #else
  1320. if (state_ == IDLE || state_ == CR_SENSE)
  1321. sleep();
  1322. #endif
  1323. }
  1324. }
  1325. void SMAC::handleACK(Packet *p) {
  1326. // internal handler for ack
  1327. struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
  1328.   
  1329. if (cf->dstAddr == index_) {
  1330. if (state_ == WAIT_ACK && cf->srcAddr == sendAddr_) {
  1331. // cancel ACK timer
  1332. mhGene_.cancel();
  1333. #ifdef JOURNAL_PAPER
  1334.                         numFrags_--;
  1335.                         succFrags_++;
  1336.                         if (numFrags_ > 0) { //need to send more frags
  1337.                                   state_ = TX_NEXT_FRAG;
  1338.                                   txFragDone();
  1339.                                } else {
  1340.                         state_ = IDLE;
  1341.                         txMsgDone();
  1342. }
  1343. #else
  1344. Packet::free(dataPkt_);
  1345. dataPkt_ = 0;
  1346. //numFrags_--;
  1347. //succFrags_++;
  1348.       
  1349. // if (numFrags_ > 0) { //need to send more frags
  1350. //  if (neighNav__ < (durDataPkt_ + durCtrlPkt_)) {
  1351. //    // used up reserved time, have to stop
  1352. //    state_ = IDLE;
  1353. //    // txMsgFailed(succFrags_);
  1354. //    txMsgDone();
  1355. //  } else { // continue on next fragment
  1356. //    state_ = WAIT_NEXTFRAG;
  1357. //    txFragDone(dataPkt_);
  1358. //  }
  1359. //       } else {
  1360. state_ = IDLE;
  1361. txMsgDone();
  1362. //}
  1363. #endif
  1364. }
  1365.     
  1366. } else { // destined to another node
  1367. if (cf->duration > 0) {
  1368. updateNav(cf->duration);
  1369. if (state_ == IDLE || state_ == CR_SENSE)
  1370. sleep();
  1371. }
  1372. }
  1373. }
  1374. #ifdef JOURNAL_PAPER
  1375. void SMAC::handleSYNC(Packet *p) 
  1376. {
  1377. struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
  1378.         int i, j,nodeId, schedId, flag;
  1379.         struct SchedTable tempSched;
  1380.         int foundNeighb = 0;
  1381. if (index_ == 5){
  1382.         double t = Scheduler::instance().clock();
  1383.         //printf("Recvd SYNC (not/f) at %d from %d.....at %.6fn", index_, sf->srcAddr, t);
  1384. }
  1385. if (numSched_ == 0) { // in choose_sched state
  1386. mhGene_.cancel();
  1387. setMySched(p);
  1388. return;
  1389. }
  1390.        if (numNeighb_ == 0 && globalSchedule_ == 1) {
  1391.          // follow this schedule if having no other neighbor and if this schedule has smaller ID
  1392.          if (schedTab_[0].syncNode > sf->syncNode || !sendSYNCFlag_ ) {
  1393.           setMySched(p);
  1394.           return;
  1395.          }
  1396.        }
  1397.        else if (numNeighb_ == 0) { // getting first sync pkt
  1398.          // follow this sched as have no other neighbor
  1399.           setMySched(p);
  1400.           return;
  1401.        }
  1402. state_ = IDLE;
  1403.        // check if sender is on my neighbor list
  1404.        nodeId = SMAC_MAX_NUM_NEIGHBORS;
  1405.        schedId = SMAC_MAX_NUM_SCHEDULES;
  1406.        for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
  1407.           if (neighbList_[i].state > 0 && neighbList_[i].nodeId == sf->srcAddr) {
  1408.              nodeId = i;
  1409.              schedId = neighbList_[i].schedId; // a known neighbor
  1410.              break;
  1411.           }
  1412.        }
  1413.        if (nodeId < SMAC_MAX_NUM_NEIGHBORS) {
  1414.           if (neighbList_[nodeId].state == sf->state) {
  1415.              // update the existing schedule
  1416.      mhCounter_[schedId]->sched(sf->sleepTime);
  1417.              neighbList_[nodeId].active = 1;
  1418.              if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
  1419.                     // change state
  1420.                     schedState_++;
  1421. //printf("#############################################################n");
  1422.                  //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6fn", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
  1423. //printf("#############################################################n");
  1424.                       tempSched.syncNode = schedTab_[schedId].syncNode;
  1425.                       tempSched.txSync = schedTab_[schedId].txSync;  // need send sync
  1426.                       tempSched.txData = schedTab_[schedId].txData;
  1427.                       tempSched.numPeriods = schedTab_[schedId].numPeriods;
  1428.                       tempSched.numNodes = schedTab_[schedId].numNodes ; //
  1429.                 tempSched.chkSched = schedTab_[schedId].chkSched;
  1430.                     if (schedTab_[0].numNodes == 1) {
  1431.                       numSched_--;
  1432.                     }
  1433.       mhCounter_[schedId]->sched(mhCounter_[0]->timeToSleep());
  1434.                       schedTab_[schedId].syncNode = schedTab_[0].syncNode;
  1435.                       schedTab_[schedId].txSync = schedTab_[0].txSync;  // need send sync
  1436.                       schedTab_[schedId].txData = schedTab_[0].txData;
  1437.                       schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
  1438.                       schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
  1439.                       schedTab_[schedId].chkSched = schedTab_[0].chkSched;
  1440.                      // new schedule is schedule 0 now
  1441.     mhCounter_[0]->sched(sf->sleepTime);
  1442.                     schedTab_[0].syncNode = sf->syncNode;
  1443.                     schedTab_[0].txSync = 1;  
  1444.                     schedTab_[0].txData = tempSched.txData;
  1445.                     schedTab_[0].numPeriods = 0; 
  1446.                     schedTab_[0].numNodes = tempSched.numNodes + 1; // I are following this sched
  1447.                     schedTab_[0].chkSched = tempSched.chkSched;
  1448.                     // change all the neighbor who was following shedule 0
  1449.                     for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
  1450.                         if (neighbList_[j].schedId == 0) { // found an empty entry
  1451.                           neighbList_[j].schedId = schedId;
  1452.                         }
  1453.                         else if (neighbList_[j].schedId == schedId) { // found an empty entry
  1454.                           neighbList_[j].schedId = 0;
  1455.                         }
  1456.                      }
  1457.                   }
  1458.              return;
  1459.           } else {
  1460.                  // decrement number of nodes on old schedule
  1461.              if (schedTab_[schedId].numNodes ==1 && txRequest_ == 1) {
  1462.                  //set flag to decrement numNodes after tx pkt is done
  1463.                 schedTab_[schedId].chkSched = 1;
  1464.              }
  1465.              else 
  1466. {
  1467.                 schedTab_[schedId].numNodes--; 
  1468.                 if (schedTab_[schedId].numNodes == 0){
  1469.                    numSched_--;
  1470.                 }
  1471.         }
  1472. }
  1473. }
  1474.        // now it's either a new node or an old node switching to a new schedule
  1475.        // it is also possible that a node switches to an existing schedule
  1476.        // check if its schedule is a known one to me
  1477.        schedId = SMAC_MAX_NUM_SCHEDULES;
  1478.        for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
  1479.           if (schedTab_[i].numNodes > 0) {
  1480.     
  1481.      double t = mhCounter_[i]->timeToSleep();
  1482.      double st = sf->sleepTime;
  1483.      double timeDiff = st - t;
  1484.              if ( timeDiff > -GUARDTIME && timeDiff < GUARDTIME) {
  1485. mhCounter_[i]->sched(sf->sleepTime);
  1486.                 schedTab_[i].numNodes++; // it will follow this schedule
  1487.                 schedId = i;
  1488.                 break;
  1489.              } 
  1490.           }
  1491.        }
  1492.        if (schedId == SMAC_MAX_NUM_SCHEDULES) {  // unknow schedule
  1493.          flag =1;
  1494.           // add an entry to the schedule table
  1495.           if (numSched_ < SMAC_MAX_NUM_SCHEDULES){
  1496.              for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
  1497.                if (schedTab_[i].numNodes == 0) { // found an empty entry
  1498.                   // check if I need to switch
  1499.    if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
  1500.                   // change state
  1501.                     schedState_++;
  1502. //printf("#############################################################n");
  1503.                  //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6fn", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
  1504.                  //printf("#############################################################n");
  1505.                     if (schedTab_[0].numNodes >= 2) { // need to move old schedule 0 to schedule i
  1506.       mhCounter_[i]->sched(mhCounter_[0]->timeToSleep());
  1507.                       schedTab_[i].syncNode = schedTab_[0].syncNode;
  1508.                       schedTab_[i].txSync = schedTab_[0].txSync;  // need send sync
  1509.                       schedTab_[i].txData = schedTab_[0].txData;
  1510.                       schedTab_[i].numPeriods = schedTab_[0].numPeriods;
  1511.                       schedTab_[i].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
  1512.                       schedTab_[i].chkSched = schedTab_[0].chkSched;
  1513.                       numSched_++;  // increment number of schedules
  1514.                       // change all the neighbor who was following shedule 0
  1515.                       for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
  1516.                         if (neighbList_[j].schedId == 0) { // found an empty entry
  1517.                           neighbList_[j].schedId = i;
  1518.                         }
  1519.                       }
  1520.                     }
  1521.                       // new schedule is schedule 0 now
  1522.     mhCounter_[0]->sched(sf->sleepTime);
  1523.                     schedTab_[0].syncNode = sf->syncNode;
  1524.                     schedTab_[0].txSync = 1;  // need send sync
  1525.                     schedTab_[0].txData = 0;
  1526.     schedTab_[0].numPeriods = 0;
  1527.                     schedTab_[0].numNodes = 2; // 1st node + I are following this sched
  1528.                     schedTab_[0].chkSched = 0;
  1529.                     schedId = 0;
  1530.                   }
  1531.                   else { // fill new schedule in schedule i
  1532.               mhCounter_[i]->sched(sf->sleepTime);
  1533.                     schedTab_[i].syncNode = sf->syncNode;
  1534.                     schedTab_[i].txSync = 1;  // need send sync
  1535.                     schedTab_[i].txData = 0;
  1536.                     schedTab_[i].numPeriods = 0;
  1537.                     schedTab_[i].numNodes = 1; // 1st node following this sched
  1538.                     schedTab_[i].chkSched = 0;
  1539.                     schedId = i;
  1540.                     numSched_++;  // increment number of schedules
  1541.                   }
  1542.                   break;
  1543.                }
  1544.              }
  1545. }
  1546. }
  1547.        if (nodeId == SMAC_MAX_NUM_NEIGHBORS) {  // a new node
  1548.           // didn't find an empty entry in schedule table, just drop the new node
  1549.           if (schedId == SMAC_MAX_NUM_SCHEDULES) return;
  1550.           // add it to my neighbor list
  1551.           if (numNeighb_ < SMAC_MAX_NUM_NEIGHBORS){
  1552.              for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
  1553.                if (neighbList_[i].state == 0) { // found an empty entry
  1554.                   neighbList_[i].state = sf->state;
  1555.                   neighbList_[i].nodeId = sf->srcAddr;
  1556.                   neighbList_[i].schedId = schedId;
  1557.                   neighbList_[i].active = 1;
  1558.                   numNeighb_++;  // increment number of neighbors
  1559.                   return;
  1560.                }
  1561.              }
  1562.          }
  1563.          // didn't find an empty entry in neighb list, just drop the new node
  1564. schedTab_[schedId].numNodes--;
  1565.         if (schedTab_[schedId].numNodes == 0)
  1566.          numSched_--;
  1567.        } else if (flag == 1) {  // old node switches to a new schedule
  1568.          // didn't find an empty entry in schedule table, delete the old node
  1569.          if (schedId == SMAC_MAX_NUM_SCHEDULES) {
  1570.              neighbList_[nodeId].state = 0;
  1571.              numNeighb_--;  // decrement number of neighbors
  1572.           } else {
  1573.              neighbList_[nodeId].state = sf->state;
  1574.              neighbList_[nodeId].schedId = schedId;
  1575.              neighbList_[nodeId].active = 1;
  1576.           }
  1577.           // maybe the old node switches from schedTab_[0]
  1578.           // check if I am the only one on schedTab_[0] now
  1579.           // if yes, I should follow the next available schedule
  1580.           if (txRequest_ == 0) {
  1581.              checkMySched();
  1582.           } else {
  1583.           // set flag to call checkMySched() when txRequest_ becomes 0
  1584.              schedTab_[0].chkSched = 1;
  1585.           }
  1586.        } else {  // old node switches to old schedule
  1587.              neighbList_[nodeId].state = sf->state;
  1588.              neighbList_[nodeId].schedId = schedId;
  1589.              neighbList_[nodeId].active = 1;
  1590.    if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
  1591. //printf("#############################################################n");
  1592.                  //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6fn", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
  1593.                  //printf("#############################################################n");
  1594.                     // change state
  1595.                     schedState_++;
  1596.                       tempSched.syncNode = schedTab_[schedId].syncNode;
  1597.                       tempSched.txSync = schedTab_[schedId].txSync;  // need send sync
  1598.                       tempSched.txData = schedTab_[schedId].txData;
  1599.                       tempSched.numPeriods = schedTab_[schedId].numPeriods;
  1600.                       tempSched.numNodes = schedTab_[schedId].numNodes ; //
  1601.                       tempSched.chkSched = schedTab_[schedId].chkSched;
  1602.                     if (schedTab_[0].numNodes == 1) {
  1603.                       numSched_--;
  1604.                     }
  1605.       mhCounter_[schedId]->sched(mhCounter_[0]->timeToSleep());
  1606.                       schedTab_[schedId].syncNode = schedTab_[0].syncNode;
  1607.                       schedTab_[schedId].txSync = schedTab_[0].txSync;  // need send sync
  1608.                       schedTab_[schedId].txData = schedTab_[0].txData;
  1609.                       schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
  1610.                       schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
  1611.                       schedTab_[schedId].chkSched = schedTab_[0].chkSched;
  1612.                      /// new schedule is schedule 0 now
  1613.                      mhCounter_[0]->sched(sf->sleepTime);
  1614.                     schedTab_[0].syncNode = sf->syncNode;
  1615.                     schedTab_[0].txSync = 1; 
  1616.                     schedTab_[0].txData = tempSched.txData;
  1617.                     schedTab_[0].numPeriods = 0;
  1618.                     schedTab_[0].numNodes = tempSched.numNodes + 1; // I are following this sched
  1619.                     schedTab_[0].chkSched = tempSched.chkSched;
  1620.                    // change all the neighbor who was following shedule 0
  1621.                     for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
  1622.                         if (neighbList_[j].schedId == 0) { // found an empty entry
  1623.                           neighbList_[j].schedId = schedId;
  1624.                         }
  1625.                         else if (neighbList_[j].schedId == schedId) { // found an empty entry
  1626.                           neighbList_[j].schedId = 0;
  1627.                         }
  1628.                      }
  1629.           }
  1630. return;
  1631. }
  1632. }
  1633. #else
  1634. void SMAC::handleSYNC(Packet *p) 
  1635. {
  1636. //printf("node: %d ..............data sent............n",index_);
  1637. if ( selfConfigFlag_ == 1) {
  1638. if(numSched_ == 0) { // in choose_sched state
  1639. mhGene_.cancel();
  1640. //double t = Scheduler::instance().clock();
  1641. //struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
  1642. //printf("Recvd SYNC (follow) at %d from %d.....at %.6fn", index_, sf->srcAddr, t);
  1643. setMySched(p);
  1644. return;
  1645. }
  1646. if (numNeighb_ == 0) { // getting first sync pkt
  1647. // follow this sched as have no other neighbor
  1648.         //double t = Scheduler::instance().clock();
  1649. //struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
  1650. //printf("Recvd SYNC (follow) at %d from %d.....at %.6fn", index_, sf->srcAddr, t);
  1651.         setMySched(p);
  1652. return;
  1653. }
  1654. }
  1655. state_ = IDLE;
  1656. // check if sender is on my neighbor list
  1657. struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
  1658. int i, j;
  1659. int foundNeighb = 0;
  1660. int schedId = SMAC_MAX_NUM_SCHEDULES;
  1661. //double t = Scheduler::instance().clock();
  1662. //printf("Recvd SYNC (not/f) at %d from %d.....at %.6fn", index_, sf->srcAddr, t);
  1663.   
  1664. for(i = 0; i < numNeighb_; i++) {
  1665. if (neighbList_[i].nodeId == sf->srcAddr) {
  1666. foundNeighb = 1;
  1667. schedId = neighbList_[i].schedId;  // a known neighbor
  1668. mhCounter_[schedId]->sched(sf->sleepTime);
  1669. break;
  1670. }
  1671. if (neighbList_[i].nodeId == sf->syncNode)
  1672. // // found its synchronizer, remember it schedule id
  1673. schedId = neighbList_[i].schedId;
  1674. }
  1675. if (!foundNeighb) { // unknown node, add it onto neighbor list
  1676. neighbList_[numNeighb_].nodeId = sf->srcAddr;
  1677. if (schedId < SMAC_MAX_NUM_SCHEDULES) {
  1678. // found its synchronizer
  1679. neighbList_[numNeighb_].schedId = schedId;
  1680. } else if (sf->syncNode == index_) { // this node follows my schedule
  1681. neighbList_[numNeighb_].schedId = 0;
  1682. } else { // its synchronizer is unknown
  1683. // check if its schedule equals to an existing one
  1684. int foundSched = 0;
  1685. for (j = 0; j < numSched_; j++) {
  1686. double t = mhCounter_[j]->timeToSleep();
  1687. double st = sf->sleepTime; 
  1688. if (t == st || (t + CLKTICK2SEC(1)) == st || t == (st + CLKTICK2SEC(1))) {
  1689. neighbList_[numNeighb_].schedId = j;
  1690. foundSched = 1;
  1691. break;
  1692. }
  1693. }
  1694. if (!foundSched) { // this is unknown schedule
  1695. schedTab_[numSched_].txSync = 1;
  1696. schedTab_[numSched_].txData = 0;
  1697. schedTab_[numSched_].numPeriods = 0;
  1698. neighbList_[numNeighb_].schedId = numSched_;
  1699. mhCounter_[numSched_]->sched(sf->sleepTime);
  1700. numSched_++;
  1701. }
  1702. }
  1703. numNeighb_++;  // increment number of neighbors
  1704. }
  1705. }
  1706. #endif
  1707. void SMAC::rxMsgDone(Packet *p) {
  1708. // no more fragments
  1709. // defragment all pkts and send them up
  1710. // fragmentation/de-frag to be implemented
  1711.   
  1712. if (p)
  1713. uptarget_->recv(p, (Handler*)0);
  1714.   
  1715. if (!syncFlag_)
  1716. // check if any pkt waiting to get tx'ed
  1717. checkToSend();
  1718. #ifdef JOURNAL_PAPER
  1719. //node tries to go to sleep after receiving the message
  1720. //we temperarily disable sleep() here, because in the testcases where ARP messages exist, more than one message need to be transmitted in one round
  1721.         else {
  1722. //                if( mhCounter_[0]->value_ == sleepTime_ ) 
  1723. //                        sleep();
  1724.         }
  1725. #endif
  1726. }
  1727. #ifdef JOURNAL_PAPER
  1728. void SMAC::rxFragDone(Packet *p) {
  1729. //  more fragments to come
  1730. }
  1731. #endif
  1732. //void SMAC::rxFragDone(Packet *p) {
  1733. // more fragments to come
  1734. //}
  1735. // mac transmission functions
  1736. void SMAC::transmit(Packet *p) {
  1737.   
  1738. radioState_ = RADIO_TX;
  1739. tx_active_ = 1;
  1740. pktTx_ = p;
  1741. double transTime = txtime(p);
  1742. hdr_cmn *ch = hdr_cmn::access(p);
  1743. ch->txtime() = transTime;
  1744. // printf("%d MAC sending at %fn",index_,NOW);
  1745. downtarget_->recv(p->copy(), this);
  1746. //Scheduler::instance().schedule(downtarget_, p, 0.000001);
  1747. mhSend_.sched(txtime(p));
  1748. }
  1749. bool SMAC::chkRadio() {
  1750. // check radiostate
  1751. if (radioState_ == RADIO_IDLE || radioState_ == RADIO_SLP)
  1752. return (1);
  1753. return (0); // phy interface is ready to tx
  1754. }
  1755. int SMAC::startBcast()
  1756. {
  1757. // broadcast data directly; don't use RTS/CTS
  1758. hdr_smac *mh = HDR_SMAC(dataPkt_);
  1759.   
  1760. mh->duration = 0;
  1761. if(chkRadio()) {
  1762. transmit(dataPkt_);
  1763. return 1;
  1764. }
  1765.   
  1766. return 0;
  1767. }
  1768. int SMAC::startUcast()
  1769. {
  1770. printf("node: %d ..............data sent Uni............n",index_);
  1771. // start unicast data; send RTS first
  1772. hdr_smac *mh = HDR_SMAC(dataPkt_);
  1773.   
  1774. sendAddr_ = mh->dstAddr;
  1775. numRetry_ = 0;
  1776. //succFrags_ = 0;
  1777. #ifdef JOURNAL_PAPER
  1778. succFrags_ = 0;
  1779. #endif
  1780. numExtend_ = 0; 
  1781. if(sendRTS()) {
  1782. state_ = WAIT_CTS;
  1783. return 1;
  1784. }
  1785.   
  1786. return 0;
  1787. }
  1788. void  SMAC::txMsgDone() 
  1789. {
  1790. #ifdef JOURNAL_PAPER
  1791.         // update schedTab and neighbList if flags are set when txRequest_=1
  1792.         update_schedTab_neighbList();
  1793.         txRequest_ = 0;
  1794. #endif
  1795. if (!syncFlag_) {
  1796. #ifdef JOURNAL_PAPER
  1797.                 txData_ = 0;
  1798. #endif
  1799. // check if any data is waiting to get tx'ed
  1800. if(checkToSend())
  1801. return;
  1802. else if (callback_) { // signal upper layer
  1803. Handler *h = callback_;
  1804. callback_ = 0;
  1805. h->handle((Event*) 0);
  1806. }
  1807. } else {
  1808. #ifdef JOURNAL_PAPER
  1809.                 schedTab_[dataSched_].txData = 0;
  1810. #endif
  1811. if (callback_) { // signal upper layer
  1812. Handler *h = callback_;
  1813. callback_ = 0;
  1814. h->handle((Event*) 0);
  1815. }
  1816. #ifdef JOURNAL_PAPER
  1817. //node tries to go to sleep after transmission is done (both unicast and broadcast)
  1818.                 if( mhCounter_[0]->value_ == sleepTime_ )
  1819.                         sleep();
  1820. #endif
  1821. }
  1822.   
  1823. }
  1824. // void SMAC::txFragDone() 
  1825. // {
  1826. //   // send next fragment
  1827. // }
  1828. #ifdef JOURNAL_PAPER
  1829. void SMAC::txFragDone()
  1830. {
  1831.    // send next fragment
  1832.         txNextFrag(&dataPkt_);
  1833. }
  1834.                                                                                                                                                             
  1835. bool SMAC::txNextFrag(void* data)
  1836. {
  1837.       // Send subsequent fragments
  1838.                                                                                                                                                             
  1839.         if (state_ != TX_NEXT_FRAG || data == 0) return 0;
  1840. //      dataPkt = (MACHeader*)data;
  1841.       // fill in MAC header fields except duration
  1842. //      dataPkt->type = DATA_PKT;  // data pkt
  1843. //      dataPkt->toAddr = sendAddr;
  1844. //      dataPkt->fromAddr = TOS_LOCAL_ADDRESS;
  1845. //      dataPkt->fragNo = txFragCount;
  1846. //      if (neighbNav >= (SIFS + durDataPkt + timeWaitCtrl)) {
  1847.          // schedule to send this fragment, no need for carrier sense
  1848. //         state = TX_PKT;
  1849.         if(sendDATA()) {
  1850.                 state_ = WAIT_ACK;
  1851.                 if (!syncFlag_)
  1852.                         txData_ = 0;
  1853.                 else
  1854.                         schedTab_[dataSched_].txData = 0;
  1855.                         //schedTab_[currSched_].txData = 0;
  1856.         }
  1857.                                                                                                                                                             
  1858. //      } // else will retry when neighbNav timeout
  1859.         return 1;
  1860. }
  1861. #endif
  1862. bool SMAC::sendMsg(Packet *pkt, Handler *h) {
  1863. struct hdr_smac *mh = HDR_SMAC(pkt);
  1864. #ifdef JOURNAL_PAPER
  1865.         struct hdr_cmn *ch = HDR_CMN(pkt);
  1866. #endif
  1867. callback_ = h;
  1868. if ((u_int32_t)mh->dstAddr == MAC_BROADCAST) {
  1869. return (bcastMsg(pkt));
  1870. } else {
  1871. #ifdef JOURNAL_PAPER
  1872.                 //printf("message length: %dn",ch->size_);
  1873.                 // need upper level support here
  1874.                 int fragNum = ch->size_ / SIZEOF_SMAC_DATAPKT ;
  1875.                 if (fragNum == 0) fragNum = 1;
  1876.                 //printf("message length:%dn",fragNum);
  1877.                 return unicastMsg(fragNum, pkt);     // for now no fragmentation
  1878. #else
  1879. return (unicastMsg(1, pkt));     // for now no fragmentation
  1880. #endif
  1881. // fragmentation limit is 40 bytes per pkt.
  1882. // max_msg_size is tentatively 1000 bytes; weiye will confirm this
  1883. }
  1884. }
  1885. bool SMAC::bcastMsg(Packet *p) {
  1886. //if (dataPkt_ != 0 || p == 0) 
  1887. //return 0;
  1888. assert(p);
  1889.   
  1890. //if (state_ != IDLE && state_ != SLEEP && state_!= WAIT_DATA)
  1891. //return 0;
  1892. //char * mh = (char *)p->access(hdr_mac::offset_);
  1893. //int dst = hdr_dst(mh);
  1894. //int src = hdr_src(mh);
  1895.   
  1896. struct hdr_smac *sh = HDR_SMAC(p);
  1897.   
  1898. sh->type = DATA_PKT;
  1899. sh->length = SIZEOF_SMAC_DATAPKT;
  1900. //sh->srcAddr = src;
  1901. //sh->dstAddr = dst;
  1902. dataPkt_ = p;
  1903. #ifdef JOURNAL_PAPER
  1904.         // Don't accept Tx request if I have already accepted a request
  1905.         if (txRequest_ == 0) {
  1906.                 txRequest_ = 1;
  1907.         }
  1908.         else {
  1909.                 return 0;
  1910.         }
  1911.                                                                                                                                                             
  1912.         for (int i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
  1913.                  if (schedTab_[i].numNodes > 0) {
  1914.                         //printf("txData[%d] = 1: ............node %d at %.6fn", i, index_, Scheduler::instance().clock());
  1915.                         schedTab_[i].txData = 1;
  1916.          }
  1917.       }
  1918. #else
  1919. for(int i=0; i < numSched_; i++) {
  1920. schedTab_[i].txData = 1;
  1921. }
  1922. #endif
  1923. if (!syncFlag_) {
  1924. txData_ = 1;
  1925. // check if can send now
  1926. if (checkToSend())
  1927. return 1;
  1928. else 
  1929. return 0;
  1930.   
  1931. } else {
  1932. numBcast_ = numSched_;
  1933. return 1;
  1934. }
  1935. }
  1936. bool SMAC::unicastMsg(int numfrags, Packet *p) {
  1937. //  if (dataPkt != 0 || p == 0)
  1938. //return 0;
  1939. assert(p);
  1940. //if (state_ != IDLE && state_ != SLEEP && state_!= WAIT_DATA)
  1941. //return 0;
  1942.   
  1943. char * mh = (char *)p->access(hdr_mac::offset_);
  1944. int dst = hdr_dst(mh);
  1945. int src = hdr_src(mh);
  1946. // search for schedule of dest node
  1947. struct hdr_smac *sh = HDR_SMAC(p);
  1948. //int dst = sh->dstAddr;
  1949. if (syncFlag_) {
  1950. int found = 0;
  1951. for (int i=0; i < numNeighb_; i++) {
  1952. if (neighbList_[i].nodeId == dst) {
  1953. found = 1;
  1954. #ifdef JOURNAL_PAPER
  1955.                                 sendAddr = UNICAST_ADDR;
  1956.                                 dataSched_ = neighbList_[i].schedId;
  1957. #endif
  1958. schedTab_[neighbList_[i].schedId].txData = 1;
  1959. break;
  1960. }
  1961. }
  1962. if (found == 0) {
  1963. printf("Neighbor unknown; cannot send pktn");
  1964. return 0;  // unknown neighbor
  1965. }
  1966. }
  1967. #ifdef JOURNAL_PAPER
  1968.         // Don't accept Tx request if I have already accepted a request
  1969.         if (txRequest_ == 0) {
  1970.                 txRequest_ = 1;
  1971.         }
  1972.         else {
  1973.                 return 0;
  1974.         }
  1975.         numFrags_ = numfrags; 
  1976. #endif
  1977. sh->type = DATA_PKT;
  1978. sh->length = SIZEOF_SMAC_DATAPKT;
  1979. sh->dstAddr = dst;
  1980. sh->srcAddr = src;
  1981. //numFrags_ = numfrags;
  1982. dataPkt_ = p;
  1983. if (!syncFlag_) {
  1984. txData_ = 1;
  1985.     
  1986. // check if can send now
  1987. if (checkToSend())
  1988. return 1;
  1989. else
  1990. return 0;
  1991.     
  1992. } else 
  1993. return 1;
  1994. }
  1995. bool SMAC::sendRTS() {
  1996. //printf("node: %d ..............data sent............n",index_);
  1997. // construct RTS pkt
  1998. Packet *p = Packet::alloc();
  1999. struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
  2000. struct hdr_cmn *ch = HDR_CMN(p);
  2001. ch->uid() = 0;
  2002. ch->ptype() = PT_SMAC;
  2003. ch->size() = SIZEOF_SMAC_CTRLPKT;
  2004. ch->iface() = UNKN_IFACE.value();
  2005. ch->direction() = hdr_cmn::DOWN;
  2006. ch->error() = 0; /* pkt not corrupt to start with */
  2007.   
  2008. bzero(cf, MAC_HDR_LEN);
  2009.   
  2010. cf->length = SIZEOF_SMAC_CTRLPKT;
  2011. cf->type = RTS_PKT;
  2012.   
  2013. cf->srcAddr = index_;  // mac_id
  2014. cf->dstAddr = sendAddr_;
  2015. // reserved time for CTS + all fragments + all acks
  2016. //cf->duration = (numFrags_ + 1) * durCtrlPkt_ + numFrags_ * durDataPkt_;
  2017. #ifdef JOURNAL_PAPER
  2018. cf->duration = (numFrags_ + 1) * durCtrlPkt_ + numFrags_ * durDataPkt_;
  2019. #else
  2020. cf->duration = (2 * durCtrlPkt_ + durDataPkt_ + 0.001 ); 
  2021. #endif
  2022. cf->crc = 0;
  2023.  
  2024. // send RTS
  2025. if (chkRadio()) {
  2026. transmit(p);
  2027. return 1;
  2028.     
  2029. } else 
  2030. return 0;
  2031. }
  2032. bool SMAC::sendCTS(double duration) {
  2033.   
  2034. // construct CTS
  2035. Packet *p = Packet::alloc();
  2036. struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
  2037. struct hdr_cmn *ch = HDR_CMN(p);
  2038. ch->uid() = 0;
  2039. ch->ptype() = PT_SMAC;
  2040. ch->size() = SIZEOF_SMAC_CTRLPKT;
  2041. ch->iface() = UNKN_IFACE.value();
  2042. ch->direction() = hdr_cmn::DOWN;
  2043. ch->error() = 0; /* pkt not corrupt to start with */
  2044. bzero(cf, MAC_HDR_LEN);
  2045.   
  2046. cf->length = SIZEOF_SMAC_CTRLPKT;
  2047. cf->type = CTS_PKT;
  2048.   
  2049. cf->srcAddr = index_;
  2050. cf->dstAddr = recvAddr_;
  2051. // input duration is the duration field from received RTS pkt  
  2052. cf->duration = duration - durCtrlPkt_ ;  
  2053. cf->crc = 0;
  2054. // send CTS
  2055. if (chkRadio()) {
  2056. transmit(p);
  2057. return 1;
  2058. } else
  2059. return 0;
  2060. }
  2061. bool SMAC::sendDATA() {
  2062. // assuming data pkt is already constructed
  2063. struct hdr_smac * sh = HDR_SMAC(dataPkt_);
  2064.   
  2065. //sh->duration = numFrags_ * durCtrlPkt_ + (numFrags_ - 1) * durDataPkt_;
  2066. #ifdef JOURNAL_PAPER
  2067. sh->duration = numFrags_ * durCtrlPkt_ + (numFrags_ - 1) * durDataPkt_;
  2068. #else
  2069. sh->duration =  durCtrlPkt_;
  2070. #endif  
  2071. // send DATA
  2072. if (chkRadio()) {
  2073. transmit(dataPkt_);
  2074. return 1;
  2075. } else 
  2076. return 0;
  2077. }
  2078. bool SMAC::sendACK(double duration) {
  2079. // construct ACK pkt
  2080. Packet *p = Packet::alloc();
  2081. struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
  2082. struct hdr_cmn *ch = HDR_CMN(p);
  2083. ch->uid() = 0;
  2084. ch->ptype() = PT_SMAC;
  2085. ch->size() = SIZEOF_SMAC_CTRLPKT;
  2086. ch->iface() = UNKN_IFACE.value();
  2087. ch->direction() = hdr_cmn::DOWN;
  2088. ch->error() = 0; /* pkt not corrupt to start with */
  2089.   
  2090. bzero(cf, MAC_HDR_LEN);
  2091.   
  2092.   cf->length = SIZEOF_SMAC_CTRLPKT;
  2093.   cf->type = ACK_PKT;
  2094.   
  2095.   cf->srcAddr = index_;
  2096.   cf->dstAddr = recvAddr_;
  2097.   
  2098.   // input duration is the duration field from recvd data pkt
  2099.   // stick to neighbNav -- should update it when rx data packet
  2100.   cf->duration = duration - durCtrlPkt_;
  2101.   //cf->duration = mhNeighNav_.timeToExpire() - durCtrlPkt_;
  2102.   
  2103.   // send ACK
  2104.   if (chkRadio()) {
  2105.     transmit(p);
  2106.     return 1;
  2107.   } else
  2108.     return 0;
  2109. }
  2110. bool SMAC::sendSYNC()
  2111. {
  2112.   // construct and send SYNC pkt
  2113.   Packet *p = Packet::alloc();
  2114.   struct smac_sync_frame *cf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
  2115.   struct hdr_cmn *ch = HDR_CMN(p);
  2116.   ch->uid() = 0;
  2117.   ch->ptype() = PT_SMAC;
  2118.   ch->size() = SIZEOF_SMAC_SYNCPKT;
  2119.   ch->iface() = UNKN_IFACE.value();
  2120.   ch->direction() = hdr_cmn::DOWN;
  2121.   ch->error() = 0; /* pkt not corrupt to start with */
  2122.   
  2123.   cf->length = SIZEOF_SMAC_SYNCPKT;
  2124.   cf->type = SYNC_PKT;
  2125.   
  2126.   cf->srcAddr = index_;
  2127. #ifdef JOURNAL_PAPER
  2128.   cf->syncNode = schedTab_[0].syncNode;
  2129.   cf->state = schedState_;
  2130. #else
  2131.  cf->syncNode = mySyncNode_;
  2132. #endif
  2133.   // shld change SYNCPKTTIME to match with the configures durSyncPkt_
  2134.   cf->sleepTime = mhCounter_[0]->timeToSleep() - CLKTICK2SEC(SYNCPKTTIME);
  2135.   if (cf->sleepTime < 0)
  2136.     cf->sleepTime += CLKTICK2SEC(cycleTime_);
  2137.   
  2138.   // send SYNC
  2139.   if (chkRadio()) {
  2140. // if(index_==0)
  2141. // printf("%d Sent SYNC at %.6fn", index_,Scheduler::instance().clock());
  2142.     transmit(p);
  2143.     //double t = Scheduler::instance().clock();
  2144.     //printf("Sent SYNC from %d.....at %.6fn", cf->srcAddr, t);
  2145.     return 1;
  2146.     
  2147.   } else 
  2148.     return 0;
  2149. }
  2150. void SMAC::sentRTS(Packet *p)
  2151. {
  2152.   // just sent RTS, set timer for CTS timeout
  2153.   mhGene_.sched(timeWaitCtrl_);
  2154.   Packet::free(p);
  2155.   
  2156. }
  2157. void SMAC::sentCTS(Packet *p)
  2158. {
  2159.   // just sent CTS, track my neighbors' NAV
  2160.   // they update NAV and go to sleep after recv CTS
  2161.   // no data timeout, just use neighbors' NAV
  2162.   // since they went to sleep, just wait data for the entire time
  2163.   struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
  2164.   
  2165.   updateNeighNav(cf->duration);
  2166.   Packet::free(p);
  2167. }
  2168. void SMAC::sentDATA(Packet *p)
  2169. {
  2170.   struct hdr_smac *mh = HDR_SMAC(p);
  2171.   
  2172.   if (howToSend_ == BCASTDATA) { // if data was brdcast
  2173.     state_ = IDLE;
  2174.     if (!syncFlag_) {
  2175.       txData_ = 0;
  2176.       dataPkt_ = 0;
  2177.       Packet::free(p);
  2178.     
  2179.       // signal upper layer
  2180.       txMsgDone(); 
  2181.     
  2182.     } else {
  2183. #ifdef JOURNAL_PAPER
  2184.       schedTab_[dataSched_].txData = 0;
  2185. #else
  2186.       schedTab_[currSched_].txData = 0;
  2187. #endif
  2188.       numBcast_--;
  2189.       if (numBcast_ == 0) {
  2190. dataPkt_ = 0;
  2191. Packet::free(p);
  2192. #ifdef JOURNAL_PAPER
  2193.         txRequest_ = 0;
  2194. #endif
  2195. // signal upper layer
  2196. txMsgDone(); 
  2197.       }
  2198. #ifdef JOURNAL_PAPER
  2199. //when broadcast data is done for one schedule, sender needs to sleep
  2200.        if( mhCounter_[0]->value_ == sleepTime_ )
  2201.           sleep();
  2202. #endif
  2203.     }
  2204.     
  2205.   } else {
  2206.     
  2207.     // unicast is done; track my neighbors' NAV
  2208.     // they update NAV and go to sleep after recv first data fragment
  2209. #ifdef JOURNAL_PAPER
  2210.     sendAddr = -1;
  2211.     txRequest_ = 0;
  2212. #endif
  2213.     updateNeighNav(mh->duration);
  2214.       
  2215.     //waiting for ACK, set timer for ACK timeout
  2216.     mhGene_.sched(timeWaitCtrl_);
  2217.   }
  2218. }
  2219. void SMAC::sentACK(Packet *p)
  2220. {
  2221.   struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
  2222.   
  2223.   updateNeighNav(cf->duration);
  2224.   Packet::free(p);
  2225. }
  2226. void SMAC::sentSYNC(Packet *p)
  2227. {
  2228. #ifdef JOURNAL_PAPER
  2229.   schedTab_[syncSched_].txSync = 0;
  2230.   schedTab_[syncSched_].numPeriods = SYNCPERIOD;
  2231. #else
  2232.   schedTab_[currSched_].txSync = 0;
  2233.   schedTab_[currSched_].numPeriods = SYNCPERIOD;
  2234. #endif
  2235.   Packet::free(p);
  2236. }
  2237. void SMAC::sleep() 
  2238. {
  2239.   // go to sleep, turn off radio
  2240.   state_ = SLEEP;
  2241.   radioState_ = RADIO_SLP;
  2242. #ifdef JOURNAL_PAPER
  2243.   //printf("SLEEP: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  2244. #endif
  2245.   // printf("SLEEP: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  2246. //printf("%d SMAC SLEEP: at %.6fn", index_,Scheduler::instance().clock());
  2247. // set node state
  2248. Phy *p;
  2249. p=netif_;
  2250. ((WirelessPhy *)p)->node_sleep();
  2251. // printf("nnetifn %d", ((WirelessPhy *)p)->testfun(34));
  2252. //
  2253. }
  2254. void SMAC::wakeup()
  2255. {
  2256.   //wakeup from sleep. turn on radio
  2257.   state_ = IDLE;
  2258.   
  2259.   // since radio can start to recv while in sleep
  2260.   // it might be in RX state
  2261.   // and eventually the pkt will not be recvd if in sleep state 
  2262.   // so careful not to change state of radio unless it is really sleeping
  2263.   if (radioState_ == RADIO_SLP)
  2264.     radioState_ = RADIO_IDLE;
  2265. #ifdef JOURNAL_PAPER
  2266.   //printf("WAKEUP: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  2267. #endif
  2268. //   printf("WAKEUP: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  2269. Phy *p;
  2270. p=netif_;
  2271. ((WirelessPhy *)p)->node_wakeup();
  2272. //printf("WAKEUP: ............node %d at %.6fn", index_, Scheduler::instance().clock());
  2273. }
  2274. void SMAC::updateNav(double d ) {
  2275.   double now = Scheduler::instance().clock();
  2276.   // already in sec
  2277.   // double d = duration * 1.0e-6; // convert to sec
  2278.   if ((now + d) > nav_) {
  2279.     nav_ = now + d;
  2280.     
  2281.     mhNav_.resched(d);
  2282.     
  2283.   }
  2284. }
  2285. void SMAC::updateNeighNav(double d ) {
  2286.   double now = Scheduler::instance().clock();
  2287.   //double d = duration * 1.0e-6; // convert to sec
  2288.   if ((now + d) > neighNav_) {
  2289.     neighNav_ = now + d;
  2290.     mhNeighNav_.resched(d);
  2291.   
  2292.   }
  2293. }
  2294. double SMAC::txtime(Packet *p)
  2295. {
  2296.   struct hdr_smac *sh = HDR_SMAC(p);
  2297.   switch(sh->type) {
  2298.   
  2299.   case DATA_PKT:
  2300.     return durDataPkt_;
  2301.     
  2302.   case RTS_PKT:
  2303.   case CTS_PKT:
  2304.   case ACK_PKT:
  2305.     return durCtrlPkt_;
  2306.   case SYNC_PKT:
  2307.     return CLKTICK2SEC(SYNCPKTTIME);
  2308.   default:
  2309.     fprintf(stderr, "invalid smac pkt type %dn", sh->type);
  2310.     exit(1);
  2311.   }
  2312.   
  2313. }
  2314. #ifdef JOURNAL_PAPER
  2315. void SMAC::dump(){
  2316.         int i;
  2317.         for (i = 0; i < 5; i++) {
  2318.                                                                                                                                                             
  2319.         printf(" neighbor: %d schedule: %d state: %d active: %d n", neighbList_[i].nodeId, neighbList_[i].schedId, neighbList_[i].state, neighbList_[i].active);
  2320.         }
  2321.                                                                                                                                                             
  2322.          for (i = 0; i < 4; i++) {
  2323.          printf(" schedule: %d numNodes: %d n",schedTab_[i].syncNode, schedTab_[i].numNodes);
  2324.          }
  2325. }
  2326. #endif