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

📄 mac-802_11e.cc

📁 在网络仿真模拟工具下实现支持QoS的MAC层EDCF协议
💻 CC
📖 第 1 页 / 共 3 页
字号:
Mac802_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 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; jitter = (-1) * jitter;}      for(int pri = 0; pri < 3; pri++){	if(jitter > 0){	  throughput = jitter + ((numbytes_[pri] * 8.) / interval_);	}else {	  throughput = (8. * numbytes_[pri]) / interval_;	}	if(throughput <= 0) throughput = 0.0001;	AkObservation((3 * (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] << "\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_11 *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_11(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(ETHER_CTS_LEN, basicRate_)			+ DSSS_EDCF_MaxPropagationDelay			// XXX			+ sec(mh->dh_duration)			+ DSSS_EDCF_MaxPropagationDelay			// XXX			- sifs_			- txtime(ETHER_ACK_LEN, 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(ETHER_ACK_LEN, 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_11 *mh;	double timeout;	assert(mhBackoff_.backoff(pri) == 0);	if(pktRTS_[pri] == 0) 		return -1;	//struct hdr_cmn *ch = HDR_CMN(pktRTS_);	mh = HDR_MAC802_11(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(ETHER_RTS_LEN, basicRate_)			+ DSSS_EDCF_MaxPropagationDelay			// XXX			+ sifs_			+ txtime(ETHER_CTS_LEN, basicRate_)			+ DSSS_EDCF_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_11 *mh;	double timeout;	assert(mhBackoff_.backoff(pri) == 0);		if(pktTx_[pri] == 0) {	    return -1;	}		mh = HDR_MAC802_11(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_EDCF_MaxPropagationDelay		// XXX			    + sifs_			    + txtime(ETHER_ACK_LEN, basicRate_)			    + DSSS_EDCF_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() = ETHER_RTS_LEN;	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(ETHER_CTS_LEN, basicRate_)			       + sifs_			       + txtime(pktTx_[pri])			       + sifs_			       + txtime(ETHER_ACK_LEN, basicRate_));			pktRTS_[pri] = p;}voidMac802_11e::sendCTS(int pri, int dst, double rts_duration){	Packet *p = Packet::alloc();	hdr_cmn* ch = HDR_CMN(p);	struct cts_frame *cf = (struct cts_frame*)p->access(hdr_mac::offset_);	assert(pktCTRL_[pri] == 0);	ch->uid() = 0;	ch->ptype() = PT_MAC;	ch->size() = ETHER_CTS_LEN;	ch->iface() = -2;	ch->error() = 0;	//ch->direction() = hdr_cmn::DOWN;	bzero(cf, MAC_HDR_LEN);	cf->cf_fc.fc_protocol_version = MAC_ProtocolVersion;	cf->cf_fc.fc_type	= MAC_Type_Control;	cf->cf_fc.fc_subtype	= MAC_Subtype_CTS; 	cf->cf_fc.fc_to_ds	= 0; 	cf->cf_fc.fc_from_ds	= 0; 	cf->cf_fc.fc_more_frag	= 0; 	cf->cf_fc.fc_retry	= 0; 	cf->cf_fc.fc_pwr_mgt	= 0; 	cf->cf_fc.fc_more_data	= 0; 	cf->cf_fc.fc_wep	= 0; 	cf->cf_fc.fc_order	= 0;		//cf->cf_duration = CTS_DURATION(rts_duration);	STORE4BYTE(&dst, (cf->cf_ra));		/* store cts tx time */	ch->txtime() = txtime(ch->size(), basicRate_);		/* calculate cts duration */	cf->cf_duration = usec(sec(rts_duration)			       - sifs_			       - txtime(ETHER_CTS_LEN, basicRate_));		pktCTRL_[pri] = p;	}voidMac802_11e::sendACK(int pri, int dst){	Packet *p = Packet::alloc();	hdr_cmn* ch = HDR_CMN(p);	struct ack_frame *af = (struct ack_frame*)p->access(hdr_mac::offset_);	assert(pktCTRL_[pri] == 0);	ch->uid() = 0; // ACK-UID	ch->ptype() = PT_MAC;	ch->size() = ETHER_ACK_LEN;	ch->iface() = -2;	ch->error() = 0;	HDR_IP(p)->prio() = pri; //same priority as data packet	bzero(af, MAC_HDR_LEN);	af->af_fc.fc_protocol_version = MAC_ProtocolVersion; 	af->af_fc.fc_type	= MAC_Type_Control; 	af->af_fc.fc_subtype	= MAC_Subtype_ACK; 	af->af_fc.fc_to_ds	= 0; 	af->af_fc.fc_from_ds	= 0; 	af->af_fc.fc_more_frag	= 0; 	af->af_fc.fc_retry	= 0; 	af->af_fc.fc_pwr_mgt	= 0; 	af->af_fc.fc_more_data	= 0; 	af->af_fc.fc_wep	= 0; 	af->af_fc.fc_order	= 0;	//af->af_duration = ACK_DURATION();	STORE4BYTE(&dst, (af->af_ra));	/* store ack tx time */ 	ch->txtime() = txtime(ch->size(), basicRate_);		/* calculate ack duration */ 	af->af_duration = 0;			pktCTRL_[pri] = p;}voidMac802_11e::sendDATA(int pri, Packet *p){	hdr_cmn* ch = HDR_CMN(p);	struct hdr_mac802_11* dh = HDR_MAC802_11(p);	assert(pktTx_[pri] == 0);	/*	 * Update the MAC header	 */	ch->size() += ETHER_HDR_LEN11;	dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion;	dh->dh_fc.fc_type       = MAC_Type_Data;	dh->dh_fc.fc_subtype    = MAC_Subtype_Data;	//printf(".....p = %x, mac-subtype-%d\n",p,dh->dh_fc.fc_subtype);		dh->dh_fc.fc_to_ds      = 0;	dh->dh_fc.fc_from_ds    = 0;	dh->dh_fc.fc_more_frag  = 0;	dh->dh_fc.fc_retry      = 0;	dh->dh_fc.fc_pwr_mgt    = 0;	dh->dh_fc.fc_more_data  = 0;	dh->dh_fc.fc_wep        = 0;	dh->dh_fc.fc_order      = 0;	/* store data tx time */	if((u_int32_t)ETHER_ADDR(dh->dh_da) != MAC_BROADCAST) {		/* store data tx time for unicast packets */		ch->txtime() = txtime(ch->size(), dataRate_);				//dh->dh_duration = DATA_DURATION();				dh->dh_duration = usec(txtime(ETHER_ACK_LEN, basicRate_)  				       + sifs_);	} else {		/* store data tx time for broadcast packets (see 9.6) */		ch->txtime() = txtime(ch->size(), basicRate_);				dh->dh_duration = 0;	}	pktTx_[pri] = p;}/* ======================================================================   Retransmission Routines   ====================================================================== */voidMac802_11e::RetransmitRTS(int pri){	assert(pktTx_[pri]);	assert(pktRTS_[pri]);	assert(mhBackoff_.backoff(pri) == 0);	macmib_->RTSFailureCount++;	ssrc_[pri] += 1;			// STA Short Retry Count	if(ssrc_[pri] >= macmib_->ShortRetryLimit) {		discard(pktRTS_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS_[pri] = 0;		/* tell the callback the send operation failed 		   before discarding the packet */		hdr_cmn *ch = HDR_CMN(pktTx_[pri]);		if (ch->xmit_failure_) {                        /*                         *  Need to remove the MAC header so that                          *  re-cycled packets don't keep getting                         *  bigger.                         */                         ch->size() -= ETHER_HDR_LEN11;                         ch->xmit_reason_ = XMIT_REASON_RTS;                        ch->xmit_failure_(pktTx_[pri]->copy(),                                          ch->xmit_failure_data_);                }		//printf("(%d)....discarding RTS:%x\n",index_,pktRTS_);		rst_cw(pri);				discard(pktTx_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_[pri] = 0;		ssrc_[pri] = 0;			} else {		//printf("(%d)...retxing RTS:%x\n",index_,pktRTS_);		struct rts_frame *rf;		rf = (struct rts_frame*)pktRTS_[pri]->access(hdr_mac::offset_);		rf->rf_fc.fc_retry = 1;		inc_cw(LEVEL(pktTx_[pri]));		mhBackoff_.start(LEVEL(pktTx_[pri]), getCW(pri), is_idle());	}}voidMac802_11e::RetransmitDATA(int pri){    	struct hdr_cmn *ch;	struct hdr_mac802_11 *mh;	u_int32_t *rcount, *thresh;	assert(mhBackoff_.backoff(pri) == 0);		assert(pktTx_[pri]);	assert(pktRTS_[pri] == 0);	ch = HDR_CMN(pktTx_[pri]);	mh = HDR_MAC802_11(pktTx_[pri]);		/*	 *  Broadcast packets don't get ACKed and therefore	 *  are never retransmitted.	 */	if((u_int32_t)ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {	  /*	   * Backoff at end of TX.	   */	  if(!cfb_ || rx_state_ != MAC_IDLE){		rst_cw(pri);		mhBackoff_.start(pri, getCW(pri), is_idle());		Packet::free(pktTx_[pri]); pktTx_[pri] = 0;		return;	  } else{	    // if this is the first packet in cfb, we must take its	    // duration into account, too.	    if(cfb_dur == 0) {	      //cout<<"Mac "<<index<<", setting cfb_dur after Broadcast\n";	      cfb_dur = txtime(pktTx_[pri])		            + sifs_;		            //+ txtime(ETHER_ACK_LEN, basicRate_);	    }	    assert(pktTx_[pri]);	    Packet::free(pktTx_[pri]); pktTx_[pri] = 0;	    cfb(pri);	    return;	    }	} else if(cfb_) cfb_dur = 0;	macmib_->ACKFailureCount++;	rtx_[pri] = 1;	if((u_int32_t) ch->size() <= macmib_->RTSThreshold) {		rcount = &ssrc_[pri];		thresh = &macmib_->ShortRetryLimit;	}	else {		rcount = &slrc_[pri];		thresh = &macmib_->LongRetryLimit;	}	(*rcount)++;	if(*rcount > *thresh) {	  numbytes_[pri] -= ch->size() - ETHER_HDR_LEN11;	  rtx_[pri] = 0;	  macmib_->FailedCount++;	  /* tell the callback the send operation failed 	     before discarding the packet */	  hdr_cmn *ch = HDR_CMN(pktTx_[pri]);	  if (ch->xmit_failure_) {	    ch->size() -= ETHER_HDR_LEN11;	    ch->xmit_reason_ = XMIT_REASON_ACK;	    ch->xmit_failure_(pktTx_[pri]->copy(),			      ch->xmit_failure_data_);                }	  rst_cw(pri);	  discard(pktTx_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_[pri] = 0;	  //printf("(%d)DATA discarded: count exceeded\n",index_);	  *rcount = 0;					}	else {		struct hdr_mac802_11 *dh;		dh = HDR_MAC802_11(pktTx_[pri]);		dh->dh_fc.fc_retry = 1;		sendRTS(pri, ETHER_ADDR(mh->dh_da));		//printf("(%d)retxing data:%x..sendRTS..\n",index_,pktTx_);		inc_cw(LEVEL(pktTx_[pri]));		mhBackoff_.start(pri, getCW(pri), is_idle());	}}/* ======================================================================   Incoming Packet Routines   ====================================================================== */voidMac802_11e::send(Packet *p, Handler *h){        int pri = LEVEL(p);	double rTime;	struct hdr_mac802_11* dh = HDR_MAC802_11(p);	/* 	 * drop the packet if the node is in sleep mode	 XXX sleep mode can't stop node from sending packets	 */	EnergyModel *em = netif_->node()->energy_model();	if (em && em->sleep()) {		em->set_node_sleep(0);		em->set_node_state(EnergyModel::INROUTE);	}	callback_[pri] = h;	sendDATA(pri, p); // framing und Berechnung der Tx-Duration 	sendRTS(pri, ETHER_ADDR(dh->dh_da)); //check, ob packet groesser als RTSthreshold 	/*	 * Assign the data packet a sequence number.	 */	dh->dh_scontrol = sta_seqno_++;	/*	 *  If the medium is IDLE, we must wait for a DIFS

⌨️ 快捷键说明

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