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

📄 ashr.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 4 页
字号:
    // else h_table > h_pkt-1, longer route, send during T3    // T3 is slots 1..numT3Slots    // slot within T3 determined by h_table - h_pkt    else if( h_table <= h_pkt + numT3Slots)    {      slot = h_table - h_pkt;      T3PktsSent[ slot]++;      forwardPkt = true;    }    else	// major topology change or isolated node; drop packet    {      DropPkts++;      forwardPkt = false;    }  }  // Backoff has been calculated, forward packet if required  if( forwardPkt == true)  {    mwlPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; %c pkt %2d; table %2d; slot %2d\n",	       (int) MyEtherAddr, (int) pkt->hdr.pre_addr, (int) pkt,	       pkt->hdr.seq_number, mwlFlag, h_pkt, h_table, slot));    backOffTime = slot * slotWidth + Random( transitionTime);    // insert an AckWindow before first slot    pkt->hdr.delay = backOffTime + AckWindow;    pkt->hdr.slotNumber = slot;    SendPacket( pkt, false);  }  else  {    mwlPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; %c pkt %2d; table %2d; dropping\n",	       (int) MyEtherAddr, (int) pkt->hdr.pre_addr, (int) pkt,	       pkt->hdr.seq_number, mwlFlag, h_pkt, h_table));    pkt->free();	// not forwarding, so free packet  }  return;}/*** Determine if a packet should generate an ACK packet.** If the packet that was just received is a REPLY or DATA packet, then check** to see if the packet is a rebroadcast of a packet that was sent by this** node. (Packet is on either the m_T3_queue or m_collPktsSent_queue.)** In addition, also gather statistics on the classification of the packet that** was received.*/template <class PLD>bool SSRv02<PLD>::determineAckStatus(  packet_t	*pkt){  if( pkt->hdr.type == REQUEST)    return false;  packet_queue_t::iterator	iter;  packet_t	*orig;  bool		doAck;  int		i = pkt->hdr.type == REPLY ? 0 : 1;	// for stats keeping  mwlPrint( ("dAS: ea %3d; Looking %s on m_T3_queue\n", (int) MyEtherAddr,	     pkt->dump().c_str()));  // get original packet from queue of sent packets  for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++)  {    mwlPrint( ("dAS: ea %3d;   Found %s on m_T3_queue\n", (int) MyEtherAddr,	       (*iter)->dump().c_str()));    if( (*iter)->hdr.src_addr == pkt->hdr.src_addr &&	(*iter)->hdr.dst_addr == pkt->hdr.dst_addr &&	(*iter)->hdr.seq_number == pkt->hdr.seq_number &&	(*iter)->hdr.type == pkt->hdr.type)      break;		// match found  }  // if not found, check COLL packet queue  if( iter == m_T3_queue.end())  {    for( iter = m_collPktsSent_queue.begin(); iter!=m_collPktsSent_queue.end();	 iter++)    {      mwlPrint( ("dAS: ea %3d;   Found %s on m_collPktsSent_queue\n",		 (int) MyEtherAddr, (*iter)->dump().c_str()));      if( (*iter)->hdr.src_addr == pkt->hdr.src_addr &&	  (*iter)->hdr.dst_addr == pkt->hdr.dst_addr &&	  (*iter)->hdr.seq_number == pkt->hdr.seq_number &&	  (*iter)->hdr.type == pkt->hdr.type)	break;		// match found    }    if( iter == m_collPktsSent_queue.end())      return false;    mwlPrint( ("dAS: ea %3d;   match m_collPktsSent_queue\n", (int) MyEtherAddr));  }  else    mwlPrint( ("dAS: ea %3d;   match m_T3_queue\n", (int) MyEtherAddr));  orig = *iter;  doAck = true;  if( orig->hdr.canceled == true)    CanceledPktsRcvd[i]++;  else if( orig->hdr.cur_addr != pkt->hdr.pre_addr)    BadAddrPktsRcvd[i]++;  else if( orig->hdr.actual_hop+1 != pkt->hdr.actual_hop)    WrongHopPktsRcvd[i]++;  else  {    // account for the AckWindow added to forwarding delay    double	delta = SimTime() - orig->hdr.xmit_end_time - AckWindow;    int		slot = (int) (delta / slotWidth);    if( slot < 1)      T1PktsRcvd[i]++;    else if( slot <= numT2Slots)      T2PktsRcvd[i][ slot - 1]++;    else if( slot <= numT2Slots + numT3Slots)      T3PktsRcvd[i][ slot - numT2Slots - 1]++;    else    {      // don't want to ack these packets      // wait for timer to expire (started in from_mac_ack)      doAck = false;      T4PktsRcvd[i]++;    }    if( doAck == true && pkt->hdr.expected_hop != orig->hdr.expected_hop - 1)      updateHopCountInCache( orig->hdr.dst_addr, pkt->hdr.expected_hop + 1,			     true, "dAS", orig);  }//mwl  else//mwl    OtherPktsRcvd[i]++;  return doAck;}/*** This node has detected the retransmission of a packet that it had sent.** - Cancel retransmission of the packet** - Send an ACK packet*/template <class PLD>void SSRv02<PLD>::performAck(  packet_t	*pkt){  CancelRetransmission( pkt->hdr.src_addr, pkt->hdr.seq_number);  if( pkt->hdr.pre_addr == MyEtherAddr)	//mwl this test shouldn't be needed  {    mwlPrint( ("pA: ea %3d; 0x%08X; sn%08X; sending ACK\n", (int) MyEtherAddr,	       (int) pkt, pkt->hdr.seq_number));    SendAck( pkt->hdr.src_addr, MyEtherAddr, MyEtherAddr, pkt->hdr.seq_number,	     0.0);  }  else  {    mwlPrint( ("pA: ea %3d; 0x%08X; sn%08X; resend<-MaxResend\n",	       (int) MyEtherAddr, (int) pkt, pkt->hdr.seq_number));    //printf("rr%d receives again %s\n",(int)MyEtherAddr,(*iter)->dump().c_str());//    (*iter)->hdr.resend = MaxResend;  }  return;}/*** A receive-receive collision has been detected.** This will affect every packet on the m_T3_queue since these are the packets** that have yet to be rebroadcast by the next node.*/template <class PLD>void SSRv02<PLD>::from_mac_recv_recv_coll( packet_t *pkt1, packet_t *pkt2){  packet_queue_t::iterator	iter;  // for each pkt on m_T3_queue  for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++)  {    packet_t	*pkt = *iter;    double	delta;    int		slot;/*** determine time slot of collision** Remember, AckWindow is added to the packet's transmission time, so account** for that value here. If a collision occurs before the end of AckWindow, it** must be an external collision, so it is ignored.*/    delta = SimTime() - pkt->hdr.xmit_end_time - AckWindow;    if( delta < 0.0)      continue;    slot = (int) (delta / slotWidth);    // record statistics    if( slot < 1)      T1Collisions++;    else if( slot <= numT2Slots)      T2Collisions[ slot - 1]++;    else if( slot <= numT2Slots + numT3Slots)      T3Collisions[ slot - 1 - numT2Slots]++;    else      IgnoreCollisions++;    // record in packet when collision was detected    if( slot < 1 + numT2Slots + numT3Slots)    {      mwlPrint( ("fmrrc: ea %3d; pkt 0x%08X sn%08X st %f @ %f [%d] (%3d, sn%08X; %3d, sn%08X)\n",		 (int) MyEtherAddr, (unsigned int) (*iter),		 (*iter)->hdr.seq_number, (*iter)->hdr.xmit_start_time,		 SimTime(), slot, (int) pkt1->hdr.cur_addr,		 pkt1->hdr.seq_number, (int) pkt2->hdr.cur_addr,		 pkt2->hdr.seq_number));      pkt->hdr.collDetected = true;      pkt->hdr.slotNumber = slot;    }  }  return;}template <class PLD>void SSRv02<PLD>::CancelPacket(  ether_addr_t	&src,  unsigned int	seq_number){//  mwlPrint( ("CP: ea %3d; src %3d; sn%08X @ %f\n", (int) MyEtherAddr,//	     (int) src, seq_number, SimTime()));  /*  ** 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)  {    mwlPrint( ("CP: ea %3d; src %3d; sn%08X cancel active @ %f\n",	       (int) MyEtherAddr, (int) src, seq_number, SimTime()));    //Printf((DumpPackets,"rr%d cancels the current packet\n",(int)MyEtherAddr));    m_active_packet->hdr.canceled = true;    cancel();    return;  }  // Now, look for the packet in m_send_queue.  packet_queue_t::iterator iter;  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;  packet_t	*pktFromQ = *iter;  // If the pending packet is an ACK, don't cancel it.  if( pktFromQ->hdr.type != ACK)  {    CanceledPackets++;//mwl    if( pktFromQ->hdr.suboptimal == true)//mwl      CanceledSuboptimal++;    pktFromQ->free();    m_send_queue.erase( iter);  }  return;}/*** Cancel future retransmissions of a packet.** - Remove the packet from the m_T3_queue** - Cancel the T1, T2 & T3 timers** - Remove the packet from the m_collPktsSent_queue*/template <class PLD>void SSRv02<PLD>::CancelRetransmission(  ether_addr_t	&src,  unsigned int	seq_number){  packet_queue_t::iterator	iter;  packet_t	*orig;  mwlPrint( ("CR: ea %3d; [%3d, sn%08X]\n", (int) MyEtherAddr, (int) src,	     seq_number));/*** Search m_T3_queue looking for a matching packet. If it is found, then send** an ACK message.*/  for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++)    if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number)      break;		// match found  // if found, cancel timers  if( iter != m_T3_queue.end())  {      orig = *iter;    mwlPrint( ("CR: ea %3d; removing 0x%08X from m_T3_queue\n",	       (int) MyEtherAddr, (int) orig));    // cancel COLL packet timers    if( endT1Timer.Active( orig->hdr.t1Index) == true)      endT1Timer.Cancel( orig->hdr.t1Index);    if( endT2Timer.Active( orig->hdr.t2Index) == true)      endT2Timer.Cancel( orig->hdr.t2Index);//mwl    if( endT3Timer.Active( orig->hdr.t3Index) == true)//mwl      endT3Timer.Cancel( orig->hdr.t3Index);    m_T3_queue.erase( iter);    orig->free();  }  // if pkt on Coll Sent queue, remove it  for( iter = m_collPktsSent_queue.begin(); iter != m_collPktsSent_queue.end();       iter++)    if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number)      break;		// match found  if( iter != m_collPktsSent_queue.end())  {    orig = *iter;    mwlPrint( ("CR: ea %3d; removing 0x%08X from m_collPktsSent_queue\n",	       (int) MyEtherAddr, (int) orig));    if( endCollTimer.Active( orig->hdr.collIndex) == true)      endCollTimer.Cancel( orig->hdr.collIndex);    m_collPktsSent_queue.erase( iter);    orig->free();  }  return;}/*** The routing layer has received an acknowledgement from the mac layer.** False indicates that the transmission failed.*/template <class PLD>void SSRv02<PLD>::from_mac_ack(  bool		flag){  bool		dataReply = m_active_packet->hdr.canceled == false &&      (m_active_packet->hdr.type == REPLY ||       m_active_packet->hdr.type == DATA);  bool		testQueue = true;  //Printf((DumpPackets,"rr%d receives an ack from mac\n",(int)MyEtherAddr));  // a non-ack packet failed, so resend it  /*  ** Resending is handled differently with ASHR. The old way (SSR) was to  ** always resechedule non-ACK packets. With ASHR, a DATA or REPLY packet that  ** is being sent by an intermediate node is not rescheduled. ASHR will send a  ** COLL packet at the end of T2. Note that if a collision occurs when the  ** source sends a packet, no COLL packet will be sent. Therefore, in this  ** case the packet must be rescheduled.  */  if( flag == false && m_active_packet->hdr.type != ACK)  {    if( MyEtherAddr == m_active_packet->hdr.src_addr ||	(m_active_packet->hdr.type != DATA &&	 m_active_packet->hdr.type != REPLY))    {      mwlPrint( ("fma: ea %3d; cur %3d; reschedule %s; @ %f\n",		 (int) MyEtherAddr, (int) m_active_packet->hdr.cur_addr,		 m_active_packet->dump().c_str(), SimTime()));      //Printf((DumpPackets,"%d resends %s\n", (int)MyEtherAddr,m_active_packet->dump().c_str()));      m_active_packet->inc_ref();      SendToMac( m_active_packet);      testQueue = false;	// just sent to mac, so don't test queue    }    else    {      mwlPrint( ("fma: ea %3d; cur %3d; dropping %s; @ %f\n",		 (int) MyEtherAddr, (int) m_active_packet->hdr.cur_addr,		 m_active_packet->dump().c_str(), SimTime()));      // add to T3 queue      m_active_packet->inc_ref();      m_T3_queue.push_back( m_active_packet);    }  }  else  {    m_active_packet->hdr.xmit_end_time = SimTime();    if( dataReply == true)    {      double	start;      mwlPrint( ("fma: ea %3d; Starting timers %3d->%3d; %c; %c; %s @ %f\n",		 (int) MyEtherAddr, (int) m_active_packet->hdr.src_addr,		 (int) m_active_packet->hdr.dst_addr,		 m_active_packet->hdr.type == DATA ? 'D' : m_active_packet->hdr.type == REPLY ? 'R' : '?',		 m_active_packet->hdr.t3Flag == true ? 'T' : 'F',		 m_active_packet->dump().c_str(), SimTime()));      // start T1, T2 & T3 timers & add pkt to end of queue      if( endT1Timer.Active( m_active_packet->hdr.t1Index) == true)	mwlPrint( ("fma: ea %3d; sn%08X; T1 (%d) active (%f)\n", (int) MyEtherAddr, m_active_packet->hdr.seq_number, m_active_packet->hdr.t1Index, endT1Timer.GetTime( m_active_packet->hdr.t1Index)));      if( endT2Timer.Active( m_active_packet->hdr.t2Index) == true)	mwlPrint( ("fma: ea %3d; sn%08X; T2 (%d) active (%f)\n", (int) MyEtherAddr, m_active_packet->hdr.seq_number, m_active_packet->hdr.t2Index, endT2Timer.GetTime( m_active_packet->hdr.t2Index)));      start = SimTime() + slotWidth + 2 * transitionTime + AckWindow;      m_active_packet->hdr.t1Index = endT1Timer.Set( m_active_packet, start);      start += (numT2Slots + 1) * slotWidth;      m_active_packet->hdr.t2Index = endT2Timer.Set( m_active_packet, start);//mwl      start += numT3Slots * slotWidth;//mwl      m_active_packet->hdr.t3Index = endT3Timer.Set( m_active_packet, start);      // add to T3 queue      m_active_packet->inc_ref();      m_T3_queue.push_back( m_active_packet);    }    else    {      mwlPrint( ("fma: ea %3d; dropping !dataReply %3d->%3d; sn %08X @ %f\n",		 (int) MyEtherAddr, (int) m_active_packet->hdr.src_addr,		 (int) m_active_packet->hdr.dst_addr,		 m_active_packet->hdr.seq_number, SimTime()));      ;    }    m_active_packet->free();  }  if( testQueue == true)    if( m_send_queue.size() != 0)    {      packet_t	*packet = m_send_queue.front();      m_send_queue.pop_front();      mwlPrint( ("fma: ea %3d; 0x%08X; sn %08X from send queue\n",		 (int) MyEtherAddr, (int) packet, 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 SSRv02<PLD>::SendAck(  ether_addr_t	src_addr,  ether_addr_t	cur_addr,  ether_addr_t	pre_addr,  unsigned int	seq_number,  simtime_t	delay){  packet_t	*p = (packet_t *) createAckPkt( src_addr, cur_addr, pre_addr,						seq_number, delay);  Printf((DumpPackets,"%d SSRv02: %d->%d %s\n",(int)MyEtherAddr,(int)cur_addr,	  (int)pre_addr,p->dump().c_str()));  mwlPrint( ("SA: ack %3d->%3d %s @ %f\n", (int) cur_addr, (int) pre_addr,	     p->dump().c_str(), SimTime()));  SendPacket( p, false);  return;}template <class PLD>void SSRv02<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++;  }  return;}template <class PLD>bool SSRv02_Struct<PLD>::hdr_struct::dump(  std::string	&str) const {   static char	pkt_type[][10]={ "REQ", "REPLY", "DATA", "ACK", "COLL",				 "HELLO", "BACK"};//mwl  char		buffer[30];  char		buffer[50];///mwl  sprintf( buffer, "0x%08X %s %d->%d %d %d", (int) this, pkt_type[type],  sprintf( buffer, "0x%08X %s %c %d->%d sn%08X %d", (int) this, pkt_type[type],	   t3Flag == true ? 'T' : 'F', (int) src_addr, (int) dst_addr,	   seq_number, size);   str = buffer;  return type == DATA;}#endif /*SSRv02_h*/

⌨️ 快捷键说明

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