📄 smac.cc
字号:
} else { return 0; } done: return 0; } else { return 0; }}void SMAC::handleNeighNavTimer() { // Timer to track my neighbor's NAV neighNav_ = 0; // probably don't need to use this variable if (state_ == WAIT_DATA) { // data timeout state_ = IDLE; // signal upper layer that rx msg is done // didnot get any/all data rxMsgDone(0); } else { if (!syncFlag_) checkToSend(); }#ifdef JOURNAL_PAPER adaptiveListen();#endif}void SMAC::handleCsTimer() { // carrier sense successful #ifdef MAC_DEBUG if (howToSend_ != BCASTSYNC && dataPkt_ == 0) numCSError++;#endif // MAC_DEBUG switch(howToSend_) { case BCASTSYNC: if (sendSYNC()) state_ = IDLE; break; case BCASTDATA: startBcast(); break; case UNICAST: startUcast(); break; }}void SMAC::handleCounterTimer(int id) { //printf("MAC:%d,id:%d - time:%.9f\n", index_,id,Scheduler::instance().clock());#ifdef JOURNAL_PAPER if (schedTab_[id].numNodes > 0) {#endif if (mhCounter_[id]->value_ == sleepTime_) { //woken up from sleep // listentime starts now if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE) goto sched_1; // cannot send if radio is sending or recving if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA ) goto sched_1;; // cannot send if not in any of these states if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) && (state_ == SLEEP || state_ == IDLE)) { if (state_ == SLEEP && (id == 0 || schedTab_[id].txSync == 1)) { wakeup(); } if (schedTab_[id].txSync == 1) { // start carrier sense for sending sync howToSend_ = BCASTSYNC;#ifdef JOURNAL_PAPER syncSched_ = id;#else currSched_ = id;#endif state_ = CR_SENSE; double cw = (Random::random() % SYNC_CW) * slotTime_sec_; mhCS_.sched(CLKTICK2SEC(difs_) + cw); } } // start to listen now sched_1: mhCounter_[id]->sched(CLKTICK2SEC(listenTime_)); } else if (mhCounter_[id]->value_ == syncTime_) { //synctime over // can start datatime now if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE) goto sched_2; // cannot send if radio is sending or recving if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA ) goto sched_2; // cannot send if not in any of these states if (schedTab_[id].txData == 1 && (!(mhNav_.busy()) && !(mhNeighNav_.busy())) && (state_ == SLEEP || state_ == IDLE)) { // schedule sending data if (state_ == SLEEP) wakeup(); struct hdr_smac *mh = (struct hdr_smac *)dataPkt_->access(hdr_mac::offset_); if ((u_int32_t)mh->dstAddr == MAC_BROADCAST) howToSend_ = BCASTDATA; else howToSend_ = UNICAST;#ifdef JOURNAL_PAPER dataSched_ = id;#else currSched_ = id;#endif state_ = CR_SENSE; // start cstimer double cw = (Random::random() % DATA_CW) * slotTime_sec_; mhCS_.sched(CLKTICK2SEC(difs_) + cw); } sched_2: mhCounter_[id]->sched(CLKTICK2SEC(dataTime_)); } else if (mhCounter_[id]->value_ == dataTime_) { //datatime over // check if in the middle of recving a pkt if (radioState_ == RADIO_RX) goto sched_3;#ifdef JOURNAL_PAPER if (id == 0 && state_ == IDLE && searchNeighb_ ==0 && adaptiveListen_ ==0 )#else if (id == 0 && state_ == IDLE && searchNeighb_ ==0 )#endif sleep(); sched_3: // now time to go to sleep mhCounter_[id]->sched(CLKTICK2SEC(cycleTime_)); // check if ready to send out sync if (schedTab_[id].numPeriods > 0) { schedTab_[id].numPeriods--; if (schedTab_[id].numPeriods == 0) { schedTab_[id].txSync = 1; // neighbor discovery if ( id == 0 ) { numSync_--; // printf("numSync_ %d: ............node %d at %.6f\n", numSync_, index_,Scheduler::instance().clock()); if ( numSync_ == 1 ) { searchNeighb_ = 1; // node will go to neighbor discovery period starting from the next frame //printf("Start Neighbor Discovery: ............node %d at %.6f\n", index_, Scheduler::instance().clock()); } else if ( numSync_ == 0 ) { searchNeighb_ = 0; // neighbor discovery period lasts exactly one SYNC period //printf("Ending Neighbor Discovery: ............node %d at %.6f\n", index_, Scheduler::instance().clock()); if ( numNeighb_ == 0 ) { numSync_ = SRCH_CYCLES_SHORT; } else { numSync_ = SRCH_CYCLES_LONG; } } } } } }#ifdef JOURNAL_PAPER }#endif}#ifdef JOURNAL_PAPERvoid SMAC::handleUpdateNeighbTimer() { //printf("SMAC::handleUpdateNeighbTimer: ............node %d at %.6f\n", index_, Scheduler::instance().clock()); if (txRequest_ == 0) { // No data waiting to be transmitted txRequest_ = 1; // temporarily disable tx when updating update_myNeighbList(); } else { updateNeighbList_ = 1; // set flag to update when tx done }} void SMAC::handleAdaptiveListenTimer() { //node tries to go to sleep after adaptive listen times out adaptiveListen_ = 0; if (state_ == IDLE && state_ != TX_PKT && mhCounter_[0]->value_ == sleepTime_) sleep();}#endif// recv function for mac layervoid SMAC::recv(Packet *p, Handler *h) { struct hdr_cmn *ch = HDR_CMN(p); assert(initialized()); // handle outgoing pkt if ( ch->direction() == hdr_cmn::DOWN) { sendMsg(p, h); return; } // handle incoming pkt // we have just recvd the first bit of a pkt on the network interface // if the interface is in tx mode it probably would not see this pkt if (radioState_ == RADIO_TX && ch->error() == 0) { assert(tx_active_); ch->error() = 1; pktRx_ = p; mhRecv_.resched(txtime(p)); return; } // cancel carrier sense timer and wait for entire pkt if (state_ == CR_SENSE) { printf("Cancelling CS- node %d\n", index_); // cancels only if timer is pending; smac could be in CR_SENSE with timer cancelled // incase it has already received a pkt and receiving again mhCS_.checkToCancel(); } // if the interface is already in process of recv'ing pkt if (radioState_ == RADIO_RX) { assert(pktRx_); assert(mhRecv_.busy()); // if power of the incoming pkt is smaller than the power // of the pkt currently being recvd by atleast the capture // threshold then we ignore the new pkt. if (pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) capture(p); else collision(p); } else { if (mhRecv_.busy()) { // and radiostate != RADIO_RX assert(radioState_ == RADIO_SLP); // The radio interface was recv'ing a pkt when it went to sleep // should it postpone sleep till it finishes recving the pkt??? mhRecv_.resched(txtime(p)); } else mhRecv_.sched(txtime(p)); radioState_ = RADIO_RX; pktRx_ = p; }}void SMAC::capture(Packet *p) { // we update NAV for this pkt txtime updateNav(CLKTICK2SEC(eifs_) + txtime(p)); Packet::free(p);}void SMAC::collision(Packet *p) { if (!mac_collision_) mac_collision_ = 1; // since a collision has occured figure out which packet that caused // the collision will "last" longer. Make this pkt pktRx_ and reset the // recv timer. if (txtime(p) > mhRecv_.timeToExpire()) { mhRecv_.resched(txtime(p)); discard(pktRx_, DROP_MAC_COLLISION); // shouldn't we free pkt here ??? pktRx_ = p; } else discard(p, DROP_MAC_COLLISION); // shouldn't we free pkt here ???}void SMAC::discard(Packet *p, const char* why){ hdr_cmn *ch = HDR_CMN(p); hdr_smac *sh = HDR_SMAC(p); /* if the rcvd pkt contains errors, a real MAC layer couldn't necessarily read any data from it, so we just toss it now */ if(ch->error() != 0) { Packet::free(p); //p = 0; return; } switch(sh->type) { case RTS_PKT: if (drop_RTS(p, why)) return; break; case CTS_PKT: case ACK_PKT: if (drop_CTS(p, why)) return; break; case DATA_PKT: if (drop_DATA(p, why)) return; break; case SYNC_PKT: if(drop_SYNC(p, why)) return; break; default: fprintf(stderr, "invalid MAC type (%x)\n", sh->type); //trace_pkt(p); exit(1); } Packet::free(p);}int SMAC::drop_RTS(Packet *p, const char* why) { struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_); if (cf->srcAddr == index_) { drop(p, why); return 1; } return 0;}int SMAC::drop_CTS(Packet *p, const char* why) { struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_); if (cf->dstAddr == index_) { drop(p, why); return 1; } return 0;}int SMAC::drop_DATA(Packet *p, const char* why) { hdr_smac *sh = HDR_SMAC(p); if ( (sh->dstAddr == index_) || (sh->srcAddr == index_) || ((u_int32_t)sh->dstAddr == MAC_BROADCAST)) { drop(p, why); return 1; } return 0;}int SMAC::drop_SYNC(Packet *p, const char* why) { drop(p, why); return 1;}#ifdef JOURNAL_PAPERvoid SMAC::checkMySched(){ // check if I am the only one on schedTab[0] // if yes, should switch and follow the next available schedule // happens when an old node switches to a new schedule // and when I drop some inactive nodes from neighbor list(updating) int i, schedId; schedId = 0; if (schedTab_[0].numNodes == 1 && numSched_ > 1 && numNeighb_ > 0) { for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) { if (schedTab_[i].numNodes > 0) { // switch to next available schedule //schedTab_[0].counter = schedTab[i].counter; schedTab_[0].numPeriods = 0; schedTab_[0].txSync = 1; schedTab_[0].txData = schedTab_[i].txData; schedTab_[0].syncNode = schedTab_[i].syncNode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -