00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
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
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
00164 void SmacCsTimer::checkToCancel() {
00165 if (status_ == TIMER_PENDING)
00166 cancel();
00167 }
00168
00169
00170
00171
00172
00173 void SmacCounterTimer::sched(double time) {
00174
00175
00176
00177
00178
00179
00180
00181 tts_ = time;
00182 stime_ = Scheduler::instance().clock();
00183
00184 if (time <= CLKTICK2SEC(cycleTime_) && time > CLKTICK2SEC(listenTime_)) {
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_)) {
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 {
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;
00240
00241
00242
00243 #ifdef JOURNAL_PAPER
00244 numFrags_ = 0;
00245 succFrags_ = 0;
00246 dataSched_ = 0;
00247 syncSched_ = 0;
00248
00249 globalSchedule_ = 0;
00250
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
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 byte_tx_time_ = 8.0 / BANDWIDTH;
00294 double start_symbol = byte_tx_time_ * 2.5;
00295 slotTime_ = CLOCKRES >= start_symbol ? CLOCKRES : start_symbol;
00296 slotTime_sec_ = slotTime_ / 1.0e3;
00297 difs_ = 10.0 * slotTime_;
00298 sifs_ = 5.0 * slotTime_;
00299 eifs_ = 50.0 * slotTime_;
00300 guardTime_ = 4.0 * slotTime_;
00301
00302
00303
00304
00305
00306
00307 durSyncPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_SYNCPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00308 durSyncPkt_ = CLKTICK2SEC(durSyncPkt_);
00309
00310
00311 durDataPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_DATAPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00312 durDataPkt_ = CLKTICK2SEC(durDataPkt_);
00313
00314
00315 durCtrlPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_CTRLPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00316 durCtrlPkt_ = CLKTICK2SEC(durCtrlPkt_);
00317
00318
00319
00320 double delay = 2 * PROC_DELAY + sifs_;
00321 timeWaitCtrl_ = CLKTICK2SEC(delay) + durCtrlPkt_;
00322
00323
00324 numSched_ = 0;
00325 numNeighb_ = 0;
00326 numSync_ = 1;
00327 schedListen_ = 1;
00328 searchNeighb_ = 1;
00329
00330 #ifdef JOURNAL_PAPER
00331 schedState_ = 1;
00332
00333
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
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;
00349 schedTab_[0].syncNode = index_;
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;
00359
00360
00361 tcl.evalf("Mac/SMAC set selfConfigFlag_");
00362 if (strcmp(tcl.result(), "0") != 0)
00363 selfConfigFlag_ = 1;
00364
00365
00366
00367 tcl.evalf("Mac/SMAC set dutyCycle_");
00368 if (strcmp(tcl.result(), "0") != 0){
00369 bind_bw("dutyCycle_", &dutyCycle_);
00370
00371
00372 }
00373 else {
00374
00375 }
00376
00377 if (!syncFlag_)
00378 txData_ = 0;
00379
00380 else {
00381
00382
00383 syncTime_ = difs_ + slotTime_ * SYNC_CW + SEC2CLKTICK(durSyncPkt_) + guardTime_;
00384 #ifdef JOURNAL_PAPER
00385
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
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
00407
00408
00409
00410
00411
00412
00413
00414 double c = CLKTICK2SEC(listenTime_) + CLKTICK2SEC(sleepTime_);
00415 double s = SYNCPERIOD + 1;
00416 double t = c * s ;
00417
00418
00419 if ( selfConfigFlag_ == 1) {
00420 #ifdef JOURNAL_PAPER
00421 adapTime_ = dataTime_;
00422 mhGene_.sched(t);
00423
00424
00425
00426 mhUpdateNeighb_.sched(SMAC_UPDATE_NEIGHB_PERIOD);
00427
00428 #else
00429 mhGene_.sched(t);
00430 #endif
00431 }
00432 }
00433 }
00434
00435 void SMAC::setMySched(Packet *pkt)
00436 {
00437
00438 state_ = IDLE;
00439 numSched_ = 1;
00440 schedTab_[0].numPeriods = 0;
00441 schedTab_[0].txData = 0;
00442 schedTab_[0].txSync = 1;
00443
00444 if (pkt == 0) {
00445 #ifdef JOURNAL_PAPER
00446
00447
00448
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_;
00456 currSched_ = 0;
00457
00458
00459 } else {
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
00467
00468
00469 schedTab_[0].numNodes++;
00470 schedTab_[0].syncNode = pf->syncNode;
00471 schedState_++;
00472
00473
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
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
00505 state_ = IDLE;
00506 numSched_ = 1;
00507 schedTab_[0].numPeriods = SYNCPERIOD;
00508 schedTab_[0].txData = 0;
00509 schedTab_[0].txSync = 1;
00510
00511
00512
00513
00514 startTime_ = startTime_ + listenTime_;
00515 if ( startTime_ >= cycleTime_ )
00516 startTime_ = startTime_ - cycleTime_;
00517
00518 mhCounter_[0]->sched(CLKTICK2SEC(startTime_));
00519 mySyncNode_ = index_;
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
00538
00539
00540
00541
00542 mhAdap_.resched(CLKTICK2SEC(adapTime_));
00543 adaptiveListen_ = 1;
00544 if (state_ == SLEEP) {
00545
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
00559
00560 void SMAC::handleSendTimer() {
00561 assert(pktTx_);
00562
00563 struct hdr_smac *sh = HDR_SMAC(pktTx_);
00564
00565
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
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();
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
00627
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();
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
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
00697 if (numSched_ == 0) {
00698 setMySched(0);
00699 return;
00700 }
00701 }
00702 if (state_ == WAIT_CTS) {
00703 if (numRetry_ < SMAC_RETRY_LIMIT) {
00704 numRetry_++;
00705
00706 state_ = IDLE;
00707 #ifdef JOURNAL_PAPER
00708
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
00722
00723
00724 txMsgDone();
00725
00726 }
00727
00728 } else if (state_ == WAIT_ACK) {
00729
00730 if (numExtend_ < SMAC_EXTEND_LIMIT) {
00731 printf("SMAC %d: no ACK received. Extend Tx time.\n", index_);
00732 numExtend_++;
00733
00734 updateNeighNav(durDataPkt_ + durCtrlPkt_);
00735
00736
00737 } else {
00738
00739
00740 }
00741 if (neighNav_ < (durDataPkt_ + durCtrlPkt_)) {
00742
00743
00744
00745 discard(dataPkt_, DROP_MAC_RETRY_COUNT_EXCEEDED);
00746 dataPkt_ = 0;
00747 pktTx_ = 0;
00748 state_ = IDLE;
00749
00750
00751
00752
00753 txMsgDone();
00754
00755 } else {
00756
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
00768 if( mhCounter_[0]->value_ == sleepTime_ )
00769 sleep();
00770 #endif
00771 }
00772 }
00773
00774
00775 void SMAC::handleNavTimer() {
00776
00777 nav_ = 0;
00778
00779 if (!syncFlag_) {
00780 if (state_ == SLEEP)
00781 wakeup();
00782
00783
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;
00803
00804 if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00805 goto done;
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
00822 #endif
00823
00824
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
00846 neighNav_ = 0;
00847
00848 if (state_ == WAIT_DATA) {
00849 state_ = IDLE;
00850
00851
00852
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
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
00892 #ifdef JOURNAL_PAPER
00893 if (schedTab_[id].numNodes > 0) {
00894 #endif
00895
00896 if (mhCounter_[id]->value_ == sleepTime_) {
00897
00898
00899 if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00900 goto sched_1;
00901
00902 if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00903 goto sched_1;;
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
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
00927 sched_1:
00928 mhCounter_[id]->sched(CLKTICK2SEC(listenTime_));
00929
00930 } else if (mhCounter_[id]->value_ == syncTime_) {
00931
00932
00933 if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00934 goto sched_2;
00935
00936 if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00937 goto sched_2;
00938
00939 if (schedTab_[id].txData == 1 &&
00940 (!(mhNav_.busy()) && !(mhNeighNav_.busy())) &&
00941 (state_ == SLEEP || state_ == IDLE)) {
00942
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
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_) {
00966
00967
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
00979 mhCounter_[id]->sched(CLKTICK2SEC(cycleTime_));
00980
00981
00982 if (schedTab_[id].numPeriods > 0) {
00983 schedTab_[id].numPeriods--;
00984 if (schedTab_[id].numPeriods == 0) {
00985
00986 schedTab_[id].txSync = 1;
00987
00988
00989 if ( id == 0 ) {
00990 numSync_--;
00991
00992
00993 if ( numSync_ == 1 ) {
00994 searchNeighb_ = 1;
00995
00996 }
00997 else if ( numSync_ == 0 ) {
00998 searchNeighb_ = 0;
00999
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
01021 if (txRequest_ == 0) {
01022 txRequest_ = 1;
01023 update_myNeighbList();
01024 } else {
01025 updateNeighbList_ = 1;
01026 }
01027 }
01028
01029 void SMAC::handleAdaptiveListenTimer() {
01030
01031 adaptiveListen_ = 0;
01032 if (state_ == IDLE && state_ != TX_PKT && mhCounter_[0]->value_ == sleepTime_)
01033 sleep();
01034 }
01035 #endif
01036
01037
01038
01039 void SMAC::recv(Packet *p, Handler *h) {
01040
01041 struct hdr_cmn *ch = HDR_CMN(p);
01042
01043 assert(initialized());
01044
01045
01046 if ( ch->direction() == hdr_cmn::DOWN) {
01047 sendMsg(p, h);
01048 return;
01049 }
01050
01051
01052
01053
01054
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
01065 if (state_ == CR_SENSE) {
01066 printf("Cancelling CS- node %d\n", index_);
01067
01068
01069 mhCS_.checkToCancel();
01070 }
01071
01072
01073 if (radioState_ == RADIO_RX) {
01074 assert(pktRx_);
01075 assert(mhRecv_.busy());
01076
01077
01078
01079
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()) {
01089 assert(radioState_ == RADIO_SLP);
01090
01091
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
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
01114
01115
01116 if (txtime(p) > mhRecv_.timeToExpire()) {
01117 mhRecv_.resched(txtime(p));
01118 discard(pktRx_, DROP_MAC_COLLISION);
01119
01120 pktRx_ = p;
01121
01122 }
01123 else
01124 discard(p, DROP_MAC_COLLISION);
01125
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
01135
01136 if(ch->error() != 0) {
01137 Packet::free(p);
01138
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
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
01219
01220
01221
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) {
01227
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
01234 schedTab_[i].numNodes = 0;
01235 numSched_--;
01236 schedId = i;
01237 break;
01238 }
01239 }
01240 if (schedId > 0){
01241 schedState_++;
01242
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
01252 void SMAC::update_schedTab_neighbList()
01253 {
01254
01255
01256
01257 check_schedFlag();
01258 if (updateNeighbList_ == 1) {
01259 update_neighbList();
01260 updateNeighbList_ = 0;
01261 schedTab_[0].chkSched = 0;
01262 } else if (schedTab_[0].chkSched == 1) {
01263 checkMySched();
01264 schedTab_[0].chkSched = 0;
01265 }
01266 }
01267
01268
01269 void SMAC::update_myNeighbList()
01270 {
01271
01272
01273 check_schedFlag();
01274 update_neighbList();
01275 updateNeighbList_ = 0;
01276 schedTab_[0].chkSched = 0;
01277 txRequest_ = 0;
01278 }
01279
01280 void SMAC::update_neighbList()
01281 {
01282
01283
01284
01285
01286
01287 int i, schedId;
01288
01289 for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
01290 if (neighbList_[i].state > 0 ){
01291 if (neighbList_[i].active != 1){
01292
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
01301 neighbList_[i].active = 0;
01302 }
01303 }
01304
01305
01306
01307
01308
01309 checkMySched();
01310 mhUpdateNeighb_.resched(SMAC_UPDATE_NEIGHB_PERIOD);
01311 }
01312
01313 void SMAC::check_schedFlag()
01314 {
01315 int i;
01316
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
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;
01336 #ifdef JOURNAL_PAPER
01337 updateNeighNav(cf->duration);
01338 #endif
01339 if(sendCTS(cf->duration)) {
01340 state_ = WAIT_DATA;
01341 lastRxFrag_ = -3;
01342 }
01343 }
01344 } else {
01345
01346
01347
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
01363 struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01364 if(cf->dstAddr == index_) {
01365 if(state_ == WAIT_CTS && cf->srcAddr == sendAddr_) {
01366
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 {
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
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) {
01399 state_ = IDLE;
01400
01401 rxMsgDone(p);
01402
01403 } else if (sh->dstAddr == index_) {
01404 if(state_ == WAIT_DATA && sh->srcAddr == recvAddr_) {
01405
01406 updateNeighNav(sh->duration);
01407 sendACK(sh->duration);
01408 #ifdef JOURNAL_PAPER
01409 if (sh->duration > durCtrlPkt_) {
01410 rxFragDone(p);
01411 state_ = WAIT_DATA;
01412 } else {
01413 state_ = IDLE;
01414 rxMsgDone(p);
01415 }
01416
01417 #else
01418
01419
01420
01421
01422
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
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 {
01452
01453
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 {
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
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
01481 mhGene_.cancel();
01482 #ifdef JOURNAL_PAPER
01483 numFrags_--;
01484 succFrags_++;
01485 if (numFrags_ > 0) {
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
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 state_ = IDLE;
01511 txMsgDone();
01512
01513 #endif
01514 }
01515
01516 } else {
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
01536 }
01537 if (numSched_ == 0) {
01538 mhGene_.cancel();
01539 setMySched(p);
01540 return;
01541 }
01542 if (numNeighb_ == 0 && globalSchedule_ == 1) {
01543
01544 if (schedTab_[0].syncNode > sf->syncNode || !sendSYNCFlag_ ) {
01545 setMySched(p);
01546 return;
01547 }
01548 }
01549 else if (numNeighb_ == 0) {
01550
01551 setMySched(p);
01552
01553 return;
01554 }
01555 state_ = IDLE;
01556
01557
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;
01564 break;
01565 }
01566 }
01567 if (nodeId < SMAC_MAX_NUM_NEIGHBORS) {
01568 if (neighbList_[nodeId].state == sf->state) {
01569
01570 mhCounter_[schedId]->sched(sf->sleepTime);
01571
01572 neighbList_[nodeId].active = 1;
01573 if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
01574
01575 schedState_++;
01576
01577
01578
01579
01580 tempSched.syncNode = schedTab_[schedId].syncNode;
01581 tempSched.txSync = schedTab_[schedId].txSync;
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;
01593 schedTab_[schedId].txData = schedTab_[0].txData;
01594 schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
01595 schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1;
01596 schedTab_[schedId].chkSched = schedTab_[0].chkSched;
01597
01598
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;
01605 schedTab_[0].chkSched = tempSched.chkSched;
01606
01607
01608 for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
01609 if (neighbList_[j].schedId == 0) {
01610 neighbList_[j].schedId = schedId;
01611 }
01612 else if (neighbList_[j].schedId == schedId) {
01613 neighbList_[j].schedId = 0;
01614 }
01615 }
01616 }
01617 return;
01618 } else {
01619
01620
01621
01622 if (schedTab_[schedId].numNodes ==1 && txRequest_ == 1) {
01623
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
01638
01639
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++;
01651 schedId = i;
01652 break;
01653 }
01654 }
01655 }
01656
01657 if (schedId == SMAC_MAX_NUM_SCHEDULES) {
01658 flag =1;
01659
01660 if (numSched_ < SMAC_MAX_NUM_SCHEDULES){
01661 for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
01662 if (schedTab_[i].numNodes == 0) {
01663
01664 if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
01665
01666 schedState_++;
01667
01668
01669
01670
01671 if (schedTab_[0].numNodes >= 2) {
01672 mhCounter_[i]->sched(mhCounter_[0]->timeToSleep());
01673 schedTab_[i].syncNode = schedTab_[0].syncNode;
01674 schedTab_[i].txSync = schedTab_[0].txSync;
01675 schedTab_[i].txData = schedTab_[0].txData;
01676 schedTab_[i].numPeriods = schedTab_[0].numPeriods;
01677 schedTab_[i].numNodes = schedTab_[0].numNodes - 1;
01678 schedTab_[i].chkSched = schedTab_[0].chkSched;
01679 numSched_++;
01680
01681 for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
01682 if (neighbList_[j].schedId == 0) {
01683 neighbList_[j].schedId = i;
01684 }
01685 }
01686 }
01687
01688 mhCounter_[0]->sched(sf->sleepTime);
01689 schedTab_[0].syncNode = sf->syncNode;
01690 schedTab_[0].txSync = 1;
01691 schedTab_[0].txData = 0;
01692 schedTab_[0].numPeriods = 0;
01693 schedTab_[0].numNodes = 2;
01694 schedTab_[0].chkSched = 0;
01695
01696 schedId = 0;
01697 }
01698 else {
01699
01700 mhCounter_[i]->sched(sf->sleepTime);
01701 schedTab_[i].syncNode = sf->syncNode;
01702 schedTab_[i].txSync = 1;
01703 schedTab_[i].txData = 0;
01704 schedTab_[i].numPeriods = 0;
01705 schedTab_[i].numNodes = 1;
01706 schedTab_[i].chkSched = 0;
01707 schedId = i;
01708 numSched_++;
01709 }
01710 break;
01711 }
01712 }
01713 }
01714 }
01715
01716 if (nodeId == SMAC_MAX_NUM_NEIGHBORS) {
01717
01718 if (schedId == SMAC_MAX_NUM_SCHEDULES) return;
01719
01720 if (numNeighb_ < SMAC_MAX_NUM_NEIGHBORS){
01721 for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
01722 if (neighbList_[i].state == 0) {
01723 neighbList_[i].state = sf->state;
01724 neighbList_[i].nodeId = sf->srcAddr;
01725 neighbList_[i].schedId = schedId;
01726 neighbList_[i].active = 1;
01727 numNeighb_++;
01728 return;
01729 }
01730 }
01731 }
01732
01733 schedTab_[schedId].numNodes--;
01734 if (schedTab_[schedId].numNodes == 0)
01735 numSched_--;
01736 } else if (flag == 1) {
01737
01738 if (schedId == SMAC_MAX_NUM_SCHEDULES) {
01739 neighbList_[nodeId].state = 0;
01740 numNeighb_--;
01741 } else {
01742 neighbList_[nodeId].state = sf->state;
01743 neighbList_[nodeId].schedId = schedId;
01744 neighbList_[nodeId].active = 1;
01745 }
01746
01747
01748
01749
01750 if (txRequest_ == 0) {
01751 checkMySched();
01752 } else {
01753
01754 schedTab_[0].chkSched = 1;
01755 }
01756 } else {
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
01762
01763
01764
01765
01766 schedState_++;
01767 tempSched.syncNode = schedTab_[schedId].syncNode;
01768 tempSched.txSync = schedTab_[schedId].txSync;
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;
01780 schedTab_[schedId].txData = schedTab_[0].txData;
01781 schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
01782 schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1;
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;
01793 schedTab_[0].chkSched = tempSched.chkSched;
01794
01795
01796 for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
01797 if (neighbList_[j].schedId == 0) {
01798 neighbList_[j].schedId = schedId;
01799 }
01800 else if (neighbList_[j].schedId == schedId) {
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
01815 if ( selfConfigFlag_ == 1) {
01816 if(numSched_ == 0) {
01817 mhGene_.cancel();
01818
01819
01820
01821 setMySched(p);
01822 return;
01823 }
01824 if (numNeighb_ == 0) {
01825
01826
01827
01828
01829 setMySched(p);
01830 return;
01831 }
01832 }
01833 state_ = IDLE;
01834
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
01840
01841
01842 for(i = 0; i < numNeighb_; i++) {
01843 if (neighbList_[i].nodeId == sf->srcAddr) {
01844 foundNeighb = 1;
01845 schedId = neighbList_[i].schedId;
01846 mhCounter_[schedId]->sched(sf->sleepTime);
01847 break;
01848 }
01849 if (neighbList_[i].nodeId == sf->syncNode)
01850
01851 schedId = neighbList_[i].schedId;
01852 }
01853 if (!foundNeighb) {
01854 neighbList_[numNeighb_].nodeId = sf->srcAddr;
01855 if (schedId < SMAC_MAX_NUM_SCHEDULES) {
01856
01857 neighbList_[numNeighb_].schedId = schedId;
01858 } else if (sf->syncNode == index_) {
01859 neighbList_[numNeighb_].schedId = 0;
01860 } else {
01861
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) {
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_++;
01882 }
01883 }
01884
01885 #endif
01886 void SMAC::rxMsgDone(Packet *p) {
01887
01888
01889
01890
01891 if (p)
01892 uptarget_->recv(p, (Handler*)0);
01893
01894 if (!syncFlag_)
01895
01896 checkToSend();
01897 #ifdef JOURNAL_PAPER
01898
01899
01900 else {
01901
01902
01903 }
01904 #endif
01905 }
01906
01907 #ifdef JOURNAL_PAPER
01908 void SMAC::rxFragDone(Packet *p) {
01909
01910 }
01911 #endif
01912
01913
01914
01915
01916
01917
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
01929 downtarget_->recv(p->copy(), this);
01930
01931 mhSend_.sched(txtime(p));
01932
01933 }
01934
01935 bool SMAC::chkRadio() {
01936
01937 if (radioState_ == RADIO_IDLE || radioState_ == RADIO_SLP)
01938 return (1);
01939
01940 return (0);
01941 }
01942
01943
01944 int SMAC::startBcast()
01945 {
01946
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
01965 hdr_smac *mh = HDR_SMAC(dataPkt_);
01966
01967 sendAddr_ = mh->dstAddr;
01968 numRetry_ = 0;
01969
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
01987 update_schedTab_neighbList();
01988 txRequest_ = 0;
01989 #endif
01990 if (!syncFlag_) {
01991 #ifdef JOURNAL_PAPER
01992 txData_ = 0;
01993 #endif
01994
01995 if(checkToSend())
01996 return;
01997 else if (callback_) {
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_) {
02008 Handler *h = callback_;
02009 callback_ = 0;
02010 h->handle((Event*) 0);
02011 }
02012 #ifdef JOURNAL_PAPER
02013
02014 if( mhCounter_[0]->value_ == sleepTime_ )
02015 sleep();
02016 #endif
02017 }
02018
02019 }
02020
02021
02022
02023
02024
02025
02026
02027 #ifdef JOURNAL_PAPER
02028 void SMAC::txFragDone()
02029 {
02030
02031 txNextFrag(&dataPkt_);
02032 }
02033
02034 bool SMAC::txNextFrag(void* data)
02035 {
02036
02037
02038 if (state_ != TX_NEXT_FRAG || data == 0) return 0;
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048 if(sendDATA()) {
02049 state_ = WAIT_ACK;
02050 if (!syncFlag_)
02051 txData_ = 0;
02052 else
02053 schedTab_[dataSched_].txData = 0;
02054
02055 }
02056
02057
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
02073
02074 int fragNum = ch->size_ / SIZEOF_SMAC_DATAPKT ;
02075 if (fragNum == 0) fragNum = 1;
02076
02077 return unicastMsg(fragNum, pkt);
02078 #else
02079 return (unicastMsg(1, pkt));
02080 #endif
02081
02082
02083 }
02084 }
02085
02086
02087 bool SMAC::bcastMsg(Packet *p) {
02088
02089
02090 assert(p);
02091
02092
02093
02094
02095
02096
02097
02098
02099 struct hdr_smac *sh = HDR_SMAC(p);
02100
02101 sh->type = DATA_PKT;
02102 sh->length = SIZEOF_SMAC_DATAPKT;
02103
02104
02105 dataPkt_ = p;
02106 #ifdef JOURNAL_PAPER
02107
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
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
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
02143
02144
02145 assert(p);
02146
02147
02148
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
02156 struct hdr_smac *sh = HDR_SMAC(p);
02157
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;
02175 }
02176 }
02177 #ifdef JOURNAL_PAPER
02178
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
02192 dataPkt_ = p;
02193
02194 if (!syncFlag_) {
02195 txData_ = 1;
02196
02197
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
02211
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;
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_;
02230 cf->dstAddr = sendAddr_;
02231
02232
02233
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
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
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;
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
02275 cf->duration = duration - durCtrlPkt_ ;
02276 cf->crc = 0;
02277
02278 if (chkRadio()) {
02279 transmit(p);
02280 return 1;
02281
02282 } else
02283 return 0;
02284 }
02285
02286
02287 bool SMAC::sendDATA() {
02288
02289
02290 struct hdr_smac * sh = HDR_SMAC(dataPkt_);
02291
02292
02293 #ifdef JOURNAL_PAPER
02294 sh->duration = numFrags_ * durCtrlPkt_ + (numFrags_ - 1) * durDataPkt_;
02295 #else
02296 sh->duration = durCtrlPkt_;
02297 #endif
02298
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
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;
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
02332
02333 cf->duration = duration - durCtrlPkt_;
02334
02335
02336
02337 if (chkRadio()) {
02338 transmit(p);
02339 return 1;
02340 } else
02341 return 0;
02342 }
02343
02344 bool SMAC::sendSYNC()
02345 {
02346
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;
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
02369 cf->sleepTime = mhCounter_[0]->timeToSleep() - CLKTICK2SEC(SYNCPKTTIME);
02370 if (cf->sleepTime < 0)
02371 cf->sleepTime += CLKTICK2SEC(cycleTime_);
02372
02373
02374 if (chkRadio()) {
02375
02376
02377
02378 transmit(p);
02379
02380
02381 return 1;
02382
02383 } else
02384 return 0;
02385 }
02386
02387
02388 void SMAC::sentRTS(Packet *p)
02389 {
02390
02391 mhGene_.sched(timeWaitCtrl_);
02392 Packet::free(p);
02393
02394 }
02395
02396 void SMAC::sentCTS(Packet *p)
02397 {
02398
02399
02400
02401
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) {
02414 state_ = IDLE;
02415
02416 if (!syncFlag_) {
02417 txData_ = 0;
02418 dataPkt_ = 0;
02419 Packet::free(p);
02420
02421
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
02438 txMsgDone();
02439 }
02440 #ifdef JOURNAL_PAPER
02441
02442 if( mhCounter_[0]->value_ == sleepTime_ )
02443 sleep();
02444 #endif
02445 }
02446
02447 } else {
02448
02449
02450
02451 #ifdef JOURNAL_PAPER
02452 sendAddr = -1;
02453 txRequest_ = 0;
02454 #endif
02455 updateNeighNav(mh->duration);
02456
02457
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
02487 state_ = SLEEP;
02488 radioState_ = RADIO_SLP;
02489 #ifdef JOURNAL_PAPER
02490
02491 #endif
02492
02493
02494
02495
02496
02497 Phy *p;
02498 p=netif_;
02499 ((WirelessPhy *)p)->node_sleep();
02500
02501
02502
02503 }
02504
02505 void SMAC::wakeup()
02506 {
02507
02508 state_ = IDLE;
02509
02510
02511
02512
02513
02514 if (radioState_ == RADIO_SLP)
02515 radioState_ = RADIO_IDLE;
02516 #ifdef JOURNAL_PAPER
02517
02518 #endif
02519
02520
02521 Phy *p;
02522 p=netif_;
02523 ((WirelessPhy *)p)->node_wakeup();
02524
02525
02526
02527 }
02528
02529 void SMAC::updateNav(double d ) {
02530 double now = Scheduler::instance().clock();
02531
02532
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
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