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

📄 mac_80211.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 3 页
字号:
    m_tx_failed=false;    m_seq_no=0;    SentPackets=RecvPackets=0;}template <class PLD>void MAC80211<PLD>::Stop(){    //printf("%s: sent %d, recv %d\n",GetName(),SentPackets,RecvPackets);}template <class PLD>void MAC80211<PLD>::from_network ( payload_t const& pld, const ether_addr_t& dst_addr, unsigned int size ){    // a new payload packet to be transmitted arrived from the higher layer    if(m_state!=MAC_IDLE)    {		Printf((DumpPackets,"mac%d state: %d, m_last_send: %f, simtime: %f\n",(int)MyEtherAddr,			m_state,m_last_send,SimTime()));		packet_t::free_pld(pld);		// only when mac is in MAC_IDLE can it transmit a payload packet. The		// below is to tell the higher layer that transmission has		// failed. In all cases an ack must be sent, whether it is a		// success or a failure		to_network_ack(false);		return;    }    if(size < RTSThreshold || dst_addr == ether_addr_t::BROADCAST )    {		m_long_pld=false;		m_ssrc=0;    }    else    {		m_long_pld=true;		m_slrc=0;    }        m_pldinfo.pld=pld;    m_pldinfo.dst_addr=dst_addr;    m_pldinfo.size=size;    m_seq_no++;    // start the defer timer without backoff. This is because    // if the medium is still free after difs or eifs then    // the packet can be sent immediately without backoff    StartDefer(false);}template <class PLD>void MAC80211<PLD>::DeferTimer(trigger_t&){    // deferral timer expires. It is now time to send out the packet    assert(m_state==MAC_DEFER);    Printf((DumpPackets,"mac%d deferal timer fires \n", (int)MyEtherAddr));    packet_t * np = packet_t::alloc();              // creates a new packet    if(m_long_pld==false)    {		// simply send out the packet without an RTS		np->hdr.dh_fc.fc_protocol_version = MAC_ProtocolVersion;		np->hdr.dh_fc.fc_type             = MAC_Type_Data;		np->hdr.dh_fc.fc_subtype          = MAC_Subtype_Data;		np->hdr.dh_da                     = m_pldinfo.dst_addr;		np->hdr.dh_sa                     = MyEtherAddr;		np->hdr.dh_scontrol               = m_seq_no;    	np->hdr.size = m_pldinfo.size + HDR_LEN;		np->hdr.tx_time = np->hdr.size / DataRate;		np->pld = m_pldinfo.pld;		if( np->hdr.dh_da != ether_addr_t::BROADCAST)		{	    	// this function increases the reference count of the packet by 1,	    	// virtually meaning this mac component partly owns the packet (together	    	// with any other components that will receive this packet, because of	    	// the use of reference counting. This mac component will regain the packet	    	// when the ack_timer expires (an ACKTimeout event).	    	np->inc_ref();	    	np->hdr.dh_duration = usec (m_sifs+ACK_LEN/BasicRate + np->hdr.size/DataRate);	    	// this function sets the ack time. Notice the first argument which is used	    	// to the packet that will be sent out. When the timer expires, whatever stored	    	// here will be returned	    	ack_timer.Set(np, np->hdr.dh_duration*1e-6 + m_difs + SimTime() );	    	m_state = MAC_ACK;          // waiting for ack		}		else		{	    	// it is a broadcast packet. just send it out and no need for ack	    	np->hdr.tx_time = np->hdr.size /BasicRate;	    	np->hdr.dh_duration = 0;	    	// send an ack to network layer, after a delay equal to the transmission time	    	assert(!network_ack_timer.Active());	    	network_ack_timer.Set(true,SimTime()+np->hdr.tx_time);	    	m_state = MAC_IDLE;		}    }    else    {		// np is now an RTS packet. Again, this mac component partly owns the packet		np->inc_ref();		np->hdr.dh_fc.fc_protocol_version = MAC_ProtocolVersion;		np->hdr.dh_fc.fc_type             = MAC_Type_Control;		np->hdr.dh_fc.fc_subtype          = MAC_Subtype_RTS;		np->hdr.dh_da                     = m_pldinfo.dst_addr;		np->hdr.dh_sa                     = MyEtherAddr;		np->hdr.size                      = RTS_LEN;                     		np->hdr.tx_time                   = np->hdr.size/BasicRate;		np->hdr.dh_duration = usec ( 3*m_sifs + CTS_LEN/BasicRate + 				     (m_pldinfo.size + HDR_LEN)/DataRate 				     + ACK_LEN/BasicRate );		// set the cts timer and change state to MAC_CTS		cts_timer.Set(np,np->hdr.dh_duration*1e-6 + m_sifs + SimTime());		m_state = MAC_CTS;    }    // send out the packet immediately. The second argument is the transmission time    TxPacket(np,np->hdr.tx_time);}template <class PLD>void MAC80211<PLD>::from_phy ( packet_t* pkt, bool errflag, double  power ){    // A packet has arrived from the physical layer. At this time, the first     // bit of the packet is just starting transmission    // printf("[%f] mac%d receiving %s (%e %d)\n",SimTime(),(int)MyEtherAddr,pkt->dump().c_str(),power,errflag);    Printf((DumpPackets,"mac%d start receiving %s (%e,%d)\n",(int)MyEtherAddr,pkt->dump().c_str(),power,errflag));    // if the recv timer is active then another receive is in progress    if( recv_timer.Active() )    {		packet_t* rx_packet = m_rxinfo.packet;			if( power > m_rxinfo.power * CPThreshold)		{	    	DropPacket(m_rxinfo.packet,"power too weak");	    	m_rxinfo.packet=pkt;	    	m_rxinfo.error=errflag;	    	m_rxinfo.power=power;	    	recv_timer.Set(SimTime()+pkt->hdr.tx_time);		}		else if (m_rxinfo.power > power * CPThreshold)		{	    	DropPacket(pkt, "power too weak");		}		else		{	    	simtime_t end_time = SimTime() + pkt->hdr.tx_time;	    	// to decide which lasts longer. The longer one takes the recv timer.	    	if( end_time > recv_timer.GetTime() )	    	{				recv_timer.Set(end_time);				DropPacket(rx_packet, "receive-receive collision");		    	m_rxinfo.packet=pkt;		    	m_rxinfo.error=errflag;	    		m_rxinfo.power=power;	    	}	    	else	    	{				DropPacket(pkt,"receive-receive collision");	    	}	    	m_rxinfo.error=1;   // set the error flag to 1		}    }    else    {    	m_rxinfo.packet=pkt;    	m_rxinfo.error=errflag;   		m_rxinfo.power=power;		// the recv timer expires as soon as the receive is done		recv_timer.Set(pkt->hdr.tx_time + SimTime());	    if(m_state==MAC_DEFER)	    {	        // if it is in the MAC_DEFER state, defer_timer must be	        // active. Have to defer it.	        assert(defer_timer.Active());	        // pt is the elapsed time after deferral starts	        double pt=SimTime()-m_defer_start;	        if(pt>m_ifs)	        {		        // pt-m_ifs is the time we have already spent		        // in the backoff period. Need to adjust		        // m_backoff_time accordingly		        m_backoff_time-= pt-m_ifs;		        assert(m_backoff_time>=0);    	    }	        defer_timer.Cancel();	        Printf((DumpPackets,"mac%d deferral suspended\n",(int)MyEtherAddr));	    }    }}template <class PLD>void MAC80211<PLD>::RecvTimer(trigger_t&){    // recv timer expires, meaning a packet has just been completely    // received.  Previously in the FromPhy function if there are    // outgoing backoff activity then it had been suspended    // (deferred). Therefore on every exit of this function, it must    // be checked by calling ResumeDefer() whether there is any    // outgoing payload packet to be sent    packet_t* p=m_rxinfo.packet;    Printf((DumpPackets,"mac%d received %s (%e,%d)\n",(int)MyEtherAddr,p->dump().c_str(),m_rxinfo.power,m_rxinfo.error));    // printf("[%f] mac%d received %s (%e,%d)\n",SimTime(),(int)MyEtherAddr,p->dump().c_str(),m_rxinfo.power,m_rxinfo.error);    if(m_rxinfo.error==1)  // if there is any error    {  	    DropPacket(p, "frame error");	    m_tx_failed = true;	    ResumeDefer();	    return ;    }    simtime_t now = SimTime();    // m_last_send is the time last packet had been sent    if( now - p->hdr.tx_time < m_last_send )    {	    // receive-send collision	    DropPacket(p,"frame error");	    m_tx_failed = true;        ResumeDefer();	    return;    }    ether_addr_t dst = p->hdr.dh_da;    uint8_t type = p->hdr.dh_fc.fc_type;    uint8_t subtype = p->hdr.dh_fc.fc_subtype;      // set the nav value    simtime_t nav = p->hdr.dh_duration*1e-6 + SimTime();    if(nav>m_nav) m_nav=nav;    RecvPackets++;    //printf(" %d %d\n",(int)p->hdr.dh_sa, (int)MyEtherAddr);    if( dst != MyEtherAddr && dst != ether_addr_t::BROADCAST)    {	    if( !Promiscuity || type!= MAC_Type_Data)  	    {             DropPacket(p,"wrong destination");	        m_tx_failed=false;	        ResumeDefer();            return;	    }    }    m_tx_failed=false;  // a transmission has been successful    switch(type)    {    case MAC_Type_Management:        DropPacket(p, "unknown MAC packet");        break;    case MAC_Type_Control:        switch(subtype)        {        case MAC_Subtype_RTS:            RecvRTS(p);            ResumeDefer();            break;        case MAC_Subtype_CTS:            RecvCTS(p);            ResumeDefer();            break;        case MAC_Subtype_ACK:            ResumeDefer();            RecvACK(p);	    break;        default:            fprintf(stderr, "recv_timer(1):Invalid MAC Control Subtype %x\n",                    subtype);            break;        }        break;    case MAC_Type_Data:        switch(subtype)        {        case MAC_Subtype_Data:            RecvData(p);	    break;        default:            fprintf(stderr, "recv_timer(2):Invalid MAC Data Subtype %x\n",                    subtype);            break;        }        break;    default:        fprintf(stderr, "recv_timer(3):Invalid MAC Type %x\n", subtype);        break;    }}template <class PLD>void MAC80211<PLD>::RecvRTS(packet_t* p){    if( m_state != MAC_IDLE && m_state != MAC_DEFER )    {	    // sorry, I am waiting for a CTS or an ACK. Clearly something	    // is wrong. A is sending me an RTS while I am communicating	    // with B. I just ignore A's request since the communication	    // with B will perhaps be successful in spite of A's presence	    DropPacket(p,"mac is busy");	    return;    }    // if nav_timer is active then another session (which may or may    // not involve this address) is already in the middle, so we have    // to ignore this packet    if( !nav_timer.Active() )    {	    // prepare a CTS packet	    packet_t* np = packet_t::alloc();	    np->hdr.dh_fc.fc_protocol_version = MAC_ProtocolVersion;	    np->hdr.dh_fc.fc_type       = MAC_Type_Control;	    np->hdr.dh_fc.fc_subtype    = MAC_Subtype_CTS;	    np->hdr.size=CTS_LEN;	    np->hdr.dh_da = p->hdr.dh_sa ;	    np->hdr.dh_sa=MyEtherAddr;	    np->hdr.tx_time = np->hdr.size/BasicRate;	    np->hdr.dh_duration = p->hdr.dh_duration - usec(m_sifs + RTS_LEN/BasicRate);	    // send out the packet at time SimTime()+m_sifs	    TxPacket(np,m_sifs,np->hdr.tx_time);		    // record session info

⌨️ 快捷键说明

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