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

📄 shr.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 4 页
字号:
    printf( "SP: sn%08X; max hop %d; %f\n", pkt->hdr.seq_number,	    pkt->hdr.max_hop, SimTime());#endif // VISUAL_ROUTE  }  pkt->hdr.newSeqNumber = false;  shrPrint( ("SP: ea %3d; sn%08X; actHC %2d; pathHC %2d; sending %s @ %f\n",	     (int) MyEtherAddr, pkt->hdr.seq_number, pkt->hdr.actual_hop,	     pkt->hdr.path.getLength(), pkt->dump().c_str(), SimTime()));  SentPackets++;  if( m_mac_busy == false)  {    m_mac_busy = true;    m_active_packet = pkt;    m_active_packet->inc_ref();    SendToMac( pkt);  }  else  {    shrPrint( ("SP: ea %3d; sn%08X; mac busy, delaying\n", (int) MyEtherAddr, pkt->hdr.seq_number));    AddToSendQueue( pkt);  }  return;}/*** SendToMac was added in February 2006.**** Its purpose is to simulate the small amount of time that elapses between** when the hardware stops sensing the carrier and it is able to actually start** transmission of the packet.**** For backwards compatibility, the transition time may be zero. In this case,** forward the packet directly to the mac layer instead of starting a timer.*/template <class PLD>void SHR<PLD>::SendToMac(  packet_t	*pkt){  m_mac_busy = true;  if( transitionTime != 0)  {    // start timer    transitionTimer.Set( SimTime() + transitionTime);    // save packet    transitionPkt = pkt;  }  else    to_mac( pkt, pkt->hdr.size, 0);  return;}/*** TransitionTimer was added in February 2006.**** Timer has expired indicating that the hardware has finished its transition** from sensing the carrier and is finally starting to transmit the packet.*/template <class PLD>void SHR<PLD>::TransitionTimer(  trigger_t	&){  // send saved packet to mac  to_mac( transitionPkt, transitionPkt->hdr.size, 0);  transitionPkt = 0;  return;}/*** Find the packet's source address in this node's cache. If the entry is not** found, create it. If the hop count in the cache is greater than the hop** count of the packet, update the cache.**** Return true if the entry was created or updated, false otherwise.*/template <class PLD>bool SHR<PLD>::updateHopCountInCache(  ether_addr_t	dst,  unsigned int	hopCount,  UpdateType	type,  const char	*str,  packet_t	*mwl){  if( dst == MyEtherAddr)    return false;  cache_t::iterator	iter;  iter = m_seq_cache.find( dst);   // If the destination address is not found, create a new record.  if( iter == m_seq_cache.end())  {    shrPrint( ("%10s: uHCIC: ea %3d; sn%08X; dst %3d; hc %2d new @ %f\n", str,	       (int) MyEtherAddr, mwl->hdr.seq_number, (int) dst, hopCount, SimTime()));    iter = (m_seq_cache.insert( make_pair( dst, seq_number_t()))).first;    iter->second.hopCount( hopCount, true, false);	// true/false doesn't matter since the entry is new    return true;  }  // if there's no change, return  if( iter->second.hopCount() == hopCount)    return false;  // if the new packet won't update the cost table entry, return false  if( type != Always && iter->second.hopCount() <= hopCount)    return false;  // update the cost table entry  shrPrint( ("%10s: uHCIC: ea %3d; sn%08X; dst %3d; hc %2d->%2d update @ %f",	     str, (int) MyEtherAddr, mwl->hdr.seq_number, (int) dst,	     iter->second.hopCount(), hopCount, SimTime()));  //mwl remember print in method hopCount  iter->second.hopCount( hopCount, type == Hello ? true : false, shrDoPrint);  return true;}/*** Interface that is used by the adjacency matrix channel model. Do not use** them with the radio model.*/template <class PLD>void SHR<PLD>::HelloTimer(  trigger_t	&){#ifdef	USE_CONFIG_FILE//  shrPrint( ("HT: ea %3d; HELLO timer @ %f\n", (int) MyEtherAddr, SimTime()));  generateHELLO();#else	// USE_CONFIG_FILE  printf( "SHR::HelloTimer may only be used with a configuration file\n");  assert( 0);#endif	// USE_CONFIG_FILE  return;}template <class PLD>void SHR<PLD>::scheduleHELLO(  double	time){#ifdef	USE_CONFIG_FILE  printf( "schedHELLO: ea %3d @ %f ", (int) MyEtherAddr, time);  if( backOff == SHRBackOff_SHR && RouteRepairEnabled == true)  {    printf( "enabled\n");    helloTimer.Set( time);  }  else    printf( "ignored\n");#else	// USE_CONFIG_FILE  printf( "SHR::scheduleHELLO may only be used with a configuration file\n");  assert( 0);#endif	// USE_CONFIG_FILE  return;}/*** The inport that is called when the power manager wakes the node up.** If the configuration file is in use, this must be defined, but it must not** do anything*/template <class PLD>void SHR<PLD>::from_pm_node_up(){#ifndef	USE_CONFIG_FILE  generateHELLO();#endif	// USE_CONFIG_FILE  return;}/*** The node has just come back up. Send out a HELLO packet for each entry in** the Cost Table.*/template <class PLD>void SHR<PLD>::generateHELLO(){  cache_t::iterator iter;  ether_addr_t	dest;  // convert entire cost table into hop count list  for( iter = m_seq_cache.begin(); iter != m_seq_cache.end(); iter++)  {    packet_t	*pkt;    dest = iter->first;    if( dest == MyEtherAddr)      continue;    pkt = (packet_t *) createHelloPkt( dest, iter->second.hopCount());    SendPacket( pkt);	// send with new sequence number  }  return;}/*** The purpose of the HELLO packet is to inform the receiving node that sending** node has come back to life. The HELLO packet contains a list of <addr, dist>** pairs. For each pair, the node determines if the entry in its cost table** needs to be updated. If so, update the cost table and add the updated entry** to a list that will be used to generate a new HELLO packet. If no changes** are made to the cost table, then no HELLO packet is sent.*/template <class PLD>void SHR<PLD>::receiveHelloPacket(  packet_t	*pkt){  cache_t::iterator	iter;  ether_addr_t	destAddr = pkt->hdr.dst_addr;  int		hopCount = pkt->hdr.helloData;  shrPrint( ("rHP: ea %3d; from %3d; for %3d; hc %d @ %f\n", (int) MyEtherAddr,	     (int) pkt->hdr.cur_addr, (int) destAddr, hopCount, SimTime()));/*** Assume that the path from this node to the destination must go through the** node that sent the HELLO packet. Therefore, increment the hop count.** If this assumption is wrong, then the hop count in the HELLO packet is** greater than the Cost Table entry.*/  hopCount++;  // if the Cost Table entry is updated, forward the HELLO packet.  if( updateHopCountInCache( destAddr, hopCount, Hello, "HELLO", pkt) == true)    SendPacket( (packet_t *) createHelloPkt( destAddr, hopCount));  return;}/******************************************************************* * We are now receiving a packet from the mac layer. *******************************************************************/template <class PLD>void SHR<PLD>::from_mac_data(  packet_t	*pkt,  double	power){  ether_addr_t src = pkt->hdr.src_addr;  bool		costTableUpdated = false;  RecvPackets++;  addToNeighborMatrix( (int) pkt->hdr.cur_addr, (int) MyEtherAddr);  Printf((DumpPackets,"%d SHR: %d %d %s \n", (int) MyEtherAddr,	  (int) pkt->hdr.cur_addr, (int) MyEtherAddr, pkt->dump().c_str()));  shrPrint( ("fmd: ea %3d<-%3d sn%08X %s @ %f\n", (int) MyEtherAddr,	     (int) pkt->hdr.cur_addr, pkt->hdr.seq_number, pkt->dump().c_str(),	     SimTime()));      if( pkt->hdr.type == HELLO)  {    receiveHelloPacket( pkt);    pkt->free();    return;  }  cache_t::iterator iter;    /*** If the packet is not an ACK, then update the cost table.**** The result of updating the cost table is used if the packet is a RREP.*/  if( pkt->hdr.type != ACK)  {    costTableUpdated = updateHopCountInCache( src, pkt->hdr.actual_hop, Lower,					      "rRRDP", pkt);    iter = m_seq_cache.find( src);   }/*** The method check (defined at the top of this file) determines if this** sequence number is greater than the sequence number in the cache. If the** packet's sequence number is greater, then this packet is new. This** comparison is not valid for resent packets.*/  if( pkt->hdr.type != ACK && (!iter->second.check( pkt->hdr.seq_number) ||			       pkt->hdr.resend))  {    // the received packet is new    RecvUniPackets++;    if( pkt->hdr.dst_addr == MyEtherAddr)    {      if( pkt->hdr.resend == 0)      {	switch( pkt->hdr.type)	{	  // this case can't happen, but it makes the compiler happy	  case HELLO:	  case ACK:	    break;	  case REQUEST:	  {	    packet_t	*rp = (packet_t *) createReplyPkt( pkt->hdr.src_addr,							   iter->second.hopCount());	    Printf( (DumpPackets, "%d SHR: %d->%d %s\n", (int) MyEtherAddr,		     (int) MyEtherAddr, (int) pkt->hdr.src_addr, rp->dump().c_str()));	    shrPrint( ("rPAD: ea %d creates REPLY %s @ %f\n", (int) MyEtherAddr,		       rp->dump().c_str(), SimTime()));	    // Send reply and check if any packets need to be sent to the src	    // of the request	    SendPacket( rp);	    CheckBuffer( pkt->hdr.src_addr, iter->second.hopCount());	  }	  break;	  case REPLY:	    Printf((DumpPackets,"%d SHR: %d<-%d %s\n", (int)MyEtherAddr,		    (int)MyEtherAddr, (int)pkt->hdr.src_addr,		    pkt->dump().c_str()));	    // Packet arrives at destination, Ack after AckWindow	    SendAck( pkt->hdr.src_addr, MyEtherAddr, pkt->hdr.cur_addr,		     pkt->hdr.seq_number, AckWindow, true);	    CheckBuffer( pkt->hdr.src_addr, iter->second.hopCount());	    break;	  case DATA:	    // the packets arrives at its destination	    // Packet arrives at destination, Ack after AckWindow	    SendAck( pkt->hdr.src_addr, MyEtherAddr, pkt->hdr.cur_addr,		     pkt->hdr.seq_number, AckWindow, true);	    pkt->inc_pld_ref();	    to_transport(pkt->pld);	    {	      int	hc = pkt->hdr.actual_hop;	      TotalHop += hc;	      if( hc > HCArraySize-1)		hc = HCArraySize-1;	      HopCounts[hc]++;	    }	    RecvDataPackets++;	    pkt->hdr.path.AddNode(MyEtherAddr);#ifdef VISUAL_ROUTE    // this printf is used by the compareHC and checkHC utilities	    printf( "VR: %f; %3d->%3d; sn%08X; %f; %d; %s\n", SimTime(),		    (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr,		    pkt->hdr.seq_number, (SimTime() - pkt->hdr.send_time),		    pkt->hdr.actual_hop, pkt->hdr.path.ToString());#endif //VISUAL_ROUTE	    visualizer->writePath( (int) pkt->hdr.src_addr,				   (int) pkt->hdr.dst_addr,pkt->hdr.seq_number,				   pkt->hdr.path, true);	    break;	}      }    }    else      {/*** If the hop count in the cost table is less than the maximum allowed by the** received packet, then forward the packet.*/      if( pkt->hdr.actual_hop < pkt->hdr.max_hop)      {	packet_t* np = pkt->copy();		// create copy of packet	np->hdr.cur_addr = MyEtherAddr;	np->hdr.pre_addr = pkt->hdr.cur_addr;	np->hdr.resend = 0;	np->hdr.actual_hop++;	np->hdr.suboptimal = false;	np->hdr.path.AddNode( MyEtherAddr);/*** How the packet is forwarded depends on the packet type.**** Data packet require an election. If the destination isn't found in the cost** table, don't participate in the election. Otherwise, the delay is dependent** on the value of the cost table entry relative to the expected hop of the** received packet.*/	if( np->hdr.type == DATA)	{	  iter = m_seq_cache.find( np->hdr.dst_addr);	  if( iter != m_seq_cache.end())	  {	    // If the packet is on the ACK list, remove it.	    // This happens when the retransmission is lost and the upstream	    // node resends the packet.	    {	      packet_t	*pktFromList = (packet_t *) getFromAckList( pkt);	      if( pktFromList != NULL)		removeFromAckList( pktFromList, true);	    }	    np->hdr.expected_hop = (*iter).second.hopCount();	    double	hop, backOffTime;	    switch( backOff)	    {/*** Calculate the amount of time to wait before responding.** The form of this equation is different than that of the paper. In the paper** the sender decrements the expected hop count before putting the value into** the packet. In the simulation, the hop count is not decremented.*/	      case SHRBackOff_SSR:	      case SHRBackOff_Incorrect:		shrPrint( ("FP: ea %3d; cost table %2d; pkt %2d\n", (int) MyEtherAddr, iter->second.hopCount(), pkt->hdr.expected_hop));		if( iter->second.hopCount() < pkt->hdr.expected_hop)		  hop = Random( 1.0/(pkt->hdr.expected_hop - iter->second.hopCount()));		else		{		  hop = Random( iter->second.hopCount() - pkt->hdr.expected_hop +1.0);		  if( backOff == SHRBackOff_SSR)		    hop += 1.0;		  SentSuboptimal++;		  np->hdr.suboptimal = true;		}		break;/*** Implement the fix that Boleslaw proposed on 3/21/2006.** If h_table <= h_expected, then**   backoff = lambda * U(0,1)/(h_e - h_t + 1)** else**   backoff = lambda * (h_t - h_e + U(0,1))*/	      case SHRBackOff_SHR:		if( iter->second.hopCount() < pkt->hdr.expected_hop)		  hop = Random(1.0)/(pkt->hdr.expected_hop - iter->second.hopCount());		else		{		  hop = iter->second.hopCount() - pkt->hdr.expected_hop + 1.0 +		      Random( 1.0);		  SentSuboptimal++;		  np->hdr.suboptimal = true;		}		break;	      default:		hop = 1;	// shouldn't happen, but quiets gcc		assert( 0);		break;	    }	    backOffTime = hop * ForwardDelay#ifdef	MWL_DOUBLE_DELAY		* (1 << pkt->hdr.resend)#endif	// MWL_DOUBLE_DELAY		;	    if( continuousBackOff == false)	// convert lambda to slot	    {	      int	slot;			      slot = (int) (backOffTime / slotWidth);	      backOffTime = slot * slotWidth + Random( transitionTime);	    }	    // Don't forward packets until after the AckWindow	    np->hdr.delay = backOffTime + AckWindow;	    shrPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; pkt %2d; table %2d; backoff %f\n",		       (int) MyEtherAddr, (int) pkt->hdr.cur_addr, (int) pkt,		       pkt->hdr.seq_number, pkt->hdr.expected_hop-1, np->hdr.expected_hop,		       backOffTime));	    SendPacket( np);	  }	  else	  {	    shrPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; not in cache\n",		       (int) MyEtherAddr, (int) pkt->hdr.cur_addr,		       (int) pkt, pkt->hdr.seq_number));	    np->free();	  }	}/*** Request packets are flooded: No election, forward after a random delay*/	else if( np->hdr.type == REQUEST)	  forwardAsFlood( np);/*** Reply packets are conditionally flooded.**** RREP (Z -> Y) from X, where Y generated the RREQ for Z and X has forwarded**      the packet to this node.** If (Y is not in the cost table)**   then the packet is dropped.** else		(Y is in the cost table)

⌨️ 快捷键说明

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