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

📄 ashr.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 4 页
字号:
/************************************************************************* *   @<title> Autonomic Self-Healing Routing </title>@ * *   @<!-- Copyright 2006 Mark Lisee, Joel Branch, Gilbert (Gang) Chen, *   Boleslaw K. Szymanski and Rensselaer Polytechnic Institute. *    *   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.-->@ * *************************************************************************//*** Modifications from rr.h** - replaced lambda by slotting** - Added T1, T2 & T3 time periods**   - code to gather statistics**   - code to set # slots per period from command line** - Added handling of collision packet**   - new packet type & field in header changed from int to enum**   - Transmission is scheduled when a collision is detected** - Added # slots to packet header**   - I added this when I thought it would be required for v2. It no longer**     is, but it's staying** - Sender may modify its hop count based on slot during which response is**   sent.*/#ifndef SSRv02_h#define SSRv02_h#include <map>#include <list>#ifdef	MWL_PRINT//#define mwlDoPrint	(SimTime() > 1400. && SimTime() < 1500.)//#define	mwlPrint(x)	 if( mwlDoPrint) printf x#define mwlDoPrint	(true)#define	mwlPrint(x)	 printf x#else	//MWL_PRINT#define	mwlPrint(x)#define	mwlDoPrint	(false)#endif	//MWL_PRINTtemplate <class PLD>struct SSRv02_Struct{  enum PktType { REQUEST, REPLY, DATA, ACK, COLL, HELLO, BACKUP};  // REQUEST: type + src_addr + dst_addr + seq_number + hop  enum { REQUEST_SIZE = 3 * sizeof(int) + 2 * ether_addr_t::LENGTH };  // REPLY: type + src_addr + dst_addr + seq_number + 2 * hop + flag  enum { REPLY_SIZE = 4 * sizeof(int) + 4 * ether_addr_t::LENGTH + sizeof( bool) };  // DATA: type + src_addr + dst_addr + seq_number + 2 * hop + flag  enum { DATA_SIZE = 4 * sizeof(int) + 4 * ether_addr_t::LENGTH + sizeof( bool) };  // ACK: type + src_addr + dst_addr + seq_number  enum { ACK_SIZE = 3 * sizeof(int) + 2 * ether_addr_t::LENGTH };  // COLL: type + src_addr + dst_addr + seq_number + slot number  enum { COLL_SIZE = 3 * sizeof(int) + 2 * ether_addr_t::LENGTH };  // BACKUP: type + src_addr + dst_addr + seq_number  enum { BACKUP_SIZE = 2 * sizeof(int) + 2 * ether_addr_t::LENGTH };  // HELLO: type + src_addr + dst_addr + seq_number + hop count  enum { HELLO_SIZE = 3 * sizeof(int) + 2 * ether_addr_t::LENGTH };      struct hdr_struct  {    PktType	type;    ether_addr_t src_addr;    ether_addr_t dst_addr;    ether_addr_t cur_addr;    ether_addr_t pre_addr;    unsigned int seq_number;    unsigned int size;    double	send_time;	// time received from transport    double	xmit_start_time;	// time sent to mac layer    double	xmit_end_time;		// time sent to mac layer    unsigned int actual_hop;    unsigned int expected_hop;    unsigned int max_hop;    double	delay;    int		t1Index;	// id of endT1Timer    int		t2Index;	// id of endT2Timer//mwl    int		t3Index;	// id of endT3Timer    int		collIndex;	// id of endCollTimer    bool	canceled;    int		resend;    int		numSlots;	// k, the number of slots in T2    int		slotNumber;    bool	collDetected;    bool	collPktSent;    bool	t3Flag;		// if true, nodes may forward this pkt in T3#ifdef VISUAL_ROUTE#ifndef VR_SIZE#define VR_SIZE 20#endif    path_t<VR_SIZE> path;#endif    bool dump(std::string& str) const;  };  typedef PLD payload_t;  typedef smart_packet_t<hdr_struct,PLD> packet_t;};#define	HCArraySize		(20+1)#define	MaxT2Slots		100#define	DefaultNumT2Slots	3#define MaxT3Slots		10#define	DefaultNumT3Slots	2/*** The AckWindow is a period of time during which only Acks from intermediate** nodes are sent. This prevents the Acks from colliding with packets that are** being forwarded. Note that the destination sends its Ack as a normal packet,** i.e. after the AckWindow. This is because when node N forwards a packet, it** causes node N-1 to send an Ack (during the AckWindow) and N+1 to forward the** packet (after the AckWindow).*/template <class PLD>component SSRv02 : public TypeII, public SSRv02_Struct<PLD>{ public:  ether_addr_t	MyEtherAddr;  simtime_t	ForwardDelay;  double	RXThresh;  bool		DumpPackets;  double	AckWindow;	// see comment above  int		MaxResend;  unsigned int	TimeToLive;  unsigned int	AdditionalHop;      int		SentPackets;  int		RecvPackets;  int		RecvUniPackets;  double	TotalDelay;  int		TotalSamples;  int		TotalHop;  int		RecvDataPackets;  int		HopCounts[ HCArraySize];  int		T1PktsSent;  int		T2PktsSent[ MaxT2Slots];  int		T3PktsSent[ MaxT3Slots];  int		T3AbnormalPktsSent;  int		DropPkts;		// # times h_table > h_pkt+n  int		T1Collisions;  int		T2Collisions[ MaxT2Slots];  int		T3Collisions[ MaxT3Slots];  int		IgnoreCollisions;	// collision after end of T3  int		T1PktsRcvd[2];  int		T2PktsRcvd[2][ MaxT2Slots];  int		T3PktsRcvd[2][ MaxT3Slots];  int		T4PktsRcvd[2];//mwl  int		OtherPktsRcvd[2];  int		CanceledPktsRcvd[2];  int		BadAddrPktsRcvd[2];  int		WrongHopPktsRcvd[2];  static const char	*pktRcvdName[2];  typedef std::list<packet_t* > packet_queue_t;/*** Fields that support the transition timer.** This timer simulates the amount of time it takes the hardware to transition** from sensing the carrier to actually transmitting a packet.*/  Timer <trigger_t> transitionTimer;  packet_t	*transitionPkt;		// pkt to be sent when timer expires  inport void	TransitionTimer( trigger_t &);/*** When a COLL packet is sent, the original packet is added to the** m_collPktsSent_queue. A list of collision packets is required to properly** implement BACKUP messages.**** In some situations, a timer is required to remove packets from the queue.** For example, N1 sends a packet. N2 forwards it, but N1 detects it as a** collision when there is no interference at N2. (N1 could be located between** the two nodes.) In this case, N1 will schedule a COLL. If the COLL** is received by N2 after N3 has forwarded the packet, the COLL packet will be** ignored. In this case, the original packet needs to be removed from N1.*/  InfiTimer <SSRv02_Struct<PLD>::packet_t*> endCollTimer;  inport void	EndCollTimer( packet_t *pkt, unsigned int index);  packet_queue_t	m_collPktsSent_queue;	// pkts for which a COLL packet has been sent/*** Fields that support the timers that expire at the ends of T1, T2 & T3.*/  InfiTimer <SSRv02_Struct<PLD>::packet_t*> endT1Timer;  InfiTimer <SSRv02_Struct<PLD>::packet_t*> endT2Timer;//mwl  InfiTimer <SSRv02_Struct<PLD>::packet_t*> endT3Timer;  inport void	EndT1Timer( packet_t *pkt, unsigned int index);  inport void	EndT2Timer( packet_t *pkt, unsigned int index);//mwl  inport void	EndT3Timer( packet_t *pkt, unsigned int index);  packet_queue_t	m_T3_queue;	// packets w/ t3 timer pending/*** Connections to transport (layer above) and mac (layer below)*/  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);  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();		SSRv02();  virtual	~SSRv02();  int		mwlGetHC( int addr);/*** Added static members for slot width, transition timer and back off*/  static void		setSlotWidth( double);  static double		getSlotWidth();  static void		setTransitionTime( double);  static double		getTransitionTime();  static void		setNumT2Slots( int);  static int		getNumT2Slots();  static void		setNumT3Slots( int);  static int		getNumT3Slots();	 private:  void		updateHopCountInCache( ether_addr_t src,				       unsigned int hopCount, bool always,				       const char *, packet_t *pkt); protected:  static double		slotWidth;  static double		transitionTime;  static int		numT2Slots;  static int		numT3Slots;  void		CancelPacket( ether_addr_t& src, unsigned int seq_number);  void		CancelRetransmission( ether_addr_t& src, unsigned int seq);  void		SendPacket( packet_t *p, bool new_seq = true);  void		ForwardPacket( packet_t *p);  void		SendToMac( packet_t *pkt);  void		SendAck( ether_addr_t, ether_addr_t, ether_addr_t,			 unsigned int, simtime_t);  void		CheckBuffer( ether_addr_t, unsigned int);  void		sendCollisionPacket( packet_t *pkt);  void		receiveCollisionPacket( packet_t *pkt);  void		receiveHelloPacket( packet_t *pkt);  void		receiveBackupPacket( packet_t *pkt);  void		receiveAckPacket( packet_t *pkt);  void		receiveReqRepDataPacket( packet_t *pkt);  bool		determineAckStatus( packet_t *pkt);  void		performAck( packet_t *pkt);    // these return pointers to packet_t, but I wasn't able to figure out  // how to avoid compiler errors, therefore cast them to void *  void		*createBasicPkt();  void		*createDataPkt( payload_t &pld, ether_addr_t dst,				unsigned int size);  void		*createT3Pkt( packet_t *pkt);  void		*createRequestPkt( ether_addr_t dst);  void		*createReplyPkt( ether_addr_t src, unsigned int expectedHop);  void		*createAckPkt( ether_addr_t src_addr, ether_addr_t cur_addr,			       ether_addr_t pre_addr, unsigned int seq_number,			       simtime_t delay);  void		*createCollPkt( packet_t *pkt);  void		*createBackupPkt( packet_t *pkt);  void		*createHelloPkt();  bool		m_mac_busy;		// if the mac layer is busy  unsigned int	m_seq_number;		// current sequence number  packet_queue_t	m_send_queue;	// list of packets to send  packet_t	*m_active_packet;  class seq_number_t      {       public:	seq_number_t () : state( Initial), 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;	    }	unsigned int	hopCount() const;	void		hopCount( unsigned int newHC, bool print);       private:	unsigned int	currentHC;	unsigned int	pendingHC;	enum { Initial, Steady, Changing}	state;	int		updateCtr;	int		current;	uint32_t	bits;	static int	maxCounter;      };/******************************************************************* * 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;  packet_queue_t m_data_buffer;      void		recvPktAtDest( packet_t *pkt, cache_t::iterator iter);};template <class PLD> double	SSRv02<PLD>::slotWidth = 0.010;template <class PLD> double	SSRv02<PLD>::transitionTime = 0.0001;template <class PLD> int	SSRv02<PLD>::numT2Slots = DefaultNumT2Slots;template <class PLD> int	SSRv02<PLD>::numT3Slots = DefaultNumT3Slots;template <class PLD> const char	*SSRv02<PLD>::pktRcvdName[2] = {"REP", "DAT"};template <class PLD> int	SSRv02<PLD>::seq_number_t::maxCounter = 2;template <class PLD>unsigned int SSRv02<PLD>::seq_number_t::hopCount() const{  switch( state)  {    case Initial:      return 99;    case Steady:    case Changing:      return currentHC;    default:      assert( 0);	// something really bad happened      return 0;  }}template <class PLD>void SSRv02<PLD>::seq_number_t::hopCount(  unsigned int	newHC,  bool		print){  switch( state)  {    case Initial:      currentHC = newHC;      updateCtr = maxCounter;      state = Steady;      break;    case Steady:      if( newHC != currentHC)      {	--updateCtr;	pendingHC = newHC;	state = Changing;	if( print) printf( " start change\n");      }      break;    case Changing:      if( newHC == currentHC)      {	if( ++updateCtr == maxCounter)	{	  state = Steady;	  if( print) printf(" back out of change\n");	}	else	  if( print) printf(" reversing\n");      }      else if( newHC == pendingHC)      {	if( --updateCtr == 0)	{	  currentHC = newHC;	  updateCtr = maxCounter;	  state = Steady;	  if( print) printf(" end change\n");	}	else	  if( print) printf(" still changing\n");      }      else	// newHC is neither the old nor new HC      {	pendingHC = newHC;	if( print) printf(" new HC during change\n");      }      break;    default:      assert( 0);	// something really bad happened  }  return;}template <class PLD>void SSRv02<PLD>::setSlotWidth(  double	sw){  slotWidth = sw;  return;}template <class PLD>double SSRv02<PLD>::getSlotWidth(){  return slotWidth;}template <class PLD>void SSRv02<PLD>::setTransitionTime(  double	tt){  transitionTime = tt;  return;}template <class PLD>double SSRv02<PLD>::getTransitionTime(){  return transitionTime;}template <class PLD>void SSRv02<PLD>::setNumT2Slots(  int		num){  numT2Slots = num;  return;}template <class PLD>int SSRv02<PLD>::getNumT2Slots(){  return numT2Slots;}template <class PLD>void SSRv02<PLD>::setNumT3Slots(  int		num){  numT3Slots = num;  return;}template <class PLD>int SSRv02<PLD>::getNumT3Slots(){  return numT3Slots;}template <class PLD>void *SSRv02<PLD>::createBasicPkt(){  packet_t	*newPkt = packet_t::alloc();  newPkt->hdr.send_time = SimTime();  newPkt->hdr.actual_hop = 1;  newPkt->hdr.resend = 0;  newPkt->hdr.seq_number = 0;  newPkt->hdr.numSlots = numT2Slots;  newPkt->hdr.collDetected = false;  newPkt->hdr.collPktSent = false;  newPkt->hdr.slotNumber = 0;  newPkt->hdr.delay = 0.0;  newPkt->hdr.t1Index = 12345;		//mwl  newPkt->hdr.t2Index = 12345;		//mwl

⌨️ 快捷键说明

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