src/devices/mesh/dot11s/hwmp-rtable.cc
changeset 4882 3eab2f6b1adc
parent 4852 123dc54d734e
child 4885 2761d3e01723
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp-rtable.cc	Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,282 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "ns3/object.h"
+#include "ns3/assert.h"
+#include "ns3/simulator.h"
+#include "ns3/ptr.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/hwmp-rtable.h"
+
+NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
+
+TypeId
+HwmpRtable::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::HwmpRtable")
+                      .SetParent<Object> ()
+                      .AddConstructor<HwmpRtable> ();
+  return tid;
+
+}
+
+HwmpRtable::HwmpRtable ()
+{
+}
+
+HwmpRtable::~HwmpRtable ()
+{
+  DoDispose ();
+}
+
+void
+HwmpRtable::DoDispose ()
+{
+  NS_LOG_UNCOND ("RTABLE DISPOSE STARTED");
+  m_routes.clear ();
+  m_roots.clear ();
+}
+
+void
+HwmpRtable::AddReactivePath (
+  Mac48Address destination,
+  Mac48Address retransmitter,
+  uint32_t port,
+  uint32_t metric,
+  Time  lifetime,
+  uint32_t seqnum
+)
+{
+  std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+  if (i == m_routes.end ())
+    {
+      ReactiveRoute newroute;
+      m_routes[destination] = newroute;
+    }
+  else
+    {
+      /**
+       * if outport differs from stored, routing info is
+       * actual and metric is worse - we ignore this
+       * information
+       */
+      if (
+        (i->second.port != port) &&
+        (i->second.metric < metric) &&
+        /**
+         * The routing info is actual or it
+         * was received from peer
+         */
+        ((i->second.whenExpire > Simulator::Now ())||(i->second.whenExpire == Seconds(0)))
+      )
+        return;
+    }
+  i = m_routes.find (destination);
+  NS_ASSERT (i != m_routes.end());
+  i->second.retransmitter = retransmitter;
+  i->second.port = port;
+  i->second.metric = metric;
+  if (lifetime != Seconds (0))
+    i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
+  else
+    /**
+     * Information about peer does not have lifetime
+     */
+    i->second.whenExpire = Seconds (0);
+  i->second.seqnum = seqnum;
+}
+
+void
+HwmpRtable::AddProactivePath (
+  uint32_t metric,
+  Mac48Address root,
+  Mac48Address retransmitter,
+  uint32_t port,
+  Time  lifetime,
+  uint32_t seqnum
+)
+{
+  ProactiveRoute newroute;
+  m_roots[port] = newroute;
+  std::map<uint32_t,ProactiveRoute>::iterator i = m_roots.find (port);
+  NS_ASSERT (i != m_roots.end());
+  i->second.root = root;
+  i->second.retransmitter = retransmitter;
+  i->second.metric = metric;
+  i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
+  i->second.seqnum = seqnum;
+
+}
+
+void
+HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t port, Mac48Address precursor)
+{
+  bool should_add = true;
+  std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+  if ((i != m_routes.end ()) && (i->second.port == port))
+    {
+      for (unsigned int j = 0 ; j < i->second.precursors.size (); j ++)
+        if (i->second.precursors[j] == precursor)
+          {
+            should_add = false;
+            break;
+          }
+      if (should_add)
+        i->second.precursors.push_back (precursor);
+    }
+  std::map<uint32_t,ProactiveRoute>::iterator k = m_roots.find (port);
+  if (k != m_roots.end ())
+    {
+      for (unsigned int j = 0 ; j < k->second.precursors.size (); j ++)
+        if (k->second.precursors[j] == precursor)
+          return;
+      k->second.precursors.push_back (precursor);
+      return;
+    }
+}
+
+void
+HwmpRtable::DeleteProactivePath (uint32_t port)
+{
+  std::map<uint32_t,ProactiveRoute>::iterator j = m_roots.find (port);
+  if (j != m_roots.end ())
+    m_roots.erase (j);
+
+}
+void
+HwmpRtable::DeleteProactivePath (Mac48Address root, uint32_t port)
+{
+  std::map<uint32_t,ProactiveRoute>::iterator j = m_roots.find (port);
+  if ((j != m_roots.end ())&&(j->second.root == root))
+    m_roots.erase (j);
+
+}
+
+void
+HwmpRtable::DeleteReactivePath (Mac48Address destination, uint32_t port)
+{
+  std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+  if (i != m_routes.end ())
+    if (i->second.port ==  port)
+      m_routes.erase (i);
+}
+
+HwmpRtable::LookupResult
+HwmpRtable::LookupReactive (Mac48Address destination)
+{
+  LookupResult result;
+  result.retransmitter = Mac48Address::GetBroadcast ();
+  result.metric = MAX_METRIC;
+  result.ifIndex = PORT_ANY;
+
+  std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+  if (i == m_routes.end ())
+    return result;
+  result.ifIndex = i->second.port;
+  //Seconds (0) means that this is routing
+  if (i->second.whenExpire < Simulator::Now ())
+    if (i->second.retransmitter != destination)
+      return result;
+  result.retransmitter = i->second.retransmitter;
+  result.metric = i->second.metric;
+  result.seqnum = i->second.seqnum;
+  return result;
+}
+
+HwmpRtable::LookupResult
+HwmpRtable::LookupProactive (uint32_t port)
+{
+  LookupResult result;
+  result.retransmitter = Mac48Address::GetBroadcast ();
+  result.metric = MAX_METRIC;
+  result.ifIndex = PORT_ANY;
+  std::map<uint32_t, ProactiveRoute>::iterator i = m_roots.find (port);
+  if (i == m_roots.end ())
+    return result;
+  result.ifIndex = i->first;
+  if (i->second.whenExpire < Simulator::Now ())
+    return result;
+  result.retransmitter = i->second.retransmitter;
+  result.metric = i->second.metric;
+  result.seqnum = i->second.seqnum;
+  return result;
+}
+
+std::vector<HwmpRtable::FailedDestination>
+HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress, uint32_t port)
+{
+  std::vector<FailedDestination> retval;
+  for (std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.begin (); i != m_routes.end(); i++)
+    if ((i->second.retransmitter == peerAddress)&& (i->second.port == port))
+      {
+        FailedDestination dst;
+        dst.destination = i->first;
+        i->second.seqnum ++;
+        dst.seqnum = i->second.seqnum;
+        retval.push_back (dst);
+      }
+  /**
+   * Lookup a path to root
+   */
+  std::map<uint32_t, ProactiveRoute>::iterator i = m_roots.find (port);
+  if ((i != m_roots.end ())&&(i->second.retransmitter == peerAddress))
+    {
+      FailedDestination dst;
+      dst.destination = i->second.root;
+      dst.seqnum = i->second.seqnum;
+      retval.push_back (dst);
+    }
+  return retval;
+}
+uint32_t
+HwmpRtable::RequestSeqnum (Mac48Address destination)
+{
+  std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+  if (i == m_routes.end ())
+    return 0;
+  return i->second.seqnum;
+}
+
+std::vector<Mac48Address>
+HwmpRtable::GetPrecursors (Mac48Address destination, uint32_t port)
+{
+  std::vector<Mac48Address> retval;
+  std::map<uint32_t, ProactiveRoute>::iterator root = m_roots.find (port);
+  if ((root != m_roots.end ()) &&(root->second.root == destination))
+    {
+      for (unsigned int i = 0; i < root->second.precursors.size (); i ++)
+        retval.push_back (root->second.precursors[i]);
+    }
+  std::map<Mac48Address, ReactiveRoute>::iterator route = m_routes.find (destination);
+  if ( (route != m_routes.end ()) && (route->second.port == port) )
+    {
+      for (unsigned int i = 0; i < route->second.precursors.size (); i ++)
+        retval.push_back (route->second.precursors[i]);
+    }
+  return retval;
+}
+
+}//namespace ns3