📄 bcast_mac.h
字号:
/************************************************************************** Copyright 2003 Gilbert (Gang) Chen, Boleslaw K. Szymanski and* Rensselaer Polytechnic Institute. All worldwide rights reserved.* A license to use, copy, modify and distribute this software for* non-commercial research purposes only is hereby granted, provided* that this copyright notice and accompanying disclaimer is not* modified or removed from the software.** DISCLAIMER: The software is distributed "AS IS" without any* express or implied warranty, including but not limited to, any* implied warranties of merchantability or fitness for a particular* purpose or any warranty of non-infringement of any current or* pending patent rights. The authors of the software make no* representations about the suitability of this software for any* particular purpose. The entire risk as to the quality and* performance of the software is with the user. Should the software* prove defective, the user assumes the cost of all necessary* servicing, repair or correction. In particular, neither Rensselaer* Polytechnic Institute, nor the authors of the software are liable* for any indirect, special, consequential, or incidental damages* related to the software, to the maximum extent the law permits.*************************************************************************/#ifndef broadcast_mac_h#define broadcast_mac_h#include <map>template <class PLD>struct BcastMAC_Struct{ // for frame format enum { MAC_ProtocolVersion=0x00, MAC_Type_Management=0x00, MAC_Type_Control=0x01, MAC_Type_Data=0x02, MAC_Type_Reserved=0x03, MAC_Subtype_RTS=0x0b, MAC_Subtype_CTS=0x0c, MAC_Subtype_ACK=0x0d, MAC_Subtype_Data=0x00 }; struct frame_control { u_char fc_subtype : 4; u_char fc_type : 2; u_char fc_protocol_version : 2; u_char fc_order : 1; u_char fc_wep : 1; u_char fc_more_data : 1; u_char fc_pwr_mgt : 1; u_char fc_retry : 1; u_char fc_more_frag : 1; u_char fc_from_ds : 1; u_char fc_to_ds : 1; }; struct hdr_struct { // fields defined in 802.11 standard struct frame_control dh_fc; u_int16_t dh_duration; ether_addr_t dh_da; ether_addr_t dh_sa; ether_addr_t dh_bssid; u_int16_t dh_scontrol; // extra fields to keep track of certain information. // They should not be counted when calculating the length of the packet double tx_time; // packet transmission time double wave_length; // needed to calculate path loss unsigned int size; bool dump(std::string& str) const; }; typedef PLD payload_t; typedef smart_packet_t<hdr_struct,PLD> packet_t; // physical layer parameters static double SlotTime; static double SIFSTime; //static int PreambleLength; //static int PLCPHeaderLength; // lengths of various frames or headers static int PLCP_HDR_LEN; static int HDR_LEN; static int FCS_LEN; // (Gang) my understanding is that unicast data frames are sent at // DataRate, while all other frames are sent at BasicRate static double DataRate; static double BasicRate; static double CPThreshold;};// define values for simulation related parameterstemplate <class PLD> double BcastMAC_Struct<PLD>::SlotTime=0.000020;//template <class PLD> int BcastMAC_Struct<PLD>::PreambleLength=144;//template <class PLD> int BcastMAC_Struct<PLD>::PLCPHeaderLength=48;template <class PLD> int BcastMAC_Struct<PLD>::PLCP_HDR_LEN = (144+48) >> 3;template <class PLD> int BcastMAC_Struct<PLD>::HDR_LEN = PLCP_HDR_LEN + FCS_LEN + 4*ether_addr_t::LENGTH + 6;template <class PLD> int BcastMAC_Struct<PLD>::FCS_LEN = 4;template <class PLD> double BcastMAC_Struct<PLD>::DataRate=1.0e6/8;template <class PLD> double BcastMAC_Struct<PLD>::BasicRate=1.0e6/8;template <class PLD> double BcastMAC_Struct<PLD>::CPThreshold=10;template <class PLD>component BcastMAC : public TypeII, public BcastMAC_Struct<PLD>{ public: enum MAC_STATE { MAC_IDLE = 0x0000, // nothing to do MAC_DEFER = 0x0001, // has a packet to send MAC_SEND = 0x0002, // is sending a packet }; ether_addr_t MyEtherAddr; bool DumpPackets; bool Promiscuity; double IFS; long SentPackets; long RecvPackets; long rrCollisions; // Frame control fields // this is the real declaration of the packet format. hdr_struct // is the header added by the 802.11 protocols, and PLD is the // payload needed to be transmitted. typedef triple<PLD,unsigned int,double> net_inf_t; // ports and timers // packets from higher layer inport void from_network( PLD const& pld, unsigned int size, double backoff); inport void cancel (); outport void to_network_data ( PLD pld, double receive_power ); outport void to_network_ack ( bool ack); // the cxx compiler doesn't support #ifdef outport void to_network_recv_recv_coll( PLD pld1, PLD pld2); inport void from_phy (packet_t* pkt, bool errflag, double power); outport void to_phy (packet_t* pkt); Timer <trigger_t> defer_timer; // for backoff Timer <trigger_t> recv_timer; // for receiving a packet Timer <trigger_t> send_timer; Timer <bool> ack_timer; BcastMAC(); virtual ~BcastMAC(); void Start(); // called when simulation starts void Stop(); // called when simulation stops void clearStats() { SentPackets = 0; RecvPackets = 0; rrCollisions = 0;} // functions to be bound to timers. Just from the name // you can tell which timer it is bound to. inport void DeferTimer(trigger_t&); inport void RecvTimer(trigger_t&); inport void SendTimer(trigger_t&); inport void AckTimer(bool&); private: void RecvData(packet_t* p); void StartDefer(); inline void ResumeDefer(); // drop a packet and tell why void DropPacket(packet_t* p, const char*); MAC_STATE m_state; // MAC's current state struct { payload_t pld; unsigned int size; double delay; }m_pldinf; // containing info about the pld to be transmitted simtime_t m_tx_end; // the end tx time of last packet struct { packet_t* packet; bool errflag; double power; } m_rxinf;// information about the packet being received u_int16_t m_seq_no; // sequence number simtime_t m_defer_start; bool m_sr_collision; // a STL container containing pairs of address and sequence // number. It is used to remove duplicate data packet. The // container is sorted so the address has to be comparable typedef std::map<ether_addr_t, u_int16_t, ether_addr_t::compare> cache_t; cache_t m_recv_cache;};template <class PLD>BcastMAC<PLD>::BcastMAC(){ connect defer_timer.to_component, DeferTimer; connect recv_timer.to_component, RecvTimer; connect send_timer.to_component, SendTimer; connect ack_timer.to_component, AckTimer;}template <class PLD>BcastMAC<PLD>::~BcastMAC(){}template <class PLD>void BcastMAC<PLD>::Start(){ // perform some initialization tasks m_state=MAC_IDLE; m_tx_end=0.0; m_seq_no=0; SentPackets=0l; RecvPackets=0l; rrCollisions = 0L;}template <class PLD>void BcastMAC<PLD>::Stop(){}template <class PLD>void BcastMAC<PLD>::from_network( PLD const &pld, unsigned int size, double backoff_delay){ Printf( (DumpPackets, "mac%d backoff delay: %f\n", (int) MyEtherAddr, backoff_delay)); // a new payload packet to be transmitted arrived from the higher layer if(m_state!=MAC_IDLE||m_tx_end>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 assert(ack_timer.Active()==false); ack_timer.Set( false, SimTime()); return; } m_pldinf.pld=pld; m_pldinf.size=size; m_pldinf.delay=backoff_delay; m_seq_no++; StartDefer();}template <class PLD>void BcastMAC<PLD>::DeferTimer( trigger_t &){ // deferral timer expires. It is now time to send out the packet if(m_state!=MAC_DEFER) { Printf((DumpPackets,"mac%d not in defer state \n",(int)MyEtherAddr)); } 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 // 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 = ether_addr_t::BROADCAST; np->hdr.dh_sa = MyEtherAddr; np->hdr.dh_scontrol = m_seq_no; np->hdr.size = m_pldinf.size + HDR_LEN; np->hdr.tx_time = np->hdr.size / DataRate; np->pld = m_pldinf.pld; // 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 m_tx_end=SimTime() + np->hdr.tx_time; m_sr_collision=false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -