📄 smac.cc
字号:
mhUpdateNeighb_.sched(SMAC_UPDATE_NEIGHB_PERIOD); //dump();#else mhGene_.sched(t);#endif } }}void SMAC::setMySched(Packet *pkt) { // set my schedule and put it into the first entry of schedule table state_ = IDLE; numSched_ = 1; schedTab_[0].numPeriods = 0; schedTab_[0].txData = 0; schedTab_[0].txSync = 1; // need to brdcast my schedule if (pkt == 0) { // freely choose my schedule#ifdef JOURNAL_PAPER //printf("#############################################################\n"); //printf(" %d is choosing its own shedule %d \n", index_, index_); //printf("#############################################################\n"); schedState_++; mhCounter_[0]->sched(CLKTICK2SEC(listenTime_+index_*10)); schedTab_[0].syncNode = index_;#else mhCounter_[0]->sched(CLKTICK2SEC(listenTime_));#endif mySyncNode_ = index_; // myself currSched_ = 0; //sendSYNC(); } else { // follow schedule in syncpkt struct smac_sync_frame *pf = (struct smac_sync_frame *)pkt->access(hdr_mac::offset_); mhCounter_[0]->sched(pf->sleepTime);#ifdef JOURNAL_PAPER mySyncNode_ = pf->syncNode; //printf("#############################################################\n"); //printf("%d receives SYNC packet from %d and starts following shedule %d \n", index_, pf->srcAddr, pf->syncNode); //printf("#############################################################\n"); schedTab_[0].numNodes++; // 2 nodes on this schedule now schedTab_[0].syncNode = pf->syncNode; schedState_++; //add node in my neighbor list neighbList_[0].nodeId = pf->srcAddr; neighbList_[0].schedId = 0; neighbList_[0].active = 1; neighbList_[0].state = pf->state;#else mySyncNode_ = pf->srcAddr; //add node in my neighbor list neighbList_[0].nodeId = mySyncNode_; neighbList_[0].schedId = 0;#endif numNeighb_ = 1; }}int SMAC::command(int argc, const char*const* argv){ if (argc == 3) { if (strcmp(argv[1], "log-target") == 0) { logtarget_ = (NsObject*) TclObject::lookup(argv[2]); if(logtarget_ == 0) return TCL_ERROR; return TCL_OK; } else if ( selfConfigFlag_ != 1) { if (strcmp(argv[1], "schedule-start-time") == 0) { startTime_ = strtod(argv[2],NULL); // set up schedule state_ = IDLE; numSched_ = 1; schedTab_[0].numPeriods = SYNCPERIOD; schedTab_[0].txData = 0; schedTab_[0].txSync = 1; // need to brdcast my schedule // schedule starts up with listen time (sync+data) // need to caculate time to sleep startTime_ = startTime_ + listenTime_; if ( startTime_ >= cycleTime_ ) startTime_ = startTime_ - cycleTime_; mhCounter_[0]->sched(CLKTICK2SEC(startTime_)); mySyncNode_ = index_; // myself currSched_ = 0; return TCL_OK; } } } return Mac::command(argc, argv);}#ifdef JOURNAL_PAPERvoid SMAC::adaptiveListen(){ // adaptively wake-up at the end of current transmission. Will try to // send only if the buffered packet is unicast. Since my next-hop // neighbor may not be aware of the Tx of my previous-hop neighbor, // broadcast now is unreliable //printf("adaptiveListen set AdaptiveTimer: node %d scheduletime: %f adapTime_: %d time:%.9f \n", index_, mhCounter_[0]->value_, adapTime_, Scheduler::instance().clock()); mhAdap_.resched(CLKTICK2SEC(adapTime_)); // set timer to bring me back to sleep adaptiveListen_ = 1; if (state_ == SLEEP) { //printf("adaptiveListen wakeup: node %d scheduletime: %f time:%.9f \n", index_, mhCounter_[0]->value_, Scheduler::instance().clock()); wakeup(); } else { } if ( schedTab_[0].txData == 1 && sendAddr == UNICAST_ADDR){ adapSend_ = 1; checkToSend(); }}#endif// XXXX smac handler functionsvoid SMAC::handleSendTimer() { assert(pktTx_); struct hdr_smac *sh = HDR_SMAC(pktTx_); // Packet tx is done so radio should go back to idle radioState_ = RADIO_IDLE; tx_active_ = 0; switch(sh->type) { case RTS_PKT: sentRTS(pktTx_); break; case CTS_PKT: sentCTS(pktTx_); break; case DATA_PKT: sentDATA(pktTx_); break; case ACK_PKT: sentACK(pktTx_); break; case SYNC_PKT: sentSYNC(pktTx_); break; default: fprintf(stderr, "unknown mac pkt type, %d\n", sh->type); break; } pktTx_ = 0;}void SMAC::handleRecvTimer() { assert(pktRx_); struct hdr_cmn *ch = HDR_CMN(pktRx_); struct hdr_smac *sh = HDR_SMAC(pktRx_); if (state_ == SLEEP) { // Bug fixed here. a collision might happen just now, need to clear the mac_collision_ flag, otherwise the node won't receive any following packet if (mac_collision_) { discard(pktRx_, DROP_MAC_COLLISION); mac_collision_ = 0; updateNav(CLKTICK2SEC(eifs_)); if (state_ == CR_SENSE) sleep(); // have to wait until next wakeup time else radioState_ = RADIO_IDLE; goto done; } discard(pktRx_, DROP_MAC_SLEEP); radioState_ = RADIO_SLP; goto done; } // if the radio interface is tx'ing when this packet arrives // I would never have seen it and should do a silent discard if (radioState_ == RADIO_TX) { Packet::free(pktRx_); goto done; } if (mac_collision_) { discard(pktRx_, DROP_MAC_COLLISION); mac_collision_ = 0; updateNav(CLKTICK2SEC(eifs_)); if (state_ == CR_SENSE) sleep(); // have to wait until next wakeup time else radioState_ = RADIO_IDLE; goto done; } if (ch->error()) { Packet::free(pktRx_); updateNav(CLKTICK2SEC(eifs_)); if (state_ == CR_SENSE) sleep(); else radioState_ = RADIO_IDLE; goto done; } // set radio from rx to idle again radioState_ = RADIO_IDLE; switch (sh->type) { case DATA_PKT: handleDATA(pktRx_); break; case RTS_PKT: handleRTS(pktRx_); Packet::free(pktRx_); break; case CTS_PKT: handleCTS(pktRx_); Packet::free(pktRx_); break; case ACK_PKT: handleACK(pktRx_); Packet::free(pktRx_); break; case SYNC_PKT: handleSYNC(pktRx_); Packet::free(pktRx_); break; default: fprintf(stderr, "Unknown smac pkt type, %d\n", sh->type); break; } done: pktRx_ = 0; }void SMAC::handleGeneTimer() { if (syncFlag_) { // still in choose-schedule state if (numSched_ == 0) { setMySched(0); // I'm the primary synchroniser return; } } if (state_ == WAIT_CTS) { // CTS timeout if (numRetry_ < SMAC_RETRY_LIMIT) { numRetry_++; // wait until receiver's next wakeup state_ = IDLE;#ifdef JOURNAL_PAPER //node tries to go to sleep if it needs to resend if( mhCounter_[0]->value_ == sleepTime_ ) sleep();#endif if (!syncFlag_) checkToSend(); } else { state_ = IDLE; Packet::free(dataPkt_); dataPkt_ = 0; numRetry_ = 0; //numFrags_ = 0; // signal upper layer about failure of tx // txMsgFailed(); txMsgDone(); } } else if (state_ == WAIT_ACK) { // ack timeout if (numExtend_ < SMAC_EXTEND_LIMIT) { // extend time printf("SMAC %d: no ACK received. Extend Tx time.\n", index_); numExtend_++; updateNeighNav(durDataPkt_ + durCtrlPkt_); //neighNav_ = (durDataPkt_ + durCtrlPkt_); } else { // reached extension limit, can't extend time //numFrags_--; } if (neighNav_ < (durDataPkt_ + durCtrlPkt_)) { // used up reserved time, stop tx discard(dataPkt_, DROP_MAC_RETRY_COUNT_EXCEEDED); dataPkt_ = 0; pktTx_ = 0; state_ = IDLE; // signal upper layer the number of transmitted frags //txMsgFailed(succFrags); -> no frag for now txMsgDone(); } else { // still have time // keep sending until use up remaining time sendDATA(); }#ifdef JOURNAL_PAPER } else if (state_ == DATA_SENSE1) { state_ = DATA_SENSE2; mhGene_.resched(timeWaitCtrl_); } else if (state_ == DATA_SENSE2) { state_ = IDLE; //node tries to go to sleep if it does not hear CTS or DATA for others' connection if( mhCounter_[0]->value_ == sleepTime_ ) sleep();#endif }}void SMAC::handleNavTimer() { // medium is now free nav_ = 0; // why have this variable?? probably not required use the timer instead if (!syncFlag_) { if (state_ == SLEEP) wakeup(); // try to send waiting data, if any checkToSend(); } #ifdef JOURNAL_PAPER adaptiveListen();#endif}int SMAC::checkToSend() {#ifdef JOURNAL_PAPER if (txRequest_ == 1 || syncFlag_) {#else if (txData_ == 1) {#endif assert(dataPkt_); struct hdr_smac *mh = HDR_SMAC(dataPkt_); if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE) goto done; // cannot send if radio is sending or recving if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA ) goto done; // cannot send if not in any of these states if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) && (state_ == SLEEP || state_ == IDLE)) { if (state_ == SLEEP) wakeup(); if ((u_int32_t)mh->dstAddr == MAC_BROADCAST) howToSend_ = BCASTDATA; else howToSend_ = UNICAST; state_ = CR_SENSE;#ifdef JOURNAL_PAPER adapSend_ = 0; //printf("adaptiveListen sendData: node %d scheduletime: %f time:%.9f \n", index_, mhCounter_[0]->value_, Scheduler::instance().clock());#endif // start cstimer double cw = (Random::random() % DATA_CW) * slotTime_sec_; mhCS_.sched(CLKTICK2SEC(difs_) + cw); return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -