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

📄 mac-802_11e.cc

📁 11e的草案 相信对相关研究人员很有用 如果你在这里搜到了
💻 CC
📖 第 1 页 / 共 4 页
字号:
}voidMac802_11e::collision(Packet *p){	switch(rx_state_) {	case MAC_RECV:		set_rx_state(MAC_COLL);		/* fall through */	case MAC_COLL:		assert(pktRx_);		assert(mhRecv_.busy());		/*		 *  Since a collision has occurred, figure out		 *  which packet that caused the collision will		 *  "last" the longest.  Make this packet,		 *  pktRx_ and reset the Recv Timer if necessary.		 */		if(txtime(p) > mhRecv_.expire()) {			mhRecv_.stop();			discard(pktRx_, DROP_MAC_COLLISION);			pktRx_ = p;			mhRecv_.start(txtime(pktRx_));		}		else {			discard(p, DROP_MAC_COLLISION);		}		break;	default:		assert(0);	}}voidMac802_11e::tx_resume(){	double rTime;	assert(mhSend_.busy() == 0);		for(int pri = 0; pri < MAX_PRI; pri++){	    //assert(mhDefer_.defer(pri) == 0);	    if(!mhDefer_.defer(pri)) {		if(pktCTRL_[pri]) {		/*		 *  Need to send a CTS or ACK.		 */		    mhSifs_.start(pri, sifs_);		} else if(pktRTS_[pri]) {		    if(mhBackoff_.backoff(pri) == 0) {		      rTime = (Random::random() % getCW(LEVEL(pktRTS_[pri]))) * phymib_.getSlotTime();		      mhDefer_.start(pri, getAIFS(LEVEL(pktRTS_[pri]))); 		    }		} else if(pktTx_[pri]) {		    if(mhBackoff_.backoff(pri) == 0) {			hdr_cmn *ch = HDR_CMN(pktTx_[pri]);			struct hdr_mac802_11e *mh = HDR_MAC802_11E(pktTx_[pri]);						if ((u_int32_t) ch->size() < macmib_.RTSThreshold ||			    (u_int32_t) ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {			  			  if((u_int32_t) ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) rTime = (Random::random() % (getCW(pri) + 1)) * phymib_.getSlotTime();			  else rTime = 0;			    mhDefer_.start(pri, getAIFS(pri) + rTime);			} else {			    mhSifs_.start(pri, sifs_); 			}		    }		} else if(callback_[pri] != 0) {		  rtx_[pri] = 0;		  Handler *h = callback_[pri];		  callback_[pri] = 0;		  h->handle((Event*) 0);		}		set_tx_state(pri, MAC_IDLE);	    }	}}voidMac802_11e::rx_resume(){  assert(pktRx_ == 0);    assert(mhRecv_.busy() == 0);    set_rx_state(MAC_IDLE);}/* ======================================================================   Timer Handler Routines   ====================================================================== */voidMac802_11e::backoffHandler(int pri){   if(pktCTRL_[pri]) {    assert(mhSend_.busy() || mhDefer_.defer(pri));    return;  }    if(check_pktRTS(pri) == 0)    return;    if(check_pktTx(pri) == 0)    return;}voidMac802_11e::deferHandler(int pri){	assert(pktCTRL_[pri] || pktRTS_[pri] || pktTx_[pri]);	if(check_pktCTRL(pri) == 0)		return;	assert(mhBackoff_.backoff(pri) == 0);	//if (mhBackoff_.busy() != 0)	//{	//	printf("deferHandler:mhBackoff_ busy!\n");	//	return;	//}	if(check_pktRTS(pri) == 0)		return;	if(check_pktTx(pri) == 0)		return;}voidMac802_11e::navHandler(){    eifs_nav_ = 0.0;    if(is_idle() && mhBackoff_.paused()) {		mhBackoff_.resume();    }}voidMac802_11e::recvHandler(){    	recv_timer();}voidMac802_11e::sendHandler(){    Scheduler &s = Scheduler::instance();    sending = 0;    check_backoff_timer();    send_timer();}voidMac802_11e::txHandler(){    tx_active_ = 0;    if(cfb_ && !cfb_broadcast) cfb_active = 0;    if(cfb_broadcast) cfb_broadcast = 0;}voidMac802_11e::defer_stop(int pri){   mhBackoff_.start(pri, getCW(pri), is_idle());}/* sends the throughput every AK_INTERVAL to Akaroa  * via AkObservation. This works only if you have  * installed Akaroa and the ns-2/Akaroa interface. */voidMac802_11e::calc_throughput(){#if AKAROA > 0  if(AKAROA){	    if(index_ > 0){      //int pri = 2;       // jitter is for cases in which the simulation is      // already in a steady state at the very beginning      if (jitter >0) {if(jitter >= 10 ) jitter -= 10; }      for(int pri = 0; pri < 3; pri++){	if(jitter > 0){	  throughput = ((numbytes_[pri] * 8.) / interval_) + Random::uniform(0,jitter);	}else {	  throughput = (8. * numbytes_[pri]) / interval_;	}	if(throughput <= 0) throughput = 0.0001;	AkObservation((3 * (index_ - 1)) + (pri + 1), throughput);	//AkObservation((6 * (index_ - 1)) + (pri + 1), throughput);	//AkObservation((pri + 1), throughput);	//AkObservation(1, throughput);	//if(index_ == 1 && pri == 0) {	cout.precision(16);	//cout<<"Mac "<<index_<<", now: "<<Scheduler::instance().clock()<<", priority "<<pri<<", throughput: "<<throughput<<", interval_: "<<interval_<<" numbytes " << numbytes_[pri] <<"  jitter "<<jitter<<"\n";	//}	numbytes_[pri] = 0; throughput = 0;      }      AK.start();    }   }#endif}/* ======================================================================   The "real" Timer Handler Routines   ====================================================================== */voidMac802_11e::send_timer(){    Scheduler &s = Scheduler::instance();    for(int pri = 0; pri < MAX_PRI; pri ++){	switch(tx_state_[pri]) {	/*	 * Sent a RTS, but did not receive a CTS.	 */	case MAC_RTS:		RetransmitRTS(pri);		break;	/*	 * Sent a CTS, but did not receive a DATA packet.	 */	case MAC_CTS:		assert(pktCTRL_[pri]);		Packet::free(pktCTRL_[pri]); pktCTRL_[pri] = 0;		break;	/*	 * Sent DATA, but did not receive an ACK packet.	 */	case MAC_SEND:		RetransmitDATA(pri);		break;	/*	 * Sent an ACK, and now ready to resume transmission.	 */	case MAC_ACK:		assert(pktCTRL_[pri]);		Packet::free(pktCTRL_[pri]); pktCTRL_[pri] = 0;		break;	case MAC_IDLE:		break;	default:		assert(0);	}    }    //  if(mhDefer_.busy()) mhDefer_.stop();    if(!cfb_active) tx_resume();    }/* ======================================================================   Outgoing Packet Routines   ====================================================================== */intMac802_11e::check_pktCTRL(int pri) {	struct hdr_mac802_11e *mh;	double timeout;	if(pktCTRL_[pri] == 0)		return -1;	if(tx_state_[pri] == MAC_CTS || tx_state_[pri] == MAC_ACK)		return -1;	mh = HDR_MAC802_11E(pktCTRL_[pri]);							  	switch(mh->dh_fc.fc_subtype) {	/*	 *  If the medium is not IDLE, don't send the CTS.	 */	    case MAC_Subtype_CTS:	      if(!is_idle()) {			discard(pktCTRL_[pri], DROP_MAC_BUSY); pktCTRL_[pri] = 0;			return 0;	      }		set_tx_state(pri, MAC_CTS);				/*		 * timeout:  cts + data tx time calculated by		 *           adding cts tx time to the cts duration		 *           minus ack tx time -- this timeout is		 *           a guess since it is unspecified		 *           (note: mh->dh_duration == cf->cf_duration)		 */		timeout = txtime(phymib_.getCTSlen(), basicRate_)			+ DSSS_EDCA_MaxPropagationDelay			// XXX			+ sec(mh->dh_duration)			+ DSSS_EDCA_MaxPropagationDelay			// XXX			- sifs_			- txtime(phymib_.getACKlen(), basicRate_);				break;		/*		 * IEEE 802.11 specs, section 9.2.8		 * Acknowledments are sent after an SIFS, without regard to		 * the busy/idle state of the medium.		 */	    case MAC_Subtype_ACK:		set_tx_state(pri, MAC_ACK);		timeout = txtime(phymib_.getACKlen(), basicRate_);				break;	default:		fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n");		exit(1);	}	transmit(pktCTRL_[pri], timeout);	return 0;}intMac802_11e::check_pktRTS(int pri) {	struct hdr_mac802_11e *mh;	double timeout;	assert(mhBackoff_.backoff(pri) == 0);	if(pktRTS_[pri] == 0) 		return -1;	//struct hdr_cmn *ch = HDR_CMN(pktRTS_);	mh = HDR_MAC802_11E(pktRTS_[pri]); 	switch(mh->dh_fc.fc_subtype) {	case MAC_Subtype_RTS:	  if(! is_idle()) {		    inc_cw(pri); 		    mhBackoff_.start(pri, getCW(pri), is_idle());		    return 0;	  }		set_tx_state(pri, MAC_RTS);		timeout = txtime(phymib_.getRTSlen(), basicRate_)			+ DSSS_EDCA_MaxPropagationDelay			// XXX			+ sifs_			+ txtime(phymib_.getCTSlen(), basicRate_)			+ DSSS_EDCA_MaxPropagationDelay;			// XXX		break;	default:	    fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n");		exit(1);	}	transmit(pktRTS_[pri], timeout);	return 0;}int Mac802_11e::check_pktTx(int pri){        struct hdr_mac802_11e *mh;	double timeout;	assert(mhBackoff_.backoff(pri) == 0);		if(pktTx_[pri] == 0) {	    return -1;	}		mh = HDR_MAC802_11E(pktTx_[pri]);       	//int len = HDR_CMN(pktTx_)->size();	switch(mh->dh_fc.fc_subtype) {	case MAC_Subtype_Data:	    	    /*if(!is_idle()){	      sendRTS(pri, ETHER_ADDR(mh->dh_da));	      inc_cw(LEVEL(pktTx_[pri]));	      mhBackoff_.start(LEVEL(pktTx_[pri]), getCW(LEVEL(pktTx_[pri])), is_idle());	      return 0;	    }*/	    	    set_tx_state(pri, MAC_SEND);	    if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST)		timeout = txtime(pktTx_[pri])		            + DSSS_EDCA_MaxPropagationDelay		// XXX			    + sifs_			    + txtime(phymib_.getACKlen(), basicRate_)			    + DSSS_EDCA_MaxPropagationDelay;		// XXX		else		    timeout = txtime(pktTx_[pri]);		break;	    default:	    fprintf(stderr, "check_pktTx:Invalid MAC Control subtype\n");		//printf("pktRTS:%x, pktCTS/ACK:%x, pktTx:%x\n",pktRTS_, pktCTRL_,pktTx_);		exit(1);	}	transmit(pktTx_[pri], timeout);	return 0;}/* * Low-level transmit functions that actually place the packet onto * the channel. */voidMac802_11e::sendRTS(int pri, int dst){	Packet *p = Packet::alloc();	hdr_cmn* ch = HDR_CMN(p);	struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_);		assert(pktTx_[pri]);	assert(pktRTS_[pri] == 0);	/*	 *  If the size of the packet is larger than the	 *  RTSThreshold, then perform the RTS/CTS exchange.	 *	 *  XXX: also skip if destination is a broadcast	 */	if( (u_int32_t) HDR_CMN(pktTx_[pri])->size() < macmib_.RTSThreshold ||	    (u_int32_t) dst == MAC_BROADCAST) {		Packet::free(p);		//p = 0;		return;	}	ch->uid() = 0;	ch->ptype() = PT_MAC;	ch->size() = phymib_.getRTSlen();	ch->iface() = -2;	ch->error() = 0;	bzero(rf, MAC_HDR_LEN);	rf->rf_fc.fc_protocol_version = MAC_ProtocolVersion; 	rf->rf_fc.fc_type	= MAC_Type_Control; 	rf->rf_fc.fc_subtype	= MAC_Subtype_RTS; 	rf->rf_fc.fc_to_ds	= 0; 	rf->rf_fc.fc_from_ds	= 0; 	rf->rf_fc.fc_more_frag	= 0; 	rf->rf_fc.fc_retry	= 0; 	rf->rf_fc.fc_pwr_mgt	= 0; 	rf->rf_fc.fc_more_data	= 0; 	rf->rf_fc.fc_wep	= 0; 	rf->rf_fc.fc_order	= 0;	//rf->rf_duration = RTS_DURATION(pktTx_);	STORE4BYTE(&dst, (rf->rf_ra));		/* store rts tx time */ 	ch->txtime() = txtime(ch->size(), basicRate_);		STORE4BYTE(&index_, (rf->rf_ta));	/* calculate rts duration field */	rf->rf_duration = usec(sifs_			       + txtime(phymib_.getCTSlen(), basicRate_)			       + sifs_			       + txtime(pktTx_[pri])			       + sifs_			       + txtime(phymib_.getACKlen(), basicRate_));			pktRTS_[pri] = p;}voidMac802_11e::sendCTS(int pri, int dst, double rts_duration){	Packet *p = Packet::alloc();

⌨️ 快捷键说明

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