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 #include "smac.h"
00052
00053 static class MacSmacClass : public TclClass {
00054 public:
00055 MacSmacClass() : TclClass("Mac/SMAC") {}
00056 TclObject* create(int, const char*const*) {
00057 return (new SMAC());
00058 }
00059 } class_macSMAC;
00060
00061
00062
00063
00064 int SmacTimer::busy()
00065 {
00066 if (status_ != TIMER_PENDING)
00067 return 0;
00068 else
00069 return 1;
00070 }
00071
00072 void SmacGeneTimer::expire(Event *e) {
00073 a_->handleGeneTimer();
00074 }
00075
00076 void SmacRecvTimer::expire(Event *e) {
00077 stime_ = rtime_ = 0;
00078 a_->handleRecvTimer();
00079 }
00080
00081 void SmacRecvTimer::sched(double time) {
00082 TimerHandler::sched(time);
00083 stime_ = Scheduler::instance().clock();
00084 rtime_ = time;
00085 }
00086
00087 double SmacRecvTimer::timeToExpire() {
00088 return ((stime_ + rtime_) - Scheduler::instance().clock());
00089 }
00090
00091 void SmacSendTimer::expire(Event *e) {
00092 a_->handleSendTimer();
00093 }
00094
00095 void SmacNavTimer::expire(Event *e) {
00096 a_->handleNavTimer();
00097 }
00098
00099 void SmacNeighNavTimer::sched(double time) {
00100 TimerHandler::sched(time);
00101 stime_ = Scheduler::instance().clock();
00102 rtime_ = time;
00103 }
00104
00105 void SmacNeighNavTimer::expire(Event *e) {
00106 stime_ = rtime_ = 0;
00107 a_->handleNeighNavTimer();
00108 }
00109
00110 double SmacNeighNavTimer::timeToExpire() {
00111 return ((stime_ + rtime_) - Scheduler::instance().clock());
00112 }
00113
00114 void SmacCsTimer::expire(Event *e) {
00115 a_->handleCsTimer();
00116 }
00117
00118
00119 void SmacCsTimer::checkToCancel() {
00120 if (status_ == TIMER_PENDING)
00121 cancel();
00122 }
00123
00124
00125
00126
00127
00128 void SmacCounterTimer::sched(double time) {
00129
00130
00131
00132
00133
00134
00135
00136 tts_ = time;
00137 stime_ = Scheduler::instance().clock();
00138
00139 if (time <= CLKTICK2SEC(cycleTime_) && time > CLKTICK2SEC(listenTime_)) {
00140 value_ = sleepTime_;
00141 if (status_ == TIMER_IDLE)
00142 TimerHandler::sched(time - CLKTICK2SEC(listenTime_));
00143 else
00144 TimerHandler::resched(time - CLKTICK2SEC(listenTime_));
00145
00146 } else if ( time <= CLKTICK2SEC(listenTime_) && time > CLKTICK2SEC(dataTime_)) {
00147 value_ = syncTime_;
00148 if (status_ == TIMER_IDLE)
00149 TimerHandler::sched(time - CLKTICK2SEC(dataTime_));
00150 else
00151 TimerHandler::resched(time - CLKTICK2SEC(dataTime_));
00152
00153 } else {
00154 assert(time <= CLKTICK2SEC(dataTime_));
00155 value_ = dataTime_;
00156 if (status_ == TIMER_IDLE)
00157 TimerHandler::sched(time);
00158 else
00159 TimerHandler::resched(time);
00160
00161 }
00162
00163 }
00164
00165 double SmacCounterTimer::timeToSleep() {
00166 return ((stime_ + tts_) - Scheduler::instance().clock()) ;
00167 }
00168
00169 void SmacCounterTimer::expire(Event *e) {
00170 tts_ = stime_ = 0;
00171 a_->handleCounterTimer(index_);
00172 }
00173
00174
00175
00176 SMAC::SMAC() : Mac(), mhNav_(this), mhNeighNav_(this), mhSend_(this), mhRecv_(this), mhGene_(this), mhCS_(this), syncFlag_(0) {
00177
00178 state_ = IDLE;
00179 radioState_ = RADIO_IDLE;
00180 tx_active_ = 0;
00181 mac_collision_ = 0;
00182
00183 sendAddr_ = -1;
00184 recvAddr_ = -1;
00185
00186 nav_ = 0;
00187 neighNav_ = 0;
00188
00189 numRetry_ = 0;
00190 numExtend_ = 0;
00191 lastRxFrag_ = -3;
00192
00193
00194
00195 dataPkt_ = 0;
00196 pktRx_ = 0;
00197 pktTx_ = 0;
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 byte_tx_time_ = 8.0 / BANDWIDTH;
00226 double start_symbol = byte_tx_time_ * 2.5;
00227 slotTime_ = CLOCKRES >= start_symbol ? CLOCKRES : start_symbol;
00228 slotTime_sec_ = slotTime_ / 1.0e3;
00229 difs_ = 10.0 * slotTime_;
00230 sifs_ = 5.0 * slotTime_;
00231 eifs_ = 50.0 * slotTime_;
00232 guardTime_ = 4.0 * slotTime_;
00233
00234
00235
00236
00237
00238
00239 durSyncPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_SYNCPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00240 durSyncPkt_ = CLKTICK2SEC(durSyncPkt_);
00241
00242
00243 durDataPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_DATAPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00244 durDataPkt_ = CLKTICK2SEC(durDataPkt_);
00245
00246
00247 durCtrlPkt_ = (PRE_PKT_BYTES + (SIZEOF_SMAC_CTRLPKT * ENCODE_RATIO)) * byte_tx_time_ + 1;
00248 durCtrlPkt_ = CLKTICK2SEC(durCtrlPkt_);
00249
00250
00251
00252 double delay = 2 * PROC_DELAY + sifs_;
00253 timeWaitCtrl_ = CLKTICK2SEC(delay) + durCtrlPkt_;
00254
00255
00256 numSched_ = 0;
00257 numNeighb_ = 0;
00258
00259 Tcl& tcl = Tcl::instance();
00260 tcl.evalf("Mac/SMAC set syncFlag_");
00261 if (strcmp(tcl.result(), "0") != 0)
00262 syncFlag_ = 1;
00263
00264 if (!syncFlag_)
00265 txData_ = 0;
00266
00267 else {
00268
00269
00270
00271 syncTime_ = difs_ + slotTime_ * SYNC_CW + SEC2CLKTICK(durSyncPkt_) + guardTime_;
00272 dataTime_ = difs_ + slotTime_ * DATA_CW + SEC2CLKTICK(durCtrlPkt_) + guardTime_;
00273 listenTime_ = syncTime_ + dataTime_;
00274 cycleTime_ = listenTime_ * 100 / SMAC_DUTY_CYCLE + 1;
00275 sleepTime_ = cycleTime_ - listenTime_;
00276
00277
00278
00279
00280 for (int i=0; i< SMAC_MAX_NUM_SCHEDULES; i++) {
00281 mhCounter_[i] = new SmacCounterTimer(this, i);
00282 mhCounter_[i]->syncTime_ = syncTime_;
00283 mhCounter_[i]->dataTime_ = dataTime_;
00284 mhCounter_[i]->listenTime_ = listenTime_;
00285 mhCounter_[i]->sleepTime_ = sleepTime_;
00286 mhCounter_[i]->cycleTime_ = cycleTime_;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 double c = CLKTICK2SEC(listenTime_) + CLKTICK2SEC(sleepTime_);
00298 double s = SYNCPERIOD + 1;
00299 double t = c * s ;
00300
00301 mhGene_.sched(t);
00302 }
00303 }
00304
00305 void SMAC::setMySched(Packet *pkt)
00306 {
00307
00308 state_ = IDLE;
00309 numSched_ = 1;
00310 schedTab_[0].numPeriods = 0;
00311 schedTab_[0].txData = 0;
00312 schedTab_[0].txSync = 1;
00313
00314 if (pkt == 0) {
00315
00316 mhCounter_[0]->sched(CLKTICK2SEC(listenTime_));
00317 mySyncNode_ = index_;
00318
00319 currSched_ = 0;
00320
00321
00322 } else {
00323
00324 struct smac_sync_frame *pf = (struct smac_sync_frame *)pkt->access(hdr_mac::offset_);
00325
00326 mhCounter_[0]->sched(pf->sleepTime);
00327
00328 mySyncNode_ = pf->srcAddr;
00329
00330
00331 neighbList_[0].nodeId = mySyncNode_;
00332 neighbList_[0].schedId = 0;
00333 numNeighb_ = 1;
00334 }
00335 }
00336
00337
00338
00339 int SMAC::command(int argc, const char*const* argv)
00340 {
00341 if (argc == 3) {
00342 if (strcmp(argv[1], "log-target") == 0) {
00343 logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
00344 if(logtarget_ == 0)
00345 return TCL_ERROR;
00346 return TCL_OK;
00347 }
00348 }
00349
00350 return Mac::command(argc, argv);
00351
00352 }
00353
00354
00355
00356
00357 void SMAC::handleSendTimer() {
00358 assert(pktTx_);
00359
00360 struct hdr_smac *sh = HDR_SMAC(pktTx_);
00361
00362
00363 radioState_ = RADIO_IDLE;
00364 tx_active_ = 0;
00365
00366 switch(sh->type) {
00367
00368 case RTS_PKT:
00369 sentRTS(pktTx_);
00370 break;
00371
00372 case CTS_PKT:
00373 sentCTS(pktTx_);
00374 break;
00375
00376 case DATA_PKT:
00377 sentDATA(pktTx_);
00378 break;
00379
00380 case ACK_PKT:
00381 sentACK(pktTx_);
00382 break;
00383 case SYNC_PKT:
00384 sentSYNC(pktTx_);
00385 break;
00386 default:
00387 fprintf(stderr, "unknown mac pkt type, %d\n", sh->type);
00388 break;
00389 }
00390
00391 pktTx_ = 0;
00392 }
00393
00394
00395 void SMAC::handleRecvTimer() {
00396 assert(pktRx_);
00397
00398 struct hdr_cmn *ch = HDR_CMN(pktRx_);
00399 struct hdr_smac *sh = HDR_SMAC(pktRx_);
00400
00401 if (state_ == SLEEP) {
00402 discard(pktRx_, DROP_MAC_SLEEP);
00403 radioState_ = RADIO_SLP;
00404 goto done;
00405 }
00406
00407
00408
00409
00410 if (radioState_ == RADIO_TX) {
00411 Packet::free(pktRx_);
00412 goto done;
00413 }
00414
00415 if (mac_collision_) {
00416 discard(pktRx_, DROP_MAC_COLLISION);
00417 mac_collision_ = 0;
00418 updateNav(CLKTICK2SEC(eifs_));
00419
00420 if (state_ == CR_SENSE)
00421 sleep();
00422 else
00423 radioState_ = RADIO_IDLE;
00424
00425 goto done;
00426 }
00427
00428 if (ch->error()) {
00429 Packet::free(pktRx_);
00430 updateNav(CLKTICK2SEC(eifs_));
00431
00432 if (state_ == CR_SENSE)
00433 sleep();
00434 else
00435 radioState_ = RADIO_IDLE;
00436
00437 goto done;
00438 }
00439
00440
00441 radioState_ = RADIO_IDLE;
00442
00443 switch (sh->type) {
00444 case DATA_PKT:
00445 handleDATA(pktRx_);
00446 break;
00447 case RTS_PKT:
00448 handleRTS(pktRx_);
00449 break;
00450 case CTS_PKT:
00451 handleCTS(pktRx_);
00452 break;
00453 case ACK_PKT:
00454 handleACK(pktRx_);
00455 break;
00456 case SYNC_PKT:
00457 handleSYNC(pktRx_);
00458 break;
00459 default:
00460 fprintf(stderr, "Unknown smac pkt type, %d\n", sh->type);
00461 break;
00462 }
00463
00464 done:
00465 pktRx_ = 0;
00466
00467 }
00468
00469 void SMAC::handleGeneTimer()
00470 {
00471
00472 if (syncFlag_) {
00473
00474 if (numSched_ == 0) {
00475 setMySched(0);
00476 return;
00477 }
00478 }
00479 if (state_ == WAIT_CTS) {
00480 if (numRetry_ < SMAC_RETRY_LIMIT) {
00481 numRetry_++;
00482
00483 state_ = IDLE;
00484
00485 if (!syncFlag_)
00486 checkToSend();
00487
00488 } else {
00489 state_ = IDLE;
00490 dataPkt_ = 0;
00491 numRetry_ = 0;
00492
00493
00494
00495 txMsgDone();
00496
00497 }
00498
00499 } else if (state_ == WAIT_ACK) {
00500
00501 if (numExtend_ < SMAC_EXTEND_LIMIT) {
00502 printf("SMAC %d: no ACK received. Extend Tx time.\n", index_);
00503 numExtend_++;
00504
00505 updateNeighNav(durDataPkt_ + durCtrlPkt_);
00506
00507
00508 } else {
00509
00510
00511 }
00512 if (neighNav_ < (durDataPkt_ + durCtrlPkt_)) {
00513
00514
00515
00516 discard(dataPkt_, DROP_MAC_RETRY_COUNT_EXCEEDED);
00517 dataPkt_ = 0;
00518 pktTx_ = 0;
00519 state_ = IDLE;
00520
00521
00522
00523
00524 txMsgDone();
00525
00526 } else {
00527
00528 sendDATA();
00529 }
00530 }
00531 }
00532
00533
00534 void SMAC::handleNavTimer() {
00535
00536 nav_ = 0;
00537
00538 if (!syncFlag_) {
00539 if (state_ == SLEEP)
00540 wakeup();
00541
00542
00543 checkToSend();
00544 }
00545 }
00546
00547
00548 int SMAC::checkToSend() {
00549 if (txData_ == 1) {
00550 assert(dataPkt_);
00551 struct hdr_smac *mh = HDR_SMAC(dataPkt_);
00552
00553 if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00554 goto done;
00555
00556 if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00557 goto done;
00558
00559 if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
00560 (state_ == SLEEP || state_ == IDLE)) {
00561
00562 if (state_ == SLEEP) wakeup();
00563
00564 if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
00565 howToSend_ = BCASTDATA;
00566 else
00567 howToSend_ = UNICAST;
00568
00569 state_ = CR_SENSE;
00570
00571
00572 double cw = (Random::random() % DATA_CW) * slotTime_sec_;
00573 mhCS_.sched(CLKTICK2SEC(difs_) + cw);
00574
00575 return 1;
00576
00577 } else {
00578 return 0;
00579 }
00580
00581 done:
00582 return 0;
00583
00584 } else {
00585 return 0;
00586 }
00587 }
00588
00589
00590 void SMAC::handleNeighNavTimer() {
00591
00592
00593 neighNav_ = 0;
00594
00595 if (state_ == WAIT_DATA) {
00596 state_ = IDLE;
00597
00598
00599
00600 rxMsgDone(0);
00601 } else {
00602 if (!syncFlag_)
00603 checkToSend();
00604 }
00605 }
00606
00607
00608 void SMAC::handleCsTimer() {
00609
00610
00611
00612 #ifdef MAC_DEBUG
00613 if (howToSend_ != BCASTSYNC && dataPkt_ == 0)
00614 numCSError++;
00615 #endif // MAC_DEBUG
00616
00617 switch(howToSend_) {
00618 case BCASTSYNC:
00619 if (sendSYNC())
00620 state_ = IDLE;
00621 break;
00622
00623 case BCASTDATA:
00624 startBcast();
00625 break;
00626
00627 case UNICAST:
00628 startUcast();
00629 break;
00630 }
00631 }
00632
00633 void SMAC::handleCounterTimer(int id) {
00634
00635
00636
00637 if (mhCounter_[id]->value_ == sleepTime_) {
00638
00639
00640 if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00641 goto sched_1;
00642
00643 if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00644 goto sched_1;;
00645
00646 if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
00647 (state_ == SLEEP || state_ == IDLE)) {
00648
00649 if (state_ == SLEEP &&
00650 (id == 0 || schedTab_[id].txSync == 1)) {
00651
00652 wakeup();
00653 }
00654 if (schedTab_[id].txSync == 1) {
00655
00656 howToSend_ = BCASTSYNC;
00657 currSched_ = id;
00658 state_ = CR_SENSE;
00659 double cw = (Random::random() % SYNC_CW) * slotTime_sec_;
00660 mhCS_.sched(CLKTICK2SEC(difs_) + cw);
00661 }
00662 }
00663
00664 sched_1:
00665 mhCounter_[id]->sched(CLKTICK2SEC(listenTime_));
00666
00667 } else if (mhCounter_[id]->value_ == syncTime_) {
00668
00669
00670 if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
00671 goto sched_2;
00672
00673 if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
00674 goto sched_2;
00675
00676 if (schedTab_[id].txData == 1 &&
00677 (!(mhNav_.busy()) && !(mhNeighNav_.busy())) &&
00678 (state_ == SLEEP || state_ == IDLE)) {
00679
00680
00681 if (state_ == SLEEP)
00682 wakeup();
00683
00684 struct hdr_smac *mh = (struct hdr_smac *)dataPkt_->access(hdr_mac::offset_);
00685 if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
00686 howToSend_ = BCASTDATA;
00687 else
00688 howToSend_ = UNICAST;
00689 currSched_ = id;
00690 state_ = CR_SENSE;
00691
00692 double cw = (Random::random() % DATA_CW) * slotTime_sec_;
00693 mhCS_.sched(CLKTICK2SEC(difs_) + cw);
00694 }
00695 sched_2:
00696 mhCounter_[id]->sched(CLKTICK2SEC(dataTime_));
00697
00698 } else if (mhCounter_[id]->value_ == dataTime_) {
00699
00700
00701 if (radioState_ == RADIO_RX)
00702 goto sched_3;
00703
00704 if (id == 0 && state_ == IDLE)
00705 sleep();
00706
00707 sched_3:
00708
00709 mhCounter_[id]->sched(CLKTICK2SEC(cycleTime_));
00710
00711
00712 if (schedTab_[id].numPeriods > 0) {
00713 schedTab_[id].numPeriods--;
00714 if (schedTab_[id].numPeriods == 0) {
00715 schedTab_[id].txSync = 1;
00716 }
00717 }
00718 }
00719 }
00720
00721
00722
00723
00724
00725 void SMAC::recv(Packet *p, Handler *h) {
00726
00727 struct hdr_cmn *ch = HDR_CMN(p);
00728
00729 assert(initialized());
00730
00731
00732 if ( ch->direction() == hdr_cmn::DOWN) {
00733 sendMsg(p, h);
00734 return;
00735 }
00736
00737
00738
00739
00740
00741 if (radioState_ == RADIO_TX && ch->error() == 0) {
00742 assert(tx_active_);
00743 ch->error() = 1;
00744 pktRx_ = p;
00745 mhRecv_.sched(txtime(p));
00746 return;
00747 }
00748
00749
00750 if (state_ == CR_SENSE) {
00751 printf("Cancelling CS- node %d\n", index_);
00752
00753
00754 mhCS_.checkToCancel();
00755 }
00756
00757
00758 if (radioState_ == RADIO_RX) {
00759 assert(pktRx_);
00760 assert(mhRecv_.busy());
00761
00762
00763
00764
00765
00766 if (pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh)
00767 capture(p);
00768 else
00769 collision(p);
00770 }
00771
00772 else {
00773 if (mhRecv_.busy()) {
00774 assert(radioState_ == RADIO_SLP);
00775
00776
00777 mhRecv_.resched(txtime(p));
00778 } else
00779 mhRecv_.sched(txtime(p));
00780
00781 radioState_ = RADIO_RX;
00782 pktRx_ = p;
00783 }
00784 }
00785
00786
00787 void SMAC::capture(Packet *p) {
00788
00789 updateNav(CLKTICK2SEC(eifs_) + txtime(p));
00790 Packet::free(p);
00791 }
00792
00793
00794 void SMAC::collision(Packet *p) {
00795 if (!mac_collision_)
00796 mac_collision_ = 1;
00797
00798
00799
00800
00801 if (txtime(p) > mhRecv_.timeToExpire()) {
00802 mhRecv_.resched(txtime(p));
00803 discard(pktRx_, DROP_MAC_COLLISION);
00804
00805 pktRx_ = p;
00806
00807 }
00808 else
00809 discard(p, DROP_MAC_COLLISION);
00810
00811 }
00812
00813
00814 void SMAC::discard(Packet *p, const char* why)
00815 {
00816 hdr_cmn *ch = HDR_CMN(p);
00817 hdr_smac *sh = HDR_SMAC(p);
00818
00819
00820
00821 if(ch->error() != 0) {
00822 Packet::free(p);
00823
00824 return;
00825 }
00826
00827 switch(sh->type) {
00828
00829 case RTS_PKT:
00830 if (drop_RTS(p, why))
00831 return;
00832 break;
00833
00834 case CTS_PKT:
00835 case ACK_PKT:
00836 if (drop_CTS(p, why))
00837 return;
00838 break;
00839
00840 case DATA_PKT:
00841 if (drop_DATA(p, why))
00842 return;
00843 break;
00844
00845 case SYNC_PKT:
00846 if(drop_SYNC(p, why))
00847 return;
00848 break;
00849
00850 default:
00851 fprintf(stderr, "invalid MAC type (%x)\n", sh->type);
00852
00853 exit(1);
00854 }
00855 Packet::free(p);
00856 }
00857
00858
00859 int SMAC::drop_RTS(Packet *p, const char* why)
00860 {
00861 struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
00862
00863 if (cf->srcAddr == index_) {
00864 drop(p, why);
00865 return 1;
00866 }
00867 return 0;
00868 }
00869
00870 int SMAC::drop_CTS(Packet *p, const char* why)
00871 {
00872 struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
00873
00874 if (cf->dstAddr == index_) {
00875 drop(p, why);
00876 return 1;
00877 }
00878 return 0;
00879 }
00880
00881 int SMAC::drop_DATA(Packet *p, const char* why)
00882 {
00883 hdr_smac *sh = HDR_SMAC(p);
00884
00885 if ( (sh->dstAddr == index_) ||
00886 (sh->srcAddr == index_) ||
00887 ((u_int32_t)sh->dstAddr == MAC_BROADCAST)) {
00888 drop(p, why);
00889 return 1;
00890 }
00891 return 0;
00892 }
00893
00894 int SMAC::drop_SYNC(Packet *p, const char* why)
00895 {
00896 drop(p, why);
00897 return 1;
00898 }
00899
00900
00901
00902
00903 void SMAC::handleRTS(Packet *p) {
00904
00905
00906 struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
00907
00908 if(cf->dstAddr == index_) {
00909 if((state_ == IDLE || state_ == CR_SENSE) && nav_ == 0) {
00910 recvAddr_ = cf->srcAddr;
00911
00912 if(sendCTS(cf->duration)) {
00913 state_ = WAIT_DATA;
00914 lastRxFrag_ = -3;
00915 }
00916 }
00917 } else {
00918
00919
00920
00921 if (state_ == CR_SENSE)
00922 state_ = IDLE;
00923 updateNav(durCtrlPkt_ + durDataPkt_);
00924 }
00925
00926 }
00927
00928 void SMAC::handleCTS(Packet *p) {
00929
00930 struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
00931 if(cf->dstAddr == index_) {
00932 if(state_ == WAIT_CTS && cf->srcAddr == sendAddr_) {
00933
00934 mhGene_.cancel();
00935
00936 if(sendDATA()) {
00937 state_ = WAIT_ACK;
00938
00939 if (!syncFlag_)
00940 txData_ = 0;
00941 else
00942 schedTab_[currSched_].txData = 0;
00943 }
00944 }
00945 } else {
00946 updateNav(cf->duration);
00947 if(state_ == IDLE || state_ == CR_SENSE)
00948 sleep();
00949 }
00950 }
00951
00952 void SMAC::handleDATA(Packet *p) {
00953
00954 struct hdr_cmn *ch = HDR_CMN(p);
00955 struct hdr_smac * sh = HDR_SMAC(p);
00956
00957 if((u_int32_t)sh->dstAddr == MAC_BROADCAST) {
00958 state_ = IDLE;
00959
00960 rxMsgDone(p);
00961
00962 } else if (sh->dstAddr == index_) {
00963 if(state_ == WAIT_DATA && sh->srcAddr == recvAddr_) {
00964
00965 updateNeighNav(sh->duration);
00966 sendACK(sh->duration);
00967
00968
00969
00970
00971
00972
00973 state_ = IDLE;
00974 if(lastRxFrag_ != ch->uid()) {
00975 lastRxFrag_ = ch->uid();
00976 rxMsgDone(p);
00977 }
00978 else {
00979 printf("Recd duplicate data pkt at %d from %d! free pkt\n",index_,sh->srcAddr);
00980 Packet::free(p);
00981 if (!syncFlag_)
00982 checkToSend();
00983 }
00984 } else if (state_ == IDLE || state_ == CR_SENSE ) {
00985 printf("got data pkt in %d state XXX %d\n", state_, index_);
00986
00987 sendACK(sh->duration);
00988 state_ = IDLE;
00989 if(lastRxFrag_ != ch->uid()) {
00990 lastRxFrag_ = ch->uid();
00991 rxMsgDone(p);
00992 }
00993 else {
00994 printf("Recd duplicate data pkt! free pkt\n");
00995 Packet::free(p);
00996 if (!syncFlag_)
00997 checkToSend();
00998 }
00999 } else {
01000
01001
01002 printf("Got data pkt in !WAIT_DATA/!CR_SENSE/!IDLE state(%d) XXX %d\n", state_, index_);
01003 printf("Dropping data pkt\n");
01004 Packet::free(p);
01005 }
01006 } else {
01007 updateNav(sh->duration);
01008 if (state_ == IDLE || state_ == CR_SENSE)
01009 sleep();
01010 }
01011 }
01012
01013
01014
01015 void SMAC::handleACK(Packet *p) {
01016
01017
01018 struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
01019
01020 if (cf->dstAddr == index_) {
01021 if (state_ == WAIT_ACK && cf->srcAddr == sendAddr_) {
01022
01023 mhGene_.cancel();
01024 dataPkt_ = 0;
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 state_ = IDLE;
01041 txMsgDone();
01042
01043 }
01044
01045 } else {
01046 if (cf->duration > 0) {
01047 updateNav(cf->duration);
01048 if (state_ == IDLE || state_ == CR_SENSE)
01049 sleep();
01050 }
01051 }
01052 }
01053
01054
01055 void SMAC::handleSYNC(Packet *p)
01056 {
01057 if(numSched_ == 0) {
01058 mhGene_.cancel();
01059
01060
01061
01062 setMySched(p);
01063 return;
01064 }
01065 if (numNeighb_ == 0) {
01066
01067
01068
01069
01070 setMySched(p);
01071 return;
01072 }
01073 state_ = IDLE;
01074
01075 struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
01076 int i, j;
01077 int foundNeighb = 0;
01078 int schedId = SMAC_MAX_NUM_SCHEDULES;
01079
01080
01081
01082 for(i = 0; i < numNeighb_; i++) {
01083 if (neighbList_[i].nodeId == sf->srcAddr) {
01084 foundNeighb = 1;
01085 schedId = neighbList_[i].schedId;
01086 mhCounter_[schedId]->sched(sf->sleepTime);
01087 break;
01088 }
01089 if (neighbList_[i].nodeId == sf->syncNode)
01090
01091 schedId = neighbList_[i].schedId;
01092 }
01093 if (!foundNeighb) {
01094 neighbList_[numNeighb_].nodeId = sf->srcAddr;
01095 if (schedId < SMAC_MAX_NUM_SCHEDULES) {
01096
01097 neighbList_[numNeighb_].schedId = schedId;
01098 } else if (sf->syncNode == index_) {
01099 neighbList_[numNeighb_].schedId = 0;
01100 } else {
01101
01102 int foundSched = 0;
01103 for (j = 0; j < numSched_; j++) {
01104 double t = mhCounter_[j]->timeToSleep();
01105 double st = sf->sleepTime;
01106 if (t == st || (t + CLKTICK2SEC(1)) == st || t == (st + CLKTICK2SEC(1))) {
01107 neighbList_[numNeighb_].schedId = j;
01108 foundSched = 1;
01109 break;
01110 }
01111 }
01112 if (!foundSched) {
01113 schedTab_[numSched_].txSync = 1;
01114 schedTab_[numSched_].txData = 0;
01115 schedTab_[numSched_].numPeriods = 0;
01116 neighbList_[numNeighb_].schedId = numSched_;
01117 mhCounter_[numSched_]->sched(sf->sleepTime);
01118 numSched_++;
01119 }
01120 }
01121 numNeighb_++;
01122 }
01123 }
01124
01125
01126 void SMAC::rxMsgDone(Packet *p) {
01127
01128
01129
01130
01131 if (p)
01132 uptarget_->recv(p, (Handler*)0);
01133
01134 if (!syncFlag_)
01135
01136 checkToSend();
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 void SMAC::transmit(Packet *p) {
01148
01149 radioState_ = RADIO_TX;
01150 tx_active_ = 1;
01151 pktTx_ = p;
01152
01153 downtarget_->recv(p->copy(), this);
01154
01155 mhSend_.sched(txtime(p));
01156
01157 }
01158
01159 bool SMAC::chkRadio() {
01160
01161 if (radioState_ == RADIO_IDLE || radioState_ == RADIO_SLP)
01162 return (1);
01163
01164 return (0);
01165 }
01166
01167
01168 int SMAC::startBcast()
01169 {
01170
01171
01172 hdr_smac *mh = HDR_SMAC(dataPkt_);
01173
01174 mh->duration = 0;
01175
01176 if(chkRadio()) {
01177 transmit(dataPkt_);
01178 return 1;
01179 }
01180
01181 return 0;
01182 }
01183
01184
01185 int SMAC::startUcast()
01186 {
01187
01188 hdr_smac *mh = HDR_SMAC(dataPkt_);
01189
01190 sendAddr_ = mh->dstAddr;
01191 numRetry_ = 0;
01192
01193 numExtend_ = 0;
01194
01195 if(sendRTS()) {
01196 state_ = WAIT_CTS;
01197 return 1;
01198 }
01199
01200 return 0;
01201 }
01202
01203
01204 void SMAC::txMsgDone()
01205 {
01206 if (!syncFlag_) {
01207
01208 if(checkToSend())
01209 return;
01210 else if (callback_) {
01211 Handler *h = callback_;
01212 callback_ = 0;
01213 h->handle((Event*) 0);
01214 }
01215 } else {
01216 if (callback_) {
01217 Handler *h = callback_;
01218 callback_ = 0;
01219 h->handle((Event*) 0);
01220 }
01221 }
01222
01223 }
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234 bool SMAC::sendMsg(Packet *pkt, Handler *h) {
01235 struct hdr_smac *mh = HDR_SMAC(pkt);
01236
01237 callback_ = h;
01238 if ((u_int32_t)mh->dstAddr == MAC_BROADCAST) {
01239 return (bcastMsg(pkt));
01240 } else {
01241 return (unicastMsg(1, pkt));
01242
01243
01244
01245 }
01246 }
01247
01248
01249 bool SMAC::bcastMsg(Packet *p) {
01250
01251
01252 assert(p);
01253
01254
01255
01256
01257
01258
01259
01260
01261 struct hdr_smac *sh = HDR_SMAC(p);
01262
01263 sh->type = DATA_PKT;
01264 sh->length = SIZEOF_SMAC_DATAPKT;
01265
01266
01267 dataPkt_ = p;
01268
01269 for(int i=0; i < numSched_; i++) {
01270 schedTab_[i].txData = 1;
01271 }
01272
01273 if (!syncFlag_) {
01274 txData_ = 1;
01275
01276 if (checkToSend())
01277 return 1;
01278 else
01279 return 0;
01280
01281 } else {
01282 numBcast_ = numSched_;
01283 return 1;
01284 }
01285 }
01286
01287 bool SMAC::unicastMsg(int numfrags, Packet *p) {
01288
01289
01290
01291 assert(p);
01292
01293
01294
01295
01296
01297 char * mh = (char *)p->access(hdr_mac::offset_);
01298 int dst = hdr_dst(mh);
01299 int src = hdr_src(mh);
01300
01301
01302 struct hdr_smac *sh = HDR_SMAC(p);
01303
01304
01305 if (syncFlag_) {
01306 int found = 0;
01307 for (int i=0; i < numNeighb_; i++) {
01308 if (neighbList_[i].nodeId == dst) {
01309 found = 1;
01310 schedTab_[neighbList_[i].schedId].txData = 1;
01311 break;
01312 }
01313 }
01314 if (found == 0) {
01315 printf("Neighbor unknown; cannot send pkt\n");
01316 return 0;
01317 }
01318 }
01319
01320 sh->type = DATA_PKT;
01321 sh->length = SIZEOF_SMAC_DATAPKT;
01322 sh->dstAddr = dst;
01323 sh->srcAddr = src;
01324
01325 dataPkt_ = p;
01326
01327 if (!syncFlag_) {
01328 txData_ = 1;
01329
01330
01331 if (checkToSend())
01332 return 1;
01333 else
01334 return 0;
01335
01336 } else
01337 return 1;
01338 }
01339
01340
01341 bool SMAC::sendRTS() {
01342
01343 Packet *p = Packet::alloc();
01344 struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
01345 struct hdr_cmn *ch = HDR_CMN(p);
01346
01347 ch->uid() = 0;
01348 ch->ptype() = PT_MAC;
01349 ch->size() = SIZEOF_SMAC_CTRLPKT;
01350 ch->iface() = UNKN_IFACE.value();
01351 ch->direction() = hdr_cmn::DOWN;
01352 ch->error() = 0;
01353
01354
01355 bzero(cf, MAC_HDR_LEN);
01356
01357 cf->length = SIZEOF_SMAC_CTRLPKT;
01358 cf->type = RTS_PKT;
01359
01360 cf->srcAddr = index_;
01361 cf->dstAddr = sendAddr_;
01362
01363
01364
01365 cf->duration = (2 * durCtrlPkt_ + durDataPkt_ + 0.001 );
01366 cf->crc = 0;
01367
01368
01369 if (chkRadio()) {
01370 transmit(p);
01371 return 1;
01372
01373 } else
01374 return 0;
01375
01376 }
01377
01378
01379 bool SMAC::sendCTS(double duration) {
01380
01381
01382 Packet *p = Packet::alloc();
01383 struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
01384 struct hdr_cmn *ch = HDR_CMN(p);
01385
01386 ch->uid() = 0;
01387 ch->ptype() = PT_MAC;
01388 ch->size() = SIZEOF_SMAC_CTRLPKT;
01389 ch->iface() = UNKN_IFACE.value();
01390 ch->direction() = hdr_cmn::DOWN;
01391 ch->error() = 0;
01392
01393 bzero(cf, MAC_HDR_LEN);
01394
01395 cf->length = SIZEOF_SMAC_CTRLPKT;
01396 cf->type = CTS_PKT;
01397
01398 cf->srcAddr = index_;
01399 cf->dstAddr = recvAddr_;
01400
01401
01402 cf->duration = duration - durCtrlPkt_ ;
01403 cf->crc = 0;
01404
01405
01406 if (chkRadio()) {
01407 transmit(p);
01408 return 1;
01409
01410 } else
01411 return 0;
01412 }
01413
01414
01415 bool SMAC::sendDATA() {
01416
01417 struct hdr_smac * sh = HDR_SMAC(dataPkt_);
01418
01419
01420 sh->duration = durCtrlPkt_;
01421
01422
01423 if (chkRadio()) {
01424 transmit(dataPkt_);
01425 return 1;
01426
01427 } else
01428 return 0;
01429
01430 }
01431
01432
01433 bool SMAC::sendACK(double duration) {
01434
01435 Packet *p = Packet::alloc();
01436 struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
01437 struct hdr_cmn *ch = HDR_CMN(p);
01438
01439 ch->uid() = 0;
01440 ch->ptype() = PT_MAC;
01441 ch->size() = SIZEOF_SMAC_CTRLPKT;
01442 ch->iface() = UNKN_IFACE.value();
01443 ch->direction() = hdr_cmn::DOWN;
01444 ch->error() = 0;
01445
01446 bzero(cf, MAC_HDR_LEN);
01447
01448 cf->length = SIZEOF_SMAC_CTRLPKT;
01449 cf->type = ACK_PKT;
01450
01451 cf->srcAddr = index_;
01452 cf->dstAddr = recvAddr_;
01453
01454
01455
01456 cf->duration = duration - durCtrlPkt_;
01457
01458
01459
01460 if (chkRadio()) {
01461 transmit(p);
01462 return 1;
01463 } else
01464 return 0;
01465 }
01466
01467 bool SMAC::sendSYNC()
01468 {
01469
01470 Packet *p = Packet::alloc();
01471 struct smac_sync_frame *cf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
01472 struct hdr_cmn *ch = HDR_CMN(p);
01473
01474 ch->uid() = 0;
01475 ch->ptype() = PT_MAC;
01476 ch->size() = SIZEOF_SMAC_SYNCPKT;
01477 ch->iface() = UNKN_IFACE.value();
01478 ch->direction() = hdr_cmn::DOWN;
01479 ch->error() = 0;
01480
01481 cf->length = SIZEOF_SMAC_SYNCPKT;
01482 cf->type = SYNC_PKT;
01483
01484 cf->srcAddr = index_;
01485 cf->syncNode = mySyncNode_;
01486
01487 cf->sleepTime = mhCounter_[0]->timeToSleep() - CLKTICK2SEC(SYNCPKTTIME);
01488 if (cf->sleepTime < 0)
01489 cf->sleepTime += CLKTICK2SEC(cycleTime_);
01490
01491
01492 if (chkRadio()) {
01493 transmit(p);
01494
01495
01496 return 1;
01497
01498 } else
01499 return 0;
01500 }
01501
01502
01503 void SMAC::sentRTS(Packet *p)
01504 {
01505
01506 mhGene_.sched(timeWaitCtrl_);
01507 Packet::free(p);
01508
01509 }
01510
01511 void SMAC::sentCTS(Packet *p)
01512 {
01513
01514
01515
01516
01517
01518 struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
01519
01520 updateNeighNav(cf->duration);
01521 Packet::free(p);
01522 }
01523
01524 void SMAC::sentDATA(Packet *p)
01525 {
01526 struct hdr_smac *mh = HDR_SMAC(p);
01527
01528 if (howToSend_ == BCASTDATA) {
01529 state_ = IDLE;
01530
01531 if (!syncFlag_) {
01532 txData_ = 0;
01533 dataPkt_ = 0;
01534 Packet::free(p);
01535
01536
01537 txMsgDone();
01538
01539 } else {
01540 schedTab_[currSched_].txData = 0;
01541 numBcast_--;
01542 if (numBcast_ == 0) {
01543 dataPkt_ = 0;
01544 Packet::free(p);
01545
01546
01547 txMsgDone();
01548 }
01549 }
01550
01551 } else {
01552
01553
01554
01555
01556 updateNeighNav(mh->duration);
01557
01558
01559 mhGene_.sched(timeWaitCtrl_);
01560
01561 }
01562 }
01563
01564 void SMAC::sentACK(Packet *p)
01565 {
01566 struct smac_control_frame *cf = (struct smac_control_frame *)p->access(hdr_mac::offset_);
01567
01568 updateNeighNav(cf->duration);
01569 Packet::free(p);
01570 }
01571
01572 void SMAC::sentSYNC(Packet *p)
01573 {
01574 schedTab_[currSched_].txSync = 0;
01575 schedTab_[currSched_].numPeriods = SYNCPERIOD;
01576 Packet::free(p);
01577
01578 }
01579
01580 void SMAC::sleep()
01581 {
01582
01583 state_ = SLEEP;
01584 radioState_ = RADIO_SLP;
01585
01586 }
01587
01588 void SMAC::wakeup()
01589 {
01590
01591 state_ = IDLE;
01592
01593
01594
01595
01596
01597 if (radioState_ == RADIO_SLP)
01598 radioState_ = RADIO_IDLE;
01599
01600
01601 }
01602
01603 void SMAC::updateNav(double d ) {
01604 double now = Scheduler::instance().clock();
01605
01606
01607
01608 if ((now + d) > nav_) {
01609 nav_ = now + d;
01610
01611 mhNav_.resched(d);
01612
01613 }
01614 }
01615
01616
01617 void SMAC::updateNeighNav(double d ) {
01618 double now = Scheduler::instance().clock();
01619
01620
01621 if ((now + d) > neighNav_) {
01622 neighNav_ = now + d;
01623
01624 mhNeighNav_.resched(d);
01625
01626 }
01627 }
01628
01629 double SMAC::txtime(Packet *p)
01630 {
01631 struct hdr_smac *sh = HDR_SMAC(p);
01632
01633 switch(sh->type) {
01634
01635 case DATA_PKT:
01636 return durDataPkt_;
01637
01638 case RTS_PKT:
01639 case CTS_PKT:
01640 case ACK_PKT:
01641 return durCtrlPkt_;
01642 case SYNC_PKT:
01643 return CLKTICK2SEC(SYNCPKTTIME);
01644 default:
01645 fprintf(stderr, "invalid smac pkt type %d\n", sh->type);
01646 exit(1);
01647 }
01648
01649 }