Fixed PERR propagation
authorKirill Andreev <andreev@iitp.ru>
Wed, 08 Jul 2009 18:45:39 +0400
changeset 5111 018748653ea8
parent 5110 fc6c60a490b2
child 5112 762835be2902
Fixed PERR propagation
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
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc	Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc	Wed Jul 08 18:45:39 2009 +0400
@@ -228,46 +228,6 @@
   m_myPreq.ClearDestinationAddressElements ();
 }
 void
-HwmpProtocolMac::SendOnePerr()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if(m_perrTimer.IsRunning ())
-    return;
-  if(m_myPerr.receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
-  {
-    m_myPerr.receivers.clear ();
-    m_myPerr.receivers.push_back (Mac48Address::GetBroadcast ());
-  }
-  m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendOnePerr, this);
-//Create packet
-  Ptr<Packet> packet  = Create<Packet> ();
-  packet->AddHeader(m_myPerr.perr);
-  //Action header:
-  WifiMeshActionHeader actionHdr;
-  WifiMeshActionHeader::ActionValue action;
-  action.pathSelection = WifiMeshActionHeader::PATH_ERROR;
-  actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action);
-  packet->AddHeader (actionHdr);
-  //create 802.11 header:
-  WifiMacHeader hdr;
-  hdr.SetAction ();
-  hdr.SetDsNotFrom ();
-  hdr.SetDsNotTo ();
-  hdr.SetAddr2 (m_parent->GetAddress ());
-  hdr.SetAddr3 (m_protocol->GetAddress ());
-  //Send Management frame
-  for(std::vector<Mac48Address>::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++)
-  {
-    hdr.SetAddr1 (*i);
-    m_stats.txPerr ++;
-    m_stats.txMgt ++;
-    m_stats.txMgtBytes += packet->GetSize ();
-    m_parent->SendManagementFrame(packet, hdr);
-  }
-  m_myPerr.perr.ResetPerr ();
-  m_myPerr.receivers.clear ();
-}
-void
 HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver)
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -295,9 +255,42 @@
   m_parent->SendManagementFrame(packet, hdr);
 }
 void
-HwmpProtocolMac::SendPerr(IePerr perr, std::vector<Mac48Address> receivers)
+HwmpProtocolMac::ForwardPerr(IePerr perr, std::vector<Mac48Address> receivers)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  Ptr<Packet> packet  = Create<Packet> ();
+  packet->AddHeader(perr);
+  //Action header:
+  WifiMeshActionHeader actionHdr;
+  WifiMeshActionHeader::ActionValue action;
+  action.pathSelection = WifiMeshActionHeader::PATH_ERROR;
+  actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action);
+  packet->AddHeader (actionHdr);
+  //create 802.11 header:
+  WifiMacHeader hdr;
+  hdr.SetAction ();
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  hdr.SetAddr2 (m_parent->GetAddress ());
+  hdr.SetAddr3 (m_protocol->GetAddress ());
+  if(receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
+  {
+    receivers.clear ();
+    receivers.push_back (Mac48Address::GetBroadcast ());
+  }
+  //Send Management frame
+  for(std::vector<Mac48Address>::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++)
+  {
+    hdr.SetAddr1 (*i);
+    m_stats.txPerr ++;
+    m_stats.txMgt ++;
+    m_stats.txMgtBytes += packet->GetSize ();
+    m_parent->SendManagementFrame(packet, hdr);
+  }
+}
+void
+HwmpProtocolMac::InitiatePerr (IePerr perr, std::vector<Mac48Address> receivers)
+{
   m_myPerr.perr.Merge(perr);
   for(unsigned int i = 0; i < receivers.size (); i ++)
   {
@@ -308,7 +301,18 @@
     if(should_add)
       m_myPerr.receivers.push_back(receivers[i]);
   }
-  SendOnePerr ();
+  SendMyPerr ();
+}
+void
+HwmpProtocolMac::SendMyPerr()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  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 ();
+  m_myPerr.receivers.clear ();
 }
 uint32_t
 HwmpProtocolMac::GetLinkMetric(Mac48Address peerAddress) const
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.h	Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.h	Wed Jul 08 18:45:39 2009 +0400
@@ -63,7 +63,10 @@
   //\{
   void SendPreq(IePreq preq);
   void SendPrep(IePrep prep, Mac48Address receiver);
-  void SendPerr(IePerr perr, std::vector<Mac48Address> receivers);
+  //Forward a peth error
+  void ForwardPerr(IePerr perr, std::vector<Mac48Address> receivers);
+  // initiate my own path error
+  void InitiatePerr(IePerr perr, 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
@@ -75,7 +78,7 @@
   
   /// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue)
   void SendMyPreq ();
-  void SendOnePerr ();
+  void SendMyPerr ();
   /// \return metric to HWMP protocol, needed only by metrics to add
   //peer as routing entry
   uint32_t GetLinkMetric (Mac48Address peerAddress) const;
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc	Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc	Wed Jul 08 18:45:39 2009 +0400
@@ -304,7 +304,7 @@
     if(result.retransmitter != Mac48Address::GetBroadcast ())
     {
       std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
-      MakePathError (destinations);
+      InitiatePathError (MakePathError (destinations));
     }
     m_stats.totalDropped ++;
     return false;
@@ -580,7 +580,7 @@
   }
   if(perr.GetNumOfDest () == 0)
     return;
-  MakePathError (destinations);
+  ForwardPathError (MakePathError (destinations));
 }
 void
 HwmpProtocol::SendPrep (
@@ -641,7 +641,7 @@
   if(status)
     return;
   std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
-  MakePathError (destinations);
+  InitiatePathError (MakePathError (destinations));
 }
 void
 HwmpProtocol::SetNeighboursCallback(Callback<std::vector<Mac48Address>, uint32_t> cb)
@@ -664,29 +664,47 @@
   }
   return false;
 }
-void
+HwmpProtocol::PathError
 HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations)
 {
+  PathError retval;
   //HwmpRtable increments a sequence number as written in 11B.9.7.2
-  std::vector<std::pair<uint32_t, Mac48Address> > receivers = GetPerrReceivers (destinations);
-  if(receivers.size () == 0)
-    return;
-  IePerr perr;
+  retval.receivers = GetPerrReceivers (destinations);
+  if(retval.receivers.size () == 0)
+    return retval;
   m_stats.initiatedPerr ++;
   for(unsigned int i = 0; i < destinations.size (); i ++)
   {
-    perr.AddAddressUnit(destinations[i]);
+    retval.perr.AddAddressUnit(destinations[i]);
     m_rtable->DeleteReactivePath(destinations[i].destination);
   }
+  return retval;
+}
+void
+HwmpProtocol::InitiatePathError(PathError perr)
+{
   for(HwmpProtocolMacMap::const_iterator i =  m_interfaces.begin (); i != m_interfaces.end (); i ++)
   {
     std::vector<Mac48Address> receivers_for_interface;
-    for(unsigned int j = 0; j < receivers.size(); j ++)
-      if(i->first == receivers[j].first)
-        receivers_for_interface.push_back(receivers[j].second);
-    i->second->SendPerr (perr, receivers_for_interface);
+    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);
   }
 }
+void
+HwmpProtocol::ForwardPathError(PathError perr)
+{
+  for(HwmpProtocolMacMap::const_iterator i =  m_interfaces.begin (); i != m_interfaces.end (); i ++)
+  {
+    std::vector<Mac48Address> receivers_for_interface;
+    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);
+  }
+}
+
 std::vector<std::pair<uint32_t, Mac48Address> >
 HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest)
 {
--- a/src/devices/mesh/dot11s/hwmp-protocol.h	Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.h	Wed Jul 08 18:45:39 2009 +0400
@@ -100,9 +100,25 @@
       uint32_t destinationSN,
       uint32_t lifetime,
       uint32_t interface);
-  
-  ///\brief forms a path error information element when list of destination fails on a given interface
-  void MakePathError (std::vector<IePerr::FailedDestination> destinations);
+  /**
+   * \brief Structure of path error: IePerr and list of receivers:
+   * interfaces and MAC address
+   */
+  struct PathError
+  {
+    IePerr perr;
+    /// interface-address
+    std::vector<std::pair<uint32_t, Mac48Address> > receivers;
+  };
+  /**
+   * \brief forms a path error information element when list of destination fails on a given interface
+   * \attention removes all entries from routing table!
+   */
+  PathError MakePathError (std::vector<IePerr::FailedDestination> destinations);
+  ///\brief Forwards a received path error
+  void ForwardPathError (PathError perr);
+  ///\brief Pasess a selg-generated PERR to interface-plugin
+  void InitiatePathError (PathError perr);
   /// \return list of addresses where a PERR should be sent to
   std::vector<std::pair<uint32_t, Mac48Address> > GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest);