src/netanim/model/animation-interface.cc
changeset 8773 25b20434eba8
parent 7823 2a669a0c452e
child 8778 bf37816b37ad
equal deleted inserted replaced
8772:ce0699130fc4 8773:25b20434eba8
    61 #define PURGE_INTERVAL 5
    61 #define PURGE_INTERVAL 5
    62 static bool initialized = false;
    62 static bool initialized = false;
    63 std::map <uint32_t, std::string> AnimationInterface::nodeDescriptions;
    63 std::map <uint32_t, std::string> AnimationInterface::nodeDescriptions;
    64 
    64 
    65 AnimationInterface::AnimationInterface ()
    65 AnimationInterface::AnimationInterface ()
    66   : m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
    66   : m_fHandle (STDOUT_FILENO), m_xml (false), m_mobilityPollInterval (Seconds(0.25)),
    67     usingSockets (false), mport (0), outputfilename (""),
    67     m_usingSockets (false), m_port (0), m_outputFileName (""),
    68     OutputFileSet (false), ServerPortSet (false), gAnimUid (0),randomPosition (true),
    68     m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0),m_randomPosition (true),
    69     m_writeCallback (0), m_started (false), 
    69     m_writeCallback (0), m_started (false), 
    70     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
    70     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
       
    71     m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE)
    71 {
    72 {
    72   initialized = true;
    73   initialized = true;
    73   StartAnimation ();
    74   StartAnimation ();
    74 }
    75 }
    75 
    76 
    76 AnimationInterface::AnimationInterface (const std::string fn, bool usingXML)
    77 AnimationInterface::AnimationInterface (const std::string fn, uint64_t maxPktsPerFile, bool usingXML)
    77   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), 
    78   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)), 
    78     usingSockets (false), mport (0), outputfilename (fn),
    79     m_usingSockets (false), m_port (0), m_outputFileName (fn),
    79     OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
    80     m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0), m_randomPosition (true),
    80     m_writeCallback (0), m_started (false), 
    81     m_writeCallback (0), m_started (false), 
    81     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
    82     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
       
    83     m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn)
    82 {
    84 {
    83   initialized = true;
    85   initialized = true;
    84   StartAnimation ();
    86   StartAnimation ();
    85 }
    87 }
    86 
    88 
    87 AnimationInterface::AnimationInterface (const uint16_t port, bool usingXML)
    89 AnimationInterface::AnimationInterface (const uint16_t port, bool usingXML)
    88   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), 
    90   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)), 
    89     usingSockets (true), mport (port), outputfilename (""),
    91     m_usingSockets (true), m_port (port), m_outputFileName (""),
    90     OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
    92     m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0), m_randomPosition (true),
    91     m_writeCallback (0), m_started (false), 
    93     m_writeCallback (0), m_started (false), 
    92     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
    94     m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
       
    95     m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE)
    93 {
    96 {
    94   initialized = true;
    97   initialized = true;
    95   StartAnimation ();
    98   StartAnimation ();
    96 }
    99 }
    97 
   100 
   105   NS_LOG_INFO ("XML output set");
   108   NS_LOG_INFO ("XML output set");
   106   m_xml = true;
   109   m_xml = true;
   107 }
   110 }
   108 
   111 
   109 
   112 
       
   113 void AnimationInterface::StartNewTraceFile ()
       
   114 {
       
   115   static int i = 0;
       
   116   std::ostringstream oss;
       
   117   oss << i;
       
   118   ++m_currentPktCount;
       
   119   if (m_currentPktCount <= m_maxPktsPerFile)
       
   120     {
       
   121       return;
       
   122     }
       
   123   StopAnimation ();
       
   124   m_outputFileName = m_originalFileName + "-" + oss.str ();
       
   125   StartAnimation (true);
       
   126   ++i;
       
   127 
       
   128 }
   110 void AnimationInterface::SetStartTime (Time t)
   129 void AnimationInterface::SetStartTime (Time t)
   111 {
   130 {
   112   m_startTime = t;
   131   m_startTime = t;
   113 }
   132 }
   114 
   133 
   117   m_stopTime = t;
   136   m_stopTime = t;
   118 }
   137 }
   119 
   138 
   120 bool AnimationInterface::SetOutputFile (const std::string& fn)
   139 bool AnimationInterface::SetOutputFile (const std::string& fn)
   121 {
   140 {
   122   if (OutputFileSet)
   141   if (m_outputFileSet)
   123     {
   142     {
   124       return true;
   143       return true;
   125     }
   144     }
   126   if (fn == "")
   145   if (fn == "")
   127     {
   146     {
   128       m_fHandle = STDOUT_FILENO;
   147       m_fHandle = STDOUT_FILENO;
   129       OutputFileSet = true;
   148       m_outputFileSet = true;
   130       return true;
   149       return true;
   131     }
   150     }
       
   151   NS_LOG_UNCOND (fn.c_str ());
   132   FILE* f = fopen (fn.c_str (), "w");
   152   FILE* f = fopen (fn.c_str (), "w");
   133   if (!f)
   153   if (!f)
   134     {
   154     {
   135       NS_FATAL_ERROR ("Unable to open Animation output file");
   155       NS_FATAL_ERROR ("Unable to open Animation output file");
   136       return false; // Can't open
   156       return false; // Can't open
   137     }
   157     }
   138   m_fHandle = fileno (f); // Set the file handle
   158   m_fHandle = fileno (f); // Set the file handle
   139   usingSockets = false;
   159   m_usingSockets = false;
   140   outputfilename = fn;
   160   m_outputFileName = fn;
   141   OutputFileSet = true;
   161   m_outputFileSet = true;
   142   return true;
   162   return true;
   143 }
   163 }
   144 
   164 
   145 void AnimationInterface::EnablePacketMetadata (bool enable)
   165 void AnimationInterface::EnablePacketMetadata (bool enable)
   146 {
   166 {
   180 }
   200 }
   181 
   201 
   182 bool AnimationInterface::SetServerPort (uint16_t port)
   202 bool AnimationInterface::SetServerPort (uint16_t port)
   183 {
   203 {
   184 #if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
   204 #if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
   185   if (ServerPortSet)
   205   if (m_serverPortSet)
   186     {
   206     {
   187       return true;
   207       return true;
   188     }
   208     }
   189   int s = socket (AF_INET, SOCK_STREAM, 0);
   209   int s = socket (AF_INET, SOCK_STREAM, 0);
   190   struct sockaddr_in addr;
   210   struct sockaddr_in addr;
   202   m_fHandle = accept (s, 0, 0);
   222   m_fHandle = accept (s, 0, 0);
   203   NS_LOG_INFO ("Got animator connection from remote");
   223   NS_LOG_INFO ("Got animator connection from remote");
   204   // set the linger socket option
   224   // set the linger socket option
   205   int t = 1;
   225   int t = 1;
   206   setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t));
   226   setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t));
   207   usingSockets = true;
   227   m_usingSockets = true;
   208   ServerPortSet = true;
   228   m_serverPortSet = true;
   209   return true;
   229   return true;
   210 #endif
   230 #endif
   211   return false; // never reached unless the above is disabled
   231   return false; // never reached unless the above is disabled
   212                 // which is done to support a platform like MinGW
   232                 // which is done to support a platform like MinGW
   213 }
   233 }
   214 
   234 
   215 bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
   235 bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
   216 {
   236 {
   217   return (pendingWifiPackets.find (AnimUid) != pendingWifiPackets.end ());
   237   return (m_pendingWifiPackets.find (AnimUid) != m_pendingWifiPackets.end ());
   218 }
   238 }
   219 
   239 
   220 bool AnimationInterface::CsmaPacketIsPending (uint64_t AnimUid)
   240 bool AnimationInterface::CsmaPacketIsPending (uint64_t AnimUid)
   221 {
   241 {
   222   return (pendingCsmaPackets.find (AnimUid) != pendingCsmaPackets.end ());
   242   return (m_pendingCsmaPackets.find (AnimUid) != m_pendingCsmaPackets.end ());
   223 }
   243 }
   224 
   244 
   225 
   245 
   226 bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
   246 bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
   227 {
   247 {
   228   return (pendingWimaxPackets.find (AnimUid) != pendingWimaxPackets.end ());
   248   return (m_pendingWimaxPackets.find (AnimUid) != m_pendingWimaxPackets.end ());
   229 }
   249 }
   230 
   250 
   231 bool AnimationInterface::LtePacketIsPending (uint64_t AnimUid)
   251 bool AnimationInterface::LtePacketIsPending (uint64_t AnimUid)
   232 {
   252 {
   233   return (pendingLtePackets.find (AnimUid) != pendingLtePackets.end ());
   253   return (m_pendingLtePackets.find (AnimUid) != m_pendingLtePackets.end ());
   234 }
   254 }
   235 
   255 
   236 void AnimationInterface::SetMobilityPollInterval (Time t)
   256 void AnimationInterface::SetMobilityPollInterval (Time t)
   237 {
   257 {
   238   mobilitypollinterval = t;
   258   m_mobilityPollInterval = t;
   239 }
   259 }
   240 
   260 
   241 void AnimationInterface::SetRandomPosition (bool setRandPos)
   261 void AnimationInterface::SetRandomPosition (bool setRandPos)
   242 {
   262 {
   243   randomPosition = setRandPos;
   263   m_randomPosition = setRandPos;
   244 }
   264 }
   245 
   265 
   246 Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
   266 Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
   247 {
   267 {
   248   Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
   268   Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
   249   if (loc)
   269   if (loc)
   250     {
   270     {
   251       nodeLocation[n->GetId ()] = loc->GetPosition ();
   271       m_nodeLocation[n->GetId ()] = loc->GetPosition ();
   252     }
   272     }
   253   else
   273   else
   254    {
   274    {
   255      NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
   275      NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
   256      Vector deterministicVector (100,100,0);
   276      Vector deterministicVector (100,100,0);
   257      Vector randomVector (UniformVariable (0, topo_maxX-topo_minX).GetValue (), UniformVariable (0, topo_maxY-topo_minY).GetValue (), 0);
   277      Vector randomVector (UniformVariable (0, m_topoMaxX - m_topoMinX).GetValue (), UniformVariable (0, m_topoMaxY - m_topoMinY).GetValue (), 0);
   258      if (randomPosition)
   278      if (m_randomPosition)
   259        {
   279        {
   260          nodeLocation[n->GetId ()] = randomVector;
   280          m_nodeLocation[n->GetId ()] = randomVector;
   261        }
   281        }
   262      else
   282      else
   263        {
   283        {
   264          nodeLocation[n->GetId ()] = deterministicVector;
   284          m_nodeLocation[n->GetId ()] = deterministicVector;
   265        }
   285        }
   266    }
   286    }
   267   return nodeLocation[n->GetId ()];
   287   return m_nodeLocation[n->GetId ()];
   268 }
   288 }
   269 
   289 
   270 Vector AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
   290 Vector AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
   271 {
   291 {
   272   nodeLocation[n->GetId ()] = v;
   292   m_nodeLocation[n->GetId ()] = v;
   273   return v;
   293   return v;
   274 }
   294 }
   275 
   295 
   276 Vector AnimationInterface::GetPosition (Ptr <Node> n)
   296 Vector AnimationInterface::GetPosition (Ptr <Node> n)
   277 {
   297 {
   278   #ifdef NS_LOG
   298   #ifdef NS_LOG
   279   if (nodeLocation.find (n->GetId()) == nodeLocation.end ())
   299   if (m_nodeLocation.find (n->GetId()) == m_nodeLocation.end ())
   280     {
   300     {
   281       NS_FATAL_ERROR ("Node:" <<n->GetId() << " not found in Location table");
   301       NS_FATAL_ERROR ("Node:" <<n->GetId() << " not found in Location table");
   282     }  
   302     }  
   283   #endif
   303   #endif
   284   return nodeLocation[n->GetId ()];
   304   return m_nodeLocation[n->GetId ()];
   285 }
   305 }
   286 
   306 
   287 void AnimationInterface::PurgePendingWifi ()
   307 void AnimationInterface::PurgePendingWifi ()
   288 {
   308 {
   289   if (pendingWifiPackets.empty ())
   309   if (m_pendingWifiPackets.empty ())
   290     return;
   310     return;
   291   std::vector <uint64_t> purgeList;
   311   std::vector <uint64_t> purgeList;
   292   for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWifiPackets.begin ();
   312   for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWifiPackets.begin ();
   293        i != pendingWifiPackets.end ();
   313        i != m_pendingWifiPackets.end ();
   294        ++i)
   314        ++i)
   295     {
   315     {
   296      
   316      
   297       AnimPacketInfo pktInfo = i->second; 
   317       AnimPacketInfo pktInfo = i->second; 
   298       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   318       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   304 
   324 
   305   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   325   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   306        i != purgeList.end ();
   326        i != purgeList.end ();
   307        ++i)
   327        ++i)
   308     {
   328     {
   309       pendingWifiPackets.erase (*i);
   329       m_pendingWifiPackets.erase (*i);
   310     }
   330     }
   311 
   331 
   312 }
   332 }
   313 
   333 
   314 void AnimationInterface::PurgePendingWimax ()
   334 void AnimationInterface::PurgePendingWimax ()
   315 {
   335 {
   316   if (pendingWimaxPackets.empty ())
   336   if (m_pendingWimaxPackets.empty ())
   317     return;
   337     return;
   318   std::vector <uint64_t> purgeList;
   338   std::vector <uint64_t> purgeList;
   319   for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWimaxPackets.begin ();
   339   for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWimaxPackets.begin ();
   320        i != pendingWimaxPackets.end ();
   340        i != m_pendingWimaxPackets.end ();
   321        ++i)
   341        ++i)
   322     {
   342     {
   323 
   343 
   324       AnimPacketInfo pktInfo = i->second;
   344       AnimPacketInfo pktInfo = i->second;
   325       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   345       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   331 
   351 
   332   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   352   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   333        i != purgeList.end ();
   353        i != purgeList.end ();
   334        ++i)
   354        ++i)
   335     {
   355     {
   336       pendingWimaxPackets.erase (*i);
   356       m_pendingWimaxPackets.erase (*i);
   337     }
   357     }
   338 
   358 
   339 }
   359 }
   340 
   360 
   341 
   361 
   342 void AnimationInterface::PurgePendingLte ()
   362 void AnimationInterface::PurgePendingLte ()
   343 {
   363 {
   344   if (pendingLtePackets.empty ())
   364   if (m_pendingLtePackets.empty ())
   345     return;
   365     return;
   346   std::vector <uint64_t> purgeList;
   366   std::vector <uint64_t> purgeList;
   347   for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingLtePackets.begin ();
   367   for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingLtePackets.begin ();
   348        i != pendingLtePackets.end ();
   368        i != m_pendingLtePackets.end ();
   349        ++i)
   369        ++i)
   350     {
   370     {
   351 
   371 
   352       AnimPacketInfo pktInfo = i->second;
   372       AnimPacketInfo pktInfo = i->second;
   353       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   373       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   359 
   379 
   360   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   380   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   361        i != purgeList.end ();
   381        i != purgeList.end ();
   362        ++i)
   382        ++i)
   363     {
   383     {
   364       pendingLtePackets.erase (*i);
   384       m_pendingLtePackets.erase (*i);
   365     }
   385     }
   366 }
   386 }
   367 
   387 
   368 void AnimationInterface::PurgePendingCsma ()
   388 void AnimationInterface::PurgePendingCsma ()
   369 {
   389 {
   370   if (pendingCsmaPackets.empty ())
   390   if (m_pendingCsmaPackets.empty ())
   371     return;
   391     return;
   372   std::vector <uint64_t> purgeList;
   392   std::vector <uint64_t> purgeList;
   373   for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingCsmaPackets.begin ();
   393   for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingCsmaPackets.begin ();
   374        i != pendingCsmaPackets.end ();
   394        i != m_pendingCsmaPackets.end ();
   375        ++i)
   395        ++i)
   376     {
   396     {
   377     
   397     
   378       AnimPacketInfo pktInfo = i->second;
   398       AnimPacketInfo pktInfo = i->second;
   379       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   399       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
   385 
   405 
   386   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   406   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
   387        i != purgeList.end ();
   407        i != purgeList.end ();
   388        ++i)
   408        ++i)
   389     {
   409     {
   390       pendingCsmaPackets.erase (*i);
   410       m_pendingCsmaPackets.erase (*i);
   391     }
   411     }
   392 
   412 
   393 }
   413 }
   394 
   414 
   395 void AnimationInterface::StartAnimation ()
   415 void AnimationInterface::StartAnimation (bool restart)
   396 {
   416 {
       
   417   m_currentPktCount = 0;
   397   m_started = true;
   418   m_started = true;
   398   if (usingSockets)
   419   if (m_usingSockets)
   399     {
   420     {
   400       SetServerPort (mport);
   421       SetServerPort (m_port);
   401     }
   422     }
   402   else
   423   else
   403     {
   424     {
   404       SetOutputFile (outputfilename);
   425       SetOutputFile (m_outputFileName);
   405     }      
   426     }      
   406 
   427 
   407   // Find the min/max x/y for the xml topology element
   428   // Find the min/max x/y for the xml topology element
   408   topo_minX = -2;
   429   m_topoMinX = -2;
   409   topo_minY = -2;
   430   m_topoMinY = -2;
   410   topo_maxX = 2;
   431   m_topoMaxX = 2;
   411   topo_maxY = 2;
   432   m_topoMaxY = 2;
   412   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
   433   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
   413     {
   434     {
   414       Ptr<Node> n = *i;
   435       Ptr<Node> n = *i;
   415       NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
   436       NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
   416       Vector v = UpdatePosition (n); 
   437       Vector v = UpdatePosition (n); 
   417       topo_minX = std::min (topo_minX, v.x);
   438       m_topoMinX = std::min (m_topoMinX, v.x);
   418       topo_minY = std::min (topo_minY, v.y);
   439       m_topoMinY = std::min (m_topoMinY, v.y);
   419       topo_maxX = std::max (topo_maxX, v.x);
   440       m_topoMaxX = std::max (m_topoMaxX, v.x);
   420       topo_maxY = std::max (topo_maxY, v.y);
   441       m_topoMaxY = std::max (m_topoMaxY, v.y);
   421     }
   442     }
   422 
   443 
   423   AddMargin ();
   444   AddMargin ();
   424   if (m_xml)
   445   if (m_xml)
   425     { // output the xml headers
   446     { // output the xml headers
   426       std::ostringstream oss;
   447       std::ostringstream oss;
   427       oss << GetXMLOpen_anim (0);
   448       oss << GetXMLOpen_anim (0);
   428       oss << GetPreamble ();
   449       oss << GetPreamble ();
   429       oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
   450       oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
   430       WriteN (m_fHandle, oss.str ());
   451       WriteN (m_fHandle, oss.str ());
   431     }
   452     }
   432   NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
   453   NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
   433   // Dump the topology
   454   // Dump the topology
   434   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
   455   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
   495             {
   516             {
   496               //NS_FATAL_ERROR ("Net animation currently only supports point-to-point links.");
   517               //NS_FATAL_ERROR ("Net animation currently only supports point-to-point links.");
   497             }
   518             }
   498         }
   519         }
   499     }
   520     }
   500   if (m_xml)
   521   if (m_xml && !restart)
   501     {
   522     {
   502       WriteN (m_fHandle, GetXMLClose ("topology"));
   523       WriteN (m_fHandle, GetXMLClose ("topology"));
   503       Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
   524       Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
   504     }
   525     }
   505 
   526   if (!restart)
   506   ConnectCallbacks ();
   527     ConnectCallbacks ();
   507 }
   528 }
   508 
   529 
   509 void AnimationInterface::ConnectCallbacks ()
   530 void AnimationInterface::ConnectCallbacks ()
   510 {
   531 {
   511   // Connect the callbacks
   532   // Connect the callbacks
   551         }
   572         }
   552       if (m_fHandle != STDOUT_FILENO)
   573       if (m_fHandle != STDOUT_FILENO)
   553         {
   574         {
   554           close (m_fHandle);
   575           close (m_fHandle);
   555         }
   576         }
   556       OutputFileSet = false;
   577       m_outputFileSet = false;
   557       m_fHandle = -1;
   578       m_fHandle = -1;
   558     }
   579     }
   559 }
   580 }
   560 
   581 
   561 int AnimationInterface::WriteN (int h, const std::string& st)
   582 int AnimationInterface::WriteN (int h, const std::string& st)
   573 
   594 
   574 // Private methods
   595 // Private methods
   575 void AnimationInterface::AddMargin ()
   596 void AnimationInterface::AddMargin ()
   576 {
   597 {
   577   // Compute width/height, and add a small margin
   598   // Compute width/height, and add a small margin
   578   double w = topo_maxX - topo_minX;
   599   double w = m_topoMaxX - m_topoMinX;
   579   double h = topo_maxY - topo_minY;
   600   double h = m_topoMaxY - m_topoMinY;
   580   topo_minX -= w * 0.05;
   601   m_topoMinX -= w * 0.05;
   581   topo_minY -= h * 0.05;
   602   m_topoMinY -= h * 0.05;
   582   topo_maxX = topo_minX + w * 1.5;
   603   m_topoMaxX = m_topoMinX + w * 1.5;
   583   topo_maxY = topo_minY + h * 1.5;
   604   m_topoMaxY = m_topoMinY + h * 1.5;
   584   NS_LOG_INFO ("Added Canvas Margin:" << topo_minX << "," <<
   605   NS_LOG_INFO ("Added Canvas Margin:" << m_topoMinX << "," <<
   585                topo_minY << "," << topo_maxX << "," << topo_maxY);                 
   606                m_topoMinY << "," << m_topoMaxX << "," << m_topoMaxY);                 
   586 }
   607 }
   587 
   608 
   588 std::vector <Ptr <Node> >  AnimationInterface::RecalcTopoBounds ()
   609 std::vector <Ptr <Node> >  AnimationInterface::RecalcTopoBounds ()
   589 {
   610 {
   590   std::vector < Ptr <Node> > MovedNodes;
   611   std::vector < Ptr <Node> > MovedNodes;
   616   return MovedNodes;
   637   return MovedNodes;
   617 }
   638 }
   618 
   639 
   619 void AnimationInterface::RecalcTopoBounds (Vector v)
   640 void AnimationInterface::RecalcTopoBounds (Vector v)
   620 {
   641 {
   621   double oldminX = topo_minX;
   642   double oldminX = m_topoMinX;
   622   double oldminY = topo_minY;
   643   double oldminY = m_topoMinY;
   623   double oldmaxX = topo_maxX;
   644   double oldmaxX = m_topoMaxX;
   624   double oldmaxY = topo_maxY;
   645   double oldmaxY = m_topoMaxY;
   625   topo_minX = std::min (topo_minX, v.x);
   646   m_topoMinX = std::min (m_topoMinX, v.x);
   626   topo_minY = std::min (topo_minY, v.y);
   647   m_topoMinY = std::min (m_topoMinY, v.y);
   627   topo_maxX = std::max (topo_maxX, v.x);
   648   m_topoMaxX = std::max (m_topoMaxX, v.x);
   628   topo_maxY = std::max (topo_maxY, v.y);
   649   m_topoMaxY = std::max (m_topoMaxY, v.y);
   629   
   650   
   630   if ((topo_minX != oldminX) || (topo_minY != oldminY) ||
   651   if ((m_topoMinX != oldminX) || (m_topoMinY != oldminY) ||
   631       (topo_maxX != oldmaxX) || (topo_maxY != oldmaxY))
   652       (m_topoMaxX != oldmaxX) || (m_topoMaxY != oldmaxY))
   632     {
   653     {
   633       AddMargin ();
   654       AddMargin ();
   634     } 
   655     } 
   635 }
   656 }
   636 
   657 
   695       oss << GetXMLOpen_packet (0, tx->GetNode ()->GetId (), fbTx, lbTx);
   716       oss << GetXMLOpen_packet (0, tx->GetNode ()->GetId (), fbTx, lbTx);
   696       oss << GetXMLOpenClose_rx (0, rx->GetNode ()->GetId (), fbRx, lbRx); 
   717       oss << GetXMLOpenClose_rx (0, rx->GetNode ()->GetId (), fbRx, lbRx); 
   697       if (m_enablePacketMetadata)
   718       if (m_enablePacketMetadata)
   698         oss << GetXMLOpenClose_meta (GetPacketMetadata (p));
   719         oss << GetXMLOpenClose_meta (GetPacketMetadata (p));
   699       oss << GetXMLClose ("packet");
   720       oss << GetXMLClose ("packet");
       
   721       StartNewTraceFile ();
       
   722       ++m_currentPktCount;
   700     }
   723     }
   701   else
   724   else
   702     {
   725     {
   703       oss << std::setprecision (10);
   726       oss << std::setprecision (10);
   704       oss << now.GetSeconds () << " P "
   727       oss << now.GetSeconds () << " P "
   725   return n->GetDevice (atoi (elements[3].c_str ()));
   748   return n->GetDevice (atoi (elements[3].c_str ()));
   726 }
   749 }
   727                                   
   750                                   
   728 void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   751 void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   729 {
   752 {
   730   pendingWifiPackets[AnimUid] = pktinfo;
   753   m_pendingWifiPackets[AnimUid] = pktinfo;
   731 }
   754 }
   732 
   755 
   733 void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   756 void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   734 {
   757 {
   735   NS_ASSERT (pktinfo.m_txnd);
   758   NS_ASSERT (pktinfo.m_txnd);
   736   pendingWimaxPackets[AnimUid] = pktinfo;
   759   m_pendingWimaxPackets[AnimUid] = pktinfo;
   737 }
   760 }
   738 
   761 
   739 void AnimationInterface::AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   762 void AnimationInterface::AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   740 {
   763 {
   741   NS_ASSERT (pktinfo.m_txnd);
   764   NS_ASSERT (pktinfo.m_txnd);
   742   pendingLtePackets[AnimUid] = pktinfo;
   765   m_pendingLtePackets[AnimUid] = pktinfo;
   743 }
   766 }
   744 
   767 
   745 void AnimationInterface::AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   768 void AnimationInterface::AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
   746 {
   769 {
   747   NS_ASSERT (pktinfo.m_txnd);
   770   NS_ASSERT (pktinfo.m_txnd);
   748   pendingCsmaPackets[AnimUid] = pktinfo;
   771   m_pendingCsmaPackets[AnimUid] = pktinfo;
   749 }
   772 }
   750 
   773 
   751 uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
   774 uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
   752 {
   775 {
   753   AnimByteTag tag;
   776   AnimByteTag tag;
   812   NS_ASSERT (ndev);
   835   NS_ASSERT (ndev);
   813   // Erase pending wifi
   836   // Erase pending wifi
   814   uint64_t AnimUid = GetAnimUidFromPacket (p);
   837   uint64_t AnimUid = GetAnimUidFromPacket (p);
   815   NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
   838   NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
   816   NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   839   NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   817   pendingWifiPackets.erase (pendingWifiPackets.find (AnimUid));
   840   m_pendingWifiPackets.erase (m_pendingWifiPackets.find (AnimUid));
   818 }
   841 }
   819 
   842 
   820 
   843 
   821 void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
   844 void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
   822                                               Ptr<const Packet> p)
   845                                               Ptr<const Packet> p)
   849       AnimPacketInfo pktinfo (0, Simulator::Now (), Simulator::Now (), UpdatePosition (txNode), m_macToNodeIdMap[oss.str ()]);
   872       AnimPacketInfo pktinfo (0, Simulator::Now (), Simulator::Now (), UpdatePosition (txNode), m_macToNodeIdMap[oss.str ()]);
   850       AddPendingWifiPacket (AnimUid, pktinfo);
   873       AddPendingWifiPacket (AnimUid, pktinfo);
   851       NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
   874       NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
   852     }
   875     }
   853   // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   876   // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   854   pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
   877   m_pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
   855   pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
   878   m_pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
   856   OutputWirelessPacket (p, pendingWifiPackets[AnimUid], pendingWifiPackets[AnimUid].GetRxInfo (ndev));
   879   OutputWirelessPacket (p, m_pendingWifiPackets[AnimUid], m_pendingWifiPackets[AnimUid].GetRxInfo (ndev));
   857 }
   880 }
   858 
   881 
   859 
   882 
   860 void AnimationInterface::WifiPhyRxEndTrace (std::string context,
   883 void AnimationInterface::WifiPhyRxEndTrace (std::string context,
   861                                             Ptr<const Packet> p)
   884                                             Ptr<const Packet> p)
   872       NS_LOG_WARN ("WifiPhyRxEndTrace: unknown Uid");
   895       NS_LOG_WARN ("WifiPhyRxEndTrace: unknown Uid");
   873       AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
   896       AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
   874       AddPendingWifiPacket (AnimUid, pktinfo);
   897       AddPendingWifiPacket (AnimUid, pktinfo);
   875     }
   898     }
   876   // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   899   // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   877   AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
   900   AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
   878   pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
   901   pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
   879   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   902   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   880   if (pktrxInfo.IsPhyRxComplete ())
   903   if (pktrxInfo.IsPhyRxComplete ())
   881     {
   904     {
   882       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
   905       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
   898     {
   921     {
   899       NS_LOG_WARN ("WifiMacRxTrace: unknown Uid");
   922       NS_LOG_WARN ("WifiMacRxTrace: unknown Uid");
   900       return;
   923       return;
   901     }
   924     }
   902   // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   925   // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
   903   AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
   926   AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
   904   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   927   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   905   if (pktrxInfo.IsPhyRxComplete ())
   928   if (pktrxInfo.IsPhyRxComplete ())
   906     {
   929     {
   907       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
   930       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
   908       OutputWirelessPacket (p, pktInfo, pktrxInfo);
   931       OutputWirelessPacket (p, pktInfo, pktrxInfo);
   942   Ptr <Node> n = ndev->GetNode ();
   965   Ptr <Node> n = ndev->GetNode ();
   943   NS_ASSERT (n);
   966   NS_ASSERT (n);
   944   uint64_t AnimUid = GetAnimUidFromPacket (p);
   967   uint64_t AnimUid = GetAnimUidFromPacket (p);
   945   NS_LOG_INFO ("WimaxRxTrace for packet:" << AnimUid);
   968   NS_LOG_INFO ("WimaxRxTrace for packet:" << AnimUid);
   946   NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
   969   NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
   947   AnimPacketInfo& pktInfo = pendingWimaxPackets[AnimUid];
   970   AnimPacketInfo& pktInfo = m_pendingWimaxPackets[AnimUid];
   948   pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
   971   pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
   949   pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
   972   pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
   950   //TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
   973   //TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
   951   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   974   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   952   OutputWirelessPacket (p, pktInfo, pktrxInfo);
   975   OutputWirelessPacket (p, pktInfo, pktrxInfo);
   984   if (!LtePacketIsPending (AnimUid))
  1007   if (!LtePacketIsPending (AnimUid))
   985     {
  1008     {
   986       NS_LOG_WARN ("LteRxTrace: unknown Uid");
  1009       NS_LOG_WARN ("LteRxTrace: unknown Uid");
   987       return;
  1010       return;
   988     }
  1011     }
   989   AnimPacketInfo& pktInfo = pendingLtePackets[AnimUid];
  1012   AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
   990   pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
  1013   pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
   991   pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
  1014   pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
   992   //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
  1015   //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
   993   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
  1016   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
   994   OutputWirelessPacket (p, pktInfo, pktrxInfo);
  1017   OutputWirelessPacket (p, pktInfo, pktrxInfo);
  1029       AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
  1052       AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
  1030       AddPendingCsmaPacket (AnimUid, pktinfo);
  1053       AddPendingCsmaPacket (AnimUid, pktinfo);
  1031       NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
  1054       NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
  1032     }
  1055     }
  1033   // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
  1056   // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
  1034   AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
  1057   AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
  1035   pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
  1058   pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
  1036 }
  1059 }
  1037 
  1060 
  1038 void AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
  1061 void AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
  1039 {
  1062 {
  1048     {
  1071     {
  1049       NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid"); 
  1072       NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid"); 
  1050       return;
  1073       return;
  1051     }
  1074     }
  1052   // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
  1075   // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
  1053   AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
  1076   AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
  1054   pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
  1077   m_pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
  1055   pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
  1078   pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
  1056   NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << AnimUid);
  1079   NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << AnimUid);
  1057 }
  1080 }
  1058 
  1081 
  1059 
  1082 
  1072     {
  1095     {
  1073       NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid"); 
  1096       NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid"); 
  1074       return;
  1097       return;
  1075     }
  1098     }
  1076   // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
  1099   // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
  1077   AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
  1100   AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
  1078   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
  1101   AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
  1079   if (pktrxInfo.IsPhyRxComplete ())
  1102   if (pktrxInfo.IsPhyRxComplete ())
  1080     {
  1103     {
  1081       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
  1104       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
  1082       OutputCsmaPacket (p, pktInfo, pktrxInfo);
  1105       OutputCsmaPacket (p, pktInfo, pktrxInfo);
  1101       v = mobility->GetPosition ();
  1124       v = mobility->GetPosition ();
  1102     }
  1125     }
  1103   UpdatePosition (n,v);
  1126   UpdatePosition (n,v);
  1104   RecalcTopoBounds (v);
  1127   RecalcTopoBounds (v);
  1105   std::ostringstream oss; 
  1128   std::ostringstream oss; 
  1106   oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
  1129   oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
  1107   oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y);
  1130   oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y);
  1108   oss << GetXMLClose ("topology");
  1131   oss << GetXMLClose ("topology");
  1109   WriteN (m_fHandle, oss.str ());
  1132   WriteN (m_fHandle, oss.str ());
  1110   WriteDummyPacket ();
  1133   WriteDummyPacket ();
  1111 }
  1134 }
  1129 {
  1152 {
  1130   if (!m_started || !IsInTimeWindow ())
  1153   if (!m_started || !IsInTimeWindow ())
  1131     return;
  1154     return;
  1132   std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
  1155   std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
  1133   std::ostringstream oss;
  1156   std::ostringstream oss;
  1134   oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
  1157   oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
  1135   for (uint32_t i = 0; i < MovedNodes.size (); i++)
  1158   for (uint32_t i = 0; i < MovedNodes.size (); i++)
  1136     {
  1159     {
  1137       Ptr <Node> n = MovedNodes [i];
  1160       Ptr <Node> n = MovedNodes [i];
  1138       NS_ASSERT (n);
  1161       NS_ASSERT (n);
  1139       Vector v = GetPosition (n);
  1162       Vector v = GetPosition (n);
  1146     {
  1169     {
  1147       PurgePendingWifi ();
  1170       PurgePendingWifi ();
  1148       PurgePendingWimax ();
  1171       PurgePendingWimax ();
  1149       PurgePendingLte ();
  1172       PurgePendingLte ();
  1150       PurgePendingCsma ();
  1173       PurgePendingCsma ();
  1151       Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
  1174       Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
  1152     }
  1175     }
  1153 }
  1176 }
  1154 
  1177 
  1155 std::string AnimationInterface::GetPacketMetadata (Ptr<const Packet> p)
  1178 std::string AnimationInterface::GetPacketMetadata (Ptr<const Packet> p)
  1156 {
  1179 {
  1157   std::ostringstream oss;
  1180   std::ostringstream oss;
  1158   p->Print (oss);
  1181   p->Print (oss);
  1159   return oss.str ();
  1182   return oss.str ();
  1160 }
  1183 }
       
  1184 
       
  1185 uint64_t AnimationInterface::GetTracePktCount ()
       
  1186 {
       
  1187   return m_currentPktCount;
       
  1188 }
       
  1189 
  1161 
  1190 
  1162 // Helper to output a wireless packet.
  1191 // Helper to output a wireless packet.
  1163 // For now, only the XML interface is supported
  1192 // For now, only the XML interface is supported
  1164 
  1193 
  1165 
  1194 
  1202 return s;
  1231 return s;
  1203 }
  1232 }
  1204 
  1233 
  1205 void AnimationInterface::OutputWirelessPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
  1234 void AnimationInterface::OutputWirelessPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
  1206 {
  1235 {
       
  1236   StartNewTraceFile ();
  1207   NS_ASSERT (m_xml);
  1237   NS_ASSERT (m_xml);
  1208   std::ostringstream oss;
  1238   std::ostringstream oss;
  1209   uint32_t nodeId =  0;
  1239   uint32_t nodeId =  0;
  1210   if (pktInfo.m_txnd)
  1240   if (pktInfo.m_txnd)
  1211     nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
  1241     nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
  1224   WriteN (m_fHandle, oss.str ());
  1254   WriteN (m_fHandle, oss.str ());
  1225 }
  1255 }
  1226 
  1256 
  1227 void AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
  1257 void AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
  1228 {
  1258 {
       
  1259   StartNewTraceFile ();
  1229   NS_ASSERT (m_xml);
  1260   NS_ASSERT (m_xml);
  1230   std::ostringstream oss;
  1261   std::ostringstream oss;
  1231   NS_ASSERT (pktInfo.m_txnd);
  1262   NS_ASSERT (pktInfo.m_txnd);
  1232   uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
  1263   uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
  1233 
  1264