smac.cc

Go to the documentation of this file.
00001 
00002 /*
00003  * smac.cc
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: smac.cc,v 1.17 2005/08/25 18:58:07 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 
00047 // smac is designed and developed by Wei Ye (SCADDS/ISI)
00048 // and is re-written for ns by Padma Haldar (CONSER/ISI).
00049 // Contributors: Yuan Li
00050 
00051 // This module implements Sensor-MAC
00052 //  http://www.isi.edu/scadds/papers/smac_report.pdf
00053 //
00054 // It has the following functions.
00055 //  1) Both virtual and physical carrier sense
00056 //  2) RTS/CTS for hidden terminal problem
00057 //  3) Backoff and retry
00058 //  4) Broadcast packets are sent directly without using RTS/CTS/ACK.
00059 //  5) A long unicast message is divided into multiple TOS_MSG (by upper
00060 //     layer). The RTS/CTS reserves the medium for the entire message.
00061 //     ACK is used for each TOS_MSG for immediate error recovery.
00062 //  6) Node goes to sleep when its neighbor is communicating with another
00063 //     node.
00064 //  7) Each node follows a periodic listen/sleep schedule
00065 //  8.1) At bootup time each node listens for a fixed SYNCPERIOD and then
00066 //     tries to send out a sync packet. It suppresses sending out of sync pkt
00067 //     if it happens to receive a sync pkt from a neighbor and follows the
00068 //     neighbor's schedule.
00069 //  8.2) Or a node can choose its own schecule instead of following others, the
00070 //       schedule start time is user configurable
00071 //  9) Neighbor Discovery: in order to prevent that two neighbors can not
00072 //     find each other due to following complete different schedules, each
00073 //     node periodically listen for a whole period of the SYNCPERIOD
00074 //  10) Duty cycle is user configurable
00075 
00076 //  New features including adaptive listen
00077 //   See http://www.isi.edu/~weiye/pub/smac_ton.pdf
00078                                                                                                                                                            
00079 #include "wireless-phy.h"
00080 #include "smac.h"
00081 
00082 static class MacSmacClass : public TclClass {
00083 public:
00084        MacSmacClass() : TclClass("Mac/SMAC") {}
00085     TclObject* create(int, const char*const*) {
00086         return (new SMAC());
00087     }
00088 } class_macSMAC;
00089 
00090 
00091 // Timers call on expiration
00092 
00093 int SmacTimer::busy()
00094 {
00095     if (status_ != TIMER_PENDING)
00096         return 0;
00097     else
00098         return 1;
00099 }
00100 
00101 #ifdef JOURNAL_PAPER
00102 void SmacUpdateNeighbTimer::expire(Event *e) {
00103         a_->handleUpdateNeighbTimer();
00104 }
00105                                                                                                                                                             
00106 void SmacAdaptiveListenTimer::expire(Event *e) {
00107         a_->handleAdaptiveListenTimer();
00108 }
00109 #endif
00110 
00111 void SmacGeneTimer::expire(Event *e) {
00112     a_->handleGeneTimer();
00113 }
00114 
00115 void SmacRecvTimer::expire(Event *e) {
00116     stime_ = rtime_ = 0;
00117     a_->handleRecvTimer();
00118 }
00119 
00120 void SmacRecvTimer::sched(double time) {
00121     TimerHandler::sched(time);
00122     stime_ = Scheduler::instance().clock();
00123     rtime_ = time;
00124 }
00125 
00126 void SmacRecvTimer::resched(double time) {
00127     TimerHandler::resched(time);
00128     stime_ = Scheduler::instance().clock();
00129     rtime_ = time;
00130 }
00131 
00132 double SmacRecvTimer::timeToExpire() {
00133     return ((stime_ + rtime_) - Scheduler::instance().clock());
00134 }
00135 
00136 void SmacSendTimer::expire(Event *e) {
00137     a_->handleSendTimer();
00138 }
00139 
00140 void SmacNavTimer::expire(Event *e) {
00141     a_->handleNavTimer();
00142 }
00143 
00144 void SmacNeighNavTimer::sched(double time) {
00145     TimerHandler::sched(time);
00146     stime_ = Scheduler::instance().clock();
00147     rtime_ = time;
00148 }
00149 
00150 void SmacNeighNavTimer::expire(Event *e) {
00151     stime_ = rtime_ = 0;
00152     a_->handleNeighNavTimer();
00153 }
00154 
00155 double SmacNeighNavTimer::timeToExpire() {
00156     return ((stime_ + rtime_) - Scheduler::instance().clock());
00157 }
00158 
00159 void SmacCsTimer::expire(Event *e) {
00160     a_->handleCsTimer();
00161 }
00162 
00163 // if pending, cancel timer
00164 void SmacCsTimer::checkToCancel() {
00165     if (status_ == TIMER_PENDING)
00166         cancel();
00167 }
00168 
00169 // void SmacChkSendTimer::expire(Event *e) {
00170 //   a_->handleChkSendTimer();
00171 // }
00172 
00173 void SmacCounterTimer::sched(double time) {
00174     // the cycle timer assumes that all time shall be scheduled with time "left to sleep" 
00175     // and not the absolute time for a given state (sleep, sync or data). Thus inorder 
00176     // to schedule for a sleep state, need to schedule with aggregate time CYCLETIME 
00177     // (sleeptime+synctime+dadatime).
00178     // Similarly for sync state, schedule with listenTime_ (synctime+datattime)
00179     // This is implemented to be in step with the counter used in actual smac.
00180 
00181     tts_ = time; // time before it goes to sleep again
00182     stime_ = Scheduler::instance().clock();
00183   
00184     if (time <= CLKTICK2SEC(cycleTime_) && time > CLKTICK2SEC(listenTime_)) { // in sleep state
00185         value_ = sleepTime_;
00186         if (status_ == TIMER_IDLE)
00187             TimerHandler::sched(time - CLKTICK2SEC(listenTime_)); 
00188         else
00189             TimerHandler::resched(time - CLKTICK2SEC(listenTime_)); 
00190     
00191     } else if ( time <= CLKTICK2SEC(listenTime_) && time > CLKTICK2SEC(dataTime_)) { // in sync state
00192         value_ = syncTime_;
00193         if (status_ == TIMER_IDLE)
00194             TimerHandler::sched(time - CLKTICK2SEC(dataTime_)); 
00195         else
00196             TimerHandler::resched(time - CLKTICK2SEC(dataTime_)); 
00197     
00198     } else { // in data state
00199         assert(time <= CLKTICK2SEC(dataTime_));
00200         value_ = dataTime_;
00201         if (status_ == TIMER_IDLE)
00202             TimerHandler::sched(time); 
00203         else
00204             TimerHandler::resched(time); 
00205     
00206     }
00207 
00208 }
00209 
00210 double SmacCounterTimer::timeToSleep() {
00211     return ((stime_ + tts_) - Scheduler::instance().clock()) ;
00212 }
00213 
00214 void SmacCounterTimer::expire(Event *e) {
00215     tts_ = stime_ = 0;
00216     a_->handleCounterTimer(index_);
00217 }
00218 
00219 
00220 #ifdef JOURNAL_PAPER
00221 SMAC::SMAC() : Mac(), mhUpdateNeighb_(this),mhNav_(this), mhNeighNav_(this), mhSend_(this), mhRecv_(this), mhGene_(this), mhCS_(this), mhAdap_(this), syncFlag_(0) {
00222         int i;
00223 #else
00224 SMAC::SMAC() : Mac(), mhNav_(this), mhNeighNav_(this), mhSend_(this), mhRecv_(this), mhGene_(this), mhCS_(this), syncFlag_(0) {
00225 #endif
00226     state_ = IDLE;
00227     radioState_ = RADIO_IDLE;
00228     tx_active_ = 0;
00229     mac_collision_ = 0;
00230   
00231     sendAddr_ = -1;
00232     recvAddr_ = -1;
00233 
00234     nav_ = 0;
00235     neighNav_ = 0;
00236   
00237     numRetry_ = 0;
00238     numExtend_ = 0;
00239     lastRxFrag_ = -3; // since -1, -2 and 0 could be valid pkt uid's
00240     //numFrags_ = 0;
00241     //succFrags_ = 0;
00242 
00243 #ifdef JOURNAL_PAPER
00244         numFrags_ = 0;
00245         succFrags_ = 0;
00246         dataSched_ = 0;
00247         syncSched_ = 0;
00248                                                                                                                                                             
00249         globalSchedule_ = 0; // Do not test global schedule
00250         //globalSchedule_ = 1; // Test global schedule
00251                                                                                                                                                             
00252         updateNeighbList_ = 0;
00253                                                                                                                                                             
00254         sendSYNCFlag_ = 0;
00255                                                                                                                                                             
00256         sendAddr = -1;
00257         adapSend_ = 0;
00258         txRequest_ = 0;
00259                                                                                                                                                             
00260         adaptiveListen_ = 0;
00261 #endif
00262 
00263     dataPkt_ = 0;
00264     pktRx_ = 0;
00265     pktTx_ = 0;
00266 
00267     /* setup internal mac and physical parameters
00268        ----------------------------------------------
00269        byte_tx_time_: time to transmit a byte, in ms. Derived from bandwidth
00270   
00271        slotTime_: time of each slot in contention window. It should be large
00272        enough to receive the whole start symbol but cannot be smaller than clock 
00273        resolution. in msec
00274   
00275        slotTime_sec_: slottime in sec
00276   
00277        difs_: DCF interframe space (from 802.11), in ms. It is used at the beginning
00278        of each contention window. It's the minmum time to wait to start a new 
00279        transmission.
00280   
00281        sifs_: short interframe space (f
00282 
00283        /rom 802.11), in ms. It is used before sending
00284        an CTS or ACK packet. It takes care of the processing delay of each pkt.
00285   
00286        eifs_: Entended interfrane space (from 802.11) in ms. Used for backing off 
00287        incase of a collision.
00288 
00289        guardTime_: guard time at the end of each listen interval, in ms.
00290 
00291     */
00292 
00293     byte_tx_time_ = 8.0 / BANDWIDTH;
00294     double start_symbol = byte_tx_time_ * 2.5;  // time to tx 20 bits
00295     slotTime_ = CLOCKRES >= start_symbol ? CLOCKRES : start_symbol;  // in msec
00296     slotTime_sec_ = slotTime_ / 1.0e3;   // in sec
00297     difs_ = 10.0 * slotTime_;
00298     sifs_ = 5.0 * slotTime_;
00299     eifs_ = 50.0 * slotTime_;
00300     guardTime_ = 4.0 * slotTime_;
00301   
00302     // calculate packet duration. Following equations assume 4b/6b coding.
00303     // All calculations yield in usec
00304 
00305     //durSyncPkt_ = ((SIZEOF_SMAC_SYNCPKT) * 12 + 18) / 1.0e4 ;
00306 
00307     durSyncPkt_ =  (PRE_PKT_BYTES + (SIZEOF_SMAC_SYNCPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00308     durSyncPkt_ = CLKTICK2SEC(durSyncPkt_);
00309 
00310     //durDataPkt_ = ((SIZEOF_SMAC_DATAPKT) * 12 + 18) / 1.0e4 ;
00311     durDataPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_DATAPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00312     durDataPkt_ = CLKTICK2SEC(durDataPkt_);
00313 
00314     //durCtrlPkt_ = ((SIZEOF_SMAC_CTRLPKT) * 12 + 18) / 1.0e4;
00315     durCtrlPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_CTRLPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00316     durCtrlPkt_ = CLKTICK2SEC(durCtrlPkt_);
00317   
00318     // time to wait for CTS or ACK
00319     //timeWaitCtrl_ = durCtrlPkt_ + CLKTICK2SEC(4) ;    // timeout time
00320     double delay = 2 * PROC_DELAY + sifs_;
00321     timeWaitCtrl_ = CLKTICK2SEC(delay) + durCtrlPkt_;    // timeout time
00322 
00323   
00324     numSched_ = 0;
00325     numNeighb_ = 0;
00326     numSync_ = 1;  // perform neighbor discovery, do not go to sleep for the first SYNC period
00327     schedListen_ = 1;
00328     searchNeighb_ = 1;
00329 
00330 #ifdef JOURNAL_PAPER
00331         schedState_ = 1;  // this is my first schedule
00332     
00333     // initialize neighbour table
00334         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
00335         neighbList_[i].nodeId = 0;
00336         neighbList_[i].schedId = 0;
00337         neighbList_[i].active = 0;
00338                 neighbList_[i].state = 0;
00339         }
00340                                                                                                                                                             
00341         // initialize schedule table
00342         for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
00343                 schedTab_[i].numNodes = 0;
00344                 schedTab_[i].syncNode = 0;
00345         }
00346                                                                                                                                                             
00347                                                                                                                                                             
00348         schedTab_[0].numNodes = 1;  // I'm the only one on this schedule
00349         schedTab_[0].syncNode = index_;  // I'm the schedule initializer
00350         schedTab_[0].txData = 0;
00351         schedTab_[0].txSync = 0;
00352         schedTab_[0].chkSched = 0;
00353 #endif
00354         
00355     Tcl& tcl = Tcl::instance();
00356     tcl.evalf("Mac/SMAC set syncFlag_");
00357     if (strcmp(tcl.result(), "0") != 0)  
00358         syncFlag_ = 1;              // syncflag is set; use sleep-wakeup cycle
00359 
00360 
00361     tcl.evalf("Mac/SMAC set selfConfigFlag_");
00362         if (strcmp(tcl.result(), "0") != 0)
00363                 selfConfigFlag_ = 1;              // autoflag is set; user can not configure the schedule start time
00364 
00365     
00366     // User can specify the duty cycle
00367     tcl.evalf("Mac/SMAC set dutyCycle_");
00368     if (strcmp(tcl.result(), "0") != 0){
00369                 bind_bw("dutyCycle_", &dutyCycle_);
00370                 //printf("dutyCyle=%f\n", dutyCycle_);
00371     
00372     }
00373         else {
00374 //                  dutyCycle_ = SMAC_DUTY_CYCLE;
00375     }
00376 
00377     if (!syncFlag_)
00378         txData_ = 0;
00379   
00380     else {
00381         // Calculate sync/data/sleeptime based on duty cycle
00382         // all time in ms
00383         syncTime_ = difs_ + slotTime_ * SYNC_CW + SEC2CLKTICK(durSyncPkt_) + guardTime_;
00384 #ifdef JOURNAL_PAPER
00385                 // added time for overhearing CTS so that can do adaptive listen
00386                 dataTime_ = difs_ + slotTime_ * DATA_CW + SEC2CLKTICK(durCtrlPkt_) + PROC_DELAY + sifs_ + SEC2CLKTICK(durCtrlPkt_) + guardTime_;
00387 #else
00388         dataTime_ = difs_ + slotTime_ * DATA_CW + SEC2CLKTICK(durCtrlPkt_) + guardTime_;
00389 #endif
00390         listenTime_ = syncTime_ + dataTime_;
00391         cycleTime_ = listenTime_ * 100 / dutyCycle_ + 1;
00392         sleepTime_ = cycleTime_ - listenTime_;
00393     
00394         //printf("cycletime=%d, sleeptime=%d, listentime=%d\n", cycleTime_, sleepTime_, listenTime_);
00395 
00396 
00397         for (int i=0; i< SMAC_MAX_NUM_SCHEDULES; i++) {
00398             mhCounter_[i] = new SmacCounterTimer(this, i);
00399             mhCounter_[i]->syncTime_ = syncTime_;
00400             mhCounter_[i]->dataTime_ = dataTime_;
00401             mhCounter_[i]->listenTime_ = listenTime_;
00402             mhCounter_[i]->sleepTime_ = sleepTime_;
00403             mhCounter_[i]->cycleTime_ = cycleTime_;
00404         }
00405 
00406         // printf("syncTime= %d, dataTime= %d, listentime = %d, sleepTime= %d, cycletime= %d\n", syncTime_, dataTime_, listenTime_, sleepTime_, cycleTime_);
00407 
00408         // listen for a whole period to choose a schedule first
00409         //double cw = (Random::random() % SYNC_CW) * slotTime_sec_ ;
00410   
00411         // The foll (higher) CW value allows neigh nodes to follow a single schedule
00412         // double w = (Random::random() % (SYNC_CW)) ;
00413         // double cw = w/10.0;
00414         double c = CLKTICK2SEC(listenTime_) + CLKTICK2SEC(sleepTime_);
00415         double s = SYNCPERIOD + 1;
00416         double t = c * s ;
00417         //mhGene_.sched(t + cw);
00418 
00419         if ( selfConfigFlag_ == 1) {
00420 #ifdef JOURNAL_PAPER
00421                 adapTime_ = dataTime_;
00422                 mhGene_.sched(t);
00423                                                                                                                                                             
00424                 //start setting timer for update neighbor list
00425                 //printf("SMAC_UPDATE_NEIGHB_PERIOD: ............node %d %d at %.6f\n", index_, SMAC_UPDATE_NEIGHB_PERIOD, Scheduler::instance().clock());
00426                 mhUpdateNeighb_.sched(SMAC_UPDATE_NEIGHB_PERIOD);
00427                 //dump();
00428 #else
00429         mhGene_.sched(t);
00430 #endif
00431         }
00432     }
00433 }
00434 
00435 void SMAC::setMySched(Packet *pkt) 
00436 {
00437     // set my schedule and put it into the first entry of schedule table
00438     state_ = IDLE;
00439     numSched_ = 1;
00440     schedTab_[0].numPeriods = 0;
00441     schedTab_[0].txData = 0;
00442     schedTab_[0].txSync = 1; // need to brdcast my schedule
00443   
00444     if (pkt == 0) { // freely choose my schedule
00445 #ifdef JOURNAL_PAPER
00446                 //printf("#############################################################\n");
00447                 //printf(" %d is choosing its own shedule %d \n", index_, index_);
00448                 //printf("#############################################################\n");
00449                 schedState_++;
00450                 mhCounter_[0]->sched(CLKTICK2SEC(listenTime_+index_*10));
00451                 schedTab_[0].syncNode = index_;
00452 #else
00453         mhCounter_[0]->sched(CLKTICK2SEC(listenTime_));
00454 #endif
00455         mySyncNode_ = index_; // myself
00456         currSched_ = 0;
00457         //sendSYNC();  
00458     
00459     } else { // follow schedule in syncpkt
00460     
00461         struct smac_sync_frame *pf = (struct smac_sync_frame *)pkt->access(hdr_mac::offset_);
00462 
00463         mhCounter_[0]->sched(pf->sleepTime);
00464 #ifdef JOURNAL_PAPER
00465                 mySyncNode_ = pf->syncNode;
00466                 //printf("#############################################################\n");
00467                 //printf("%d receives SYNC packet from %d and starts following shedule %d \n", index_, pf->srcAddr, pf->syncNode);
00468                 //printf("#############################################################\n");
00469                 schedTab_[0].numNodes++;  // 2 nodes on this schedule now
00470                 schedTab_[0].syncNode = pf->syncNode;
00471                 schedState_++;
00472                                                                                                                                                             
00473                 //add node in my neighbor list
00474                 neighbList_[0].nodeId = pf->srcAddr;
00475                 neighbList_[0].schedId = 0;
00476                 neighbList_[0].active = 1;
00477                 neighbList_[0].state = pf->state;
00478 #else
00479         mySyncNode_ = pf->srcAddr;    
00480         //add node in my neighbor list
00481         neighbList_[0].nodeId = mySyncNode_;
00482         neighbList_[0].schedId = 0;
00483 #endif
00484         numNeighb_ = 1;
00485     }
00486 }
00487 
00488 
00489 
00490 int SMAC::command(int argc, const char*const* argv)
00491 {
00492     if (argc == 3) {
00493         if (strcmp(argv[1], "log-target") == 0) {
00494             logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
00495             if(logtarget_ == 0)
00496                 return TCL_ERROR;
00497             return TCL_OK;
00498         }
00499         else if ( selfConfigFlag_ != 1) {
00500             if (strcmp(argv[1], "schedule-start-time") == 0) {
00501 
00502                             startTime_ = strtod(argv[2],NULL);
00503 
00504                             // set up schedule
00505                             state_ = IDLE;
00506                             numSched_ = 1;
00507                             schedTab_[0].numPeriods = SYNCPERIOD;
00508                             schedTab_[0].txData = 0;
00509                             schedTab_[0].txSync = 1; // need to brdcast my schedule
00510 
00511                             // schedule starts up with listen time (sync+data)
00512                             // need to caculate time to sleep
00513 
00514                             startTime_ = startTime_ + listenTime_;
00515                             if ( startTime_ >= cycleTime_ )
00516                                     startTime_ = startTime_ - cycleTime_;
00517 
00518                             mhCounter_[0]->sched(CLKTICK2SEC(startTime_));
00519                             mySyncNode_ = index_; // myself
00520 
00521                             currSched_ = 0;
00522 
00523                             return TCL_OK;
00524         
00525                     }
00526 
00527         }
00528     }
00529 
00530     return Mac::command(argc, argv);
00531 
00532 }
00533 
00534 #ifdef JOURNAL_PAPER
00535 void SMAC::adaptiveListen()
00536 {
00537         // adaptively wake-up at the end of current transmission. Will try to
00538         // send only if the buffered packet is unicast. Since my next-hop
00539         // neighbor may not be aware of the Tx of my previous-hop neighbor,
00540         // broadcast now is unreliable
00541         //printf("adaptiveListen set AdaptiveTimer: node %d scheduletime: %f adapTime_: %d time:%.9f \n", index_, mhCounter_[0]->value_, adapTime_, Scheduler::instance().clock());
00542         mhAdap_.resched(CLKTICK2SEC(adapTime_)); // set timer to bring me back to sleep
00543         adaptiveListen_ = 1;
00544         if (state_ == SLEEP) {
00545                 //printf("adaptiveListen wakeup: node %d scheduletime: %f time:%.9f \n", index_, mhCounter_[0]->value_, Scheduler::instance().clock());
00546                 wakeup();
00547         }
00548          else {
00549         }
00550                                                                                                                                                             
00551         if ( schedTab_[0].txData == 1 && sendAddr == UNICAST_ADDR){
00552                 adapSend_ = 1;
00553                 checkToSend();
00554         }
00555 }
00556 #endif
00557 
00558 // XXXX smac handler functions
00559 
00560 void SMAC::handleSendTimer() {
00561     assert(pktTx_);
00562   
00563     struct hdr_smac *sh = HDR_SMAC(pktTx_);
00564   
00565     // Packet tx is done so radio should go back to idle
00566     radioState_ = RADIO_IDLE;
00567     tx_active_ = 0;
00568   
00569     switch(sh->type) {
00570     
00571     case RTS_PKT:
00572         sentRTS(pktTx_);
00573         break;
00574 
00575     case CTS_PKT:
00576         sentCTS(pktTx_);
00577         break;
00578     
00579     case DATA_PKT:
00580         sentDATA(pktTx_);
00581         break;
00582   
00583     case ACK_PKT:
00584         sentACK(pktTx_);
00585         break;
00586     case SYNC_PKT:
00587         sentSYNC(pktTx_);
00588         break;
00589     default:
00590         fprintf(stderr, "unknown mac pkt type, %d\n", sh->type);
00591         break;
00592     }
00593   
00594     pktTx_ = 0;
00595 }
00596 
00597 
00598 void SMAC::handleRecvTimer() {
00599     assert(pktRx_);
00600   
00601     struct hdr_cmn *ch = HDR_CMN(pktRx_);
00602     struct hdr_smac *sh = HDR_SMAC(pktRx_);
00603 
00604     if (state_ == SLEEP) {
00605 
00606         // 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
00607 
00608         if (mac_collision_) {
00609                     discard(pktRx_, DROP_MAC_COLLISION);
00610                     mac_collision_ = 0;
00611                     updateNav(CLKTICK2SEC(eifs_));
00612 
00613                     if (state_ == CR_SENSE)
00614                             sleep(); // have to wait until next wakeup time
00615                     else
00616                             radioState_ = RADIO_IDLE;
00617 
00618                     goto done;
00619                 }
00620 
00621         discard(pktRx_, DROP_MAC_SLEEP);
00622         radioState_ = RADIO_SLP;
00623         goto done;
00624     }
00625   
00626     // if the radio interface is tx'ing when this packet arrives
00627     // I would never have seen it and should do a silent discard 
00628   
00629     if (radioState_ == RADIO_TX) {
00630         Packet::free(pktRx_);
00631         goto done;
00632     }
00633   
00634     if (mac_collision_) {
00635         discard(pktRx_, DROP_MAC_COLLISION);
00636         mac_collision_ = 0;
00637         updateNav(CLKTICK2SEC(eifs_));
00638     
00639         if (state_ == CR_SENSE) 
00640             sleep(); // have to wait until next wakeup time
00641         else 
00642             radioState_ = RADIO_IDLE;
00643     
00644         goto done;
00645     }
00646   
00647     if (ch->error()) {
00648         Packet::free(pktRx_);
00649         updateNav(CLKTICK2SEC(eifs_)); 
00650 
00651         if (state_ == CR_SENSE) 
00652             sleep();
00653         else 
00654             radioState_ = RADIO_IDLE;
00655       
00656         goto done;
00657     }
00658   
00659     // set radio from rx to idle again
00660     radioState_ = RADIO_IDLE;
00661 
00662     switch (sh->type) {
00663     case DATA_PKT:
00664         handleDATA(pktRx_);
00665         break;
00666     case RTS_PKT:
00667         handleRTS(pktRx_);
00668         Packet::free(pktRx_);
00669         break;
00670     case CTS_PKT:
00671         handleCTS(pktRx_);
00672         Packet::free(pktRx_);
00673         break;
00674     case ACK_PKT:
00675         handleACK(pktRx_);
00676         Packet::free(pktRx_);
00677         break;
00678     case SYNC_PKT:
00679         handleSYNC(pktRx_);
00680         Packet::free(pktRx_);
00681         break;
00682     default:
00683         fprintf(stderr, "Unknown smac pkt type, %d\n", sh->type);
00684         break;
00685     }
00686   
00687  done:
00688     pktRx_ = 0;
00689   
00690 }
00691 
00692 void SMAC::handleGeneTimer() 
00693 {
00694   
00695     if (syncFlag_) {
00696         // still in choose-schedule state
00697         if (numSched_ == 0) {
00698             setMySched(0); // I'm the primary synchroniser
00699             return;
00700         } 
00701     }
00702     if (state_ == WAIT_CTS) {  // CTS timeout
00703         if (numRetry_ < SMAC_RETRY_LIMIT) {
00704             numRetry_++;
00705             // wait until receiver's next wakeup
00706             state_ = IDLE;
00707 #ifdef JOURNAL_PAPER
00708             //node tries to go to sleep if it needs to resend
00709                     if( mhCounter_[0]->value_ == sleepTime_ )
00710                             sleep();
00711 #endif
00712  
00713             if (!syncFlag_)
00714                 checkToSend();
00715       
00716         } else {
00717             state_ = IDLE;
00718             Packet::free(dataPkt_);
00719             dataPkt_ = 0;
00720             numRetry_ = 0;
00721             //numFrags_ = 0;
00722             // signal upper layer about failure of tx 
00723             // txMsgFailed();
00724             txMsgDone();
00725       
00726         }
00727     
00728     } else if (state_ == WAIT_ACK) { // ack timeout
00729     
00730         if (numExtend_ < SMAC_EXTEND_LIMIT) { // extend time
00731             printf("SMAC %d: no ACK received. Extend Tx time.\n", index_);
00732             numExtend_++;
00733       
00734             updateNeighNav(durDataPkt_ + durCtrlPkt_);
00735             //neighNav_ = (durDataPkt_ + durCtrlPkt_);
00736       
00737         } else { // reached extension limit, can't extend time
00738             //numFrags_--;
00739       
00740         }
00741         if (neighNav_ < (durDataPkt_ + durCtrlPkt_)) {
00742       
00743             // used up reserved time, stop tx
00744       
00745             discard(dataPkt_, DROP_MAC_RETRY_COUNT_EXCEEDED);
00746             dataPkt_ = 0;
00747             pktTx_ = 0;
00748             state_ = IDLE;
00749       
00750             // signal upper layer the number of transmitted frags
00751             //txMsgFailed(succFrags); -> no frag for now
00752       
00753             txMsgDone();
00754       
00755         } else { // still have time
00756             // keep sending until use up remaining time
00757             sendDATA();
00758         }
00759 
00760 #ifdef JOURNAL_PAPER
00761         } else if (state_ == DATA_SENSE1) {
00762                 state_ = DATA_SENSE2;
00763                 mhGene_.resched(timeWaitCtrl_);
00764                                                                                                                                                             
00765         } else if (state_ == DATA_SENSE2) {
00766                 state_ = IDLE;
00767         //node tries to go to sleep if it does not hear CTS or DATA for others' connection
00768                 if( mhCounter_[0]->value_ == sleepTime_ )
00769                         sleep();
00770 #endif
00771     }
00772 }
00773 
00774 
00775 void SMAC::handleNavTimer() {
00776     // medium is now free
00777     nav_ = 0; // why have this variable?? probably not required use the timer instead
00778   
00779     if (!syncFlag_) {
00780         if (state_ == SLEEP)
00781             wakeup();
00782 
00783         // try to send waiting data, if any
00784         checkToSend();
00785     } 
00786 #ifdef JOURNAL_PAPER
00787         adaptiveListen();
00788 #endif
00789 }
00790 
00791 
00792 int SMAC::checkToSend() {
00793 #ifdef JOURNAL_PAPER
00794         if (txRequest_ == 1 || syncFlag_) {
00795 #else
00796     if (txData_ == 1) {
00797 #endif
00798         assert(dataPkt_);
00799         struct hdr_smac *mh = HDR_SMAC(dataPkt_);
00800     
00801         if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00802             goto done;  // cannot send if radio is sending or recving
00803     
00804         if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00805             goto done; // cannot send if not in any of these states
00806     
00807         if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
00808             (state_ == SLEEP || state_ == IDLE)) {
00809       
00810             if (state_ == SLEEP) wakeup();
00811       
00812             if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
00813                 howToSend_ = BCASTDATA;
00814             else
00815                 howToSend_ = UNICAST;
00816       
00817             state_ = CR_SENSE;
00818 
00819 #ifdef JOURNAL_PAPER
00820                         adapSend_ = 0;
00821             //printf("adaptiveListen sendData: node %d scheduletime: %f time:%.9f \n", index_, mhCounter_[0]->value_, Scheduler::instance().clock());
00822 #endif
00823     
00824             // start cstimer
00825             double cw = (Random::random() % DATA_CW) * slotTime_sec_;
00826             mhCS_.sched(CLKTICK2SEC(difs_) + cw);
00827       
00828             return 1;
00829     
00830         } else {
00831             return 0;
00832         }
00833     
00834     done:
00835         return 0;
00836     
00837     } else {
00838         return 0;
00839     }
00840 }
00841 
00842 
00843 void SMAC::handleNeighNavTimer() {
00844   
00845     // Timer to track my neighbor's NAV
00846     neighNav_ = 0;         // probably don't need to use this variable
00847   
00848     if (state_ == WAIT_DATA) { // data timeout
00849         state_ = IDLE;
00850     
00851         // signal upper layer that rx msg is done
00852         // didnot get any/all data
00853         rxMsgDone(0); 
00854     } else {
00855         if (!syncFlag_)
00856             checkToSend();
00857     }
00858 #ifdef JOURNAL_PAPER
00859         adaptiveListen();
00860 #endif
00861 }
00862 
00863 
00864 void SMAC::handleCsTimer() {
00865   
00866     // carrier sense successful
00867   
00868 #ifdef MAC_DEBUG
00869     if (howToSend_ != BCASTSYNC && dataPkt_ == 0)
00870         numCSError++;
00871 #endif // MAC_DEBUG
00872   
00873     switch(howToSend_) {
00874     case BCASTSYNC:
00875         if (sendSYNC())
00876             state_ = IDLE;
00877         break;
00878     
00879     case BCASTDATA:
00880         startBcast();
00881         break;
00882     
00883     case UNICAST:
00884         startUcast();
00885         break;
00886     }
00887 }
00888 
00889 void SMAC::handleCounterTimer(int id) {
00890   
00891     //printf("MAC:%d,id:%d - time:%.9f\n", index_,id,Scheduler::instance().clock());
00892 #ifdef JOURNAL_PAPER
00893         if (schedTab_[id].numNodes > 0) {
00894 #endif
00895 
00896     if (mhCounter_[id]->value_ == sleepTime_) { //woken up from sleep
00897         // listentime starts now
00898 
00899         if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00900             goto sched_1;  // cannot send if radio is sending or recving
00901     
00902         if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00903             goto sched_1;; // cannot send if not in any of these states
00904     
00905         if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
00906             (state_ == SLEEP || state_ == IDLE)) {
00907     
00908             if (state_ == SLEEP &&
00909                 (id == 0 || schedTab_[id].txSync == 1)) {
00910     
00911                 wakeup();
00912             }
00913             if (schedTab_[id].txSync == 1) {
00914                 // start carrier sense for sending sync
00915                 howToSend_ = BCASTSYNC;
00916 #ifdef JOURNAL_PAPER
00917                 syncSched_ = id;
00918 #else
00919                 currSched_ = id;
00920 #endif
00921                 state_ = CR_SENSE;
00922                 double cw = (Random::random() % SYNC_CW) * slotTime_sec_;
00923                 mhCS_.sched(CLKTICK2SEC(difs_) + cw);
00924             }
00925         }
00926         // start to listen now
00927     sched_1:
00928         mhCounter_[id]->sched(CLKTICK2SEC(listenTime_));
00929     
00930     } else if (mhCounter_[id]->value_ == syncTime_) { //synctime over
00931         // can start datatime now
00932     
00933         if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00934             goto sched_2;  // cannot send if radio is sending or recving
00935     
00936         if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00937             goto sched_2; // cannot send if not in any of these states
00938     
00939         if (schedTab_[id].txData == 1 &&
00940             (!(mhNav_.busy()) && !(mhNeighNav_.busy())) &&
00941             (state_ == SLEEP || state_ == IDLE)) {
00942             // schedule sending data
00943       
00944             if (state_ == SLEEP)
00945                 wakeup();
00946       
00947             struct hdr_smac *mh = (struct hdr_smac *)dataPkt_->access(hdr_mac::offset_);
00948             if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
00949                 howToSend_ = BCASTDATA;
00950             else
00951                 howToSend_ = UNICAST;
00952 #ifdef JOURNAL_PAPER
00953                         dataSched_ = id;
00954 #else
00955             currSched_ = id;
00956 #endif
00957             state_ = CR_SENSE;
00958             // start cstimer
00959             double cw = (Random::random() % DATA_CW) * slotTime_sec_;
00960             mhCS_.sched(CLKTICK2SEC(difs_) + cw);
00961         }
00962     sched_2:
00963         mhCounter_[id]->sched(CLKTICK2SEC(dataTime_));
00964     
00965     } else if (mhCounter_[id]->value_ == dataTime_) { //datatime over
00966 
00967         // check if in the middle of recving a pkt
00968         if (radioState_ == RADIO_RX)
00969             goto sched_3;
00970 #ifdef JOURNAL_PAPER    
00971         if (id == 0 && state_ == IDLE && searchNeighb_ ==0 && adaptiveListen_ ==0 )
00972 #else
00973         if (id == 0 && state_ == IDLE && searchNeighb_ ==0 )
00974 #endif
00975             sleep();
00976 
00977     sched_3:
00978         // now time to go to sleep
00979         mhCounter_[id]->sched(CLKTICK2SEC(cycleTime_));
00980     
00981         // check if ready to send out sync 
00982         if (schedTab_[id].numPeriods > 0) {
00983             schedTab_[id].numPeriods--;
00984             if (schedTab_[id].numPeriods == 0) {
00985     
00986                 schedTab_[id].txSync = 1; 
00987 
00988                 // neighbor discovery
00989                 if ( id == 0 ) {
00990                     numSync_--;
00991                 //  printf("numSync_ %d: ............node %d at %.6f\n", numSync_, index_,Scheduler::instance().clock());
00992 
00993                     if ( numSync_ == 1 ) {
00994                         searchNeighb_ = 1;  // node will go to neighbor discovery period starting from the next frame
00995                         //printf("Start Neighbor Discovery: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
00996                     }
00997                     else if ( numSync_ == 0 ) {
00998                         searchNeighb_  = 0;  // neighbor discovery period lasts exactly one SYNC period
00999                         //printf("Ending Neighbor Discovery: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
01000                         if ( numNeighb_ == 0 ) {
01001                             numSync_ = SRCH_CYCLES_SHORT;
01002                         }
01003                         else {
01004                             numSync_ = SRCH_CYCLES_LONG;
01005 
01006                         }
01007                     }       
01008 
01009                 }   
01010             }
01011         }
01012     }
01013 #ifdef JOURNAL_PAPER
01014     }
01015 #endif
01016 }
01017 
01018 #ifdef JOURNAL_PAPER
01019 void SMAC::handleUpdateNeighbTimer() {
01020         //printf("SMAC::handleUpdateNeighbTimer: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
01021         if (txRequest_ == 0) { // No data waiting to be transmitted
01022                 txRequest_ = 1; // temporarily disable tx when updating
01023                 update_myNeighbList();
01024         } else {
01025                 updateNeighbList_ = 1; // set flag to update when tx done
01026         }
01027 }
01028                                                                                                                                                             
01029 void SMAC::handleAdaptiveListenTimer() {
01030     //node tries to go to sleep after adaptive listen times out
01031         adaptiveListen_ = 0;
01032         if (state_ == IDLE && state_ != TX_PKT && mhCounter_[0]->value_ == sleepTime_)
01033                 sleep();
01034 }
01035 #endif
01036 
01037 // recv function for mac layer
01038 
01039 void SMAC::recv(Packet *p, Handler *h) {
01040                                                                                                                                                             
01041     struct hdr_cmn *ch = HDR_CMN(p);
01042 
01043     assert(initialized());
01044 
01045     // handle outgoing pkt
01046     if ( ch->direction() == hdr_cmn::DOWN) {
01047         sendMsg(p, h);
01048         return;
01049     }
01050 
01051     // handle incoming pkt
01052     // we have just recvd the first bit of a pkt on the network interface  
01053   
01054     // if the interface is in tx mode it probably would not see this pkt
01055     if (radioState_ == RADIO_TX && ch->error() == 0) {
01056         assert(tx_active_);
01057         ch->error() = 1;
01058         pktRx_ = p;
01059         mhRecv_.resched(txtime(p));
01060 
01061         return;
01062     }
01063   
01064     // cancel carrier sense timer and wait for entire pkt
01065     if (state_ == CR_SENSE) {
01066         printf("Cancelling CS- node %d\n", index_);
01067         // cancels only if timer is pending; smac could be in CR_SENSE with timer cancelled
01068         // incase it has already received a pkt and receiving again
01069         mhCS_.checkToCancel();
01070     }
01071   
01072     // if the interface is already in process of recv'ing pkt
01073     if (radioState_ == RADIO_RX) {
01074         assert(pktRx_); 
01075         assert(mhRecv_.busy());
01076     
01077         // if power of the incoming pkt is smaller than the power 
01078         // of the pkt currently being recvd by atleast the capture 
01079         // threshold then we ignore the new pkt.
01080     
01081         if (pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) 
01082             capture(p);
01083         else
01084             collision(p);
01085     } 
01086   
01087     else {
01088         if (mhRecv_.busy()) { // and radiostate != RADIO_RX
01089             assert(radioState_ == RADIO_SLP);
01090             // The radio interface was recv'ing a pkt when it went to sleep
01091             // should it postpone sleep till it finishes recving the pkt???
01092             mhRecv_.resched(txtime(p));
01093         } else
01094             mhRecv_.sched(txtime(p));
01095     
01096         radioState_ = RADIO_RX;
01097         pktRx_ = p;
01098     }
01099 }
01100 
01101 
01102 void SMAC::capture(Packet *p) {
01103     // we update NAV for this pkt txtime
01104     updateNav(CLKTICK2SEC(eifs_) + txtime(p));
01105     Packet::free(p);
01106 }
01107 
01108 
01109 void SMAC::collision(Packet *p) {
01110     if (!mac_collision_)
01111         mac_collision_ = 1;
01112   
01113     // since a collision has occured figure out which packet that caused 
01114     // the collision will "last" longer. Make this pkt pktRx_ and reset the
01115     // recv timer.
01116     if (txtime(p) > mhRecv_.timeToExpire()) {
01117         mhRecv_.resched(txtime(p));
01118         discard(pktRx_, DROP_MAC_COLLISION);
01119         // shouldn't we free pkt here ???
01120         pktRx_ = p;
01121 
01122     }
01123     else 
01124         discard(p, DROP_MAC_COLLISION);
01125     // shouldn't we free pkt here ???
01126 }
01127 
01128 
01129 void SMAC::discard(Packet *p, const char* why)
01130 {
01131     hdr_cmn *ch = HDR_CMN(p);
01132     hdr_smac *sh = HDR_SMAC(p);
01133   
01134     /* if the rcvd pkt contains errors, a real MAC layer couldn't
01135        necessarily read any data from it, so we just toss it now */
01136     if(ch->error() != 0) {
01137         Packet::free(p);
01138         //p = 0;
01139         return;
01140     }
01141 
01142     switch(sh->type) {
01143     
01144     case RTS_PKT:
01145         if (drop_RTS(p, why))
01146             return;
01147         break;
01148     
01149     case CTS_PKT:
01150     case ACK_PKT:
01151         if (drop_CTS(p, why))
01152             return;
01153         break;
01154   
01155     case DATA_PKT:
01156         if (drop_DATA(p, why))
01157             return;
01158         break;
01159 
01160     case SYNC_PKT:
01161         if(drop_SYNC(p, why))
01162             return;
01163         break;
01164 
01165     default:
01166         fprintf(stderr, "invalid MAC type (%x)\n", sh->type);
01167         //trace_pkt(p);
01168         exit(1);
01169     }
01170     Packet::free(p);
01171 }
01172 
01173 
01174 int SMAC::drop_RTS(Packet *p, const char* why) 
01175 {
01176     struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01177   
01178     if (cf->srcAddr == index_) {
01179         drop(p, why);
01180         return 1;
01181     }
01182     return 0;
01183 }
01184 
01185 int SMAC::drop_CTS(Packet *p, const char* why) 
01186 {
01187     struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01188 
01189     if (cf->dstAddr == index_) {
01190         drop(p, why);
01191         return 1;
01192     }
01193     return 0;
01194 }
01195 
01196 int SMAC::drop_DATA(Packet *p, const char* why) 
01197 {
01198     hdr_smac *sh = HDR_SMAC(p);
01199 
01200     if ( (sh->dstAddr == index_) ||
01201          (sh->srcAddr == index_) ||
01202          ((u_int32_t)sh->dstAddr == MAC_BROADCAST)) {
01203         drop(p, why);
01204         return 1;
01205     }
01206     return 0;
01207 }
01208 
01209 int SMAC::drop_SYNC(Packet *p, const char* why) 
01210 {
01211     drop(p, why);
01212     return 1;
01213 }
01214 
01215 #ifdef JOURNAL_PAPER
01216 void SMAC::checkMySched()
01217 {
01218         // check if I am the only one on schedTab[0]
01219         // if yes, should switch and follow the next available schedule
01220         // happens when an old node switches to a new schedule
01221         // and when I drop some inactive nodes from neighbor list(updating)
01222         int i, schedId;
01223         schedId = 0;
01224         if (schedTab_[0].numNodes == 1 && numSched_ > 1 && numNeighb_ > 0) {
01225                 for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) {
01226                         if (schedTab_[i].numNodes > 0) {  // switch to next available schedule
01227                                 //schedTab_[0].counter = schedTab[i].counter;
01228                                 schedTab_[0].numPeriods = 0;
01229                                 schedTab_[0].txSync = 1;
01230                                 schedTab_[0].txData = schedTab_[i].txData;
01231                                 schedTab_[0].syncNode = schedTab_[i].syncNode;
01232                                 schedTab_[0].numNodes = schedTab_[i].numNodes + 1;
01233                                 // delete this schedule
01234                                 schedTab_[i].numNodes = 0;
01235                                 numSched_--;
01236                                 schedId = i;
01237                                 break;
01238                         }
01239                 }
01240                 if (schedId > 0){
01241                         schedState_++;
01242                         // update my neighbor list which relative to this schedId
01243                         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
01244                                 if (neighbList_[i].state > 0 )
01245                                         if (neighbList_[i].schedId == schedId)
01246                                                 neighbList_[i].schedId = 0;
01247                         }
01248                 }
01249         }
01250 }
01251 // update_schedTab_neighbList() is executed whenever the transmission is done
01252 void SMAC::update_schedTab_neighbList()
01253 {
01254         //update schedTab and neighbList if flag is set
01255         //we should update the schedTab[].numNodes before we call checkMySched()
01256         //to ensure the next available schedule is correct
01257         check_schedFlag();
01258         if (updateNeighbList_ == 1) {
01259                 update_neighbList();
01260                 updateNeighbList_ = 0;
01261                 schedTab_[0].chkSched = 0;  //we already did checkMySched() in update_neighbList()
01262         } else if (schedTab_[0].chkSched == 1) {
01263                 checkMySched();
01264                 schedTab_[0].chkSched = 0;
01265         }
01266 }
01267                                                                                                                                                             
01268 //update_myNeighbList() is executed whenever the UpdateNeighb timer timesout
01269 void SMAC::update_myNeighbList()
01270 {
01271         //we should update the schedTab[].numNodes before we call checkMySched()
01272         //to ensure the next available schedule is correct
01273         check_schedFlag();
01274         update_neighbList();
01275         updateNeighbList_ = 0;
01276         schedTab_[0].chkSched = 0;  //we already did checkMySched() in update_neighbList()
01277         txRequest_ = 0;
01278 }
01279                                                                                                                                                             
01280 void SMAC::update_neighbList()
01281 {
01282         // update neighbor list,
01283         // if the node is not active (moved away or died) for a certain time,
01284         // need to drop it from neighbor list
01285                                                                                                                                                             
01286         //printf("\nupdate_neighbList:node %d at %.6f \n", index_, Scheduler::instance().clock());
01287         int i, schedId;
01288         //dump();
01289         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
01290                 if (neighbList_[i].state > 0 ){
01291                         if (neighbList_[i].active != 1){ // this node is not active recently
01292                                 //printf("node %d lost a neighbor of node %d: ............at %.6f\n", index_, neighbList_[i].nodeId, Scheduler::instance().clock());
01293                                 schedId = neighbList_[i].schedId;
01294                                 schedTab_[schedId].numNodes--;
01295                                 if (schedTab_[schedId].numNodes == 0)
01296                                         numSched_--;
01297                                 neighbList_[i].state = 0;
01298                                 numNeighb_--;
01299                         } else
01300                                 //printf("node %d has a neighbor of node %d: ............at %.6f\n", index_, neighbList_[i].nodeId, Scheduler::instance().clock());
01301                         neighbList_[i].active = 0;
01302                 }
01303         }
01304         //printf("#####################################################\n");
01305                                                                                                                                                             
01306         // maybe the inactive nodes were dropped from schedTab[0]
01307         // check if I am the only one on schedTab[0]
01308         // if yes, I should follow the next available schedule
01309         checkMySched();
01310         mhUpdateNeighb_.resched(SMAC_UPDATE_NEIGHB_PERIOD);
01311 }
01312 
01313 void SMAC::check_schedFlag()
01314 {
01315         int i;
01316         // decrease the numNodes in the old schedule first
01317         for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) {
01318                 if (schedTab_[i].numNodes > 0 && schedTab_[i].chkSched == 1){
01319                         schedTab_[i].chkSched = 0;
01320                         schedTab_[i].numNodes--;
01321                         if (schedTab_[i].numNodes == 0)
01322                                 numSched_--;
01323                 }
01324         }
01325 }
01326 #endif
01327 
01328 void SMAC::handleRTS(Packet *p) {
01329     // internal handler for RTS
01330 
01331     struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01332   
01333     if(cf->dstAddr == index_) {
01334         if((state_ == IDLE || state_ == CR_SENSE) && nav_ == 0) {
01335             recvAddr_ = cf->srcAddr; // remember sender's addr
01336 #ifdef JOURNAL_PAPER
01337                         updateNeighNav(cf->duration);
01338 #endif
01339             if(sendCTS(cf->duration)) {
01340                 state_ = WAIT_DATA;
01341                 lastRxFrag_ = -3; //reset frag no 
01342             }
01343         }
01344     } else { 
01345         // pkt destined to another node
01346         // don't go to sleep unless hear first data fragment
01347         // so I know how long to sleep
01348         if (state_ == CR_SENSE)
01349             state_ = IDLE;
01350 #ifdef JOURNAL_PAPER
01351                 updateNav(cf->duration);
01352                 state_ = DATA_SENSE1;
01353                 mhGene_.sched(timeWaitCtrl_);
01354 #else
01355         updateNav(durCtrlPkt_ + durDataPkt_);
01356 #endif
01357     }
01358 
01359 }
01360 
01361 void SMAC::handleCTS(Packet *p) {
01362     // internal handler for CTS
01363     struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01364     if(cf->dstAddr == index_) { // for me
01365         if(state_ == WAIT_CTS && cf->srcAddr == sendAddr_) {
01366             // cancel CTS timer
01367             mhGene_.cancel();
01368 
01369             if(sendDATA()) {
01370                 state_ = WAIT_ACK;
01371 #ifndef JORNAL_PAPER
01372                 if (!syncFlag_)
01373                     txData_ = 0;
01374                 else
01375                     schedTab_[currSched_].txData = 0;
01376 #endif
01377             }
01378         }
01379     } else { // for others
01380         updateNav(cf->duration);
01381 #ifdef JOURNAL_PAPER
01382                 if(state_ == DATA_SENSE1 || state_ == DATA_SENSE2) { mhGene_.cancel();}
01383                 if(state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE1 || state_ == DATA_SENSE2)
01384                         sleep();
01385 #else
01386         if(state_ == IDLE || state_ == CR_SENSE)
01387             sleep();
01388 #endif
01389     }
01390 }
01391 
01392 void SMAC::handleDATA(Packet *p) {
01393 
01394     // internal handler for DATA packet
01395     struct hdr_cmn *ch = HDR_CMN(p);
01396     struct hdr_smac * sh = HDR_SMAC(p);
01397  
01398     if((u_int32_t)sh->dstAddr == MAC_BROADCAST) { // brdcast pkt
01399         state_ = IDLE;
01400         // hand pkt over to higher layer
01401         rxMsgDone(p);
01402     
01403     } else if (sh->dstAddr == index_) { // unicast pkt
01404         if(state_ == WAIT_DATA && sh->srcAddr == recvAddr_) {
01405             // Should track neighbors' NAV, in case tx extended
01406             updateNeighNav(sh->duration);
01407             sendACK(sh->duration);
01408 #ifdef JOURNAL_PAPER
01409                         if (sh->duration > durCtrlPkt_) { // wait for more frag
01410                                 rxFragDone(p);   //no frag for now
01411                                 state_ = WAIT_DATA;
01412                         } else {   // no more fragments
01413                             state_ = IDLE;
01414                                 rxMsgDone(p);
01415                         }
01416 
01417 #else
01418       
01419             //if (sh->duration > durCtrlPkt_) { // wait for more frag
01420             //rxFragDone(p);   no frag for now
01421             //state_ = IDLE;
01422             //} else {   // no more fragments
01423       
01424             state_ = IDLE;
01425             if(lastRxFrag_ != ch->uid()) {
01426                 lastRxFrag_ = ch->uid();
01427                 rxMsgDone(p);
01428             }
01429             else {
01430                 printf("Recd duplicate data pkt at %d from %d! free pkt\n",index_,sh->srcAddr);
01431                 Packet::free(p);
01432                 if (!syncFlag_)
01433                     checkToSend();
01434             }
01435 #endif
01436         } else if (state_ == IDLE || state_ == CR_SENSE ) {
01437             printf("got data pkt in %d state XXX %d\n", state_, index_);
01438             //updateNav(sh->duration + 0.00001);  // incase I have a pkt to send
01439             sendACK(sh->duration);
01440             state_ = IDLE;
01441             if(lastRxFrag_ != ch->uid()) {
01442                 lastRxFrag_ = ch->uid();
01443                 rxMsgDone(p);
01444             }
01445             else {
01446                 printf("Recd duplicate data pkt! free pkt\n");
01447                 Packet::free(p);
01448                 if (!syncFlag_)
01449                     checkToSend();
01450             }
01451         } else { // some other state
01452             // not sure we can handle this
01453             // so drop pkt
01454             printf("Got data pkt in !WAIT_DATA/!CR_SENSE/!IDLE state(%d) XXX %d\n", state_, index_);
01455             printf("Dropping data pkt\n");
01456             Packet::free(p);
01457         }
01458     } else { // unicast pkt destined to other node
01459         updateNav(sh->duration);
01460         Packet::free(p);
01461 #ifdef JOURNAL_PAPER
01462                 if (state_ == DATA_SENSE2) { mhGene_.cancel();}
01463                 if (state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE2)
01464                         sleep();
01465 #else
01466         if (state_ == IDLE || state_ == CR_SENSE)
01467             sleep();
01468 #endif
01469     }
01470 }
01471 
01472 
01473 
01474 void SMAC::handleACK(Packet *p) {
01475     // internal handler for ack
01476     struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01477   
01478     if (cf->dstAddr == index_) {
01479         if (state_ == WAIT_ACK && cf->srcAddr == sendAddr_) {
01480             // cancel ACK timer
01481             mhGene_.cancel();
01482 #ifdef JOURNAL_PAPER
01483                         numFrags_--;
01484                         succFrags_++;
01485                         if (numFrags_ > 0) { //need to send more frags
01486                                   state_ = TX_NEXT_FRAG;
01487                                   txFragDone();
01488                                } else {
01489                         state_ = IDLE;
01490                         txMsgDone();
01491             }
01492 #else
01493             Packet::free(dataPkt_);
01494             dataPkt_ = 0;
01495             //numFrags_--;
01496             //succFrags_++;
01497       
01498             // if (numFrags_ > 0) { //need to send more frags
01499             //  if (neighNav__ < (durDataPkt_ + durCtrlPkt_)) {
01500             //    // used up reserved time, have to stop
01501             //    state_ = IDLE;
01502             //    // txMsgFailed(succFrags_);
01503             //    txMsgDone();
01504             //  } else { // continue on next fragment
01505             //    state_ = WAIT_NEXTFRAG;
01506             //    txFragDone(dataPkt_);
01507             //  }
01508 
01509             //       } else {
01510             state_ = IDLE;
01511             txMsgDone();
01512             //}
01513 #endif
01514         }
01515     
01516     } else { // destined to another node
01517         if (cf->duration > 0) {
01518             updateNav(cf->duration);
01519             if (state_ == IDLE || state_ == CR_SENSE)
01520                 sleep();
01521         }
01522     }
01523 }
01524 
01525 #ifdef JOURNAL_PAPER
01526 void SMAC::handleSYNC(Packet *p) 
01527 {
01528 
01529     struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
01530         int i, j,nodeId, schedId, flag;
01531         struct SchedTable tempSched;
01532         int foundNeighb = 0;
01533     if (index_ == 5){
01534         double t = Scheduler::instance().clock();
01535         //printf("Recvd SYNC (not/f) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t);
01536     }
01537     if (numSched_ == 0) { // in choose_sched state
01538         mhGene_.cancel();
01539         setMySched(p);
01540         return;
01541     }
01542         if (numNeighb_ == 0 && globalSchedule_ == 1) {
01543          // follow this schedule if having no other neighbor and if this schedule has smaller ID
01544             if (schedTab_[0].syncNode > sf->syncNode || !sendSYNCFlag_ ) {
01545                 setMySched(p);
01546                 return;
01547             }
01548         }
01549         else if (numNeighb_ == 0) { // getting first sync pkt
01550          // follow this sched as have no other neighbor
01551             setMySched(p);
01552 
01553             return;
01554         }
01555     state_ = IDLE;
01556 
01557         // check if sender is on my neighbor list
01558         nodeId = SMAC_MAX_NUM_NEIGHBORS;
01559         schedId = SMAC_MAX_NUM_SCHEDULES;
01560         for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
01561             if (neighbList_[i].state > 0 && neighbList_[i].nodeId == sf->srcAddr) {
01562                     nodeId = i;
01563                     schedId = neighbList_[i].schedId; // a known neighbor
01564                     break;
01565             }
01566         }
01567         if (nodeId < SMAC_MAX_NUM_NEIGHBORS) {
01568             if (neighbList_[nodeId].state == sf->state) {
01569                     // update the existing schedule
01570                 mhCounter_[schedId]->sched(sf->sleepTime);
01571 
01572                     neighbList_[nodeId].active = 1;
01573                     if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
01574                         // change state
01575                         schedState_++;
01576                 //printf("#############################################################\n");
01577                         //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
01578                 //printf("#############################################################\n");
01579 
01580                             tempSched.syncNode = schedTab_[schedId].syncNode;
01581                             tempSched.txSync = schedTab_[schedId].txSync;  // need send sync
01582                             tempSched.txData = schedTab_[schedId].txData;
01583                             tempSched.numPeriods = schedTab_[schedId].numPeriods;
01584                             tempSched.numNodes = schedTab_[schedId].numNodes ; //
01585                         tempSched.chkSched = schedTab_[schedId].chkSched;
01586 
01587                         if (schedTab_[0].numNodes == 1) {
01588                                 numSched_--;
01589                         }
01590                     mhCounter_[schedId]->sched(mhCounter_[0]->timeToSleep());
01591                             schedTab_[schedId].syncNode = schedTab_[0].syncNode;
01592                             schedTab_[schedId].txSync = schedTab_[0].txSync;  // need send sync
01593                             schedTab_[schedId].txData = schedTab_[0].txData;
01594                             schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
01595                             schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
01596                             schedTab_[schedId].chkSched = schedTab_[0].chkSched;
01597 
01598                             // new schedule is schedule 0 now
01599                 mhCounter_[0]->sched(sf->sleepTime);
01600                         schedTab_[0].syncNode = sf->syncNode;
01601                         schedTab_[0].txSync = 1;  
01602                         schedTab_[0].txData = tempSched.txData;
01603                         schedTab_[0].numPeriods = 0; 
01604                         schedTab_[0].numNodes = tempSched.numNodes + 1; // I are following this sched
01605                         schedTab_[0].chkSched = tempSched.chkSched;
01606 
01607                         // change all the neighbor who was following shedule 0
01608                         for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
01609                                 if (neighbList_[j].schedId == 0) { // found an empty entry
01610                                     neighbList_[j].schedId = schedId;
01611                                 }
01612                                 else if (neighbList_[j].schedId == schedId) { // found an empty entry
01613                                     neighbList_[j].schedId = 0;
01614                                 }
01615                             }
01616                     }
01617                 return;
01618             } else {
01619 
01620                     // decrement number of nodes on old schedule
01621 
01622                     if (schedTab_[schedId].numNodes ==1 && txRequest_ == 1) {
01623                         //set flag to decrement numNodes after tx pkt is done
01624                         schedTab_[schedId].chkSched = 1;
01625                     }
01626                     else 
01627             {
01628                         schedTab_[schedId].numNodes--; 
01629                         if (schedTab_[schedId].numNodes == 0){
01630                             numSched_--;
01631                         }
01632                 }
01633 
01634         }
01635     }
01636 
01637         // now it's either a new node or an old node switching to a new schedule
01638         // it is also possible that a node switches to an existing schedule
01639         // check if its schedule is a known one to me
01640         schedId = SMAC_MAX_NUM_SCHEDULES;
01641         for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
01642             if (schedTab_[i].numNodes > 0) {
01643         
01644                 double t = mhCounter_[i]->timeToSleep();
01645                 double st = sf->sleepTime;
01646                 double timeDiff = st - t;
01647                     if ( timeDiff > -GUARDTIME && timeDiff < GUARDTIME) {
01648                 mhCounter_[i]->sched(sf->sleepTime);
01649 
01650                         schedTab_[i].numNodes++; // it will follow this schedule
01651                         schedId = i;
01652                         break;
01653                     } 
01654             }
01655         }
01656 
01657         if (schedId == SMAC_MAX_NUM_SCHEDULES) {  // unknow schedule
01658             flag =1;
01659             // add an entry to the schedule table
01660             if (numSched_ < SMAC_MAX_NUM_SCHEDULES){
01661                     for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
01662                         if (schedTab_[i].numNodes == 0) { // found an empty entry
01663                         // check if I need to switch
01664                 if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
01665                             // change state
01666                             schedState_++;
01667                     //printf("#############################################################\n");
01668                             //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
01669                             //printf("#############################################################\n");
01670 
01671                             if (schedTab_[0].numNodes >= 2) { // need to move old schedule 0 to schedule i
01672                             mhCounter_[i]->sched(mhCounter_[0]->timeToSleep());
01673                                     schedTab_[i].syncNode = schedTab_[0].syncNode;
01674                                     schedTab_[i].txSync = schedTab_[0].txSync;  // need send sync
01675                                     schedTab_[i].txData = schedTab_[0].txData;
01676                                     schedTab_[i].numPeriods = schedTab_[0].numPeriods;
01677                                     schedTab_[i].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
01678                                     schedTab_[i].chkSched = schedTab_[0].chkSched;
01679                                     numSched_++;  // increment number of schedules
01680                                     // change all the neighbor who was following shedule 0
01681                                     for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
01682                                         if (neighbList_[j].schedId == 0) { // found an empty entry
01683                                             neighbList_[j].schedId = i;
01684                                         }
01685                                     }
01686                             }
01687                             // new schedule is schedule 0 now
01688                     mhCounter_[0]->sched(sf->sleepTime);
01689                             schedTab_[0].syncNode = sf->syncNode;
01690                             schedTab_[0].txSync = 1;  // need send sync
01691                             schedTab_[0].txData = 0;
01692                     schedTab_[0].numPeriods = 0;
01693                             schedTab_[0].numNodes = 2; // 1st node + I are following this sched
01694                             schedTab_[0].chkSched = 0;
01695 
01696                             schedId = 0;
01697                         }
01698                         else { // fill new schedule in schedule i
01699 
01700                         mhCounter_[i]->sched(sf->sleepTime);
01701                             schedTab_[i].syncNode = sf->syncNode;
01702                             schedTab_[i].txSync = 1;  // need send sync
01703                             schedTab_[i].txData = 0;
01704                             schedTab_[i].numPeriods = 0;
01705                             schedTab_[i].numNodes = 1; // 1st node following this sched
01706                             schedTab_[i].chkSched = 0;
01707                             schedId = i;
01708                             numSched_++;  // increment number of schedules
01709                         }
01710                         break;
01711                         }
01712                     }
01713         }
01714     }
01715 
01716         if (nodeId == SMAC_MAX_NUM_NEIGHBORS) {  // a new node
01717             // didn't find an empty entry in schedule table, just drop the new node
01718             if (schedId == SMAC_MAX_NUM_SCHEDULES) return;
01719             // add it to my neighbor list
01720             if (numNeighb_ < SMAC_MAX_NUM_NEIGHBORS){
01721                 for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
01722                     if (neighbList_[i].state == 0) { // found an empty entry
01723                         neighbList_[i].state = sf->state;
01724                         neighbList_[i].nodeId = sf->srcAddr;
01725                         neighbList_[i].schedId = schedId;
01726                         neighbList_[i].active = 1;
01727                         numNeighb_++;  // increment number of neighbors
01728                         return;
01729                     }
01730                 }
01731          }
01732          // didn't find an empty entry in neighb list, just drop the new node
01733     schedTab_[schedId].numNodes--;
01734         if (schedTab_[schedId].numNodes == 0)
01735             numSched_--;
01736         } else if (flag == 1) {  // old node switches to a new schedule
01737             // didn't find an empty entry in schedule table, delete the old node
01738             if (schedId == SMAC_MAX_NUM_SCHEDULES) {
01739                     neighbList_[nodeId].state = 0;
01740                     numNeighb_--;  // decrement number of neighbors
01741             } else {
01742                     neighbList_[nodeId].state = sf->state;
01743                     neighbList_[nodeId].schedId = schedId;
01744                     neighbList_[nodeId].active = 1;
01745             }
01746 
01747             // maybe the old node switches from schedTab_[0]
01748             // check if I am the only one on schedTab_[0] now
01749             // if yes, I should follow the next available schedule
01750             if (txRequest_ == 0) {
01751                     checkMySched();
01752             } else {
01753                 // set flag to call checkMySched() when txRequest_ becomes 0
01754                     schedTab_[0].chkSched = 1;
01755             }
01756         } else {  // old node switches to old schedule
01757                 neighbList_[nodeId].state = sf->state;
01758                 neighbList_[nodeId].schedId = schedId;
01759                 neighbList_[nodeId].active = 1;
01760         if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
01761             //printf("#############################################################\n");
01762                     //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
01763                     //printf("#############################################################\n");
01764 
01765                     // change state
01766                     schedState_++;
01767                         tempSched.syncNode = schedTab_[schedId].syncNode;
01768                         tempSched.txSync = schedTab_[schedId].txSync;  // need send sync
01769                         tempSched.txData = schedTab_[schedId].txData;
01770                         tempSched.numPeriods = schedTab_[schedId].numPeriods;
01771                         tempSched.numNodes = schedTab_[schedId].numNodes ; //
01772                         tempSched.chkSched = schedTab_[schedId].chkSched;
01773 
01774                     if (schedTab_[0].numNodes == 1) {
01775                             numSched_--;
01776                     }
01777                 mhCounter_[schedId]->sched(mhCounter_[0]->timeToSleep());
01778                         schedTab_[schedId].syncNode = schedTab_[0].syncNode;
01779                         schedTab_[schedId].txSync = schedTab_[0].txSync;  // need send sync
01780                         schedTab_[schedId].txData = schedTab_[0].txData;
01781                         schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
01782                         schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
01783                         schedTab_[schedId].chkSched = schedTab_[0].chkSched;
01784 
01786                         mhCounter_[0]->sched(sf->sleepTime);
01787 
01788                     schedTab_[0].syncNode = sf->syncNode;
01789                     schedTab_[0].txSync = 1; 
01790                     schedTab_[0].txData = tempSched.txData;
01791                     schedTab_[0].numPeriods = 0;
01792                     schedTab_[0].numNodes = tempSched.numNodes + 1; // I are following this sched
01793                     schedTab_[0].chkSched = tempSched.chkSched;
01794 
01795                     // change all the neighbor who was following shedule 0
01796                     for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
01797                             if (neighbList_[j].schedId == 0) { // found an empty entry
01798                                 neighbList_[j].schedId = schedId;
01799                             }
01800                             else if (neighbList_[j].schedId == schedId) { // found an empty entry
01801                                 neighbList_[j].schedId = 0;
01802                             }
01803                         }
01804 
01805             }
01806         return;
01807     }
01808 
01809 }
01810 #else
01811 
01812 void SMAC::handleSYNC(Packet *p) 
01813 {
01814 //printf("node: %d ..............data sent............\n",index_);
01815     if ( selfConfigFlag_ == 1) {
01816         if(numSched_ == 0) { // in choose_sched state
01817             mhGene_.cancel();
01818             //double t = Scheduler::instance().clock();
01819             //struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
01820             //printf("Recvd SYNC (follow) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t);
01821             setMySched(p);
01822             return;
01823         }
01824         if (numNeighb_ == 0) { // getting first sync pkt
01825             // follow this sched as have no other neighbor
01826                 //double t = Scheduler::instance().clock();
01827             //struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
01828             //printf("Recvd SYNC (follow) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t);
01829                 setMySched(p);
01830             return;
01831         }
01832     }
01833     state_ = IDLE;
01834     // check if sender is on my neighbor list
01835     struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
01836     int i, j;
01837     int foundNeighb = 0;
01838     int schedId = SMAC_MAX_NUM_SCHEDULES;
01839     //double t = Scheduler::instance().clock();
01840     //printf("Recvd SYNC (not/f) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t);
01841   
01842     for(i = 0; i < numNeighb_; i++) {
01843         if (neighbList_[i].nodeId == sf->srcAddr) {
01844             foundNeighb = 1;
01845             schedId = neighbList_[i].schedId;  // a known neighbor
01846             mhCounter_[schedId]->sched(sf->sleepTime);
01847             break;
01848         }
01849         if (neighbList_[i].nodeId == sf->syncNode)
01850             // // found its synchronizer, remember it schedule id
01851             schedId = neighbList_[i].schedId;
01852     }
01853     if (!foundNeighb) { // unknown node, add it onto neighbor list
01854         neighbList_[numNeighb_].nodeId = sf->srcAddr;
01855         if (schedId < SMAC_MAX_NUM_SCHEDULES) {
01856             // found its synchronizer
01857             neighbList_[numNeighb_].schedId = schedId;
01858         } else if (sf->syncNode == index_) { // this node follows my schedule
01859             neighbList_[numNeighb_].schedId = 0;
01860         } else { // its synchronizer is unknown
01861             // check if its schedule equals to an existing one
01862             int foundSched = 0;
01863             for (j = 0; j < numSched_; j++) {
01864                 double t = mhCounter_[j]->timeToSleep();
01865                 double st = sf->sleepTime; 
01866                 if (t == st || (t + CLKTICK2SEC(1)) == st || t == (st + CLKTICK2SEC(1))) {
01867                     neighbList_[numNeighb_].schedId = j;
01868                     foundSched = 1;
01869                     break;
01870                 }
01871             }
01872             if (!foundSched) { // this is unknown schedule
01873                 schedTab_[numSched_].txSync = 1;
01874                 schedTab_[numSched_].txData = 0;
01875                 schedTab_[numSched_].numPeriods = 0;
01876                 neighbList_[numNeighb_].schedId = numSched_;
01877                 mhCounter_[numSched_]->sched(sf->sleepTime);
01878                 numSched_++;
01879             }
01880         }
01881         numNeighb_++;  // increment number of neighbors
01882     }
01883 }
01884 
01885 #endif
01886 void SMAC::rxMsgDone(Packet *p) {
01887     // no more fragments
01888     // defragment all pkts and send them up
01889     // fragmentation/de-frag to be implemented
01890   
01891     if (p)
01892         uptarget_->recv(p, (Handler*)0);
01893   
01894     if (!syncFlag_)
01895         // check if any pkt waiting to get tx'ed
01896         checkToSend();
01897 #ifdef JOURNAL_PAPER
01898     //node tries to go to sleep after receiving the message
01899     //we temperarily disable sleep() here, because in the testcases where ARP messages exist, more than one message need to be transmitted in one round
01900         else {
01901 //                if( mhCounter_[0]->value_ == sleepTime_ ) 
01902 //                        sleep();
01903         }
01904 #endif
01905 }
01906 
01907 #ifdef JOURNAL_PAPER
01908 void SMAC::rxFragDone(Packet *p) {
01909 //  more fragments to come
01910 }
01911 #endif
01912 
01913 //void SMAC::rxFragDone(Packet *p) {
01914 // more fragments to come
01915 //}
01916 
01917 // mac transmission functions
01918 
01919 void SMAC::transmit(Packet *p) {
01920   
01921     radioState_ = RADIO_TX;
01922     tx_active_ = 1;
01923     pktTx_ = p;
01924 
01925     double transTime = txtime(p);
01926     hdr_cmn *ch = hdr_cmn::access(p);
01927     ch->txtime() = transTime;
01928 //  printf("%d MAC sending at %f\n",index_,NOW);    
01929     downtarget_->recv(p->copy(), this);
01930     //Scheduler::instance().schedule(downtarget_, p, 0.000001);
01931     mhSend_.sched(txtime(p));
01932 
01933 }
01934 
01935 bool SMAC::chkRadio() {
01936     // check radiostate
01937     if (radioState_ == RADIO_IDLE || radioState_ == RADIO_SLP)
01938         return (1);
01939 
01940     return (0); // phy interface is ready to tx
01941 }
01942 
01943 
01944 int SMAC::startBcast()
01945 {
01946     // broadcast data directly; don't use RTS/CTS
01947 
01948     hdr_smac *mh = HDR_SMAC(dataPkt_);
01949   
01950     mh->duration = 0;
01951 
01952     if(chkRadio()) {
01953         transmit(dataPkt_);
01954         return 1;
01955     }
01956   
01957     return 0;
01958 }
01959 
01960 
01961 int SMAC::startUcast()
01962 {
01963 printf("node: %d ..............data sent Uni............\n",index_);
01964     // start unicast data; send RTS first
01965     hdr_smac *mh = HDR_SMAC(dataPkt_);
01966   
01967     sendAddr_ = mh->dstAddr;
01968     numRetry_ = 0;
01969     //succFrags_ = 0;
01970 #ifdef JOURNAL_PAPER
01971     succFrags_ = 0;
01972 #endif
01973     numExtend_ = 0; 
01974     if(sendRTS()) {
01975         state_ = WAIT_CTS;
01976         return 1;
01977     }
01978   
01979     return 0;
01980 }
01981 
01982 
01983 void  SMAC::txMsgDone() 
01984 {
01985 #ifdef JOURNAL_PAPER
01986         // update schedTab and neighbList if flags are set when txRequest_=1
01987         update_schedTab_neighbList();
01988         txRequest_ = 0;
01989 #endif
01990     if (!syncFlag_) {
01991 #ifdef JOURNAL_PAPER
01992                 txData_ = 0;
01993 #endif
01994         // check if any data is waiting to get tx'ed
01995         if(checkToSend())
01996             return;
01997         else if (callback_) { // signal upper layer
01998             Handler *h = callback_;
01999             callback_ = 0;
02000             h->handle((Event*) 0);
02001         }
02002     } else {
02003 #ifdef JOURNAL_PAPER
02004                 schedTab_[dataSched_].txData = 0;
02005 #endif
02006 
02007         if (callback_) { // signal upper layer
02008             Handler *h = callback_;
02009             callback_ = 0;
02010             h->handle((Event*) 0);
02011         }
02012 #ifdef JOURNAL_PAPER
02013         //node tries to go to sleep after transmission is done (both unicast and broadcast)
02014                 if( mhCounter_[0]->value_ == sleepTime_ )
02015                         sleep();
02016 #endif
02017     }
02018   
02019 }
02020 
02021 // void SMAC::txFragDone() 
02022 // {
02023 //   // send next fragment
02024 
02025 // }
02026 
02027 #ifdef JOURNAL_PAPER
02028 void SMAC::txFragDone()
02029 {
02030    // send next fragment
02031         txNextFrag(&dataPkt_);
02032 }
02033                                                                                                                                                             
02034 bool SMAC::txNextFrag(void* data)
02035 {
02036       // Send subsequent fragments
02037                                                                                                                                                             
02038         if (state_ != TX_NEXT_FRAG || data == 0) return 0;
02039 //      dataPkt = (MACHeader*)data;
02040       // fill in MAC header fields except duration
02041 //      dataPkt->type = DATA_PKT;  // data pkt
02042 //      dataPkt->toAddr = sendAddr;
02043 //      dataPkt->fromAddr = TOS_LOCAL_ADDRESS;
02044 //      dataPkt->fragNo = txFragCount;
02045 //      if (neighbNav >= (SIFS + durDataPkt + timeWaitCtrl)) {
02046          // schedule to send this fragment, no need for carrier sense
02047 //         state = TX_PKT;
02048         if(sendDATA()) {
02049                 state_ = WAIT_ACK;
02050                 if (!syncFlag_)
02051                         txData_ = 0;
02052                 else
02053                         schedTab_[dataSched_].txData = 0;
02054                         //schedTab_[currSched_].txData = 0;
02055         }
02056                                                                                                                                                             
02057 //      } // else will retry when neighbNav timeout
02058         return 1;
02059 }
02060 #endif
02061 
02062 bool SMAC::sendMsg(Packet *pkt, Handler *h) {
02063     struct hdr_smac *mh = HDR_SMAC(pkt);
02064 #ifdef JOURNAL_PAPER
02065         struct hdr_cmn *ch = HDR_CMN(pkt);
02066 #endif
02067     callback_ = h;
02068     if ((u_int32_t)mh->dstAddr == MAC_BROADCAST) {
02069         return (bcastMsg(pkt));
02070     } else {
02071 #ifdef JOURNAL_PAPER
02072                 //printf("message length: %d\n",ch->size_);
02073                 // need upper level support here
02074                 int fragNum = ch->size_ / SIZEOF_SMAC_DATAPKT ;
02075                 if (fragNum == 0) fragNum = 1;
02076                 //printf("message length:%d\n",fragNum);
02077                 return unicastMsg(fragNum, pkt);     // for now no fragmentation
02078 #else
02079         return (unicastMsg(1, pkt));     // for now no fragmentation
02080 #endif
02081         // fragmentation limit is 40 bytes per pkt.
02082         // max_msg_size is tentatively 1000 bytes; weiye will confirm this
02083     }
02084 }
02085 
02086 
02087 bool SMAC::bcastMsg(Packet *p) {
02088     //if (dataPkt_ != 0 || p == 0) 
02089     //return 0;
02090     assert(p);
02091   
02092     //if (state_ != IDLE && state_ != SLEEP && state_!= WAIT_DATA)
02093     //return 0;
02094 
02095     //char * mh = (char *)p->access(hdr_mac::offset_);
02096     //int dst = hdr_dst(mh);
02097     //int src = hdr_src(mh);
02098   
02099     struct hdr_smac *sh = HDR_SMAC(p);
02100   
02101     sh->type = DATA_PKT;
02102     sh->length = SIZEOF_SMAC_DATAPKT;
02103     //sh->srcAddr = src;
02104     //sh->dstAddr = dst;
02105     dataPkt_ = p;
02106 #ifdef JOURNAL_PAPER
02107         // Don't accept Tx request if I have already accepted a request
02108         if (txRequest_ == 0) {
02109                 txRequest_ = 1;
02110         }
02111         else {
02112                 return 0;
02113         }
02114                                                                                                                                                             
02115         for (int i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
02116                  if (schedTab_[i].numNodes > 0) {
02117                         //printf("txData[%d] = 1: ............node %d at %.6f\n", i, index_, Scheduler::instance().clock());
02118                         schedTab_[i].txData = 1;
02119          }
02120       }
02121 #else
02122     for(int i=0; i < numSched_; i++) {
02123         schedTab_[i].txData = 1;
02124     }
02125 #endif
02126     if (!syncFlag_) {
02127         txData_ = 1;
02128         // check if can send now
02129         if (checkToSend())
02130             return 1;
02131         else 
02132             return 0;
02133   
02134     } else {
02135         numBcast_ = numSched_;
02136         return 1;
02137     }
02138 }
02139 
02140 bool SMAC::unicastMsg(int numfrags, Packet *p) {
02141 
02142     //  if (dataPkt != 0 || p == 0)
02143     //return 0;
02144 
02145     assert(p);
02146 
02147     //if (state_ != IDLE && state_ != SLEEP && state_!= WAIT_DATA)
02148     //return 0;
02149 
02150   
02151     char * mh = (char *)p->access(hdr_mac::offset_);
02152     int dst = hdr_dst(mh);
02153     int src = hdr_src(mh);
02154 
02155     // search for schedule of dest node
02156     struct hdr_smac *sh = HDR_SMAC(p);
02157     //int dst = sh->dstAddr;
02158 
02159     if (syncFlag_) {
02160         int found = 0;
02161         for (int i=0; i < numNeighb_; i++) {
02162             if (neighbList_[i].nodeId == dst) {
02163                 found = 1;
02164 #ifdef JOURNAL_PAPER
02165                                 sendAddr = UNICAST_ADDR;
02166                                 dataSched_ = neighbList_[i].schedId;
02167 #endif
02168                 schedTab_[neighbList_[i].schedId].txData = 1;
02169                 break;
02170             }
02171         }
02172         if (found == 0) {
02173             printf("Neighbor unknown; cannot send pkt\n");
02174             return 0;  // unknown neighbor
02175         }
02176     }
02177 #ifdef JOURNAL_PAPER
02178         // Don't accept Tx request if I have already accepted a request
02179         if (txRequest_ == 0) {
02180                 txRequest_ = 1;
02181         }
02182         else {
02183                 return 0;
02184         }
02185         numFrags_ = numfrags; 
02186 #endif
02187     sh->type = DATA_PKT;
02188     sh->length = SIZEOF_SMAC_DATAPKT;
02189     sh->dstAddr = dst;
02190     sh->srcAddr = src;
02191     //numFrags_ = numfrags;
02192     dataPkt_ = p;
02193 
02194     if (!syncFlag_) {
02195         txData_ = 1;
02196     
02197         // check if can send now
02198         if (checkToSend())
02199             return 1;
02200         else
02201             return 0;
02202     
02203     } else 
02204         return 1;
02205 }
02206 
02207 
02208 bool SMAC::sendRTS() {
02209 
02210 //printf("node: %d ..............data sent............\n",index_);
02211     // construct RTS pkt
02212     Packet *p = Packet::alloc();
02213     struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
02214     struct hdr_cmn *ch = HDR_CMN(p);
02215 
02216     ch->uid() = 0;
02217     ch->ptype() = PT_SMAC;
02218     ch->size() = SIZEOF_SMAC_CTRLPKT;
02219     ch->iface() = UNKN_IFACE.value();
02220     ch->direction() = hdr_cmn::DOWN;
02221     ch->error() = 0;    /* pkt not corrupt to start with */
02222   
02223 
02224     bzero(cf, MAC_HDR_LEN);
02225   
02226     cf->length = SIZEOF_SMAC_CTRLPKT;
02227     cf->type = RTS_PKT;
02228   
02229     cf->srcAddr = index_;  // mac_id
02230     cf->dstAddr = sendAddr_;
02231 
02232     // reserved time for CTS + all fragments + all acks
02233     //cf->duration = (numFrags_ + 1) * durCtrlPkt_ + numFrags_ * durDataPkt_;
02234 #ifdef JOURNAL_PAPER
02235     cf->duration = (numFrags_ + 1) * durCtrlPkt_ + numFrags_ * durDataPkt_;
02236 #else
02237     cf->duration = (2 * durCtrlPkt_ + durDataPkt_ + 0.001 ); 
02238 #endif
02239     cf->crc = 0;
02240  
02241     // send RTS
02242     if (chkRadio()) {
02243         transmit(p);
02244         return 1;
02245     
02246     } else 
02247         return 0;
02248 
02249 }
02250 
02251 
02252 bool SMAC::sendCTS(double duration) {
02253   
02254     // construct CTS
02255     Packet *p = Packet::alloc();
02256     struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
02257     struct hdr_cmn *ch = HDR_CMN(p);
02258 
02259     ch->uid() = 0;
02260     ch->ptype() = PT_SMAC;
02261     ch->size() = SIZEOF_SMAC_CTRLPKT;
02262     ch->iface() = UNKN_IFACE.value();
02263     ch->direction() = hdr_cmn::DOWN;
02264     ch->error() = 0;    /* pkt not corrupt to start with */
02265 
02266     bzero(cf, MAC_HDR_LEN);
02267   
02268     cf->length = SIZEOF_SMAC_CTRLPKT;
02269     cf->type = CTS_PKT;
02270   
02271     cf->srcAddr = index_;
02272     cf->dstAddr = recvAddr_;
02273 
02274     // input duration is the duration field from received RTS pkt  
02275     cf->duration = duration - durCtrlPkt_ ;  
02276     cf->crc = 0;
02277     // send CTS
02278     if (chkRadio()) {
02279         transmit(p);
02280         return 1;
02281 
02282     } else
02283         return 0;
02284 }
02285 
02286 
02287 bool SMAC::sendDATA() {
02288 
02289     // assuming data pkt is already constructed
02290     struct hdr_smac * sh = HDR_SMAC(dataPkt_);
02291   
02292     //sh->duration = numFrags_ * durCtrlPkt_ + (numFrags_ - 1) * durDataPkt_;
02293 #ifdef JOURNAL_PAPER
02294     sh->duration = numFrags_ * durCtrlPkt_ + (numFrags_ - 1) * durDataPkt_;
02295 #else
02296     sh->duration =  durCtrlPkt_;
02297 #endif  
02298     // send DATA
02299     if (chkRadio()) {
02300         transmit(dataPkt_);
02301         
02302         return 1;
02303 
02304     } else 
02305         return 0;
02306 
02307 }
02308 
02309 
02310 bool SMAC::sendACK(double duration) {
02311     // construct ACK pkt
02312     Packet *p = Packet::alloc();
02313     struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
02314     struct hdr_cmn *ch = HDR_CMN(p);
02315 
02316     ch->uid() = 0;
02317     ch->ptype() = PT_SMAC;
02318     ch->size() = SIZEOF_SMAC_CTRLPKT;
02319     ch->iface() = UNKN_IFACE.value();
02320     ch->direction() = hdr_cmn::DOWN;
02321     ch->error() = 0;    /* pkt not corrupt to start with */
02322   
02323     bzero(cf, MAC_HDR_LEN);
02324   
02325   cf->length = SIZEOF_SMAC_CTRLPKT;
02326   cf->type = ACK_PKT;
02327   
02328   cf->srcAddr = index_;
02329   cf->dstAddr = recvAddr_;
02330   
02331   // input duration is the duration field from recvd data pkt
02332   // stick to neighbNav -- should update it when rx data packet
02333   cf->duration = duration - durCtrlPkt_;
02334   //cf->duration = mhNeighNav_.timeToExpire() - durCtrlPkt_;
02335   
02336   // send ACK
02337   if (chkRadio()) {
02338     transmit(p);
02339     return 1;
02340   } else
02341     return 0;
02342 }
02343 
02344 bool SMAC::sendSYNC()
02345 {
02346   // construct and send SYNC pkt
02347   Packet *p = Packet::alloc();
02348   struct smac_sync_frame *cf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
02349   struct hdr_cmn *ch = HDR_CMN(p);
02350 
02351   ch->uid() = 0;
02352   ch->ptype() = PT_SMAC;
02353   ch->size() = SIZEOF_SMAC_SYNCPKT;
02354   ch->iface() = UNKN_IFACE.value();
02355   ch->direction() = hdr_cmn::DOWN;
02356   ch->error() = 0;  /* pkt not corrupt to start with */
02357   
02358   cf->length = SIZEOF_SMAC_SYNCPKT;
02359   cf->type = SYNC_PKT;
02360   
02361   cf->srcAddr = index_;
02362 #ifdef JOURNAL_PAPER
02363   cf->syncNode = schedTab_[0].syncNode;
02364   cf->state = schedState_;
02365 #else
02366  cf->syncNode = mySyncNode_;
02367 #endif
02368   // shld change SYNCPKTTIME to match with the configures durSyncPkt_
02369   cf->sleepTime = mhCounter_[0]->timeToSleep() - CLKTICK2SEC(SYNCPKTTIME);
02370   if (cf->sleepTime < 0)
02371     cf->sleepTime += CLKTICK2SEC(cycleTime_);
02372   
02373   // send SYNC
02374   if (chkRadio()) {
02375 //  if(index_==0)
02376 //  printf("%d Sent SYNC at %.6f\n", index_,Scheduler::instance().clock());
02377 
02378     transmit(p);
02379     //double t = Scheduler::instance().clock();
02380     //printf("Sent SYNC from %d.....at %.6f\n", cf->srcAddr, t);
02381     return 1;
02382     
02383   } else 
02384     return 0;
02385 }
02386 
02387 
02388 void SMAC::sentRTS(Packet *p)
02389 {
02390   // just sent RTS, set timer for CTS timeout
02391   mhGene_.sched(timeWaitCtrl_);
02392   Packet::free(p);
02393   
02394 }
02395 
02396 void SMAC::sentCTS(Packet *p)
02397 {
02398   // just sent CTS, track my neighbors' NAV
02399   // they update NAV and go to sleep after recv CTS
02400   // no data timeout, just use neighbors' NAV
02401   // since they went to sleep, just wait data for the entire time
02402 
02403   struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
02404   
02405   updateNeighNav(cf->duration);
02406   Packet::free(p);
02407 }
02408 
02409 void SMAC::sentDATA(Packet *p)
02410 {
02411   struct hdr_smac *mh = HDR_SMAC(p);
02412   
02413   if (howToSend_ == BCASTDATA) { // if data was brdcast
02414     state_ = IDLE;
02415 
02416     if (!syncFlag_) {
02417       txData_ = 0;
02418       dataPkt_ = 0;
02419       Packet::free(p);
02420     
02421       // signal upper layer
02422       txMsgDone(); 
02423     
02424     } else {
02425 #ifdef JOURNAL_PAPER
02426       schedTab_[dataSched_].txData = 0;
02427 #else
02428       schedTab_[currSched_].txData = 0;
02429 #endif
02430       numBcast_--;
02431       if (numBcast_ == 0) {
02432     dataPkt_ = 0;
02433     Packet::free(p);
02434 #ifdef JOURNAL_PAPER
02435         txRequest_ = 0;
02436 #endif  
02437     // signal upper layer
02438     txMsgDone(); 
02439       }
02440 #ifdef JOURNAL_PAPER
02441     //when broadcast data is done for one schedule, sender needs to sleep
02442         if( mhCounter_[0]->value_ == sleepTime_ )
02443              sleep();
02444 #endif
02445     }
02446     
02447   } else {
02448     
02449     // unicast is done; track my neighbors' NAV
02450     // they update NAV and go to sleep after recv first data fragment
02451 #ifdef JOURNAL_PAPER
02452     sendAddr = -1;
02453     txRequest_ = 0;
02454 #endif
02455     updateNeighNav(mh->duration);
02456       
02457     //waiting for ACK, set timer for ACK timeout
02458     mhGene_.sched(timeWaitCtrl_);
02459 
02460   }
02461 }
02462 
02463 void SMAC::sentACK(Packet *p)
02464 {
02465   struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
02466   
02467   updateNeighNav(cf->duration);
02468   Packet::free(p);
02469 }
02470 
02471 void SMAC::sentSYNC(Packet *p)
02472 {
02473 #ifdef JOURNAL_PAPER
02474   schedTab_[syncSched_].txSync = 0;
02475   schedTab_[syncSched_].numPeriods = SYNCPERIOD;
02476 #else
02477   schedTab_[currSched_].txSync = 0;
02478   schedTab_[currSched_].numPeriods = SYNCPERIOD;
02479 #endif
02480   Packet::free(p);
02481 
02482 }
02483 
02484 void SMAC::sleep() 
02485 {
02486   // go to sleep, turn off radio
02487   state_ = SLEEP;
02488   radioState_ = RADIO_SLP;
02489 #ifdef JOURNAL_PAPER
02490   //printf("SLEEP: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
02491 #endif
02492   // printf("SLEEP: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
02493 //printf("%d SMAC SLEEP: at %.6f\n", index_,Scheduler::instance().clock());
02494 
02495 
02496 // set node state
02497     Phy *p;
02498     p=netif_;           
02499     ((WirelessPhy *)p)->node_sleep();
02500 //  printf("\nnetif\n %d", ((WirelessPhy *)p)->testfun(34));
02501 //
02502 
02503 }
02504 
02505 void SMAC::wakeup()
02506 {
02507   //wakeup from sleep. turn on radio
02508   state_ = IDLE;
02509   
02510   // since radio can start to recv while in sleep
02511   // it might be in RX state
02512   // and eventually the pkt will not be recvd if in sleep state 
02513   // so careful not to change state of radio unless it is really sleeping
02514   if (radioState_ == RADIO_SLP)
02515     radioState_ = RADIO_IDLE;
02516 #ifdef JOURNAL_PAPER
02517   //printf("WAKEUP: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
02518 #endif
02519 //   printf("WAKEUP: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
02520 
02521     Phy *p;
02522     p=netif_;           
02523     ((WirelessPhy *)p)->node_wakeup();
02524 
02525 
02526 //printf("WAKEUP: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
02527 }
02528 
02529 void SMAC::updateNav(double d ) {
02530   double now = Scheduler::instance().clock();
02531   // already in sec
02532   // double d = duration * 1.0e-6; // convert to sec
02533 
02534   if ((now + d) > nav_) {
02535     nav_ = now + d;
02536     
02537     mhNav_.resched(d);
02538     
02539   }
02540 }
02541     
02542 
02543 void SMAC::updateNeighNav(double d ) {
02544   double now = Scheduler::instance().clock();
02545   //double d = duration * 1.0e-6; // convert to sec
02546 
02547   if ((now + d) > neighNav_) {
02548     neighNav_ = now + d;
02549 
02550     mhNeighNav_.resched(d);
02551   
02552   }
02553 }
02554 
02555 double SMAC::txtime(Packet *p)
02556 {
02557   struct hdr_smac *sh = HDR_SMAC(p);
02558 
02559   switch(sh->type) {
02560   
02561   case DATA_PKT:
02562     return durDataPkt_;
02563     
02564   case RTS_PKT:
02565   case CTS_PKT:
02566   case ACK_PKT:
02567     return durCtrlPkt_;
02568   case SYNC_PKT:
02569     return CLKTICK2SEC(SYNCPKTTIME);
02570   default:
02571     fprintf(stderr, "invalid smac pkt type %d\n", sh->type);
02572     exit(1);
02573   }
02574   
02575 }
02576 #ifdef JOURNAL_PAPER
02577 void SMAC::dump(){
02578         int i;
02579         for (i = 0; i < 5; i++) {
02580                                                                                                                                                             
02581         printf(" neighbor: %d schedule: %d state: %d active: %d \n", neighbList_[i].nodeId, neighbList_[i].schedId, neighbList_[i].state, neighbList_[i].active);
02582         }
02583                                                                                                                                                             
02584          for (i = 0; i < 4; i++) {
02585          printf(" schedule: %d numNodes: %d \n",schedTab_[i].syncNode, schedTab_[i].numNodes);
02586          }
02587 }
02588 #endif

Generated on Tue Mar 6 16:47:51 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6