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

📄 smac.cc

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