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

📄 smac.cc

📁 网络仿真模拟工具NS2下实现的支持传感器网络的MAC协议SMAC
💻 CC
📖 第 1 页 / 共 5 页
字号:
                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 + -