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

📄 shr.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 4 页
字号:
**   If (this packet updated Z's entry in the cost table)**     forward packet w/o election**   else**     the packet is dropped.*/	else	{	  iter = m_seq_cache.find( np->hdr.dst_addr);	  if( iter == m_seq_cache.end())	    np->free();	  else	  {	    if( costTableUpdated == true)	      forwardAsFlood( np);	    else	      np->free();	  }	}      }      else      {/*** TTL exceeded, dropping packet;** Create a copy of the packet solely for the purpose of recording the full** path. This is because pkt is used by other nodes.*/	packet_t	*np = pkt->copy();	np->hdr.path.AddNode( MyEtherAddr);	visualizer->writePath( (int) np->hdr.src_addr, (int) np->hdr.dst_addr,			       np->hdr.seq_number, np->hdr.path, false);	np->free();      }    }  }  else	// packet should be on ack queue  {    if( pkt->hdr.type == ACK)      receiveAck( pkt);    else      receiveDataRep( pkt);  }  pkt->free();  return;}template <class PLD>void SHR<PLD>::forwardAsFlood(  packet_t	*pkt){  // AckWindow doesn't apply when flooding a packet.  pkt->hdr.delay = Random( ForwardDelay);  TotalDelay += pkt->hdr.delay;  TotalSamples++;  SendPacket( pkt);  return;}/*** The m_ack_list contains a list of packets that have already been sent and** are waiting for acknowledgement.**** The processing for reception of an ACK is:** - if the ACK was initiated by a packet sent by another node (pre_addr != self)**   - cancel PKT**   - remove PKT from ack queue** - else (this node generated packet that initiated ACK)**   - if the ACK is from the destination (cur_addr == dest_addr)**     - get packet from ack queue**     - Send an ACK. This is the same processing as when node detects that**       a packet has been forwarded.**     - remove PKT from ack queue**   - else (ACK is from an intermediate node)**     - ignore the ACK*/template <class PLD>void SHR<PLD>::receiveAck(  packet_t	*ackPkt){  shrPrint( ("rA: ea %3d; 0x%08X; sn%08X; src %3d; cur %3d; pre %3d @ %f\n",	     (int) MyEtherAddr, (int) ackPkt, ackPkt->hdr.seq_number,	     (int) ackPkt->hdr.src_addr, (int) ackPkt->hdr.cur_addr,	     (int) ackPkt->hdr.pre_addr, SimTime()));#ifndef	SHR_ACK  CancelPacket( ackPkt->hdr.src_addr, ackPkt->hdr.seq_number);#else	// SHR_ACK  packet_t	*pktFromList;  // If the ack is in response to a packet generated by another node  if( ackPkt->hdr.pre_addr != MyEtherAddr)  {    shrPrint( ("rA: ea %3d; sn%08X; Canceling packet\n", (int) MyEtherAddr, ackPkt->hdr.seq_number));    CancelPacket( ackPkt->hdr.src_addr, ackPkt->hdr.seq_number);    pktFromList = (packet_t *) getFromAckList( ackPkt);    if( pktFromList != NULL)      removeFromAckList( pktFromList, true);  }  else		// Ack is in response to packet generated by this node.  {    pktFromList = (packet_t *) getFromAckList( ackPkt);    if( pktFromList != NULL)    {      // Respond to ack, but only if it's from the destination      if( ackPkt->hdr.ackType == AT_Destination)      {	shrPrint( ("rA: ea %3d; sn%08X; Sending ack\n", (int) MyEtherAddr, ackPkt->hdr.seq_number));	doRouteRepair( pktFromList, ackPkt);	SendAck( ackPkt->hdr.src_addr, MyEtherAddr, ackPkt->hdr.cur_addr,		 ackPkt->hdr.seq_number, 0.0, false);	removeFromAckList( pktFromList, true);      }    }  }#endif	// SHR_ACK  return;}template <class PLD>void SHR<PLD>::receiveDataRep(  packet_t	*rcvdPkt){  packet_queue_t::iterator iter;  packet_t	*pktFromList;  shrPrint( ("rDR: ea %3d; 0x%08X; sn%08X; src %3d; cur %3d; pre %3d @ %f\n",	     (int) MyEtherAddr, (int) rcvdPkt, rcvdPkt->hdr.seq_number,	     (int) rcvdPkt->hdr.src_addr, (int) rcvdPkt->hdr.cur_addr,	     (int) rcvdPkt->hdr.pre_addr, SimTime()));  CancelPacket( rcvdPkt->hdr.src_addr, rcvdPkt->hdr.seq_number);  // m_ack_list is for storing packets that need to be ACKed  // In theory, an ACK with a previous address of this node should be on the  // ack list, but it's possible for things to get out of sync.  pktFromList = (packet_t *) getFromAckList( rcvdPkt);  // If packet wasn't found, there's nothing to do.  if( pktFromList == NULL)    return;  if( rcvdPkt->hdr.pre_addr == MyEtherAddr)  {    doRouteRepair( pktFromList, rcvdPkt);    SendAck( rcvdPkt->hdr.src_addr, MyEtherAddr, rcvdPkt->hdr.cur_addr,	     rcvdPkt->hdr.seq_number, 0.0, false);    removeFromAckList( pktFromList, true);  }  else		// forwarding of packet from another node  {    shrPrint( ("rDR: ea %3d; 0x%08X; sn%08X; resend <- %d; iter %3d<-%3d; "	       "pkt %3d<-%3d\n", (int) MyEtherAddr, (unsigned int) pktFromList,	       pktFromList->hdr.seq_number, MaxResend,	       (int) pktFromList->hdr.cur_addr, (int)pktFromList->hdr.pre_addr,	       (int) rcvdPkt->hdr.cur_addr, (int) rcvdPkt->hdr.pre_addr));    pktFromList->hdr.resend = MaxResend;  }  return;}template <class PLD>void *SHR<PLD>::getFromAckList(  packet_t	*pkt){  packet_queue_t::iterator iter;  // m_ack_list is for storing packets that need to be ACKed  for( iter = m_ack_list.begin(); iter != m_ack_list.end(); iter++)    if( (*iter)->hdr.src_addr == pkt->hdr.src_addr &&	(*iter)->hdr.seq_number == pkt->hdr.seq_number)      break;  if( iter != m_ack_list.end())    return *iter;  return NULL;}template <class PLD>void SHR<PLD>::removeFromAckList(  packet_t	*pkt,  bool		cancelTimer){  shrPrint( ("rFAL: ea %3d; sn%08X\n", (int) MyEtherAddr, pkt->hdr.seq_number));  if( cancelTimer == true)  {    ackTimer.Cancel( pkt->hdr.ackIndex);    pkt->free();  }  m_ack_list.remove( pkt);  return;}template <class PLD>void SHR<PLD>::doRouteRepair(  packet_t	*pktFromList,  packet_t	*rcvdPkt){  if( RouteRepairEnabled == false ||      rcvdPkt->hdr.expected_hop == pktFromList->hdr.expected_hop - 1)    return;    const char	*str;  switch( rcvdPkt->hdr.type)  {    case ACK:      str = "dAS-ack";      break;    case DATA:      str = "dAS-data";      break;    case REPLY:      str = "dAS-reply";      break;    default:      str = "dAS-other";      break;  }  updateHopCountInCache( pktFromList->hdr.dst_addr, rcvdPkt->hdr.expected_hop			 + 1, Always, str, rcvdPkt);  return;}template <class PLD>int SHR<PLD>::getHCFromCostTable(  int		addr){  cache_t::iterator	iter;  ether_addr_t		ea = addr;  iter = m_seq_cache.find( ea);  return (int) iter->second.hopCount();}/*** Receive notification of receive-receive collisions. This must be defined** since the cxx compiler doesn't support #ifdef.*/template <class PLD>void SHR<PLD>::from_mac_recv_recv_coll( packet_t *pkt1, packet_t *pkt2){//  addToNeighborMatrix( (int) pkt1->hdr.pre_addr, (int) MyEtherAddr);//  addToNeighborMatrix( (int) pkt2->hdr.pre_addr, (int) MyEtherAddr);  shrPrint( ("fmrrc: ea %3d; sn%08X (%3d) & sn%08X (%3d) @ %f\n",	     (int) MyEtherAddr, pkt1->hdr.seq_number, (int) pkt1->hdr.cur_addr,	     pkt2->hdr.seq_number, (int) pkt2->hdr.cur_addr, SimTime()));  return;}template <class PLD>void SHR<PLD>::CancelPacket(  ether_addr_t	&src,  unsigned int	seq_number){  /*  ** If the incoming packet is the same as the outgoing packet, cancel the  ** outgoing packet. But, if the outgoing packet is an ACK, don't cancel it.  ** This prevents the case of a slightly delayed DATA (or REPLY) packet that  ** doesn't cause a collision from cancelling an ACK.  */  if( m_mac_busy == true && m_active_packet->hdr.src_addr == src &&      m_active_packet->hdr.seq_number == seq_number &&      m_active_packet->hdr.type != ACK)  {//    shrPrint( ("CP: ea %3d; in progress 0x%08X; sn%08X\n", (int) MyEtherAddr, (unsigned int) m_active_packet, m_active_packet->hdr.seq_number));    //Printf((DumpPackets,"rr%d cancels the current packet\n",(int)MyEtherAddr));    CanceledPackets++;    if( m_active_packet->hdr.suboptimal == true)      CanceledSuboptimal++;    m_active_packet->hdr.canceled = true;    cancel();    return;  }  packet_queue_t::iterator iter;  packet_t	*pktFromQ;  // Now, look for the packet in the backoff list  // Packets sourced from this node don't have a sequence number, but those  // packets won't be cancelled.  for( iter = m_delay_list.begin(); iter != m_delay_list.end(); iter++)    if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number)      break;  if( iter != m_delay_list.end())  {    shrPrint( ("CP: ea %3d; 0x%08X; sn%08X; %f\n", (int) MyEtherAddr,	    (unsigned int) *iter, (*iter)->hdr.seq_number, SimTime()));    pktDelayTimer.Cancel( (*iter)->hdr.pktDelayIndex);    (*iter)->free();    m_delay_list.erase( iter);    return;  }  // Now, look for the packet in m_send_queue.  for( iter = m_send_queue.begin(); iter != m_send_queue.end(); iter++)    if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number)      break;  // If not found, then nothing to do.  if( iter == m_send_queue.end())    return;  pktFromQ = *iter;  // If the pending packet is an ACK, don't cancel it.  if( pktFromQ->hdr.type != ACK)  {    CanceledPackets++;    if( pktFromQ->hdr.suboptimal == true)      CanceledSuboptimal++;    pktFromQ->free();    m_send_queue.erase( iter);  }  return;}/*** The routing layer has received an acknowledgement from the mac layer.** False indicates that the transmission failed.*/template <class PLD>void SHR<PLD>::from_mac_ack(  bool		flag){  bool		testQueue = true;  bool		slotted = continuousBackOff == false &&      (MyEtherAddr != m_active_packet->hdr.src_addr) ? true : false;  //Printf((DumpPackets,"rr%d receives an ack from mac\n",(int)MyEtherAddr));  // a non-ack packet failed, so resend it  /*  ** Continuous and slotted SSR handle resending differently.  **   ** Continuous: Just send the packet back to the MAC layer.  **   ** Slotted: Intermediate nodes delay the packet until the start of the next  ** slot. Source nodes behave as continuous SSR.  */  if( flag == false && m_active_packet->hdr.type != ACK)  {    //Printf((DumpPackets,"%d resends %s\n", (int)MyEtherAddr,m_active_packet->dump().c_str()));    if( slotted == true)    {      m_active_packet->hdr.delay = slotWidth;      SendPacket( m_active_packet);    }    else    {//      printf( "fma: rescheduling\n");      m_active_packet->hdr.delay = 0;      m_active_packet->inc_ref();      SendToMac( m_active_packet);      testQueue = false;	// just sent to mac, so don't test queue    }  }  else  {#ifdef SHR_ACK// Because RREP packets are now flooded, they no longer put onto the ack queue.    if( m_active_packet->hdr.canceled == false &&	m_active_packet->hdr.type == DATA &&	m_active_packet->hdr.actual_hop < m_active_packet->hdr.max_hop-1)    {      m_active_packet->inc_ref();      m_active_packet->hdr.ackIndex =	  ackTimer.Set( m_active_packet,			 SimTime() + MWLTimeoutMultiplier *#ifdef	MWL_DOUBLE_DELAY			 (1<<m_active_packet->hdr.resend) *#endif	// MWL_DOUBLE_DELAY			 ForwardDelay);      m_ack_list.push_back( m_active_packet);    }#endif //SHR_ACK    m_active_packet->free();  }  if( testQueue == true)    if( m_send_queue.size())    {      packet_t	*packet = m_send_queue.front();      m_send_queue.pop_front();      shrPrint( ("fma: ea %3d; sn%08X; sending from queue\n", (int)MyEtherAddr,		 packet->hdr.seq_number));      //Printf((DumpPackets,"rr%d forwards %s from queue\n",(int)MyEtherAddr,packet->dump().c_str()));      m_active_packet = packet;      m_active_packet->inc_ref();      SendToMac( packet);    }    else      m_mac_busy = false;  return;}template <class PLD>void SHR<PLD>::AckTimer(  packet_t	*pkt,  unsigned int){  shrPrint( ("AT: ea %3d; 0x%08X; sn%08X; resend %d\n", (int) MyEtherAddr,	     (unsigned int) pkt, pkt->hdr.seq_number, pkt->hdr.resend));  removeFromAckList( pkt, false);  // Need to resend the packet, but do it without any delay  pkt->hdr.delay = 0;  if( pkt->hdr.resend < MaxResend)  {    //Printf((DumpPackets,"rr%d resends %s\n",(int)MyEtherAddr,pkt->dump().c_str()));    pkt->hdr.resend++;    SendPacket( pkt);  }}template <class PLD>void SHR<PLD>::SendAck(  ether_addr_t	src_addr,  ether_addr_t	cur_addr,  ether_addr_t	pre_addr,  unsigned int	seq_number,  simtime_t	delay,  bool		fromDest){  packet_t	*pkt = (packet_t *) createAckPkt( src_addr, cur_addr, pre_addr,						  seq_number, delay, fromDest);  Printf( (DumpPackets, "%d SHR: %d->%d %s\n", (int) MyEtherAddr, (int)cur_addr,	  (int) pre_addr, pkt->dump().c_str()));  shrPrint( ("SA: sn%08X; %3d->%3d %s @ %f\n", seq_number, (int) cur_addr, (int) pre_addr,	     pkt->dump().c_str(), SimTime()));  SendPacket( pkt);  return;}template <class PLD>void SHR<PLD>::CheckBuffer(  ether_addr_t	src_addr,  unsigned int	expected_hop){  packet_queue_t::iterator db_iter;  db_iter = m_data_buffer.begin();  while(db_iter != m_data_buffer.end())  {    if( (*db_iter)->hdr.dst_addr == src_addr)    {      packet_queue_t::iterator t=db_iter;      db_iter++;      (*t)->hdr.expected_hop = expected_hop;      (*t)->hdr.max_hop = expected_hop + AdditionalHop;      (*t)->hdr.delay = AckWindow;      SendPacket( *t);      m_data_buffer.erase( t);    }    else      db_iter++;  }}template <class PLD>bool SHR_Struct<PLD>::hdr_struct::dump(  std::string	&str) const {   static char	pkt_type[5][10] = { "REQ", "REPLY", "DATA", "ACK", "HELLO"};  char		buffer[30];  sprintf( buffer, "%s %d->%d %d %d", pkt_type[type], (int) src_addr,	   (int) dst_addr, seq_number, size);   str = buffer;  return type == DATA;}#endif /*_shr_h_*/

⌨️ 快捷键说明

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