From f67f082657500da5c1f9e4ae802a4388db9df55c Mon Sep 17 00:00:00 2001 From: John Abraham Date: Mon, 3 Dec 2012 13:30:17 -0800 Subject: [PATCH] NetAnim: Add support for tracking routing table --- src/netanim/examples/wireless-animation.cc | 3 + src/netanim/model/animation-interface.cc | 168 +++++++++++++++------ src/netanim/model/animation-interface.h | 96 +++++++----- 3 files changed, 188 insertions(+), 79 deletions(-) diff --git a/src/netanim/examples/wireless-animation.cc b/src/netanim/examples/wireless-animation.cc index 31d2e2e56..23e16d835 100644 --- a/src/netanim/examples/wireless-animation.cc +++ b/src/netanim/examples/wireless-animation.cc @@ -157,8 +157,11 @@ main (int argc, char *argv[]) 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; diff --git a/src/netanim/model/animation-interface.cc b/src/netanim/model/animation-interface.cc index 6d799a3cc..99b4d6f1f 100644 --- a/src/netanim/model/animation-interface.cc +++ b/src/netanim/model/animation-interface.cc @@ -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 #include @@ -61,15 +62,16 @@ std::map AnimationInterface 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 (); - initialized = true; StartAnimation (); } @@ -79,6 +81,65 @@ AnimationInterface::~AnimationInterface () 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 n) +{ + + NS_ASSERT (n); + Ptr ipv4 = n->GetObject (); + if (!ipv4) + { + NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object"); + return ""; + } + std::stringstream stream; + Ptr routingstream = Create (&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 n = *i; + WriteN (GetXMLOpenClose_routing (n->GetId (), GetIpv4RoutingTable (n)), m_routingF); + } + } + else + { + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) + { + Ptr 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 @@ bool AnimationInterface::SetOutputFile (const std::string& fn) 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 @@ void AnimationInterface::StartAnimation (bool restart) } } - 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 "< 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 @@ void AnimationInterface::StartAnimation (bool restart) { oss << "0.0 L " << n1Id << " " << n2Id << std::endl; } - WriteN (oss.str ()); + WriteN (oss.str (), m_f); } } } @@ -494,7 +558,7 @@ void AnimationInterface::StartAnimation (bool restart) 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 @@ void AnimationInterface::StopAnimation () { 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 > AnimationInterface::RecalcTopoBounds () @@ -674,7 +743,7 @@ void AnimationInterface::RecalcTopoBounds (Vector v) } -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 @@ int AnimationInterface::WriteN (const char* data, uint32_t count) 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 @@ void AnimationInterface::WriteDummyPacket () 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 @@ void AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv { std::ostringstream oss; oss << GetXMLOpenClose_NonP2pLinkProperties (id, ipv4Address, channelType); - WriteN (oss.str ()); + WriteN (oss.str (), m_f); } void AnimationInterface::DevTxTrace (std::string context, Ptr p, @@ -747,7 +816,7 @@ void AnimationInterface::DevTxTrace (std::string context, Ptr p, << (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 @@ void AnimationInterface::MobilityCourseChangeTrace (Ptr mo 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 @@ void AnimationInterface::MobilityAutoCheck () 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 @@ void AnimationInterface::OutputWirelessPacket (Ptr p, AnimPacketIn 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 p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo) @@ -1405,7 +1474,7 @@ void AnimationInterface::OutputCsmaPacket (Ptr p, AnimPacketInfo & 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 n, double x, double y, double z) @@ -1439,7 +1508,7 @@ void AnimationInterface::ShowNode (uint32_t nodeId, bool show) 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 @@ void AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, nodeColors[nodeId] = rgb; std::ostringstream oss; oss << GetXMLOpenClose_nodeupdate (nodeId); - WriteN (oss.str ()); + WriteN (oss.str (), m_f); } @@ -1482,7 +1551,7 @@ void AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNo { std::ostringstream oss; oss << GetXMLOpenClose_linkupdate (fromNode, toNode, linkDescription); - WriteN (oss.str ()); + WriteN (oss.str (), m_f); } void AnimationInterface::UpdateLinkDescription (Ptr fromNode, Ptr toNode, @@ -1492,7 +1561,7 @@ void AnimationInterface::UpdateLinkDescription (Ptr fromNode, Ptr 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 @@ void AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string des nodeDescriptions[nodeId] = descr; std::ostringstream oss; oss << GetXMLOpenClose_nodeupdate (nodeId); - WriteN (oss.str ()); + WriteN (oss.str (), m_f); } @@ -1704,6 +1773,15 @@ std::string AnimationInterface::GetXMLOpen_packet (uint32_t fromLp, uint32_t fro 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, diff --git a/src/netanim/model/animation-interface.h b/src/netanim/model/animation-interface.h index f0bb0546b..deb8e66ac 100644 --- a/src/netanim/model/animation-interface.h +++ b/src/netanim/model/animation-interface.h @@ -113,6 +113,33 @@ public: */ ~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 @@ -120,28 +147,6 @@ public: */ 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 * @@ -357,14 +362,6 @@ public: */ 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 @@ -373,7 +370,6 @@ public: */ void EnablePacketMetadata (bool enable); - /** * * \brief Get trace file packet count (This used only for testing) @@ -394,9 +390,10 @@ public: 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 @@ private: 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 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 @@ private: void MobilityCourseChangeTrace (Ptr mob); // Write a string to the specified handle; - int WriteN (const std::string&); + int WriteN (const std::string&, FILE * f); void OutputWirelessPacket (Ptr p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo); void OutputCsmaPacket (Ptr p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo); @@ -582,6 +609,7 @@ private: std::string GetXMLClose (std::string name) {return "\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.