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

📄 ssab.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
字号:
/**************************************************************************   @<title> A SSAB Component </title>@**   @<!-- 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 SSAB_h#define SSAB_h#include <map>#include <list>template <class PLD>struct SSAB_Struct{    struct hdr_struct    {	unsigned int seq_number;	unsigned int size;	double send_time;	unsigned int hop;		bool dump(std::string& str) const 	{ 	    char buffer[30];	    sprintf(buffer,"%d %d",seq_number,size); 	    str=buffer;	    return true;	}    };    typedef PLD payload_t;    typedef smart_packet_t<hdr_struct,PLD> packet_t;};template <class PLD>component SSAB : public TypeII, public SSAB_Struct<PLD>{ public:    ether_addr_t MyEtherAddr;    simtime_t ForwardDelay;    double RXThresh;    bool DumpPackets;    int SentPackets;    int RecvPackets;    int RecvUniPackets;    double TotalDelay;    int TotalSamples;    int TotalHop;        inport inline void from_transport( payload_t& pld, ether_addr_t& dst, unsigned int size);    inport inline void from_mac_data (packet_t* pkt, double power);    inport inline void from_mac_ack (bool errflag);    inport inline void	from_mac_recv_recv_coll( packet_t *pkt1, packet_t *pkt2);    // This is called when the power manager wakes up the node.    inport void	from_pm_node_up();    outport void cancel ();    outport void to_transport ( payload_t& pld );    outport void to_mac (packet_t* pkt, unsigned int size, double backoff);    void Start();    void Stop();    SSAB();    virtual ~SSAB();	 protected:    bool m_mac_busy;                  // if the mac layer is busy    unsigned int m_seq_number;        // current sequence number    typedef std::list<pair<packet_t*,double> > packet_buffer_t;    packet_buffer_t m_packet_buffer;    packet_t* m_active_packet;    class seq_number_t    {    public:	seq_number_t () : current(0),bits(0u) {}	bool check(int n)	{	    if( n + (int)sizeof(unsigned long) <= current ) return true;	    if ( n > current )	    {		bits = bits << (n - current);		current = n;	    }	    unsigned long flag = 1 << (current - n);	    unsigned long r = flag & bits;	    bits |= flag;	    return r;	}    private:	int current;	uint32_t bits;    };	/******************************************************************* * For each source, we must maintain a @seq_number_t@ object, so we better * keep them in a map. *******************************************************************/    typedef std::map<ether_addr_t, seq_number_t, ether_addr_t::compare> cache_t;    cache_t m_seq_cache;};template <class PLD>SSAB<PLD>::SSAB(){}template <class PLD>SSAB<PLD>::~SSAB(){}template <class PLD>void SSAB<PLD>::Start() {    m_mac_busy=false;    m_seq_number=1u;    m_seq_cache.insert(make_pair(MyEtherAddr,seq_number_t()));    SentPackets=RecvPackets=RecvUniPackets=0l;    TotalDelay=0.0;    TotalHop=0;    TotalSamples=0;}template <class PLD>void SSAB<PLD>::Stop() {    //printf("%s: sent %d, recv %d\n",GetName(),SentPackets,RecvPackets);    //printf("%s: %f \n", GetName(), (double)RecvPackets/RecvUniPackets);}template <class PLD>void SSAB<PLD>::from_transport( payload_t& pld, ether_addr_t& dst, unsigned int size){    packet_t* p=packet_t::alloc();    p->pld=pld;    m_seq_number++;    m_seq_cache[MyEtherAddr].check(m_seq_number);    p->hdr.seq_number=m_seq_number;    p->hdr.size=size+2*sizeof(unsigned int);    p->hdr.hop=0;    SentPackets++;    Printf((DumpPackets,"ssab%d creates %s\n",(int)MyEtherAddr,p->dump().c_str()));    p->hdr.send_time=SimTime();    if(!m_mac_busy)    {	m_mac_busy=true;	m_active_packet=p;	to_mac(p,size,0.0);    }    else    {	packet_buffer_t::iterator iter=m_packet_buffer.begin();	while(iter!=m_packet_buffer.end()&&(*iter).second<=0.0)iter++;	m_packet_buffer.insert(iter,make_pair(p,0.0));    }}/******************************************************************* * We are now receiving a packet from the mac layer. *******************************************************************/template <class PLD>void SSAB<PLD>::from_mac_data (packet_t* pkt, double power){    ether_addr_t src;    src=pkt->access_pld().src_addr;    RecvPackets++;    Printf((DumpPackets,"ssab%d receives %s \n",(int)MyEtherAddr,pkt->dump().c_str()));    cache_t::iterator iter=m_seq_cache.find(src);     if(iter==m_seq_cache.end())    {	// couldn't find the source address in the cache.	// so we create a new record	iter=(m_seq_cache.insert(make_pair(src,seq_number_t()))).first;    }    if( !iter->second.check(pkt->hdr.seq_number) )    {	// the received packet is new	RecvUniPackets++;	if(pkt->access_pld().dst_addr==MyEtherAddr||pkt->access_pld().dst_addr==ether_addr_t::BROADCAST)	{	    // the packets arrivs at its destination	    pkt->inc_pld_ref();	    to_transport(pkt->pld);	    TotalHop+=pkt->hdr.hop;	}	else  	{	    double delay;#ifdef USING_SSAB	    delay=Random();	    delay=ForwardDelay*(1-RXThresh/power);#else	    delay=Random(ForwardDelay);#endif	    TotalDelay+=delay;	    TotalSamples++;	    // rebroadcast needed	    packet_t* np = pkt->copy();	    np->hdr.hop++;	    pkt->free();	    if(m_mac_busy==false)	    {		Printf((DumpPackets,"ssab%d forwards %s\n",(int)MyEtherAddr,np->dump().c_str()));		SentPackets++;		np->hdr.send_time=SimTime();		m_mac_busy=true;		m_active_packet=np;		to_mac(np,np->hdr.size,delay);	    }	    else	    {                packet_buffer_t::iterator iter=m_packet_buffer.begin();                while(iter!=m_packet_buffer.end()&&(*iter).second<=delay)iter++;                m_packet_buffer.insert(iter,make_pair(np,delay));	    }	    return;	}    }    else    {        if(m_mac_busy==true&&m_active_packet->access_pld().src_addr==pkt->access_pld().src_addr&&	   m_active_packet->hdr.seq_number==pkt->hdr.seq_number)        {	    Printf((DumpPackets,"ssab%d cancels the current packet\n",(int)MyEtherAddr));            cancel();        }        else        {            packet_buffer_t::iterator iter;            for(iter=m_packet_buffer.begin();iter!=m_packet_buffer.end();iter++)            {                if((*iter).first->access_pld().src_addr==pkt->access_pld().src_addr&&                    (*iter).first->hdr.seq_number==pkt->hdr.seq_number)                {		    Printf((DumpPackets,"ssab%d cancels a buffered packet\n",(int)MyEtherAddr));fflush(stdout);                    (*iter).first->free();                    m_packet_buffer.erase(iter);                    break;                }            }        }    }    pkt->free();}/*** Receive notification of receive-receive collisions. This must be defined** since the cxx compiler doesn't support #ifdef.*/template <class PLD>void SSAB<PLD>::from_mac_recv_recv_coll(  packet_t	*pkt1,  packet_t	*pkt2){  return;}template <class PLD>void SSAB<PLD>::from_mac_ack(bool){    Printf((DumpPackets,"ssab%d recevies an ack\n",(int)MyEtherAddr));    if(m_packet_buffer.size())    {        packet_t* packet=m_packet_buffer.front().first;        double delay=m_packet_buffer.front().second;        m_packet_buffer.pop_front();    	Printf((DumpPackets,"ssab%d forwards %s from buffer\n",(int)MyEtherAddr,packet->dump().c_str()));    	m_active_packet=packet;        to_mac(packet,packet->hdr.size,delay);    }    else        m_mac_busy=false;    return;}/*** The inport that is called when the power manager wakes the node up.** This must be defined even if the protocol doesn't use it.*/template <class PLD>void SSAB<PLD>::from_pm_node_up(){  return;}#endif /*SSAB_h*/

⌨️ 快捷键说明

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