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

📄 smac.cc

📁 在ns2中仿真无线传感器网络mac层协议的代码smac
💻 CC
📖 第 1 页 / 共 5 页
字号:

#else
      
            //if (sh->duration > durCtrlPkt_) { // wait for more frag
            //rxFragDone(p);   no frag for now
            //state_ = IDLE;
            //} else {   // no more fragments
      
            state_ = IDLE;
            if(lastRxFrag_ != ch->uid()) {
                lastRxFrag_ = ch->uid();
                rxMsgDone(p);
    		}
            else {
                printf("Recd duplicate data pkt at %d from %d! free pkt\n",index_,sh->srcAddr);
                Packet::free(p);
                if (!syncFlag_)
                    checkToSend();
    		}
#endif
        } else if (state_ == IDLE || state_ == CR_SENSE ) {
            printf("got data pkt in %d state XXX %d\n", state_, index_);
            //updateNav(sh->duration + 0.00001);  // incase I have a pkt to send
            sendACK(sh->duration);
            state_ = IDLE;
            if(lastRxFrag_ != ch->uid()) {
                lastRxFrag_ = ch->uid();
                rxMsgDone(p);
    		}
            else {
                printf("Recd duplicate data pkt! free pkt\n");
                Packet::free(p);
                if (!syncFlag_)
                    checkToSend();
    		}
        } else { // some other state
            // not sure we can handle this
            // so drop pkt
            printf("Got data pkt in !WAIT_DATA/!CR_SENSE/!IDLE state(%d) XXX %d\n", state_, index_);
            printf("Dropping data pkt\n");
            Packet::free(p);
    	}
    } else { // unicast pkt destined to other node
        updateNav(sh->duration);
        Packet::free(p);
#ifdef JOURNAL_PAPER
                if (state_ == DATA_SENSE2) { mhGene_.cancel();}
                if (state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE2)
                        sleep();
#else
        if (state_ == IDLE || state_ == CR_SENSE)
            sleep();
#endif
    }
}



void SMAC::handleACK(Packet *p) {
    // internal handler for ack
    struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
  
    if (cf->dstAddr == index_) {
        if (state_ == WAIT_ACK && cf->srcAddr == sendAddr_) {
            // cancel ACK timer
            mhGene_.cancel();
#ifdef JOURNAL_PAPER
                        numFrags_--;
                        succFrags_++;
                        if (numFrags_ > 0) { //need to send more frags
                                  state_ = TX_NEXT_FRAG;
                                  txFragDone();
                               } else {
                        state_ = IDLE;
                        txMsgDone();
    		}
#else
            Packet::free(dataPkt_);
            dataPkt_ = 0;
            //numFrags_--;
            //succFrags_++;
      
            // if (numFrags_ > 0) { //need to send more frags
            //  if (neighNav__ < (durDataPkt_ + durCtrlPkt_)) {
            //    // used up reserved time, have to stop
            //    state_ = IDLE;
            //    // txMsgFailed(succFrags_);
            //    txMsgDone();
            //  } else { // continue on next fragment
            //    state_ = WAIT_NEXTFRAG;
            //    txFragDone(dataPkt_);
        	// 	}

            //       } else {
            state_ = IDLE;
            txMsgDone();
        	//}
#endif
    	}
    
    } else { // destined to another node
        if (cf->duration > 0) {
            updateNav(cf->duration);
            if (state_ == IDLE || state_ == CR_SENSE)
            	sleep();
    	}
    }
}

#ifdef JOURNAL_PAPER
void SMAC::handleSYNC(Packet *p) 
{

    struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_);
        int i, j,nodeId, schedId, flag;
        struct SchedTable tempSched;
        int foundNeighb = 0;
    if (index_ == 5){
        double t = Scheduler::instance().clock();
        //printf("Recvd SYNC (not/f) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t);
    }
    if (numSched_ == 0) { // in choose_sched state
        mhGene_.cancel();
        setMySched(p);
        return;
    }
        if (numNeighb_ == 0 && globalSchedule_ == 1) {
         // follow this schedule if having no other neighbor and if this schedule has smaller ID
            if (schedTab_[0].syncNode > sf->syncNode || !sendSYNCFlag_ ) {
                setMySched(p);
                return;
            }
        }
        else if (numNeighb_ == 0) { // getting first sync pkt
         // follow this sched as have no other neighbor
            setMySched(p);

            return;
        }
    state_ = IDLE;

        // check if sender is on my neighbor list
        nodeId = SMAC_MAX_NUM_NEIGHBORS;
        schedId = SMAC_MAX_NUM_SCHEDULES;
        for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
            if (neighbList_[i].state > 0 && neighbList_[i].nodeId == sf->srcAddr) {
                    nodeId = i;
                    schedId = neighbList_[i].schedId; // a known neighbor
                    break;
            }
        }
        if (nodeId < SMAC_MAX_NUM_NEIGHBORS) {
            if (neighbList_[nodeId].state == sf->state) {
                    // update the existing schedule
                mhCounter_[schedId]->sched(sf->sleepTime);

                    neighbList_[nodeId].active = 1;
                    if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
                        // change state
                        schedState_++;
                //printf("#############################################################\n");
                        //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
                //printf("#############################################################\n");

                            tempSched.syncNode = schedTab_[schedId].syncNode;
                            tempSched.txSync = schedTab_[schedId].txSync;  // need send sync
                            tempSched.txData = schedTab_[schedId].txData;
                            tempSched.numPeriods = schedTab_[schedId].numPeriods;
                            tempSched.numNodes = schedTab_[schedId].numNodes ; //
                        tempSched.chkSched = schedTab_[schedId].chkSched;

                        if (schedTab_[0].numNodes == 1) {
                                numSched_--;
                        }
                    mhCounter_[schedId]->sched(mhCounter_[0]->timeToSleep());
                            schedTab_[schedId].syncNode = schedTab_[0].syncNode;
                            schedTab_[schedId].txSync = schedTab_[0].txSync;  // need send sync
                            schedTab_[schedId].txData = schedTab_[0].txData;
                            schedTab_[schedId].numPeriods = schedTab_[0].numPeriods;
                            schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
                            schedTab_[schedId].chkSched = schedTab_[0].chkSched;

                            // new schedule is schedule 0 now
                mhCounter_[0]->sched(sf->sleepTime);
                        schedTab_[0].syncNode = sf->syncNode;
                        schedTab_[0].txSync = 1;  
                        schedTab_[0].txData = tempSched.txData;
                        schedTab_[0].numPeriods = 0; 
                        schedTab_[0].numNodes = tempSched.numNodes + 1; // I are following this sched
                        schedTab_[0].chkSched = tempSched.chkSched;

                        // change all the neighbor who was following shedule 0
                        for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
                                if (neighbList_[j].schedId == 0) { // found an empty entry
                                    neighbList_[j].schedId = schedId;
                            	}
                                else if (neighbList_[j].schedId == schedId) { // found an empty entry
                                    neighbList_[j].schedId = 0;
                            	}
                        	}
                    }
                return;
            } else {

                    // decrement number of nodes on old schedule

                    if (schedTab_[schedId].numNodes ==1 && txRequest_ == 1) {
                        //set flag to decrement numNodes after tx pkt is done
                        schedTab_[schedId].chkSched = 1;
                	}
                    else 
    		{
                        schedTab_[schedId].numNodes--; 
                        if (schedTab_[schedId].numNodes == 0){
                            numSched_--;
                    	}
            	}

    	}
    }

        // now it's either a new node or an old node switching to a new schedule
        // it is also possible that a node switches to an existing schedule
        // check if its schedule is a known one to me
        schedId = SMAC_MAX_NUM_SCHEDULES;
        for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
            if (schedTab_[i].numNodes > 0) {
        
                double t = mhCounter_[i]->timeToSleep();
                double st = sf->sleepTime;
                double timeDiff = st - t;
                    if ( timeDiff > -GUARDTIME && timeDiff < GUARDTIME) {
                mhCounter_[i]->sched(sf->sleepTime);

                        schedTab_[i].numNodes++; // it will follow this schedule
                        schedId = i;
                        break;
                	} 
            }
        }

        if (schedId == SMAC_MAX_NUM_SCHEDULES) {  // unknow schedule
            flag =1;
            // add an entry to the schedule table
            if (numSched_ < SMAC_MAX_NUM_SCHEDULES){
                    for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) {
                        if (schedTab_[i].numNodes == 0) { // found an empty entry
                        // check if I need to switch
                if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
                            // change state
                            schedState_++;
                    //printf("#############################################################\n");
                            //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
                            //printf("#############################################################\n");

                            if (schedTab_[0].numNodes >= 2) { // need to move old schedule 0 to schedule i
                            mhCounter_[i]->sched(mhCounter_[0]->timeToSleep());
                                    schedTab_[i].syncNode = schedTab_[0].syncNode;
                                    schedTab_[i].txSync = schedTab_[0].txSync;  // need send sync
                                    schedTab_[i].txData = schedTab_[0].txData;
                                    schedTab_[i].numPeriods = schedTab_[0].numPeriods;
                                    schedTab_[i].numNodes = schedTab_[0].numNodes - 1; // I switch schedule
                                    schedTab_[i].chkSched = schedTab_[0].chkSched;
                                    numSched_++;  // increment number of schedules
                                    // change all the neighbor who was following shedule 0
                                    for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) {
                                        if (neighbList_[j].schedId == 0) { // found an empty entry
                                            neighbList_[j].schedId = i;
                                		}
                            		}
                        	}
                            // new schedule is schedule 0 now
                    mhCounter_[0]->sched(sf->sleepTime);
                            schedTab_[0].syncNode = sf->syncNode;
                            schedTab_[0].txSync = 1;  // need send sync
                            schedTab_[0].txData = 0;
                    schedTab_[0].numPeriods = 0;
                            schedTab_[0].numNodes = 2; // 1st node + I are following this sched
                            schedTab_[0].chkSched = 0;

                            schedId = 0;
                    	}
                        else { // fill new schedule in schedule i

                        mhCounter_[i]->sched(sf->sleepTime);
                            schedTab_[i].syncNode = sf->syncNode;
                            schedTab_[i].txSync = 1;  // need send sync
                            schedTab_[i].txData = 0;
                            schedTab_[i].numPeriods = 0;
                            schedTab_[i].numNodes = 1; // 1st node following this sched
                            schedTab_[i].chkSched = 0;
                            schedId = i;
                            numSched_++;  // increment number of schedules
                    	}
                        break;
                    	}
                	}
    	}
    }

        if (nodeId == SMAC_MAX_NUM_NEIGHBORS) {  // a new node
            // didn't find an empty entry in schedule table, just drop the new node
            if (schedId == SMAC_MAX_NUM_SCHEDULES) return;
            // add it to my neighbor list
            if (numNeighb_ < SMAC_MAX_NUM_NEIGHBORS){
                for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) {
                    if (neighbList_[i].state == 0) { // found an empty entry
                        neighbList_[i].state = sf->state;
                        neighbList_[i].nodeId = sf->srcAddr;
                        neighbList_[i].schedId = schedId;
                        neighbList_[i].active = 1;
                        numNeighb_++;  // increment number of neighbors
                        return;
                    }
                }
         }
         // didn't find an empty entry in neighb list, just drop the new node
    schedTab_[schedId].numNodes--;
        if (schedTab_[schedId].numNodes == 0)
            numSched_--;
        } else if (flag == 1) {  // old node switches to a new schedule
            // didn't find an empty entry in schedule table, delete the old node
            if (schedId == SMAC_MAX_NUM_SCHEDULES) {
                    neighbList_[nodeId].state = 0;
                    numNeighb_--;  // decrement number of neighbors
            } else {
                    neighbList_[nodeId].state = sf->state;
                    neighbList_[nodeId].schedId = schedId;
                    neighbList_[nodeId].active = 1;
            }

            // maybe the old node switches from schedTab_[0]
            // check if I am the only one on schedTab_[0] now
            // if yes, I should follow the next available schedule
            if (txRequest_ == 0) {
                    checkMySched();
            } else {
                // set flag to call checkMySched() when txRequest_ becomes 0
                    schedTab_[0].chkSched = 1;
            }
        } else {  // old node switches to old schedule
                neighbList_[nodeId].state = sf->state;
                neighbList_[nodeId].schedId = schedId;
                neighbList_[nodeId].active = 1;
        if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){
            //printf("#############################################################\n");
                    //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock());
                    //printf("#############################################################\n");

                    // change state
                    schedState_++;
                        tempSched.syncNode = schedTab_[schedId].syncNode;
               

⌨️ 快捷键说明

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