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

📄 mac-802_11e.cc

📁 在网络仿真模拟工具下实现支持QoS的MAC层EDCF协议
💻 CC
📖 第 1 页 / 共 3 页
字号:
	 *  Space before transmitting.	 */        assert(mhDefer_.defer(pri) == 0); 	//fuer den Fall, dass medium nicht idle: CW und PS-Factor zu weisen	if(mhBackoff_.backoff(pri) == 0) { //Mac can be still  in post-backoff	  if(is_idle()) { 			/*			 * If we are already deferring, there is no			 * need to reset the Defer timer.			 */			if(mhDefer_.defer(pri) == 0) {			    rTime = ((Random::random() % getCW(LEVEL(p))) * phymib_->SlotTime);			    mhDefer_.start(LEVEL(p), getAIFS(LEVEL(p))); // + rTime);// - phymib_->SlotTime);							}					}	/*	 * If the medium is NOT IDLE, then we start	 * the backoff timer.	 */		else {		    mhBackoff_.start(LEVEL(p),getCW(LEVEL(p)), is_idle());		}	}  	    }voidMac802_11e::recv(Packet *p, Handler *h){   	struct hdr_cmn *hdr = HDR_CMN(p);	/*	 * Sanity Check	 */	//assert(initialized());	/*	 *  Handle outgoing packets.	 */	if(hdr->direction() == hdr_cmn::DOWN) {	    Scheduler &s = Scheduler::instance();	    send(p, h);	    return;        }	/*	 *  Handle incoming packets.	 *	 *  We just received the 1st bit of a packet on the network	 *  interface.	 *	 */	/*	 *  If the interface is currently in transmit mode, then	 *  it probably won't even see this packet.  However, the	 *  "air" around me is BUSY so I need to let the packet	 *  proceed.  Just set the error flag in the common header	 *  to that the packet gets thrown away.	 */	Scheduler &s = Scheduler::instance();	if(tx_active_ && hdr->error() == 0 ) {        		hdr->error() = 1;		}	if(rx_state_ == MAC_IDLE) {		SET_RX_STATE(MAC_RECV);		pktRx_ = p;		/*		 * Schedule the reception of this packet, in		 * txtime seconds.		 */		mhRecv_.start(txtime(p));	} else {		/*		 *  If the power of the incoming packet is smaller than the		 *  power of the packet currently being received by at least                 *  the capture threshold, then we ignore the new packet.		 */		if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) {			capture(p);		} else {			collision(p);		}	}}voidMac802_11e::recv_timer(){     Scheduler &s = Scheduler::instance();	u_int32_t src; 	hdr_cmn *ch = HDR_CMN(pktRx_);	hdr_mac802_11 *mh = HDR_MAC802_11(pktRx_);	u_int32_t dst = ETHER_ADDR(mh->dh_da);	// XXX debug	//struct cts_frame *cf = (struct cts_frame*)pktRx_->access(hdr_mac::offset_);	//u_int32_t src = ETHER_ADDR(mh->dh_sa);		u_int8_t  type = mh->dh_fc.fc_type;	u_int8_t  subtype = mh->dh_fc.fc_subtype;	assert(pktRx_);	assert(rx_state_ == MAC_RECV || rx_state_ == MAC_COLL);	        /*         *  If the interface is in TRANSMIT mode when this packet         *  "arrives", then I would never have seen it and should         *  do a silent discard without adjusting the NAV.         */        if(tx_active_) {                Packet::free(pktRx_);                goto done;        }	/*	 * Handle collisions.	 */	if(rx_state_ == MAC_COLL) {	    discard(pktRx_, DROP_MAC_COLLISION);	    set_nav(usec(eifs_));	    eifs_nav_ = eifs_;	    goto done;	}		/*	 * Check to see if this packet was received with enough	 * bit errors that the current level of FEC still could not	 * fix all of the problems - ie; after FEC, the checksum still	 * failed.	 */	if( ch->error() ) {	    Packet::free(pktRx_);	    set_nav(usec(eifs_));	    eifs_nav_ = eifs_;	    goto done;	}		/*	 * avoid Nav-reset bug:	 * if received packet has no  errors and had no collision, but nav 	 * was set due to an earlier collision, nav has to be reset!	 */         if(mhNav_.busy()) reset_eifs_nav();		/*	 * IEEE 802.11 specs, section 9.2.5.6	 *	- update the NAV (Network Allocation Vector)	 */	if(dst != (u_int32_t)index_) {	    set_nav(mh->dh_duration);	}        /* tap out - */        if (tap_ && type == MAC_Type_Data &&            MAC_Subtype_Data == subtype ) 		tap_->tap(pktRx_);	/*	 * Adaptive Fidelity Algorithm Support - neighborhood infomation 	 * collection	 *	 * Hacking: Before filter the packet, log the neighbor node	 * I can hear the packet, the src is my neighbor	 */	if (netif_->node()->energy_model() && 	    netif_->node()->energy_model()->adaptivefidelity()) {		src = ETHER_ADDR(mh->dh_sa);		netif_->node()->energy_model()->add_neighbor(src);	}	/*	 * Address Filtering	 */	if(dst != (u_int32_t)index_ && dst != MAC_BROADCAST) {		/*		 *  We don't want to log this event, so we just free		 *  the packet instead of calling the drop routine.		 */		discard(pktRx_, "---");		goto done;	}	switch(type) {	case MAC_Type_Management:		discard(pktRx_, DROP_MAC_PACKET_ERROR);		goto done;		break;	case MAC_Type_Control:		switch(subtype) {		case MAC_Subtype_RTS:			recvRTS(pktRx_);			break;		case MAC_Subtype_CTS:			recvCTS(pktRx_);			break;		case MAC_Subtype_ACK:			recvACK(pktRx_);			break;		default:			fprintf(stderr,"recvTimer1:Invalid MAC Control Subtype %x\n",				subtype);			exit(1);		}		break;	case MAC_Type_Data:		switch(subtype) {		case MAC_Subtype_Data:			recvDATA(pktRx_);			break;		default:			fprintf(stderr, "recv_timer2:Invalid MAC Data Subtype %x\n",				subtype);			exit(1);		}		break;	default:		fprintf(stderr, "recv_timer3:Invalid MAC Type %x\n", subtype);		exit(1);	} done:	pktRx_ = 0;	rx_resume();}voidMac802_11e::recvRTS(Packet *p){        int pri = LEVEL(p);	struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_);	if(tx_state_[pri] != MAC_IDLE) {		discard(p, DROP_MAC_BUSY);		return;	}	/*	 *  If I'm responding to someone else, discard this RTS.	 */	if(pktCTRL_[pri]) {		discard(p, DROP_MAC_BUSY);		return;	}	sendCTS(pri, ETHER_ADDR(rf->rf_ta), rf->rf_duration);	/*	 *  Stop deferring - will be reset in tx_resume().	 */	//	if(mhDefer_.busy()) mhDefer_.stop();	tx_resume();	mac_log(p);}/* * txtime()	- pluck the precomputed tx time from the packet header */doubleMac802_11e::txtime(Packet *p) {	 struct hdr_cmn *ch = HDR_CMN(p);	 double t = ch->txtime();	 if (t < 0.0) {		 drop(p, "XXX"); 		exit(1);	 }	 return t; } /* * txtime()	- calculate tx time for packet of size "psz" bytes  *		  at rate "drt" bps */doubleMac802_11e::txtime(double psz, double drt){	double dsz = psz - PLCP_HDR_LEN;	int plcp_hdr = PLCP_HDR_LEN << 3;	int datalen = (int)dsz << 3;		double t = (((double)plcp_hdr)/phymib_->PLCPDataRate) + (((double)datalen)/drt);	return(t);}voidMac802_11e::recvCTS(Packet *p){        int pri = LEVEL(p);	if(tx_state_[pri] != MAC_RTS) {		discard(p, DROP_MAC_INVALID_STATE);		return;	}	assert(pktRTS_[pri]);	Packet::free(pktRTS_[pri]); pktRTS_[pri] = 0;	assert(pktTx_[pri]);	// debug	//struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_);	//printf("(%d):recvCTS:pktTx_-%x,mac-subtype-%d & pktCTS_:%x\n",index_,pktTx_,mh->dh_fc.fc_subtype,p);		mhSend_.stop();	/*	 * The successful reception of this CTS packet implies	 * that our RTS was successful.  Hence, we can reset	 * the Short Retry Count and the CW.	 */	//ssrc_ = 0;	//rst_cw();	//	if(mhDefer_.busy()) mhDefer_.stop();	tx_resume();	mac_log(p);}voidMac802_11e::recvDATA(Packet *p){        int pri = LEVEL(p);	struct hdr_mac802_11 *dh = HDR_MAC802_11(p);	u_int32_t dst, src, size;	{	struct hdr_cmn *ch = HDR_CMN(p);		dst = ETHER_ADDR(dh->dh_da);		src = ETHER_ADDR(dh->dh_sa);		size = ch->size();		/*		 * Adjust the MAC packet size - ie; strip		 * off the mac header		 */		ch->size() -= ETHER_HDR_LEN11;		ch->num_forwards() += 1;	}	/*	 *  If we sent a CTS, clean up...	 */	if(dst != MAC_BROADCAST) {		if(size >= macmib_->RTSThreshold) {			if (tx_state_[pri] == MAC_CTS) {				assert(pktCTRL_[pri]);				Packet::free(pktCTRL_[pri]); pktCTRL_[pri] = 0;				mhSend_.stop();				/*				 * Our CTS got through.				 */				printf("(%d): RECVING DATA!\n",index_);				//ssrc_ = 0;				//rst_cw();			}			else {				discard(p, DROP_MAC_BUSY);				printf("(%d)..discard DATA\n",index_);				return;			}		                              // from my point of view, all defers have to be canceled		       // because we are going to send an ACK		       // => Backoff for all others			//			if(mhDefer_.busy()) mhDefer_.stop();			sendACK(pri, src);			tx_resume(); 		}		/*		 *  We did not send a CTS and there's no		 *  room to buffer an ACK.		 */		else {			if(pktCTRL_[pri]) {				discard(p, DROP_MAC_BUSY);				return;			}			//			if(mhDefer_.busy()) mhDefer_.stop();			sendACK(pri, src);			if(mhSend_.busy() == 0){			    tx_resume();			}		}	}	/* ============================================================	    Make/update an entry in our sequence number cache.	   ============================================================ */	/* Changed by Debojyoti Dutta. This upper loop of if{}else was 	   suggested by Joerg Diederich <dieder@ibr.cs.tu-bs.de>. 	   Changed on 19th Oct'2000 */        if(dst != MAC_BROADCAST) {                if (src < (u_int32_t) cache_node_count_) {		            Host *h = &cache_[src];                        if(h->seqno && h->seqno == dh->dh_scontrol) {			    discard(p, DROP_MAC_DUPLICATE);			    return;                        }                        h->seqno = dh->dh_scontrol;		                    } else {			static int count = 0;			if (++count <= 10) {				printf ("MAC_802_11e: accessing MAC cache_ array out of range (src %u, dst %u, size %d)!\n", src, dst, cache_node_count_);				if (count == 10)					printf ("[suppressing additional MAC cache_ warnings]\n");			};		};	}		/*	 *  Pass the packet up to the link-layer.	 *  XXX - we could schedule an event to account	 *  for this processing delay.	 */	//p->incoming = 1;	// XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details. 	uptarget_->recv(p, (Handler*) 0);}voidMac802_11e::recvACK(Packet *p){        int pri = LEVEL(p);	struct hdr_cmn *ch = HDR_CMN(p);	if(tx_state_[pri] != MAC_SEND) {	    discard(p, DROP_MAC_INVALID_STATE);	return;	}	//printf("(%d)...................recving ACK:%x\n",index_,p);		mhSend_.stop();		/*	 * The successful reception of this ACK packet implies	 * that our DATA transmission was successful.  Hence,	 * we can reset the Short/Long Retry Count and the CW.	 */	if((u_int32_t) ch->size() <= macmib_->RTSThreshold)		ssrc_[pri] = 0;	else		slrc_[pri] = 0;	/* succesful transmission => give throughput	 * to Akaroa	 */	if(rtx_[pri]) rtx_[pri] = 0;	sending = 0;	CHECK_BACKOFF_TIMER();        /*	 * Backoff before sending again.	 */	if(!cfb_ || ch->size() > macmib_->RTSThreshold) {	  assert(mhBackoff_.backoff(pri) == 0);	  rst_cw(pri);	  mhBackoff_.start(pri, getCW(pri), is_idle());	  assert(pktTx_[pri]);	  Packet::free(pktTx_[pri]); pktTx_[pri] = 0;	  tx_resume();	}	else{	  // if this is the first packet in cfb, we must take its	  // duration into account, too.	  if(cfb_dur == 0) {	      cfb_dur = txtime(pktTx_[pri])		            + sifs_		            + txtime(ETHER_ACK_LEN, basicRate_);	  }	  pktRx_ = 0;	  rx_resume();	  assert(pktTx_[pri]);	  Packet::free(pktTx_[pri]); pktTx_[pri] = 0;	  cfb(pri);	}	mac_log(p);}void Mac802_11e::cfb(int pri){  double timeout;  struct hdr_mac802_11 *mh;    // next packet out of queue  //cout<<"packets in queue:"<<queue_->pri_[pri].getLen()<<"\n";  if(queue_->pri_[pri].getLen() > 0) {      Packet* p = queue_->pri_[pri].deque();       // framing      sendDATA(pri, p);      hdr_cmn *ch = HDR_CMN(pktTx_[pri]);      mh = HDR_MAC802_11(pktTx_[pri]);      //cout<<"Mac "<<index_<<" in cfb(), pri "<<pri<<", cfb_bytes "<<cfb_bytes<<" + "<<ch->size()<<", cfb_maxbytes "<<cfb_maxbytes_<<"\n";      if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST) {	  cfb_dur +=  sifs_                       + txtime(pktTx_[pri])		      + sifs_                      + txtime(ETHER_ACK_LEN, basicRate_);	  cfb_broadcast = 0;      } else {	      cfb_dur += sifs_ 	              + txtime(pktTx_[pri]);              cfb_broadcast = 1;      }  } else cfb_dur = txop_limit_[pri] + 1;    if(cfb_dur <= txop_limit_[pri]) {    // send    if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST)      timeout = txtime(pktTx_[pri])	                    + DSSS_EDCF_MaxPropagationDelay				    + sifs_			    + txtime(ETHER_ACK_LEN, basicRate_)			    + DSSS_EDCF_MaxPropagationDelay;    else      timeout = txtime(pktTx_[pri]);        cfb_active = 1;    mhSifs_.start(pri, sifs_);  }  else {    cfb_dur = 0;    cfb_broadcast = 0;    assert(mhBackoff_.backoff(pri) == 0);    rst_cw(pri);    mhBackoff_.start(pri, getCW(pri), is_idle());    //assert(pktTx_[pri]);    //Packet::free(pktTx_[pri]); pktTx_[pri] = 0;    tx_resume();  }}// request parameters for each priority from the corresponding queuesdouble Mac802_11e::getAIFS(int pri){    if(!AIFSset){      levels = queue_->getLevels();      for(int i = 0; i < levels; i++ ){	slotnum = queue_->pri_[i].getAIFS();	aifs_[i] = sifs_ + (slotnum * phymib_->SlotTime);	txop_limit_[i] = queue_->pri_[i].getTXOPLimit();	//	    cout<<"Mac "<<index_<<", pri: "<<i<<", txop_limit:"<<txop_limit_[i]<<"\n";      }      AIFSset = 1;    }    return aifs_[pri];}int Mac802_11e::getCW(int level){    if(!CWset){	levels = queue_->getLevels();	for(int i = 0; i < levels; i++ ){	    cw_[i] = queue_->pri_[i].getCW_MIN();	    cwmin_[i] = queue_->pri_[i].getCW_MIN(); 	    cwmax_[i] = queue_->pri_[i].getCW_MAX(); 	}	CWset = 1;    }    return cw_[level];}voidMac802_11e::setQ(PriQ* priqueue){    queue_ = priqueue;}inline void Mac802_11e::reset_eifs_nav() {  if (eifs_nav_ > 0) {    double now = Scheduler::instance().clock();        assert(nav_ > now);    assert(mhNav_.busy());        mhNav_.stop();    nav_ -= eifs_nav_;    eifs_nav_ = 0.0;    if (nav_ > now) {      mhNav_.start(nav_ - now);    } else {      nav_ = now;      CHECK_BACKOFF_TIMER();    }  }}

⌨️ 快捷键说明

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