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

📄 mac-802_11.cc

📁 在网络仿真模拟工具下实现MAC层802.11DCF协议
💻 CC
📖 第 1 页 / 共 4 页
字号:
inline int Mac802_11::hdr_src(char* hdr, int src ){	struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;	// change wrt Mike's code	/*if(src > -2)		STORE4BYTE(&src, (dh->dh_sa));	return ETHER_ADDR(dh->dh_sa);*/        if(src > -2)               STORE4BYTE(&src, (dh->dh_ta));        return ETHER_ADDR(dh->dh_ta);	// change ends}inline int Mac802_11::hdr_type(char* hdr, u_int16_t type){	struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;	if(type)		STORE2BYTE(&type,(dh->dh_body));	return GET2BYTE(dh->dh_body);}/* ======================================================================   Misc Routines   ====================================================================== */// change wrt Mike's code#undef INTERLEAVING// change endsinline intMac802_11::is_idle(){	// change wrt Mike's code #ifdef INTERLEAVING #define INTERLEAVING_TIME 0.030       Scheduler &s = Scheduler::instance();       double st = s.clock();       double nextCycle = floor(st / (INTERLEAVING_TIME*2) + 1)                               * INTERLEAVING_TIME*2;       double nextSwitch = nextCycle - INTERLEAVING_TIME               - phymib_.getDIFS()               - phymib_.getSIFS()                              + txtime(phymib_.getCTSlen(), basicRate_)               - txtime(phymib_.getCTSlen(), basicRate_) * 2               - (Random::random() % cw_) * phymib_.getSlotTime();       if ((st >= nextSwitch) && (st < nextCycle)) {               if (nextCycle > nav_) {                       nav_ = nextCycle;                       if (mhNav_.busy()) {                               mhNav_.stop();                       }                       mhNav_.start(nextCycle - st);               }               return(0);       } #endif	// change ends	if(rx_state_ != MAC_IDLE)		return 0;	if(tx_state_ != MAC_IDLE)		return 0;	if(nav_ > Scheduler::instance().clock())		return 0;		return 1;}voidMac802_11::discard(Packet *p, const char* why){	hdr_mac802_11* mh = HDR_MAC802_11(p);	hdr_cmn *ch = HDR_CMN(p);#if 0	/* old logic 8/8/98 -dam */	/*	 * If received below the RXThreshold, then just free.	 */	if(p->txinfo_.Pr < p->txinfo_.ant.RXThresh) {		Packet::free(p);		//p = 0;		return;	}#endif // 0	/* 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(mh->dh_fc.fc_type) {	case MAC_Type_Management:		drop(p, why);		return;	case MAC_Type_Control:		switch(mh->dh_fc.fc_subtype) {		case MAC_Subtype_RTS:			// change wrt Mike's code			//if((u_int32_t)ETHER_ADDR(mh->dh_sa) == 			 if((u_int32_t)ETHER_ADDR(mh->dh_ta) ==  (u_int32_t)index_) {				drop(p, why);				return;			}			//change ends			/* fall through - if necessary */		case MAC_Subtype_CTS:		case MAC_Subtype_ACK:			// change wrt Mike's code			//if((u_int32_t)ETHER_ADDR(mh->dh_da) == 			if((u_int32_t)ETHER_ADDR(mh->dh_ra) == \			 (u_int32_t)index_) {				drop(p, why);				return;			}			break;		default:			fprintf(stderr, "invalid MAC Control subtype\n");			exit(1);		}		break;	case MAC_Type_Data:		switch(mh->dh_fc.fc_subtype) {		case MAC_Subtype_Data:			// change wrt Mike's code			/*if((u_int32_t)ETHER_ADDR(mh->dh_da) == \			   (u_int32_t)index_ ||			   (u_int32_t)ETHER_ADDR(mh->dh_sa) == \			   (u_int32_t)index_ ||			   (u_int32_t)ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {				drop(p,why);				return;			*/			if((u_int32_t)ETHER_ADDR(mh->dh_ra) == \                           (u_int32_t)index_ ||                          (u_int32_t)ETHER_ADDR(mh->dh_ta) == \                           (u_int32_t)index_ ||                          (u_int32_t)ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) {                                drop(p,why);                                return;			}			break;		default:			fprintf(stderr, "invalid MAC Data subtype\n");			exit(1);		}		break;	default:		fprintf(stderr, "invalid MAC type (%x)\n", mh->dh_fc.fc_type);		trace_pkt(p);		exit(1);	}	Packet::free(p);}voidMac802_11::capture(Packet *p){	/*	 * Update the NAV so that this does not screw	 * up carrier sense.	 */	// change wrt Mike's code	//set_nav(usec(eifs_ + txtime(p)));		set_nav(usec(phymib_.getEIFS() + txtime(p)));	Packet::free(p);}voidMac802_11::collision(Packet *p){	switch(rx_state_) {	case MAC_RECV:		// change wrt Mike's code		//SET_RX_STATE(MAC_COLL);		setRxState(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_11::tx_resume(){	double rTime;	assert(mhSend_.busy() == 0);	assert(mhDefer_.busy() == 0);	if(pktCTRL_) {		/*		 *  Need to send a CTS or ACK.		 */		// change wrt Mike's code		//mhDefer_.start(sifs_);		mhDefer_.start(phymib_.getSIFS());	} else if(pktRTS_) {		if(mhBackoff_.busy() == 0) {			// change wrt Mike's code			/*			rTime = (Random::random() % cw_) * phymib_->SlotTime;			mhDefer_.start(difs_ + rTime);			*/			 rTime = (Random::random() % cw_)                               * phymib_.getSlotTime();                       mhDefer_.start( phymib_.getDIFS() + rTime);		}	} else if(pktTx_) {		if(mhBackoff_.busy() == 0) {			hdr_cmn *ch = HDR_CMN(pktTx_);			struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_);						// change wrt Mike's code			/*			if ((u_int32_t) ch->size() < macmib_->RTSThreshold ||			    (u_int32_t) ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {				rTime = (Random::random() % cw_) * phymib_->SlotTime;				mhDefer_.start(difs_ + rTime);			} else {				mhDefer_.start(sifs_);			}			*/			if ((u_int32_t) ch->size() < macmib_.getRTSThreshold()                                || (u_int32_t) ETHER_ADDR(mh->dh_ra)                                               == MAC_BROADCAST)                       {                               rTime = (Random::random() % cw_)                                       * phymib_.getSlotTime();                               mhDefer_.start(phymib_.getDIFS() + rTime);                        } else {                               mhDefer_.start(phymib_.getSIFS());                        }		}	} else if(callback_) {		Handler *h = callback_;		callback_ = 0;		h->handle((Event*) 0);	}	// change wrt Mike's code	//SET_TX_STATE(MAC_IDLE);	setTxState(MAC_IDLE);}voidMac802_11::rx_resume(){	assert(pktRx_ == 0);	assert(mhRecv_.busy() == 0);	// change wrt Mike's code	//SET_RX_STATE(MAC_IDLE);	setRxState(MAC_IDLE);}/* ======================================================================   Timer Handler Routines   ====================================================================== */voidMac802_11::backoffHandler(){///-ak-------//	printf("backoff andler \n");	if(pktCTRL_) {		assert(mhSend_.busy() || mhDefer_.busy());		return;	}	if(check_pktRTS() == 0)		return;	if(check_pktTx() == 0)		return;}// change wrt Mike's code void Mac802_11::beaconHandler() {       /* schedule timer for the next beacon! */ //    mhBeacon_.start(cfp_period_); }voidMac802_11::deferHandler(){	assert(pktCTRL_ || pktRTS_ || pktTx_);	if(check_pktCTRL() == 0)		return;	assert(mhBackoff_.busy() == 0);	//if (mhBackoff_.busy() != 0)	//{	//	printf("deferHandler:mhBackoff_ busy!\n");	//	return;	//}	if(check_pktRTS() == 0)		return;	if(check_pktTx() == 0)		return;}voidMac802_11::navHandler(){	if(is_idle() && mhBackoff_.paused())		// change wrt Mike's code		//mhBackoff_.resume(difs_);		mhBackoff_.resume(phymib_.getDIFS());}voidMac802_11::recvHandler(){	recv_timer();}voidMac802_11::sendHandler(){	send_timer();}voidMac802_11::txHandler(){	// change wrtt Mike's code       if (EOTtarget_) {               assert(eotPacket_);               EOTtarget_->recv(eotPacket_, (Handler *) 0);               eotPacket_ = NULL;       }	tx_active_ = 0;}/* ======================================================================   The "real" Timer Handler Routines   ====================================================================== */voidMac802_11::send_timer(){	switch(tx_state_) {	/*	 * Sent a RTS, but did not receive a CTS.	 */	case MAC_RTS:		RetransmitRTS();		break;	/*	 * Sent a CTS, but did not receive a DATA packet.	 */	case MAC_CTS:		assert(pktCTRL_);		Packet::free(pktCTRL_); pktCTRL_ = 0;		break;	/*	 * Sent DATA, but did not receive an ACK packet.	 */	case MAC_SEND:		RetransmitDATA();		break;	/*	 * Sent an ACK, and now ready to resume transmission.	 */	case MAC_ACK:		assert(pktCTRL_);		Packet::free(pktCTRL_); pktCTRL_ = 0;		break;	case MAC_IDLE:		break;	default:		assert(0);	}	tx_resume();}/* ======================================================================   Outgoing Packet Routines   ====================================================================== */intMac802_11::check_pktCTRL(){	struct hdr_mac802_11 *mh;	double timeout;	if(pktCTRL_ == 0)		return -1;	if(tx_state_ == MAC_CTS || tx_state_ == MAC_ACK)		return -1;	mh = HDR_MAC802_11(pktCTRL_);							  	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_, DROP_MAC_BUSY); pktCTRL_ = 0;			return 0;		}		// change wrt Mike's code		//SET_TX_STATE(MAC_CTS);		setTxState(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)		 */		// change wrt Mike's code		/*timeout = txtime(ETHER_CTS_LEN, basicRate_)			+ DSSS_MaxPropagationDelay			// XXX			+ sec(mh->dh_duration)			+ DSSS_MaxPropagationDelay			// XXX			- sifs_			- txtime(ETHER_ACK_LEN, basicRate_);*/				 timeout = txtime(phymib_.getCTSlen(), basicRate_)                        + DSSS_MaxPropagationDelay                      // XXX                        + sec(mh->dh_duration)                        + DSSS_MaxPropagationDelay                      // XXX                       - phymib_.getSIFS()                       - 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:				// change wrt Mike's code		/*SET_TX_STATE(MAC_ACK);		timeout = txtime(ETHER_ACK_LEN, basicRate_);*/		setTxState(MAC_ACK);                timeout = txtime(phymib_.getACKlen(), basicRate_);				break;	default:		fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n");		exit(1);	}	// change wrt Mike's code //       TRANSMIT(pktCTRL_, timeout);	transmit(pktCTRL_, timeout);	return 0;}intMac802_11::check_pktRTS(){	struct hdr_mac802_11 *mh;	double timeout;	assert(mhBackoff_.busy() == 0);	if(pktRTS_ == 0) 		return -1;	//struct hdr_cmn *ch = HDR_CMN(pktRTS_);	mh = HDR_MAC802_11(pktRTS_); 	switch(mh->dh_fc.fc_subtype) {	case MAC_Subtype_RTS:		if(! is_idle()) {			inc_cw();			mhBackoff_.start(cw_, is_idle());			return 0;		}		// change wrt Mike's code		/*SET_TX_STATE(MAC_RTS);		timeout = txtime(ETHER_RTS_LEN, basicRate_)			+ DSSS_MaxPropagationDelay			// XXX			+ sifs_			+ txtime(ETHER_CTS_LEN, basicRate_)			+ DSSS_MaxPropagationDelay;			// XXX		*/		setTxState(MAC_RTS);               timeout = txtime(phymib_.getRTSlen(), basicRate_)                       + DSSS_MaxPropagationDelay                      // XXX                       + phymib_.getSIFS()                       + txtime(phymib_.getCTSlen(), basicRate_)                       + DSSS_MaxPropagationDelay;		break;	default:		fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n");		exit(1);	}	// change wrt Mike's code	// TRANSMIT(pktRTS_, timeout);

⌨️ 快捷键说明

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