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

📄 mac-802_11_brdcst.cc

📁 thomson_mesh_modules_Enhanced Wireless Mesh Networking for ns-2 simulator
💻 CC
📖 第 1 页 / 共 4 页
字号:
	 * failed.	 */	if( ch->error() ) {		Packet::free(pktRx_);		set_nav(usec(phymib_.getEIFS()));		goto done;	}	/*	 * 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);	}	// VIVEK Scenario dependent logging	// ETT_ETX_HACK	// For ETX Only log data pkts here, not ACK, RTS, CTS etc.  if ((type == MAC_Type_Data) && (MAC_Subtype_Data == subtype) && (ch->size() == 127)) 		printf(TIME_FORMAT " %d %d %d %f %f %f %d\n", Scheduler::instance().clock(), addr(), ETHER_ADDR(mh->dh_ta), ETHER_ADDR(mh->dh_ra), mWtodB(pktRx_->txinfo_.RxPr*1000.0), mWtodB(pktRx_->get_interference()*1000.0), mWtodB(pktRx_->txinfo_.CPThresh), ch->size());	// For ETT Only log data pkts addressed to me//  if ((type == MAC_Type_Data) && (MAC_Subtype_Data == subtype) && (addr() == ETHER_ADDR(mh->dh_ra)) && (ch->size() == 127)) //		printf(TIME_FORMAT " %d %d %d %f %f %f %d\n", Scheduler::instance().clock(), addr(), ETHER_ADDR(mh->dh_ta), ETHER_ADDR(mh->dh_ra), mWtodB(pktRx_->txinfo_.RxPr*1000.0), mWtodB(pktRx_->get_interference()*1000.0), mWtodB(pktRx_->txinfo_.CPThresh), ch->size());//		printf(TIME_FORMAT " [%d]: %d->%d Pr=%f, interf=%f, CPTh=%f, lth=%d\n", Scheduler::instance().clock(), addr(), ETHER_ADDR(mh->dh_ta), ETHER_ADDR(mh->dh_ra), mWtodB(pktRx_->txinfo_.RxPr*1000.0), mWtodB(pktRx_->get_interference()*1000.0), mWtodB(pktRx_->txinfo_.CPThresh), ch->size());        /* 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_ta);		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;	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_11::recvRTS(Packet *p){	struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_);	if(tx_state_ != MAC_IDLE) {		discard(p, DROP_MAC_BUSY);		return;	}	/*	 *  If I'm responding to someone else, discard this RTS.	 */	if(pktCTRL_) {		discard(p, DROP_MAC_BUSY);		return;	}	sendCTS(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_11::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_11::txtime(double psz, double drt){	double dsz = psz - phymib_.getPLCPhdrLen();        int plcp_hdr = phymib_.getPLCPhdrLen() << 3;		int datalen = (int)dsz << 3;	double t = (((double)plcp_hdr)/phymib_.getPLCPDataRate())                                       + (((double)datalen)/drt);	return(t);}voidMac802_11::recvCTS(Packet *p){	if(tx_state_ != MAC_RTS) {		discard(p, DROP_MAC_INVALID_STATE);		return;	}	assert(pktRTS_);	Packet::free(pktRTS_); pktRTS_ = 0;	assert(pktTx_);		mhSend_.stop();	/*	 * The successful reception of this CTS packet implies	 * that our RTS was successful. 	 * According to the IEEE spec 9.2.5.3, you must 	 * reset the ssrc_, but not the congestion window.	 */	ssrc_ = 0;	tx_resume();	mac_log(p);}voidMac802_11::recvDATA(Packet *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_ra);	src = ETHER_ADDR(dh->dh_ta);	size = ch->size();	/*	 * Adjust the MAC packet size - ie; strip	 * off the mac header	 */	ch->size() -= phymib_.getHdrLen11();	ch->num_forwards() += 1;	/*	 *  If we sent a CTS, clean up...	 */	if(dst != MAC_BROADCAST) {		if(size >= macmib_.getRTSThreshold()) {			if (tx_state_ == MAC_CTS) {				assert(pktCTRL_);				Packet::free(pktCTRL_); pktCTRL_ = 0;				mhSend_.stop();				/*				 * Our CTS got through.				 */			} else {				discard(p, DROP_MAC_BUSY);				return;			}			sendACK(src);			tx_resume();		} else {			/*			 *  We did not send a CTS and there's no			 *  room to buffer an ACK.			 */			if(pktCTRL_) {				discard(p, DROP_MAC_BUSY);				return;			}			sendACK(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_11: 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.	 */		/* in BSS mode, if a station receives a packet via	 * the AP, and higher layers are interested in looking	 * at the src address, we might need to put it at	 * the right place - lest the higher layers end up	 * believing the AP address to be the src addr! a quick	 * grep didn't turn up any higher layers interested in	 * the src addr though!	 * anyway, here if I'm the AP and the destination	 * address (in dh_3a) isn't me, then we have to fwd	 * the packet; we pick the real destination and set	 * set it up for the LL; we save the real src into	 * the dh_3a field for the 'interested in the info'	 * receiver; we finally push the packet towards the	 * LL to be added back to my queue - accomplish this	 * by reversing the direction!*/	if ((bss_id() == addr()) && ((u_int32_t)ETHER_ADDR(dh->dh_ra)!= MAC_BROADCAST)&& ((u_int32_t)ETHER_ADDR(dh->dh_3a) != ((u_int32_t)addr()))) {		struct hdr_cmn *ch = HDR_CMN(p);		u_int32_t dst = ETHER_ADDR(dh->dh_3a);		u_int32_t src = ETHER_ADDR(dh->dh_ta);		/* if it is a broadcast pkt then send a copy up		 * my stack also		 */		if (dst == MAC_BROADCAST) {			uptarget_->recv(p->copy(), (Handler*) 0);		}		ch->next_hop() = dst;		STORE4BYTE(&src, (dh->dh_3a));		ch->addr_type() = NS_AF_ILINK;		ch->direction() = hdr_cmn::DOWN;	}	uptarget_->recv(p, (Handler*) 0);}voidMac802_11::recvACK(Packet *p){		// VIVEK_ARF	struct hdr_mac802_11* dh = HDR_MAC802_11(pktTx_); 	// Rcvr address is in pktTx_, not in p which is the ACK pkt	int arf_index;	if(tx_state_ != MAC_SEND) {		discard(p, DROP_MAC_INVALID_STATE);		return;	}	assert(pktTx_);	mhSend_.stop();	// VIVEK_ARF Increase rate if possible	arf_index = ARF_find_index(dh->dh_ra);	if((arf_index != -1) && (ARF_Entry[arf_index].algorithm != AUTO_RATE_NONE)){// Do this only if Auto rate is used		ARF_success(arf_index);	}	/*	 * 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.	 *	 * need to check the size of the packet we sent that's being	 * ACK'd, not the size of the ACK packet.	 */	if((u_int32_t) HDR_CMN(pktTx_)->size() <= macmib_.getRTSThreshold())		ssrc_ = 0;	else		slrc_ = 0;	rst_cw();	Packet::free(pktTx_); 	pktTx_ = 0;		/*	 * Backoff before sending again.	 */	assert(mhBackoff_.busy() == 0);	mhBackoff_.start(cw_, is_idle());	tx_resume();	mac_log(p);}// VIVEK_ARF// ARF Algorithm details obtained from//// ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-5208.pdf//// IEEE 802.11 Rate Adaptation: A Practical Approach//        Mathieu Lacage, Hossein Manshaei, Thierry Turletti// See mac-802_11.h for details//void Mac802_11::ARF_success(int index){	ARF_Entry[index].num_failed = 0;// Reset failure counter	if(ARF_Entry[index].probing_tx){// This was a probing tx, and it succeeded		ARF_Entry[index].probing_tx = 0;// Next tx is normal	}	ARF_Entry[index].num_success++;	if(ARF_Entry[index].num_success == ARF_Entry[index].success_thresh){		if(ARF_Entry[index].rate_index<NUM_DISCRETE_RATES-1){			ARF_Entry[index].rate_index++;     // Increase rate			ARF_Entry[index].num_success  = 0; // Reset success counter			ARF_Entry[index].timer        = ARF_TIMEOUT;// Reset timer			ARF_Entry[index].probing_tx   = 1; // Next tx is a probe//			printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: Thresh:     Rate increased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index);		}	}	return;}void Mac802_11::ARF_timer_expired(int index){	ARF_Entry[index].timer        = ARF_TIMEOUT;// Reset timer	if(ARF_Entry[index].rate_index<NUM_DISCRETE_RATES-1){		ARF_Entry[index].rate_index++;     // Increase rate		ARF_Entry[index].probing_tx   = 1; // Next tx is a probe //		printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: Probe:      Rate increased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index);	}	return;}void Mac802_11::ARF_decr_rate(int index){	ARF_Entry[index].num_failed++;	ARF_Entry[index].num_success  = 0; // Reset success counter	if((ARF_Entry[index].probing_tx) || (ARF_Entry[index].num_failed == ARF_FAILURE_THRESHOLD)){		// This was a probing tx, and it failed, lower rate		// Or, you have ARF_FAILURE_THRESHOLD successive failures		if(ARF_Entry[index].rate_index>0){			ARF_Entry[index].rate_index--; // Decrease rate if possible//			if(ARF_Entry[index].probing_tx)//				printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: Probe loss: Rate decreased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index);//			else//				printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: 2-pkt loss: Rate decreased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index);		}		// AARF		// This is the only place where ARF and AARF differ		if((ARF_Entry[index].probing_tx) && (ARF_Entry[index].algorithm==AUTO_RATE_AARF) && (2*ARF_Entry[index].success_thresh < MAX_AARF_SUCCESS_THRESHOLD)){			// Probing pkt lost // Algo is AARF // threshold can be doubled				ARF_Entry[index].success_thresh *= 2; // Binary Exponential Backoff//				printf("ARF_DEBUG Node[%d]->%d: BEB AARF thresh %d to %d\n", addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].success_thresh/2, ARF_Entry[index].success_thresh);		}				if((ARF_Entry[index].num_failed == ARF_FAILURE_THRESHOLD) && (ARF_Entry[index].algorithm==AUTO_RATE_AARF)){			// 2 consecutive lost pkts // Algorithm is AARF //				printf("ARF_DEBUG Node[%d]->%d: Reset AARF thresh %d to %d\n", addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].success_thresh, ARF_SUCCESS_THRESHOLD);				ARF_Entry[index].success_thresh = ARF_SUCCESS_THRESHOLD; // reset to minimum		}		// AARF		ARF_Entry[index].timer = ARF_TIMEOUT; // reset timer		if(ARF_Entry[index].num_failed == ARF_FAILURE_THRESHOLD)			ARF_Entry[index].num_failed = 0; //Reset this counter//		printf("Node[%d]->%d: Reset timer\n", addr(), ARF_Entry[index].MAC_ID);		ARF_Entry[index].probing_tx = 0; // Next tx is normal, not probe;	}	return;}int Mac802_11::ARF_find_index(u_char* macaddr){	int i, MAC_ID;	MAC_ID = (u_int32_t)ETHER_ADDR(macaddr);	if(counter_==0) // No auto rate. Defualt		return -1;	for(i=0;i<counter_;i++){//		printf("Node[%d]: ARF_Entry[%d].MAC_ID=%d\n", addr(), i, ARF_Entry[i].MAC_ID);		if(MAC_ID == ARF_Entry[i].MAC_ID)			return i;	}//	printf("ARF_find_index(): Something WRONG, MAC_ID=%d!\n", MAC_ID);	return -1;}void Mac802_11::ARF_update_txtime(Packet *p, int index){	hdr_cmn* ch = HDR_CMN(p);//	printf("Node[%d]->%d; Index:CPTHRESH:TXTIME from %f:%f to ", addr(), p->txinfo_.CPThresh, ch->txtime());	p->txinfo_.CPThresh = link_SINR[ARF_Entry[index].rate_index];	ch->txtime() = txtime(ch->size(), link_bitrate[ARF_Entry[index].rate_index]);//	printf("%f:%f\n", p->txinfo_.CPThresh, ch->txtime());	return;}// VIVEK_ARF

⌨️ 快捷键说明

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