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

📄 mac_80211.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 3 页
字号:
	    m_in_session=true;	    m_session_peer=p->hdr.dh_sa;	    assert(m_nav>=SimTime());	    nav_timer.Set(m_nav);	    // discard the RTS packet. Other mac components may be still processing	    // this packet so here only the reference count is decreased by one	    p->free();      }    else    {	    DropPacket(p,"unexpected RTS");	    return;    }}template <class PLD>void MAC80211<PLD>::RecvCTS(packet_t* p){    if(m_state != MAC_CTS)    {	    // sorry I don't need a CTS. Simply drop the packet and	    // do nothing.	    DropPacket(p, "CTS without RTS");	    return;    }        // prepare the data packet. Please refer to the same code in    // Defer() function.    packet_t* np = packet_t::alloc();    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=p->hdr.dh_sa;;    np->hdr.dh_sa=MyEtherAddr;    np->hdr.dh_scontrol=m_seq_no;	    np->hdr.size=m_pldinfo.size+HDR_LEN;    np->pld=m_pldinfo.pld;    np->hdr.tx_time = np->hdr.size/DataRate;    np->hdr.dh_duration = usec(2*m_sifs+ACK_LEN/BasicRate + np->hdr.size/DataRate);    m_state = MAC_ACK;    ack_timer.Set(np, np->hdr.dh_duration*1e-6 + m_difs + SimTime());    np->inc_ref();  // I need to keep a hand on this packet    TxPacket(np,m_sifs,np->hdr.tx_time);    // discard the CTS packet    p->free();    // cts timer still stores the RTS packet. Now need to discard it too    cts_timer.GetData()->free();    cts_timer.Cancel();  // the CTS packet has been received, so cancels                         // the CTSTimeout event    // (Gang) Actually cts timer doesn't need to store the RTS packet.    // The RTS packet can be immediately freed when the CTS is sent,    // for it is not used in the CTSTimer() function. The code has    // been so because of my initial misunderstanding of the protocol.    // I believed RTS must be retransmitted when CTSTimeout fires. Now    // I know deferral has to be restarted when this happens (am I    // right?)}template <class PLD>void MAC80211<PLD>::RecvData(packet_t* p){    if( m_state != MAC_IDLE && m_state != MAC_DEFER )    {	    // sorry, I am waiting for a CTS or an ACK	    DropPacket(p,"mac is busy");	    return;    }    if(p->hdr.dh_da==MyEtherAddr )//  ack is needed    {	    // if nav_timer is not active, we can ack the data packet.	    // Otherwise, we need to check if the current session involves	    // this address (by looking at m_in_session) and if the sender of	    // the data packet is the session peer. Only when both conditions	    // are satisfied can we reply this data packet.	    if( nav_timer.Active() && !(m_in_session&&p->hdr.dh_sa==m_session_peer) )	    {            ResumeDefer();	        DropPacket(p,"unexpected DATA");	        return;	    }	    	    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_ACK;	    np->hdr.dh_da=p->hdr.dh_sa;	    np->hdr.dh_sa=MyEtherAddr;	    np->hdr.size = ACK_LEN;	    np->hdr.tx_time = np->hdr.size /BasicRate;	    np->hdr.dh_duration = 0;	    TxPacket(np,m_sifs,np->hdr.tx_time);    }    ResumeDefer();    // maintain a database of latest sequence numbers received    // from each neighbor    cache_t::iterator src=m_recv_cache.find(p->hdr.dh_sa);    if(src!=m_recv_cache.end())    {	    // src->second is the latest sequence number	    // recently seen from the same source	    if(src->second==p->hdr.dh_scontrol)	    {	        // duplicate data packets. It seems that the source	        // did not receive the ack in the last round of 	        // transmissions	        DropPacket(p,"duplicated DATA packet");	        return;	    }	    else	    {	        // update the sequence number	        src->second=p->hdr.dh_scontrol;	    }    }    else    {	    // source not found in the neighbor list, so add it to the cache	    m_recv_cache.insert(make_pair(p->hdr.dh_sa,p->hdr.dh_scontrol));    }    // increase the reference count of the payload by one. This is to    // claim that I now partly own the payload. The ownership will be    // transferred to the hight layer.    p->inc_pld_ref();    // forward the payload contained in the data packet to higher layer.    to_network_data(p->pld,p->hdr.dh_da);    p->free(); // discard the data packet;}template <class PLD>void MAC80211<PLD>::RecvACK(packet_t* p){    if(m_state != MAC_ACK)    {	    DropPacket(p, "ACK without DATA");	    return;    }    p->free();                   // discard the ack packet    ack_timer.GetData()->free(); // discard the data packet    ack_timer.Cancel();     m_state=MAC_IDLE;                m_cw=CWMin;                  // reset the contention window    to_network_ack(true);  // inform the higher layer that                                 // the transmission has been successful}template <class PLD>void MAC80211<PLD>::CTSTimer(packet_t*& p){    // discard the RTS packet. It was stored in the cts timer when the cts    // timer was set. Now it is returned as the first argument of the CTSTimer    // function    p->free();                       assert(m_state==MAC_CTS);    // QUESTION FOR YOU: should I increase ssrc or slrc?    m_ssrc++;    if(m_ssrc< ShortRetryLimit )     {	    if(m_cw<CWMax)m_cw=2*m_cw+1;   // nearly double the contention window	    StartDefer(true);              // as name implies, must use backoff    }    else    {	    m_state=MAC_IDLE;              	    m_cw=CWMin;                    // reset the contention window	    to_network_ack(false);   // say sorry to the higher layer    }}template <class PLD>void MAC80211<PLD>::ACKTimer(packet_t*& p){    assert(m_state==MAC_ACK);    bool retry=false;    if(m_long_pld)    { 	    m_slrc++;	    if(m_slrc < LongRetryLimit)	        retry=true;    }    else    {	    m_ssrc++;	    if(m_ssrc < ShortRetryLimit)	        retry=true;    }    if(retry)                          // same as above    {	    if(m_cw<CWMax)m_cw=2*m_cw+1;	    StartDefer(true);	    p->inc_pld_ref();    }    else    {	    m_state=MAC_IDLE;	    m_cw=CWMin;      	to_network_ack(false);    }     p->free();}template <class PLD>void MAC80211<PLD>::NAVTimer(trigger_t&){    // the current session should terminate at this time    m_in_session=false;}template <class PLD>void MAC80211<PLD>::StartDefer(bool backoff){    // if the state is MAC_DEFER then ResumeDefer instead of this function must be called    assert(m_state!=MAC_DEFER);    assert(defer_timer.Active()==false);    m_backoff_time = Random( m_cw * SlotTime);  // select a backoff time    Printf((DumpPackets, "mac%d deferring (%d)\n",(int)MyEtherAddr,m_state));    // if the recv timer is active then do nothing except changing     // the state to MAC_DEFER, because it is guaranteed that at the    // end of RecvTimer, backoff must be resumed.    if(!recv_timer.Active())                        {	    // if last transmission failed, eifs must be used	    if(m_tx_failed) m_ifs=m_eifs;	    else m_ifs=m_difs;		    double pt = m_ifs;	    if(backoff) pt+=m_backoff_time; // may not need backoff	    double now=SimTime();	    if(now<m_last_send)now=m_last_send;	    if(m_nav>now)	        m_defer_start=m_nav;	    else	        m_defer_start=now;	    defer_timer.Set(m_defer_start+pt);    }    m_state=MAC_DEFER;}template <class PLD>void MAC80211<PLD>::ResumeDefer(){    // backoff can only be resumed when it is already in this state    if(m_state!=MAC_DEFER)return;    // don't need to select a new backoff time    if(defer_timer.Active())printf("Mac%d\n",(int)MyEtherAddr);    assert(defer_timer.Active()==false);    if(m_tx_failed) m_ifs=m_eifs;    else m_ifs=m_difs;    double now=SimTime();    if(now<m_last_send)now=m_last_send;    if(m_nav>now)	    m_defer_start=m_nav;    else	    m_defer_start=now;    defer_timer.Set(m_defer_start+m_ifs+m_backoff_time);      Printf((DumpPackets, "mac%d resumes deferring\n", (int)MyEtherAddr));}template <class PLD>void MAC80211<PLD>::TxPacket(packet_t* p, simtime_t tx_time){    // sends out a packet immediately    double now=SimTime();    Printf((DumpPackets,"mac%d sends %s until %f\n",(int)MyEtherAddr, p->dump().c_str(),now+tx_time));    if(now<m_last_send)    {	    printf("two sends overlap\n");	    return;    }    m_last_send=now+tx_time;    to_phy(p);    SentPackets++;}template <class PLD>void MAC80211<PLD>::TxPacket(packet_t* p, simtime_t start_time, simtime_t tx_time){    // sends out a packet with certain delay    double start=SimTime()+start_time;    Printf((DumpPackets,"mac%d sends %s from %f to %f\n",(int)MyEtherAddr,p->dump().c_str(),start,start+tx_time));    if(start<m_last_send)    {	    printf("two sends overlap\n");	    return;    }    m_last_send=start+tx_time;    assert(!phy_timer.Active());    phy_timer.Set(p,start);    SentPackets++;}template <class PLD>void MAC80211<PLD>::NetworkAckTimer(bool& ack){    to_network_ack(ack);}template <class PLD>void MAC80211<PLD>::PhyTimer(packet_t* &p){    to_phy(p);}template <class PLD>void MAC80211<PLD>::DropPacket(packet_t* p, const char* reason){    Printf((DumpPackets,"mac%d drops %s (%s)\n",(int)MyEtherAddr,p->dump().c_str(),reason));    p->free();}#endif /* mac80211_h */

⌨️ 快捷键说明

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