PREQ, PREP overflow is handled correctly
authorKirill Andreev <andreev@iitp.ru>
Thu, 09 Jul 2009 14:07:14 +0400
changeset 5113 a912d4372406
parent 5112 762835be2902
child 5114 505e762ea818
PREQ, PREP overflow is handled correctly
src/devices/mesh/dot11s/hwmp-protocol-mac.cc
src/devices/mesh/dot11s/hwmp-protocol-mac.h
src/devices/mesh/dot11s/hwmp-protocol.cc
src/devices/mesh/dot11s/hwmp-protocol.h
src/devices/mesh/dot11s/ie-dot11s-perr.cc
src/devices/mesh/dot11s/ie-dot11s-perr.h
src/devices/mesh/dot11s/ie-dot11s-prep.cc
src/devices/mesh/dot11s/ie-dot11s-preq.cc
src/devices/mesh/dot11s/ie-dot11s-preq.h
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc	Thu Jul 09 14:07:14 2009 +0400
@@ -102,11 +102,11 @@
   IePreq preq;
   IePrep prep;
   IePerr perr;
-  while (packet->RemoveHeader(rann))
+  while (packet->RemoveHeader (rann))
   {
     NS_LOG_WARN("RANN is not supported!");
   }
-  while (packet->RemoveHeader(preq))
+  while (packet->RemoveHeader (preq))
   {
     m_stats.rxPreq ++;
     if (preq.GetOriginatorAddress () == m_protocol->GetAddress ())
@@ -116,7 +116,7 @@
     preq.DecrementTtl ();
     m_protocol->ReceivePreq (preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ()));
   }
-  while (packet->RemoveHeader(prep))
+  while (packet->RemoveHeader (prep))
   {
     m_stats.rxPrep ++;
     if (prep.GetTtl () == 0)
@@ -124,11 +124,17 @@
     prep.DecrementTtl ();
     m_protocol->ReceivePrep (prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ()));
   }
-  while(packet->RemoveHeader(perr))
+  std::vector<IePerr::FailedDestination> failedDestinations;
+  while (packet->RemoveHeader (perr))
   {
     m_stats.rxPerr ++;
-    m_protocol->ReceivePerr (perr, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
+    std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector ();
+    for(std::vector<IePerr::FailedDestination>::const_iterator i = destinations.begin (); i != destinations.end (); i ++)
+      failedDestinations.push_back (*i);
   }
+  if (failedDestinations.size () > 0)
+    m_protocol->ReceivePerr (failedDestinations, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
+  NS_ASSERT(packet->GetSize () == 0);
   return false;
 }
 
@@ -156,10 +162,10 @@
   m_stats.txData ++;
   m_stats.txDataBytes += packet->GetSize ();
   MeshHeader meshHdr;
-  meshHdr.SetMeshSeqno(tag.GetSeqno());
-  meshHdr.SetMeshTtl(tag.GetTtl());
-  packet->AddHeader(meshHdr);
-  header.SetAddr1(tag.GetAddress());
+  meshHdr.SetMeshSeqno (tag.GetSeqno());
+  meshHdr.SetMeshTtl (tag.GetTtl());
+  packet->AddHeader (meshHdr);
+  header.SetAddr1 (tag.GetAddress());
   return true;
 }
 WifiMeshActionHeader
@@ -175,8 +181,18 @@
 HwmpProtocolMac::SendPreq(IePreq preq)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  std::vector<IePreq> preq_vector;
+  preq_vector.push_back(preq);
+  SendPreq(preq_vector);
+}
+void
+HwmpProtocolMac::SendPreq(std::vector<IePreq> preq)
+{
   Ptr<Packet> packet = Create<Packet> ();
-  packet->AddHeader(preq);
+  for(std::vector<IePreq>::const_iterator i = preq.begin (); i != preq.end (); i ++)
+  {
+    packet->AddHeader (*i);
+  }
   packet->AddHeader (GetWifiMeshActionHeader ());
   //create 802.11 header:
   WifiMacHeader hdr;
@@ -200,16 +216,22 @@
 HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  if(m_myPreq.GetDestCount () == 0)
+  for(std::vector<IePreq>::iterator i = m_myPreq.begin (); i != m_myPreq.end(); i ++)
   {
-    m_myPreq.SetHopcount (0);
-    m_myPreq.SetTTL (m_protocol->GetMaxTtl ());
-    m_myPreq.SetPreqID (m_protocol->GetNextPreqId ());
-    m_myPreq.SetOriginatorAddress (m_protocol->GetAddress ());
-    m_myPreq.SetOriginatorSeqNumber (originator_seqno);
-    m_myPreq.SetLifetime (m_protocol->GetActivePathLifetime ());
+    if(i->IsFull ())
+      continue;
+    NS_ASSERT (i->GetDestCount () > 0);
+    i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
   }
-  m_myPreq.AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
+  IePreq preq;
+  preq.SetHopcount (0);
+  preq.SetTTL (m_protocol->GetMaxTtl ());
+  preq.SetPreqID (m_protocol->GetNextPreqId ());
+  preq.SetOriginatorAddress (m_protocol->GetAddress ());
+  preq.SetOriginatorSeqNumber (originator_seqno);
+  preq.SetLifetime (m_protocol->GetActivePathLifetime ());
+  preq.AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
+  m_myPreq.push_back(preq);
   SendMyPreq ();
 }
 void
@@ -218,13 +240,13 @@
   NS_LOG_FUNCTION_NOARGS ();
   if(m_preqTimer.IsRunning ())
     return;
-  if(m_myPreq.GetDestCount () == 0)
+  if(m_myPreq.size () == 0)
     return;
   //reschedule sending PREQ
   NS_ASSERT (!m_preqTimer.IsRunning());
   m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendMyPreq, this);
   SendPreq (m_myPreq);
-  m_myPreq.ClearDestinationAddressElements ();
+  m_myPreq.clear ();
 }
 void
 HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver)
@@ -232,7 +254,7 @@
   NS_LOG_FUNCTION_NOARGS ();
   //Create packet
   Ptr<Packet> packet  = Create<Packet> ();
-  packet->AddHeader(prep);
+  packet->AddHeader (prep);
   packet->AddHeader (GetWifiMeshActionHeader ());
   //create 802.11 header:
   WifiMacHeader hdr;
@@ -249,11 +271,23 @@
   m_parent->SendManagementFrame(packet, hdr);
 }
 void
-HwmpProtocolMac::ForwardPerr(IePerr perr, std::vector<Mac48Address> receivers)
+HwmpProtocolMac::ForwardPerr(std::vector<IePerr::FailedDestination> failedDestinations, std::vector<Mac48Address> receivers)
 {
   NS_LOG_FUNCTION_NOARGS ();
   Ptr<Packet> packet  = Create<Packet> ();
-  packet->AddHeader(perr);
+  IePerr perr;
+  for(std::vector<IePerr::FailedDestination>::const_iterator i = failedDestinations.begin (); i != failedDestinations.end (); i ++)
+  {
+    if(!perr.IsFull ())
+      perr.AddAddressUnit (*i);
+    else
+    {
+      packet->AddHeader (perr);
+      perr.ResetPerr ();
+    }
+  }
+  if(perr.GetNumOfDest () > 0)
+    packet->AddHeader (perr);
   packet->AddHeader (GetWifiMeshActionHeader ());
   //create 802.11 header:
   WifiMacHeader hdr;
@@ -278,17 +312,37 @@
   }
 }
 void
-HwmpProtocolMac::InitiatePerr (IePerr perr, std::vector<Mac48Address> receivers)
+HwmpProtocolMac::InitiatePerr (std::vector<IePerr::FailedDestination> failedDestinations, std::vector<Mac48Address> receivers)
 {
-  m_myPerr.perr.Merge(perr);
-  for(unsigned int i = 0; i < receivers.size (); i ++)
+  //All duplicates in PERR are checked here, and there is no reason to
+  //check it at any athoer place
   {
-    bool should_add = true;
-    for (unsigned int j = 0; j < m_myPerr.receivers.size (); j ++)
-      if(receivers[i] == m_myPerr.receivers[j])
-        should_add = false;
-    if(should_add)
-      m_myPerr.receivers.push_back(receivers[i]);
+    std::vector<Mac48Address>::const_iterator end = receivers.end();
+    for(std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != end; i ++)
+    {
+      bool should_add = true;
+      for (std::vector<Mac48Address>::const_iterator j = m_myPerr.receivers.begin (); j != m_myPerr.receivers.end (); j ++)
+        if ((*i) == (*j))
+          should_add = false;
+      if (should_add)
+        m_myPerr.receivers.push_back(*i);
+    }
+  }
+  {
+    std::vector<IePerr::FailedDestination>::const_iterator end =  failedDestinations.end ();
+    for(std::vector<IePerr::FailedDestination>::const_iterator i = failedDestinations.begin (); i != end; i ++)
+    {
+      bool should_add = true;
+      for
+        (
+         std::vector<IePerr::FailedDestination>::const_iterator j = m_myPerr.destinations.begin ();
+         j != m_myPerr.destinations.end ();
+         j ++)
+        if ( ((*i).destination == (*j).destination) && ((*j).seqnum > (*i).seqnum) )
+          should_add = false;
+      if (should_add)
+        m_myPerr.destinations.push_back(*i);
+    }
   }
   SendMyPerr ();
 }
@@ -299,8 +353,8 @@
   if(m_perrTimer.IsRunning ())
     return;
   m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr, this);
-  ForwardPerr (m_myPerr.perr, m_myPerr.receivers);
-  m_myPerr.perr.ResetPerr ();
+  ForwardPerr (m_myPerr.destinations, m_myPerr.receivers);
+  m_myPerr.destinations.clear ();
   m_myPerr.receivers.clear ();
 }
 uint32_t
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.h	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.h	Thu Jul 09 14:07:14 2009 +0400
@@ -63,12 +63,13 @@
   static WifiMeshActionHeader GetWifiMeshActionHeader ();
   ///\name Intercation with HWMP:
   //\{
-  void SendPreq(IePreq preq);
-  void SendPrep(IePrep prep, Mac48Address receiver);
+  void SendPreq (IePreq preq);
+  void SendPreq (std::vector<IePreq> preq);
+  void SendPrep (IePrep prep, Mac48Address receiver);
   //Forward a peth error
-  void ForwardPerr(IePerr perr, std::vector<Mac48Address> receivers);
+  void ForwardPerr(std::vector<IePerr::FailedDestination> destinations, std::vector<Mac48Address> receivers);
   // initiate my own path error
-  void InitiatePerr(IePerr perr, std::vector<Mac48Address> receivers);
+  void InitiatePerr (std::vector<IePerr::FailedDestination> destinations, std::vector<Mac48Address> receivers);
   /** \brief Request a destination. If can not send preq immediately -
    * add a destination to exisying PREQ generated by me and stored in
    * PREQ queue
@@ -96,13 +97,13 @@
   ///\name my PREQ and PREQ timer:
   //\{
   EventId m_preqTimer;
-  IePreq  m_myPreq;
+  std::vector<IePreq>  m_myPreq;
   //\}
   ///\name PERR timer and stored path error
   //\{
   EventId m_perrTimer;
   struct MyPerr {
-    IePerr perr;
+    std::vector<IePerr::FailedDestination> destinations;
     std::vector<Mac48Address> receivers;
   };
   MyPerr m_myPerr;
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc	Thu Jul 09 14:07:14 2009 +0400
@@ -34,7 +34,6 @@
 #include "airtime-metric.h"
 #include "ie-dot11s-preq.h"
 #include "ie-dot11s-prep.h"
-#include "ie-dot11s-perr.h"
 
 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
 
@@ -559,28 +558,25 @@
   prep_sender->second->SendPrep (prep, result.retransmitter);
 }
 void
-HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface, Mac48Address fromMp)
+HwmpProtocol::ReceivePerr (std::vector<IePerr::FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
 {
   //Acceptance cretirea:
   NS_LOG_DEBUG("I am "<<GetAddress ()<<", received PERR from "<<from);
-  std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector ();
+  std::vector<IePerr::FailedDestination> retval;
   HwmpRtable::LookupResult result;
   for(unsigned int i = 0; i < destinations.size (); i ++)
   {
     result = m_rtable->LookupReactive (destinations[i].destination);
-    if (
+    if (!(
         (result.retransmitter != from) ||
         (result.ifIndex != interface) ||
         (result.seqnum > destinations[i].seqnum)
-        )
-    {
-      perr.DeleteAddressUnit(destinations[i].destination);
-      continue;
-    }
+        ))
+      retval.push_back(destinations[i]);
   }
-  if(perr.GetNumOfDest () == 0)
+  if(retval.size() == 0)
     return;
-  ForwardPathError (MakePathError (destinations));
+  ForwardPathError (MakePathError (retval));
 }
 void
 HwmpProtocol::SendPrep (
@@ -675,7 +671,7 @@
   m_stats.initiatedPerr ++;
   for(unsigned int i = 0; i < destinations.size (); i ++)
   {
-    retval.perr.AddAddressUnit(destinations[i]);
+    retval.destinations.push_back(destinations[i]);
     m_rtable->DeleteReactivePath(destinations[i].destination);
   }
   return retval;
@@ -689,7 +685,7 @@
     for(unsigned int j = 0; j < perr.receivers.size(); j ++)
       if(i->first == perr.receivers[j].first)
         receivers_for_interface.push_back(perr.receivers[j].second);
-    i->second->InitiatePerr (perr.perr, receivers_for_interface);
+    i->second->InitiatePerr (perr.destinations, receivers_for_interface);
   }
 }
 void
@@ -701,7 +697,7 @@
     for(unsigned int j = 0; j < perr.receivers.size(); j ++)
       if(i->first == perr.receivers[j].first)
         receivers_for_interface.push_back(perr.receivers[j].second);
-    i->second->ForwardPerr (perr.perr, receivers_for_interface);
+    i->second->ForwardPerr (perr.destinations, receivers_for_interface);
   }
 }
 
--- a/src/devices/mesh/dot11s/hwmp-protocol.h	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.h	Thu Jul 09 14:07:14 2009 +0400
@@ -90,7 +90,7 @@
   //\{
   void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric);
   void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric);
-  void ReceivePerr(IePerr perr, Mac48Address from, uint32_t interface, Mac48Address fromMp);
+  void ReceivePerr(std::vector<IePerr::FailedDestination>, Mac48Address from, uint32_t interface, Mac48Address fromMp);
   void SendPrep (
       Mac48Address src,
       Mac48Address dst,
@@ -106,7 +106,7 @@
    */
   struct PathError
   {
-    IePerr perr;
+    std::vector<IePerr::FailedDestination> destinations;
     /// interface-address
     std::vector<std::pair<uint32_t, Mac48Address> > receivers;
   };
--- a/src/devices/mesh/dot11s/ie-dot11s-perr.cc	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-perr.cc	Thu Jul 09 14:07:14 2009 +0400
@@ -119,20 +119,6 @@
       }
 }
 void
-IePerr::Merge(const IePerr perr)
-{
-  std::vector<FailedDestination> to_merge = perr.GetAddressUnitVector ();
-  for (std::vector<FailedDestination>::iterator i = to_merge.begin (); i != to_merge.end(); i ++)
-  {
-    bool should_add = true;
-    for (std::vector<FailedDestination>::iterator j = m_addressUnits.begin (); j != m_addressUnits.end(); j ++)
-      if ((i->destination == j->destination) && (i->seqnum <= j->seqnum))
-        should_add = false;
-    if(should_add)
-      AddAddressUnit (*i);
-  }
-}
-void
 IePerr::ResetPerr ()
 {
   m_addressUnits.clear ();
@@ -178,10 +164,6 @@
   dest.seqnum = 3;
   a.AddAddressUnit(dest);
   
-  IePerr b = a;
-  b.Merge(a);
-  NS_TEST_ASSERT_EQUAL (a, b);
-  
   result = result && TestRoundtripSerialization (a);
   return result;
 }
--- a/src/devices/mesh/dot11s/ie-dot11s-perr.h	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-perr.h	Thu Jul 09 14:07:14 2009 +0400
@@ -47,7 +47,6 @@
   bool IsFull () const;
   std::vector<FailedDestination> GetAddressUnitVector () const;
   void DeleteAddressUnit (Mac48Address address);
-  void Merge(const IePerr perr);
   void ResetPerr ();
 private:
   WifiElementId ElementId () const{
--- a/src/devices/mesh/dot11s/ie-dot11s-prep.cc	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-prep.cc	Thu Jul 09 14:07:14 2009 +0400
@@ -188,8 +188,7 @@
     +4 //Lifetime
     +4 //metric
     +6 //Originator address
-    +4 //Originator seqno
-    +1; //destination count
+    +4; //Originator seqno
   return retval;
 };
 void
--- a/src/devices/mesh/dot11s/ie-dot11s-preq.cc	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-preq.cc	Thu Jul 09 14:07:14 2009 +0400
@@ -410,10 +410,15 @@
     return false;
   if(m_destinations[0]->GetDestinationAddress () == Mac48Address::GetBroadcast ())
     return false;
-  if(GetInformationSize () + 11 > 255)
+  if((GetInformationSize () + 11) > 255)
     return false;
   return true;
 }
+bool
+IePreq::IsFull () const
+{
+  return ((GetInformationSize () + 11) > 255);
+}
 #ifdef RUN_SELF_TESTS
 
 /// Built-in self test for IePreq
--- a/src/devices/mesh/dot11s/ie-dot11s-preq.h	Thu Jul 09 00:07:53 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-preq.h	Thu Jul 09 14:07:14 2009 +0400
@@ -118,7 +118,7 @@
    * this preq is not proactive
    */
   bool MayAddAddress(Mac48Address originator);
-
+  bool IsFull () const;
 private:
   WifiElementId ElementId () const{
     return IE11S_PREQ;