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

📄 mac-802_11.cc

📁 ns2.1b5版本中cbrp碼
💻 CC
📖 第 1 页 / 共 2 页
字号:
        TRANSMIT(pktTx, timeout);	return 0;}/* * Low-level transmit functions that actually place the packet onto * the channel. */voidMac802_11::sendRTS(int dst){	Packet *p = Packet::alloc();	hdr_cmn* ch = HDR_CMN(p);	struct rts_frame *rf = (struct rts_frame*)p->access(off_mac_);	assert(pktTx);	assert(pktRTS == 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)->size() < macmib->RTSThreshold ||	    (u_int32_t) dst == MAC_BROADCAST) {		Packet::free(p);		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);	ETHER_ADDR(rf->rf_ra) = dst;	ETHER_ADDR(rf->rf_ta) = index;	// rf->rf_fcs;	pktRTS = p;}voidMac802_11::sendCTS(int dst, double rts_duration){	Packet *p = Packet::alloc();	hdr_cmn* ch = HDR_CMN(p);	struct cts_frame *cf = (struct cts_frame*)p->access(off_mac_);	assert(pktCTRL == 0);	ch->uid() = 0;	ch->ptype() = PT_MAC;	ch->size() = ETHER_CTS_LEN;	ch->iface() = -2;	ch->error() = 0;	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);	ETHER_ADDR(cf->cf_ra) = dst;	// cf->cf_fcs;	pktCTRL = p;}voidMac802_11::sendACK(int dst){	Packet *p = Packet::alloc();	hdr_cmn* ch = HDR_CMN(p);	struct ack_frame *af = (struct ack_frame*)p->access(off_mac_);	assert(pktCTRL == 0);	ch->uid() = 0;	ch->ptype() = PT_MAC;	ch->size() = ETHER_ACK_LEN;	ch->iface() = -2;	ch->error() = 0;	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();	ETHER_ADDR(af->af_ra) = dst;	// af->af_fcs;	pktCTRL = p;}voidMac802_11::sendDATA(Packet *p){	hdr_cmn* ch = HDR_CMN(p);	struct hdr_mac802_11* dh = HDR_MAC(p);	assert(pktTx == 0);	/*	 * Update the MAC header	 */	ch->size() += ETHER_HDR_LEN;	dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion;	dh->dh_fc.fc_type       = MAC_Type_Data;	dh->dh_fc.fc_subtype    = MAC_Subtype_Data;	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;	if(ETHER_ADDR(dh->dh_da) != MAC_BROADCAST)		dh->dh_duration = DATA_DURATION();	else		dh->dh_duration = 0;	pktTx = p;}/* ======================================================================   Retransmission Routines   ====================================================================== */voidMac802_11::RetransmitRTS(){	assert(pktTx);	assert(pktRTS);	assert(mhBackoff.busy() == 0);	macmib->RTSFailureCount++;	ssrc += 1;			// STA Short Retry Count	if(ssrc >= macmib->ShortRetryLimit) {		discard(pktRTS, DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS = 0;		/* tell the callback the send operation failed 		   before discarding the packet */		hdr_cmn *ch = HDR_CMN(pktTx);		if (ch->xmit_failure_) {                        /*                         *  Need to remove the MAC header so that                          *  re-cycled packets don't keep getting                         *  bigger.                         */                        ch->size() -= ETHER_HDR_LEN;                        ch->xmit_reason_ = XMIT_REASON_RTS;                        ch->xmit_failure_(pktTx->copy(),                                          ch->xmit_failure_data_);                }		discard(pktTx, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx = 0;		ssrc = 0;		rst_cw();	}	else {		struct rts_frame *rf;		rf = (struct rts_frame*)pktRTS->access(off_mac_);		rf->rf_fc.fc_retry = 1;		inc_cw();		mhBackoff.start(cw, is_idle());	}}voidMac802_11::RetransmitDATA(){	struct hdr_cmn *ch;	struct hdr_mac802_11 *mh;	u_int32_t *rcount, *thresh;	assert(mhBackoff.busy() == 0);	assert(pktTx);	assert(pktRTS == 0);	ch = HDR_CMN(pktTx);	mh = HDR_MAC(pktTx);	/*	 *  Broadcast packets don't get ACKed and therefore	 *  are never retransmitted.	 */	if(ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {		Packet::free(pktTx); pktTx = 0;		/*		 * Backoff at end of TX.		 */		rst_cw();		mhBackoff.start(cw, is_idle());		return;	}	macmib->ACKFailureCount++;	if((u_int32_t) ch->size() <= macmib->RTSThreshold) {		rcount = &ssrc;		thresh = &macmib->ShortRetryLimit;	}	else {		rcount = &slrc;		thresh = &macmib->LongRetryLimit;	}	(*rcount)++;	if(*rcount > *thresh) {		macmib->FailedCount++;		/* tell the callback the send operation failed 		   before discarding the packet */		hdr_cmn *ch = HDR_CMN(pktTx);		if (ch->xmit_failure_) {                        ch->size() -= ETHER_HDR_LEN;                        ch->xmit_reason_ = XMIT_REASON_ACK;                        ch->xmit_failure_(pktTx->copy(),                                          ch->xmit_failure_data_);                }		discard(pktTx, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx = 0;		*rcount = 0;		rst_cw();	}	else {		struct hdr_mac802_11 *dh;		dh = HDR_MAC(pktTx);		dh->dh_fc.fc_retry = 1;		sendRTS(ETHER_ADDR(mh->dh_da));		inc_cw();		mhBackoff.start(cw, is_idle());	}}/* ======================================================================   Incoming Packet Routines   ====================================================================== */voidMac802_11::send(Packet *p, Handler *h){	struct hdr_mac802_11* dh = HDR_MAC(p);	upcall_ = h;	sendDATA(p);	sendRTS(ETHER_ADDR(dh->dh_da));	/*	 * Assign the data packet a sequence number.	 */	dh->dh_scontrol = sta_seqno++;	/*	 *  If the medium is IDLE, we must wait for a DIFS	 *  Space before transmitting.	 */	if(mhBackoff.busy() == 0) {		if(is_idle()) {			/*			 * If we are already deferring, there is no			 * need to reset the Defer timer.			 */			if(mhDefer.busy() == 0)				mhDefer.start(difs);		}		/*		 * If the medium is NOT IDLE, then we start		 * the backoff timer.		 */		else {		mhBackoff.start(cw, is_idle());		}	}}voidMac802_11::recv(Packet *p, Handler *h){	struct hdr_cmn *hdr = HDR_CMN(p);	/*	 * Sanity Check	 */	assert(initialized());	/*	 *  Handle outgoing packets.	 */	if(h) {                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.	 */	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(TX_Time(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_11::recv_timer(){	hdr_cmn *ch = HDR_CMN(pktRx);	hdr_mac802_11 *mh = HDR_MAC(pktRx);	u_int32_t dst = ETHER_ADDR(mh->dh_da);	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));		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));		goto done;	}	/*	 * IEEE 802.11 specs, section 9.2.5.6	 *	- update the NAV (Network Allocation Vector)	 */	if(dst != index) {		set_nav(mh->dh_duration);	}        /* tap out */        if (tap && type == MAC_Type_Data &&            MAC_Subtype_Data == subtype) tap->tap(pktRx);	/*	 * Address Filtering	 */	if(dst != 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, "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, "Invalid MAC Data Subtype %x\n",				subtype);			exit(1);		}		break;	default:		fprintf(stderr, "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(off_mac_);	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);}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.  Hence, we can reset	 * the Short Retry Count and the CW.	 */	ssrc = 0;	rst_cw();	tx_resume();	mac_log(p);}voidMac802_11::recvDATA(Packet *p){	struct hdr_mac802_11 *dh = HDR_MAC(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_LEN;		ch->num_forwards() += 1;	}	/*	 *  If we sent a CTS, clean up...	 */	if(dst != MAC_BROADCAST) {		if(size >= macmib->RTSThreshold) {			if (tx_state == MAC_CTS) {				assert(pktCTRL);				Packet::free(pktCTRL); pktCTRL = 0;				mhSend.stop();				/*				 * Our CTS got through.				 */				ssrc = 0;				rst_cw();			}			else {				discard(p, DROP_MAC_BUSY);				return;			}			sendACK(src);			tx_resume();		}		/*		 *  We did not send a CTS and there's no		 *  room to buffer an ACK.		 */		else {			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.	   ============================================================ */	if(dst != MAC_BROADCAST) {		Host *h = &cache[src];		if(h->seqno && h->seqno == dh->dh_scontrol) {			discard(p, DROP_MAC_DUPLICATE);			return;		}		h->seqno = dh->dh_scontrol;	}	/*	 *  Pass the packet up to the link-layer.	 *  XXX - we could schedule an event to account	 *  for this processing delay.	 */	p->incoming = 1;	recvtarget_->recv(p, (Handler*) 0);}voidMac802_11::recvACK(Packet *p){	struct hdr_cmn *ch = HDR_CMN(p);	if(tx_state != MAC_SEND) {		discard(p, DROP_MAC_INVALID_STATE);		return;	}	assert(pktTx);	Packet::free(pktTx); pktTx = 0;	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 = 0;	else		slrc = 0;      /*       * Backoff before sending again.       */	rst_cw();	assert(mhBackoff.busy() == 0);	mhBackoff.start(cw, is_idle());	tx_resume();	mac_log(p);}

⌨️ 快捷键说明

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