NetAnim: Add support for tracking routing table
authorJohn Abraham <john.abraham.in@gmail.com>
Mon, 03 Dec 2012 13:30:17 -0800
changeset 9161 9c62cfdc7946
parent 9160 38c7ba91b8bd
child 9162 b587372eb2de
NetAnim: Add support for tracking routing table
src/netanim/examples/wireless-animation.cc
src/netanim/model/animation-interface.cc
src/netanim/model/animation-interface.h
--- a/src/netanim/examples/wireless-animation.cc	Mon Dec 03 10:18:06 2012 -0500
+++ b/src/netanim/examples/wireless-animation.cc	Mon Dec 03 13:30:17 2012 -0800
@@ -157,8 +157,11 @@
   AnimationInterface::SetNodeColor (wifiApNode, 0, 255, 0); // Optional
   AnimationInterface::SetNodeColor (wifiStaNodes, 255, 0, 0); // Optional
   AnimationInterface::SetNodeColor (csmaNodes, 0, 0, 255); // Optional
+
   AnimationInterface anim ("wireless-animation.xml"); // Mandatory
+
   anim.EnablePacketMetadata (true); // Optional
+  anim.EnableIpv4RouteTracking ("routingtable-wireless.xml", Seconds(0), Seconds(5), Seconds(0.25)); //Optional
   Simulator::Run ();
   Simulator::Destroy ();
   return 0;
--- a/src/netanim/model/animation-interface.cc	Mon Dec 03 10:18:06 2012 -0500
+++ b/src/netanim/model/animation-interface.cc	Mon Dec 03 13:30:17 2012 -0800
@@ -39,6 +39,7 @@
 #include "ns3/uan-net-device.h"
 #include "ns3/uan-mac.h"
 #include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h" 
 
 #include <cstdio>
 #include <unistd.h>
@@ -61,15 +62,16 @@
 
 
 AnimationInterface::AnimationInterface (const std::string fn, uint64_t maxPktsPerFile, bool usingXML)
-  : m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)), 
+  : m_routingF (0), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)), 
     m_outputFileName (fn),
     m_outputFileSet (false), gAnimUid (0), m_randomPosition (true),
     m_writeCallback (0), m_started (false), 
     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
-    m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn)
+    m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn),
+    m_routingStopTime (Seconds (0)), m_routingFileName (""),
+    m_routingPollInterval (Seconds (5))
 {
   m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
-
   initialized = true;
   StartAnimation ();
 }
@@ -79,6 +81,65 @@
   StopAnimation ();
 }
 
+void AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, Time pollInterval)
+{
+  m_routingFileName = fileName;
+  SetRoutingOutputFile (m_routingFileName);
+  m_routingStopTime = stopTime;
+  m_routingPollInterval = pollInterval;
+  WriteN (GetXMLOpen_anim (0), m_routingF); 
+  Simulator::Schedule (startTime, &AnimationInterface::TrackIpv4Route, this);
+}
+
+void AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, NodeContainer nc, Time pollInterval)
+{
+  m_routingNc = nc;
+  EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
+}
+
+std::string AnimationInterface::GetIpv4RoutingTable (Ptr <Node> n)
+{
+
+  NS_ASSERT (n);
+  Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
+  if (!ipv4)
+    {
+      NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
+      return "";
+    }
+  std::stringstream stream;
+  Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
+  ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
+  return stream.str();
+
+}
+
+void AnimationInterface::TrackIpv4Route ()
+{
+  if (Simulator::Now () > m_routingStopTime)
+  {
+    NS_LOG_INFO ("TrackIpv4Route completed");
+    return;
+  }
+  if (m_routingNc.GetN ())
+    {
+      for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
+        {
+          Ptr <Node> n = *i;
+          WriteN (GetXMLOpenClose_routing (n->GetId (), GetIpv4RoutingTable (n)), m_routingF);
+        }
+    }
+  else
+    {
+      for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
+        {
+          Ptr <Node> n = *i;
+          WriteN (GetXMLOpenClose_routing (n->GetId (), GetIpv4RoutingTable (n)), m_routingF);
+        }
+    }
+  Simulator::Schedule (m_routingPollInterval, &AnimationInterface::TrackIpv4Route, this);
+}
+
 void AnimationInterface::SetXMLOutput ()
 {
   NS_LOG_INFO ("XML output set");
@@ -136,6 +197,22 @@
   return true;
 }
 
+bool AnimationInterface::SetRoutingOutputFile (const std::string& fn)
+{
+  if (m_routingF)
+    {
+      NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
+      return false;
+    }
+  m_routingF = std::fopen (fn.c_str (), "w");
+  if (!m_routingF)
+    {
+      NS_FATAL_ERROR ("Unable to open Animation Routing output file");
+      return false;
+    }
+  return true;
+}
+
 void AnimationInterface::EnablePacketMetadata (bool enable)
 {
    m_enablePacketMetadata = enable;
@@ -410,35 +487,22 @@
       }
     }
 
-  if (m_xml)
-    { // output the xml headers
-      std::ostringstream oss;
-      oss << GetXMLOpen_anim (0);
-      oss << GetPreamble ();
-      oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
-      WriteN (oss.str ());
-    }
+  
+  std::ostringstream oss;
+  oss << GetXMLOpen_anim (0);
+  oss << GetPreamble ();
+  oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
+  WriteN (oss.str (), m_f);
   NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
   // Dump the topology
   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
     {
       Ptr<Node> n = *i;
       std::ostringstream oss;
-      if (m_xml)
-        {
-          Vector v = GetPosition (n);
-          struct Rgb rgb = nodeColors[n->GetId ()];
-          oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, rgb);
-	  WriteN (oss.str ());
-        }
-      else
-        {
-          // Location exists, dump it
-          Vector v = GetPosition (n);
-          oss << "0.0 N " << n->GetId () 
-              << " " << v.x << " " << v.y << std::endl;
-      	  WriteN (oss.str ().c_str (), oss.str ().length ());
-        }
+      Vector v = GetPosition (n);
+      struct Rgb rgb = nodeColors[n->GetId ()];
+      oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, rgb);
+      WriteN (oss.str (), m_f);
     }
   NS_LOG_INFO ("Setting p2p links");
   // Now dump the p2p links
@@ -480,7 +544,7 @@
                         {
                           oss << "0.0 L "  << n1Id << " " << n2Id << std::endl;
                         }
-                      WriteN (oss.str ());
+                      WriteN (oss.str (), m_f);
                     }
                 }
             }
@@ -494,7 +558,7 @@
   linkProperties.clear ();
   if (m_xml && !restart)
     {
-      WriteN (GetXMLClose ("topology"));
+      WriteN (GetXMLClose ("topology"), m_f);
       Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
     }
   if (!restart)
@@ -618,20 +682,25 @@
     {
       if (m_xml)
         { // Terminate the anim element
-          WriteN (GetXMLClose ("anim"));
+          WriteN (GetXMLClose ("anim"), m_f);
         }
       std::fclose (m_f);
     }
     m_outputFileSet = false;
+  if (m_routingF)
+    {
+      WriteN (GetXMLClose ("anim"), m_routingF);
+      std::fclose (m_routingF);
+    }
 }
 
-int AnimationInterface::WriteN (const std::string& st)
+int AnimationInterface::WriteN (const std::string& st, FILE * f)
 {
   if (m_writeCallback)
     {
       m_writeCallback (st.c_str ());
     }
-  return WriteN (st.c_str (), st.length ());
+  return WriteN (st.c_str (), st.length (), f);
 }
 
 std::vector <Ptr <Node> >  AnimationInterface::RecalcTopoBounds ()
@@ -674,7 +743,7 @@
   
 }
 
-int AnimationInterface::WriteN (const char* data, uint32_t count)
+int AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
 { 
   // Write count bytes to h from data
   uint32_t    nLeft   = count;
@@ -682,7 +751,7 @@
   uint32_t    written = 0;
   while (nLeft)
     {
-      int n = std::fwrite (p, 1,  nLeft, m_f);
+      int n = std::fwrite (p, 1,  nLeft, f);
       if (n <= 0) 
         {
           return written;
@@ -703,7 +772,7 @@
   double fbRx = now.GetSeconds ();
   double lbRx = now.GetSeconds ();
   oss << GetXMLOpenClose_p ("p", 0, fbTx, lbTx, 0, fbRx, lbRx, "", "DummyPktIgnoreThis");
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 
 
 }
@@ -713,7 +782,7 @@
 {
   std::ostringstream oss;
   oss << GetXMLOpenClose_NonP2pLinkProperties (id, ipv4Address, channelType);
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 void AnimationInterface::DevTxTrace (std::string context, Ptr<const Packet> p,
@@ -747,7 +816,7 @@
           << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time
           << (now + rxTime).GetSeconds () << std::endl;         // last bit rx time
     }
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 
@@ -1248,7 +1317,7 @@
   oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
   oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, nodeColors[n->GetId ()]);
   oss << GetXMLClose ("topology");
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
   WriteDummyPacket ();
 }
 
@@ -1282,7 +1351,7 @@
       oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
     }
   oss << GetXMLClose ("topology");
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
   WriteDummyPacket ();
   if (!Simulator::IsFinished ())
     {
@@ -1391,7 +1460,7 @@
 
   oss << GetXMLOpenClose_p ("wp", nodeId, pktInfo.m_fbTx, lbTx, rxId,
                             pktrxInfo.m_fbRx, pktrxInfo.m_lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 void AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
@@ -1405,7 +1474,7 @@
 
   oss << GetXMLOpenClose_p ("p", nodeId, pktInfo.m_fbTx, pktInfo.m_lbTx, rxId,
                             pktrxInfo.m_fbRx, pktrxInfo.m_lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 void AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
@@ -1439,7 +1508,7 @@
   NS_LOG_INFO ("Setting node visibility for Node Id:" << nodeId); 
   std::ostringstream oss;
   oss << GetXMLOpenClose_nodeupdate (nodeId, show);
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 
 }
 
@@ -1461,7 +1530,7 @@
   nodeColors[nodeId] = rgb;
   std::ostringstream oss;
   oss << GetXMLOpenClose_nodeupdate (nodeId);
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 
@@ -1482,7 +1551,7 @@
 {
   std::ostringstream oss;
   oss << GetXMLOpenClose_linkupdate (fromNode, toNode, linkDescription);
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 void AnimationInterface::UpdateLinkDescription (Ptr <Node> fromNode, Ptr <Node> toNode,
@@ -1492,7 +1561,7 @@
   NS_ASSERT (toNode);
   std::ostringstream oss;
   oss << GetXMLOpenClose_linkupdate (fromNode->GetId (), toNode->GetId (), linkDescription);
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 void AnimationInterface::SetLinkDescription (uint32_t fromNode, uint32_t toNode, 
@@ -1549,7 +1618,7 @@
   nodeDescriptions[nodeId] = descr;
   std::ostringstream oss;
   oss << GetXMLOpenClose_nodeupdate (nodeId);
-  WriteN (oss.str ());
+  WriteN (oss.str (), m_f);
 }
 
 
@@ -1704,6 +1773,15 @@
   return oss.str ();
 }
 
+std::string AnimationInterface::GetXMLOpenClose_routing (uint32_t nodeId, std::string routingInfo)
+{
+  std::ostringstream oss;
+  oss << "<" << "rt" << " t=\"" << Simulator::Now ().GetSeconds () << "\"" 
+      << " id=\"" << nodeId << "\""
+      << " info=\"" << routingInfo.c_str () << "\""
+      << "/>" << std::endl;
+  return oss.str ();
+}
 
 std::string AnimationInterface::GetXMLOpenClose_p (std::string pktType, uint32_t fId, double fbTx, double lbTx, 
                                                    uint32_t tId, double fbRx, double lbRx, std::string metaInfo, 
--- a/src/netanim/model/animation-interface.h	Mon Dec 03 10:18:06 2012 -0500
+++ b/src/netanim/model/animation-interface.h	Mon Dec 03 13:30:17 2012 -0800
@@ -114,6 +114,33 @@
   ~AnimationInterface ();
 
   /**
+   * \brief Enable tracking of the Ipv4 routing table for all Nodes
+   *
+   * \param fileName Trace file for storing routing table information 
+   * \param startTime Start time for capture
+   * \param stopTime  End time for capture
+   * \param pollInterval The periodic interval at which routing table information is polled
+   *        Default: 5s
+   *
+   * \returns none
+   */
+  void EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, Time pollInterval = Seconds(5));
+
+  /**
+   * \brief Enable tracking of the Ipv4 routing table for a set of Nodes
+   *
+   * \param fileName Trace file for storing routing table information
+   * \param startTime Start time for capture
+   * \param stopTime  End time for capture
+   * \param nc A NodeContainer containing nodes for which Routing table has to be tracked
+   * \param pollInterval The periodic interval at which routing table information is polled
+   *        Default: 5s
+   *
+   * \returns none
+   */
+  void EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, NodeContainer nc, Time pollInterval = Seconds(5));
+
+  /**
    * \brief Check if AnimationInterface is initialized
    * \returns true if AnimationInterface was already initialized
    *
@@ -121,28 +148,6 @@
   static bool IsInitialized (void);
 
   /**
-   * \brief Specify that animation commands are to be written
-   * to the specified output file.
-   *
-   * This call is used to write the animation information to a text
-   * file that can later be used as input to the network animator tool.
-   *
-   * \param fn The name of the output file.
-   * \returns true if successful open.
-   *
-   */
-  bool SetOutputFile (const std::string& fn);
-
-  /**
-   * \brief Specify that animation commands are to be written
-   * in XML format.
-   *
-   * \returns none
-   *
-   */
-  void SetXMLOutput ();
-
-  /**
    * \brief Specify the time at which capture should start
    * 
    * \param t The time at which AnimationInterface should begin capture of traffic info
@@ -358,14 +363,6 @@
   bool IsStarted (void);
 
   /**
-   * \brief Show all 802.11 frames. Default: show only frames accepted by mac layer
-   * \param showAll if true shows all 802.11 frames including beacons, association
-   *  request and acks (very chatty). if false only frames accepted by mac layer
-   *
-   */
-  void ShowAll802_11 (bool showAll); 
-
-  /**
    *
    * \brief Enable Packet metadata
    * \param enable if true enables writing the packet metadata to the XML trace file
@@ -373,7 +370,6 @@
    */
   void EnablePacketMetadata (bool enable);
 
-
   /**
    *
    * \brief Get trace file packet count (This used only for testing)
@@ -394,9 +390,10 @@
   int64_t AssignStreams (int64_t stream);
 
 private:
-  FILE * m_f; // File handle for output (-1 if none)
+  FILE * m_f; // File handle for output (0 if none)
+  FILE * m_routingF; // File handle for routing table output (0 if None);
   // Write specified amount of data to the specified handle
-  int WriteN (const char*, uint32_t);
+  int WriteN (const char*, uint32_t, FILE * f);
   bool m_xml;      // True if xml format desired
   Time m_mobilityPollInterval;
   std::string m_outputFileName;
@@ -410,6 +407,36 @@
   Time m_stopTime;
   uint64_t m_maxPktsPerFile;
   std::string m_originalFileName;
+  Time m_routingStopTime;
+  std::string m_routingFileName;
+  Time m_routingPollInterval;
+  NodeContainer m_routingNc;
+  
+  void TrackIpv4Route ();
+  std::string GetIpv4RoutingTable (Ptr <Node> n);
+
+  /**
+   * \brief Specify that animation commands are to be written
+   * to the specified output file.
+   *
+   * This call is used to write the animation information to a text
+   * file that can later be used as input to the network animator tool.
+   *
+   * \param fn The name of the output file.
+   * \returns true if successful open.
+   *
+   */
+  bool SetOutputFile (const std::string& fn);
+  bool SetRoutingOutputFile (const std::string& fn);
+
+  /**
+   * \brief Specify that animation commands are to be written
+   * in XML format.
+   *
+   * \returns none
+   *
+   */
+  void SetXMLOutput ();
 
   /**
    * \brief Writes the topology information and sets up the appropriate
@@ -486,7 +513,7 @@
   void MobilityCourseChangeTrace (Ptr <const MobilityModel> mob);
 
   // Write a string to the specified handle;
-  int  WriteN (const std::string&);
+  int  WriteN (const std::string&, FILE * f);
 
   void OutputWirelessPacket (Ptr<const Packet> p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
   void OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
@@ -582,6 +609,7 @@
   std::string GetXMLClose (std::string name) {return "</" + name + ">\n"; }
   std::string GetXMLOpenClose_meta (std::string metaInfo);
   std::string GetXMLOpenClose_NonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType);
+  std::string GetXMLOpenClose_routing (uint32_t id, std::string routingInfo);
 
 
   /// Provides uniform random variables.