⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smac.cc

📁 无线传感器网络经典MAC协议SMAC协议源码
💻 CC
📖 第 1 页 / 共 5 页
字号:
            //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;
    
        } 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_PAPER
void 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 layer

void 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -