1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  *
16  * Author: George F. Riley<riley@ece.gatech.edu>
17  * Modified by: John Abraham <john.abraham@gatech.edu>
18  * Contributions: Eugene Kalishenko <ydginster@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
19  *                Tommaso Pecorella <tommaso.pecorella@unifi.it>
20  *                Pavel Vasilyev <pavel.vasilyev@sredasolutions.com>
21  */
22 
23 // Interface between ns-3 and the network animator
24 
25 
26 
27 #include <cstdio>
28 #ifndef WIN32
29 #include <unistd.h>
30 #endif
31 #include <sstream>
32 #include <fstream>
33 #include <string>
34 #include <iomanip>
35 #include <map>
36 
37 // ns3 includes
38 #include "ns3/animation-interface.h"
39 #include "ns3/channel.h"
40 #include "ns3/config.h"
41 #include "ns3/node.h"
42 #include "ns3/mobility-model.h"
43 #include "ns3/packet.h"
44 #include "ns3/simulator.h"
45 #include "ns3/wifi-mac-header.h"
46 #include "ns3/wimax-mac-header.h"
47 #include "ns3/wifi-net-device.h"
48 #include "ns3/wifi-mac.h"
49 #include "ns3/wifi-psdu.h"
50 #include "ns3/lr-wpan-mac-header.h"
51 #include "ns3/lr-wpan-net-device.h"
52 #include "ns3/constant-position-mobility-model.h"
53 #include "ns3/lte-ue-phy.h"
54 #include "ns3/lte-enb-phy.h"
55 #include "ns3/uan-net-device.h"
56 #include "ns3/uan-mac.h"
57 #include "ns3/double.h"
58 #include "ns3/ipv4.h"
59 #include "ns3/ipv6.h"
60 #include "ns3/ipv4-routing-protocol.h"
61 #include "ns3/energy-source-container.h"
62 #include "animation-interface.h"
63 
64 namespace ns3 {
65 
66 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
67 
68 // Globals
69 
70 static bool initialized = false; //!< Initialization flag
71 
72 
73 // Public methods
74 
AnimationInterface(const std::string fn)75 AnimationInterface::AnimationInterface (const std::string fn)
76   : m_f (0),
77     m_routingF (0),
78     m_mobilityPollInterval (Seconds (0.25)),
79     m_outputFileName (fn),
80     gAnimUid (0),
81     m_writeCallback (0),
82     m_started (false),
83     m_enablePacketMetadata (false),
84     m_startTime (Seconds (0)),
85     m_stopTime (Seconds (3600 * 1000)),
86     m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE),
87     m_originalFileName (fn),
88     m_routingStopTime (Seconds (0)),
89     m_routingFileName (""),
90     m_routingPollInterval (Seconds (5)),
91     m_trackPackets (true)
92 {
93   initialized = true;
94   StartAnimation ();
95 }
96 
~AnimationInterface()97 AnimationInterface::~AnimationInterface ()
98 {
99   StopAnimation ();
100 }
101 
102 void
SkipPacketTracing()103 AnimationInterface::SkipPacketTracing ()
104 {
105   m_trackPackets = false;
106 }
107 
108 void
EnableWifiPhyCounters(Time startTime,Time stopTime,Time pollInterval)109 AnimationInterface::EnableWifiPhyCounters (Time startTime, Time stopTime, Time pollInterval)
110 {
111   m_wifiPhyCountersStopTime = stopTime;
112   m_wifiPhyCountersPollInterval = pollInterval;
113   m_wifiPhyTxDropCounterId = AddNodeCounter ("WifiPhy TxDrop", AnimationInterface::DOUBLE_COUNTER);
114   m_wifiPhyRxDropCounterId = AddNodeCounter ("WifiPhy RxDrop", AnimationInterface::DOUBLE_COUNTER);
115   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
116     {
117       Ptr<Node> n = *i;
118       m_nodeWifiPhyTxDrop[n->GetId ()] = 0;
119       m_nodeWifiPhyRxDrop[n->GetId ()] = 0;
120       UpdateNodeCounter (m_wifiPhyTxDropCounterId, n->GetId (), 0);
121       UpdateNodeCounter (m_wifiPhyRxDropCounterId, n->GetId (), 0);
122     }
123   Simulator::Schedule (startTime, &AnimationInterface::TrackWifiPhyCounters, this);
124 
125 }
126 
127 void
EnableWifiMacCounters(Time startTime,Time stopTime,Time pollInterval)128 AnimationInterface::EnableWifiMacCounters (Time startTime, Time stopTime, Time pollInterval)
129 {
130   m_wifiMacCountersStopTime = stopTime;
131   m_wifiMacCountersPollInterval = pollInterval;
132   m_wifiMacTxCounterId = AddNodeCounter ("WifiMac Tx", AnimationInterface::DOUBLE_COUNTER);
133   m_wifiMacTxDropCounterId = AddNodeCounter ("WifiMac TxDrop", AnimationInterface::DOUBLE_COUNTER);
134   m_wifiMacRxCounterId = AddNodeCounter ("WifiMac Rx", AnimationInterface::DOUBLE_COUNTER);
135   m_wifiMacRxDropCounterId = AddNodeCounter ("WifiMac RxDrop", AnimationInterface::DOUBLE_COUNTER);
136   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
137     {
138       Ptr<Node> n = *i;
139       m_nodeWifiMacTx[n->GetId ()] = 0;
140       m_nodeWifiMacTxDrop[n->GetId ()] = 0;
141       m_nodeWifiMacRx[n->GetId ()] = 0;
142       m_nodeWifiMacRxDrop[n->GetId ()] = 0;
143       UpdateNodeCounter (m_wifiMacTxCounterId, n->GetId (), 0);
144       UpdateNodeCounter (m_wifiMacTxDropCounterId, n->GetId (), 0);
145       UpdateNodeCounter (m_wifiMacRxCounterId, n->GetId (), 0);
146       UpdateNodeCounter (m_wifiMacRxDropCounterId, n->GetId (), 0);
147     }
148   Simulator::Schedule (startTime, &AnimationInterface::TrackWifiMacCounters, this);
149 }
150 
151 void
EnableQueueCounters(Time startTime,Time stopTime,Time pollInterval)152 AnimationInterface::EnableQueueCounters (Time startTime, Time stopTime, Time pollInterval)
153 {
154   m_queueCountersStopTime = stopTime;
155   m_queueCountersPollInterval = pollInterval;
156   m_queueEnqueueCounterId = AddNodeCounter ("Enqueue", AnimationInterface::DOUBLE_COUNTER);
157   m_queueDequeueCounterId = AddNodeCounter ("Dequeue", AnimationInterface::DOUBLE_COUNTER);
158   m_queueDropCounterId = AddNodeCounter ("Queue Drop", AnimationInterface::DOUBLE_COUNTER);
159   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
160     {
161       Ptr<Node> n = *i;
162       m_nodeQueueEnqueue[n->GetId ()] = 0;
163       m_nodeQueueDequeue[n->GetId ()] = 0;
164       m_nodeQueueDrop[n->GetId ()] = 0;
165       UpdateNodeCounter (m_queueEnqueueCounterId, n->GetId (), 0);
166       UpdateNodeCounter (m_queueDequeueCounterId, n->GetId (), 0);
167       UpdateNodeCounter (m_queueDropCounterId, n->GetId (), 0);
168     }
169   Simulator::Schedule (startTime, &AnimationInterface::TrackQueueCounters, this);
170 }
171 
172 void
EnableIpv4L3ProtocolCounters(Time startTime,Time stopTime,Time pollInterval)173 AnimationInterface::EnableIpv4L3ProtocolCounters (Time startTime, Time stopTime, Time pollInterval)
174 {
175   m_ipv4L3ProtocolCountersStopTime = stopTime;
176   m_ipv4L3ProtocolCountersPollInterval = pollInterval;
177   m_ipv4L3ProtocolTxCounterId = AddNodeCounter ("Ipv4 Tx", AnimationInterface::DOUBLE_COUNTER);
178   m_ipv4L3ProtocolRxCounterId = AddNodeCounter ("Ipv4 Rx", AnimationInterface::DOUBLE_COUNTER);
179   m_ipv4L3ProtocolDropCounterId = AddNodeCounter ("Ipv4 Drop", AnimationInterface::DOUBLE_COUNTER);
180   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
181     {
182       Ptr<Node> n = *i;
183       m_nodeIpv4Tx[n->GetId ()] = 0;
184       m_nodeIpv4Rx[n->GetId ()] = 0;
185       m_nodeIpv4Drop[n->GetId ()] = 0;
186       UpdateNodeCounter (m_ipv4L3ProtocolTxCounterId, n->GetId (), 0);
187       UpdateNodeCounter (m_ipv4L3ProtocolRxCounterId, n->GetId (), 0);
188       UpdateNodeCounter (m_ipv4L3ProtocolDropCounterId, n->GetId (), 0);
189     }
190   Simulator::Schedule (startTime, &AnimationInterface::TrackIpv4L3ProtocolCounters, this);
191 }
192 
193 AnimationInterface &
EnableIpv4RouteTracking(std::string fileName,Time startTime,Time stopTime,Time pollInterval)194 AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, Time pollInterval)
195 {
196   SetOutputFile (fileName, true);
197   m_routingStopTime = stopTime;
198   m_routingPollInterval = pollInterval;
199   WriteXmlAnim (true);
200   Simulator::Schedule (startTime, &AnimationInterface::TrackIpv4Route, this);
201   return *this;
202 }
203 
204 AnimationInterface &
EnableIpv4RouteTracking(std::string fileName,Time startTime,Time stopTime,NodeContainer nc,Time pollInterval)205 AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, NodeContainer nc, Time pollInterval)
206 {
207   m_routingNc = nc;
208   return EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
209 }
210 
211 AnimationInterface &
AddSourceDestination(uint32_t fromNodeId,std::string ipv4Address)212 AnimationInterface::AddSourceDestination (uint32_t fromNodeId, std::string ipv4Address)
213 {
214   Ipv4RouteTrackElement element = { ipv4Address, fromNodeId };
215   m_ipv4RouteTrackElements.push_back (element);
216   return *this;
217 }
218 
219 void
SetStartTime(Time t)220 AnimationInterface::SetStartTime (Time t)
221 {
222   m_startTime = t;
223 }
224 
225 void
SetStopTime(Time t)226 AnimationInterface::SetStopTime (Time t)
227 {
228   m_stopTime = t;
229 }
230 
231 void
SetMaxPktsPerTraceFile(uint64_t maxPacketsPerFile)232 AnimationInterface::SetMaxPktsPerTraceFile (uint64_t maxPacketsPerFile)
233 {
234   m_maxPktsPerFile = maxPacketsPerFile;
235 }
236 
237 uint32_t
AddNodeCounter(std::string counterName,CounterType counterType)238 AnimationInterface::AddNodeCounter (std::string counterName, CounterType counterType)
239 {
240   m_nodeCounters.push_back (counterName);
241   uint32_t counterId = m_nodeCounters.size () - 1; // counter ID is zero-indexed
242   WriteXmlAddNodeCounter (counterId, counterName, counterType);
243   return counterId;
244 }
245 
246 uint32_t
AddResource(std::string resourcePath)247 AnimationInterface::AddResource (std::string resourcePath)
248 {
249   m_resources.push_back (resourcePath);
250   uint32_t resourceId = m_resources.size () -  1; // resource ID is zero-indexed
251   WriteXmlAddResource (resourceId, resourcePath);
252   return resourceId;
253 }
254 
255 void
EnablePacketMetadata(bool enable)256 AnimationInterface::EnablePacketMetadata (bool enable)
257 {
258   m_enablePacketMetadata = enable;
259   if (enable)
260     {
261       Packet::EnablePrinting ();
262     }
263 }
264 
265 bool
IsInitialized()266 AnimationInterface::IsInitialized ()
267 {
268   return initialized;
269 }
270 
271 bool
IsStarted()272 AnimationInterface::IsStarted ()
273 {
274   return m_started;
275 }
276 
277 void
SetAnimWriteCallback(AnimWriteCallback cb)278 AnimationInterface::SetAnimWriteCallback (AnimWriteCallback cb)
279 {
280   m_writeCallback = cb;
281 }
282 
283 void
ResetAnimWriteCallback()284 AnimationInterface::ResetAnimWriteCallback ()
285 {
286   m_writeCallback = 0;
287 }
288 
289 void
SetMobilityPollInterval(Time t)290 AnimationInterface::SetMobilityPollInterval (Time t)
291 {
292   m_mobilityPollInterval = t;
293 }
294 
295 
296 void
SetConstantPosition(Ptr<Node> n,double x,double y,double z)297 AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
298 {
299   NS_ASSERT (n);
300   Ptr<ConstantPositionMobilityModel> loc =  n->GetObject<ConstantPositionMobilityModel> ();
301   if (loc == 0)
302     {
303       loc = CreateObject<ConstantPositionMobilityModel> ();
304       n->AggregateObject (loc);
305     }
306   Vector hubVec (x, y, z);
307   loc->SetPosition (hubVec);
308   NS_LOG_INFO ("Node:" << n->GetId () << " Position set to:(" << x << "," << y << "," << z << ")");
309 
310 }
311 
312 void
UpdateNodeImage(uint32_t nodeId,uint32_t resourceId)313 AnimationInterface::UpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
314 {
315   NS_LOG_INFO ("Setting node image for Node Id:" << nodeId);
316   if (resourceId > (m_resources.size () - 1))
317     {
318       NS_FATAL_ERROR ("Resource Id:" << resourceId << " not found. Did you use AddResource?");
319     }
320   WriteXmlUpdateNodeImage (nodeId, resourceId);
321 }
322 
323 void
UpdateNodeCounter(uint32_t nodeCounterId,uint32_t nodeId,double counter)324 AnimationInterface::UpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counter)
325 {
326   if (nodeCounterId > (m_nodeCounters.size () - 1))
327     {
328       NS_FATAL_ERROR ("NodeCounter Id:" << nodeCounterId << " not found. Did you use AddNodeCounter?");
329     }
330   WriteXmlUpdateNodeCounter (nodeCounterId, nodeId, counter);
331 }
332 
333 void
SetBackgroundImage(std::string fileName,double x,double y,double scaleX,double scaleY,double opacity)334 AnimationInterface::SetBackgroundImage (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
335 {
336   if ((opacity < 0) || (opacity > 1))
337     {
338       NS_FATAL_ERROR ("Opacity must be between 0.0 and 1.0");
339     }
340   WriteXmlUpdateBackground (fileName, x, y, scaleX, scaleY, opacity);
341 }
342 
343 void
UpdateNodeSize(uint32_t nodeId,double width,double height)344 AnimationInterface::UpdateNodeSize (uint32_t nodeId, double width, double height)
345 {
346   AnimationInterface::NodeSize s = { width, height };
347   m_nodeSizes[nodeId] = s;
348   WriteXmlUpdateNodeSize (nodeId, s.width, s.height);
349 }
350 
351 void
UpdateNodeColor(Ptr<Node> n,uint8_t r,uint8_t g,uint8_t b)352 AnimationInterface::UpdateNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
353 {
354   UpdateNodeColor (n->GetId (), r, g, b);
355 }
356 
357 void
UpdateNodeColor(uint32_t nodeId,uint8_t r,uint8_t g,uint8_t b)358 AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
359 {
360   NS_ASSERT (NodeList::GetNode (nodeId));
361   NS_LOG_INFO ("Setting node color for Node Id:" << nodeId);
362   Rgb rgb = {r, g, b};
363   m_nodeColors[nodeId] = rgb;
364   WriteXmlUpdateNodeColor (nodeId, r, g, b);
365 }
366 
367 void
UpdateLinkDescription(uint32_t fromNode,uint32_t toNode,std::string linkDescription)368 AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNode,
369                                            std::string linkDescription)
370 {
371   WriteXmlUpdateLink (fromNode, toNode, linkDescription);
372 }
373 
374 void
UpdateLinkDescription(Ptr<Node> fromNode,Ptr<Node> toNode,std::string linkDescription)375 AnimationInterface::UpdateLinkDescription (Ptr <Node> fromNode, Ptr <Node> toNode,
376                                            std::string linkDescription)
377 {
378   NS_ASSERT (fromNode);
379   NS_ASSERT (toNode);
380   WriteXmlUpdateLink (fromNode->GetId (), toNode->GetId (), linkDescription);
381 }
382 
383 void
UpdateNodeDescription(Ptr<Node> n,std::string descr)384 AnimationInterface::UpdateNodeDescription (Ptr <Node> n, std::string descr)
385 {
386   UpdateNodeDescription (n->GetId (), descr);
387 }
388 
389 void
UpdateNodeDescription(uint32_t nodeId,std::string descr)390 AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string descr)
391 {
392   NS_ASSERT (NodeList::GetNode (nodeId));
393   m_nodeDescriptions[nodeId] = descr;
394   WriteXmlUpdateNodeDescription (nodeId);
395 }
396 
397 // Private methods
398 
399 
400 double
GetNodeEnergyFraction(Ptr<const Node> node) const401 AnimationInterface::GetNodeEnergyFraction (Ptr <const Node> node) const
402 {
403   const EnergyFractionMap::const_iterator fractionIter = m_nodeEnergyFraction.find (node->GetId ());
404   NS_ASSERT (fractionIter != m_nodeEnergyFraction.end ());
405   return fractionIter->second;
406 }
407 
408 void
MobilityCourseChangeTrace(Ptr<const MobilityModel> mobility)409 AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
410 {
411   CHECK_STARTED_INTIMEWINDOW;
412   Ptr <Node> n = mobility->GetObject <Node> ();
413   NS_ASSERT (n);
414   Vector v;
415   if (!mobility)
416     {
417       v = GetPosition (n);
418     }
419   else
420     {
421       v = mobility->GetPosition ();
422     }
423   UpdatePosition (n, v);
424   WriteXmlUpdateNodePosition (n->GetId (), v.x, v.y);
425 }
426 
427 bool
NodeHasMoved(Ptr<Node> n,Vector newLocation)428 AnimationInterface::NodeHasMoved (Ptr <Node> n, Vector newLocation)
429 {
430   Vector oldLocation = GetPosition (n);
431   bool moved = true;
432   if ((ceil (oldLocation.x) == ceil (newLocation.x))
433       && (ceil (oldLocation.y) == ceil (newLocation.y)))
434     {
435       moved = false;
436     }
437   else
438     {
439       moved = true;
440     }
441   return moved;
442 }
443 
444 void
MobilityAutoCheck()445 AnimationInterface::MobilityAutoCheck ()
446 {
447   CHECK_STARTED_INTIMEWINDOW;
448   std::vector <Ptr <Node> > MovedNodes = GetMovedNodes ();
449   for (uint32_t i = 0; i < MovedNodes.size (); i++)
450     {
451       Ptr <Node> n = MovedNodes [i];
452       NS_ASSERT (n);
453       Vector v = GetPosition (n);
454       WriteXmlUpdateNodePosition (n->GetId (), v.x, v.y);
455     }
456   if (!Simulator::IsFinished ())
457     {
458       PurgePendingPackets (AnimationInterface::WIFI);
459       PurgePendingPackets (AnimationInterface::WIMAX);
460       PurgePendingPackets (AnimationInterface::LTE);
461       PurgePendingPackets (AnimationInterface::CSMA);
462       PurgePendingPackets (AnimationInterface::LRWPAN);
463       PurgePendingPackets (AnimationInterface::WAVE);
464       Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
465     }
466 }
467 
468 std::vector <Ptr <Node> >
GetMovedNodes()469 AnimationInterface::GetMovedNodes ()
470 {
471   std::vector < Ptr <Node> > movedNodes;
472   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
473     {
474       Ptr<Node> n = *i;
475       NS_ASSERT (n);
476       Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
477       Vector newLocation;
478       if (!mobility)
479         {
480           newLocation = GetPosition (n);
481         }
482       else
483         {
484           newLocation = mobility->GetPosition ();
485         }
486       if (!NodeHasMoved (n, newLocation))
487         {
488           continue; //Location has not changed
489         }
490       else
491         {
492           UpdatePosition (n, newLocation);
493           movedNodes.push_back (n);
494         }
495     }
496   return movedNodes;
497 }
498 
499 int
WriteN(const std::string & st,FILE * f)500 AnimationInterface::WriteN (const std::string& st, FILE * f)
501 {
502   if (!f)
503     {
504       return 0;
505     }
506   if (m_writeCallback)
507     {
508       m_writeCallback (st.c_str ());
509     }
510   return WriteN (st.c_str (), st.length (), f);
511 }
512 
513 int
WriteN(const char * data,uint32_t count,FILE * f)514 AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
515 {
516   if (!f)
517     {
518       return 0;
519     }
520   // Write count bytes to h from data
521   uint32_t    nLeft   = count;
522   const char* p       = data;
523   uint32_t    written = 0;
524   while (nLeft)
525     {
526       int n = std::fwrite (p, 1,  nLeft, f);
527       if (n <= 0)
528         {
529           return written;
530         }
531       written += n;
532       nLeft -= n;
533       p += n;
534     }
535   return written;
536 }
537 
538 void
WriteRoutePath(uint32_t nodeId,std::string destination,Ipv4RoutePathElements rpElements)539 AnimationInterface::WriteRoutePath (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
540 {
541   NS_LOG_INFO ("Writing Route Path From :" << nodeId << " To: " << destination.c_str ());
542   WriteXmlRp (nodeId, destination, rpElements);
543   /*for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
544        i != rpElements.end ();
545        ++i)
546     {
547       Ipv4RoutePathElement rpElement = *i;
548       NS_LOG_INFO ("Node:" << rpElement.nodeId << "-->" << rpElement.nextHop.c_str ());
549       WriteN (GetXmlRp (rpElement.node, GetIpv4RoutingTable (n)), m_routingF);
550 
551     }
552   */
553 }
554 
555 void
WriteNonP2pLinkProperties(uint32_t id,std::string ipv4Address,std::string channelType)556 AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
557 {
558   WriteXmlNonP2pLinkProperties (id, ipv4Address, channelType);
559 }
560 
561 const std::vector<std::string>
GetElementsFromContext(const std::string & context) const562 AnimationInterface::GetElementsFromContext (const std::string& context) const
563 {
564   std::vector <std::string> elements;
565   std::size_t pos1 = 0, pos2;
566   while (pos1 != context.npos)
567     {
568       pos1 = context.find ("/",pos1);
569       pos2 = context.find ("/",pos1 + 1);
570       elements.push_back (context.substr (pos1 + 1,pos2 - (pos1 + 1)));
571       pos1 = pos2;
572       pos2 = context.npos;
573     }
574   return elements;
575 }
576 
577 Ptr <Node>
GetNodeFromContext(const std::string & context) const578 AnimationInterface::GetNodeFromContext (const std::string& context) const
579 {
580   // Use "NodeList/*/ as reference
581   // where element [1] is the Node Id
582 
583   std::vector <std::string> elements = GetElementsFromContext (context);
584   Ptr <Node> n = NodeList::GetNode (atoi (elements.at (1).c_str ()));
585   NS_ASSERT (n);
586 
587   return n;
588 }
589 
590 Ptr <NetDevice>
GetNetDeviceFromContext(std::string context)591 AnimationInterface::GetNetDeviceFromContext (std::string context)
592 {
593   // Use "NodeList/*/DeviceList/*/ as reference
594   // where element [1] is the Node Id
595   // element [2] is the NetDevice Id
596 
597   std::vector <std::string> elements = GetElementsFromContext (context);
598   Ptr <Node> n = GetNodeFromContext (context);
599 
600   return n->GetDevice (atoi (elements.at (3).c_str ()));
601 }
602 
603 uint64_t
GetAnimUidFromPacket(Ptr<const Packet> p)604 AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
605 {
606   AnimByteTag tag;
607   TypeId tid = tag.GetInstanceTypeId ();
608   ByteTagIterator i = p->GetByteTagIterator ();
609   bool found = false;
610   while (i.HasNext ())
611     {
612       ByteTagIterator::Item item = i.Next ();
613       if (tid == item.GetTypeId ())
614         {
615           item.GetTag (tag);
616           found = true;
617         }
618     }
619   if (found)
620     {
621       return tag.Get ();
622     }
623   else
624     {
625       return 0;
626     }
627 }
628 
629 void
AddByteTag(uint64_t animUid,Ptr<const Packet> p)630 AnimationInterface::AddByteTag (uint64_t animUid, Ptr<const Packet> p)
631 {
632   AnimByteTag tag;
633   tag.Set (animUid);
634   p->AddByteTag (tag);
635 }
636 
637 void
RemainingEnergyTrace(std::string context,double previousEnergy,double currentEnergy)638 AnimationInterface::RemainingEnergyTrace (std::string context, double previousEnergy, double currentEnergy)
639 {
640   CHECK_STARTED_INTIMEWINDOW;
641   const Ptr <const Node> node = GetNodeFromContext (context);
642   const uint32_t nodeId = node->GetId ();
643 
644   NS_LOG_INFO ("Remaining energy on one of sources on node " << nodeId << ": " << currentEnergy);
645 
646   const Ptr<EnergySource> energySource = node->GetObject<EnergySource> ();
647 
648   NS_ASSERT (energySource);
649   // Don't call GetEnergyFraction () because of recursion
650   const double energyFraction = currentEnergy / energySource->GetInitialEnergy ();
651 
652   NS_LOG_INFO ("Total energy fraction on node " << nodeId << ": " << energyFraction);
653 
654   m_nodeEnergyFraction[nodeId] = energyFraction;
655   UpdateNodeCounter (m_remainingEnergyCounterId, nodeId, energyFraction);
656 }
657 
658 void
WifiPhyTxDropTrace(std::string context,Ptr<const Packet> p)659 AnimationInterface::WifiPhyTxDropTrace (std::string context, Ptr<const Packet> p)
660 {
661   const Ptr <const Node> node = GetNodeFromContext (context);
662   ++m_nodeWifiPhyTxDrop[node->GetId ()];
663 }
664 
665 void
WifiPhyRxDropTrace(std::string context,Ptr<const Packet> p,WifiPhyRxfailureReason reason)666 AnimationInterface::WifiPhyRxDropTrace (std::string context, Ptr<const Packet> p, WifiPhyRxfailureReason reason)
667 {
668   const Ptr <const Node> node = GetNodeFromContext (context);
669   ++m_nodeWifiPhyRxDrop[node->GetId ()];
670 }
671 
672 void
WifiMacTxTrace(std::string context,Ptr<const Packet> p)673 AnimationInterface::WifiMacTxTrace (std::string context, Ptr<const Packet> p)
674 {
675   const Ptr <const Node> node = GetNodeFromContext (context);
676   ++m_nodeWifiMacTx[node->GetId ()];
677 }
678 
679 void
WifiMacTxDropTrace(std::string context,Ptr<const Packet> p)680 AnimationInterface::WifiMacTxDropTrace (std::string context, Ptr<const Packet> p)
681 {
682   const Ptr <const Node> node = GetNodeFromContext (context);
683   ++m_nodeWifiMacTxDrop[node->GetId ()];
684 }
685 
686 void
WifiMacRxTrace(std::string context,Ptr<const Packet> p)687 AnimationInterface::WifiMacRxTrace (std::string context, Ptr<const Packet> p)
688 {
689   const Ptr <const Node> node = GetNodeFromContext (context);
690   ++m_nodeWifiMacRx[node->GetId ()];
691 }
692 
693 void
WifiMacRxDropTrace(std::string context,Ptr<const Packet> p)694 AnimationInterface::WifiMacRxDropTrace (std::string context, Ptr<const Packet> p)
695 {
696   const Ptr <const Node> node = GetNodeFromContext (context);
697   ++m_nodeWifiMacRxDrop[node->GetId ()];
698 }
699 
700 void
LrWpanMacTxTrace(std::string context,Ptr<const Packet> p)701 AnimationInterface::LrWpanMacTxTrace (std::string context, Ptr<const Packet> p)
702 {
703   const Ptr <const Node> node = GetNodeFromContext (context);
704   ++m_nodeLrWpanMacTx[node->GetId ()];
705 }
706 
707 void
LrWpanMacTxDropTrace(std::string context,Ptr<const Packet> p)708 AnimationInterface::LrWpanMacTxDropTrace (std::string context, Ptr<const Packet> p)
709 {
710   const Ptr <const Node> node = GetNodeFromContext (context);
711   ++m_nodeLrWpanMacTxDrop[node->GetId ()];
712 }
713 
714 void
LrWpanMacRxTrace(std::string context,Ptr<const Packet> p)715 AnimationInterface::LrWpanMacRxTrace (std::string context, Ptr<const Packet> p)
716 {
717   const Ptr <const Node> node = GetNodeFromContext (context);
718   ++m_nodeLrWpanMacRx[node->GetId ()];
719 }
720 
721 void
LrWpanMacRxDropTrace(std::string context,Ptr<const Packet> p)722 AnimationInterface::LrWpanMacRxDropTrace (std::string context, Ptr<const Packet> p)
723 {
724   const Ptr <const Node> node = GetNodeFromContext (context);
725   ++m_nodeLrWpanMacRxDrop[node->GetId ()];
726 }
727 
728 void
Ipv4TxTrace(std::string context,Ptr<const Packet> p,Ptr<Ipv4> ipv4,uint32_t interfaceIndex)729 AnimationInterface::Ipv4TxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
730 {
731   const Ptr <const Node> node = GetNodeFromContext (context);
732   ++m_nodeIpv4Tx[node->GetId ()];
733 }
734 
735 void
Ipv4RxTrace(std::string context,Ptr<const Packet> p,Ptr<Ipv4> ipv4,uint32_t interfaceIndex)736 AnimationInterface::Ipv4RxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
737 {
738   const Ptr <const Node> node = GetNodeFromContext (context);
739   ++m_nodeIpv4Rx[node->GetId ()];
740 }
741 
742 void
Ipv4DropTrace(std::string context,const Ipv4Header & ipv4Header,Ptr<const Packet> p,Ipv4L3Protocol::DropReason dropReason,Ptr<Ipv4> ipv4,uint32_t)743 AnimationInterface::Ipv4DropTrace (std::string context,
744                                    const Ipv4Header & ipv4Header,
745                                    Ptr<const Packet> p,
746                                    Ipv4L3Protocol::DropReason dropReason,
747                                    Ptr<Ipv4> ipv4,
748                                    uint32_t)
749 {
750   const Ptr <const Node> node = GetNodeFromContext (context);
751   ++m_nodeIpv4Drop[node->GetId ()];
752 }
753 
754 void
EnqueueTrace(std::string context,Ptr<const Packet> p)755 AnimationInterface::EnqueueTrace (std::string context,
756                                   Ptr<const Packet> p)
757 {
758   const Ptr <const Node> node = GetNodeFromContext (context);
759   ++m_nodeQueueEnqueue[node->GetId ()];
760 }
761 
762 void
DequeueTrace(std::string context,Ptr<const Packet> p)763 AnimationInterface::DequeueTrace (std::string context,
764                                   Ptr<const Packet> p)
765 {
766   const Ptr <const Node> node = GetNodeFromContext (context);
767   ++m_nodeQueueDequeue[node->GetId ()];
768 }
769 
770 void
QueueDropTrace(std::string context,Ptr<const Packet> p)771 AnimationInterface::QueueDropTrace (std::string context,
772                                     Ptr<const Packet> p)
773 {
774   const Ptr <const Node> node = GetNodeFromContext (context);
775   ++m_nodeQueueDrop[node->GetId ()];
776 }
777 
778 void
DevTxTrace(std::string context,Ptr<const Packet> p,Ptr<NetDevice> tx,Ptr<NetDevice> rx,Time txTime,Time rxTime)779 AnimationInterface::DevTxTrace (std::string context,
780                                 Ptr<const Packet> p,
781                                 Ptr<NetDevice> tx,
782                                 Ptr<NetDevice> rx,
783                                 Time txTime,
784                                 Time rxTime)
785 {
786   NS_LOG_FUNCTION (this);
787   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
788   NS_ASSERT (tx);
789   NS_ASSERT (rx);
790   Time now = Simulator::Now ();
791   double fbTx = now.GetSeconds ();
792   double lbTx = (now + txTime).GetSeconds ();
793   double fbRx = (now + rxTime - txTime).GetSeconds ();
794   double lbRx = (now + rxTime).GetSeconds ();
795   CheckMaxPktsPerTraceFile ();
796   WriteXmlP ("p",
797              tx->GetNode ()->GetId (),
798              fbTx,
799              lbTx,
800              rx->GetNode ()->GetId (),
801              fbRx,
802              lbRx,
803              m_enablePacketMetadata ? GetPacketMetadata (p) : "");
804 }
805 
806 void
GenericWirelessTxTrace(std::string context,Ptr<const Packet> p,ProtocolType protocolType)807 AnimationInterface::GenericWirelessTxTrace (std::string context, Ptr<const Packet> p, ProtocolType protocolType)
808 {
809   NS_LOG_FUNCTION (this);
810   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
811   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
812   NS_ASSERT (ndev);
813   UpdatePosition (ndev);
814 
815   ++gAnimUid;
816   NS_LOG_INFO (ProtocolTypeToString (protocolType).c_str () << " GenericWirelessTxTrace for packet:" << gAnimUid);
817   AddByteTag (gAnimUid, p);
818   AnimPacketInfo pktInfo (ndev, Simulator::Now ());
819   AddPendingPacket (protocolType, gAnimUid, pktInfo);
820 
821   Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
822   if (netDevice)
823     {
824       Mac48Address nodeAddr = netDevice->GetMac ()->GetAddress ();
825       std::ostringstream oss;
826       oss << nodeAddr;
827       Ptr <Node> n = netDevice->GetNode ();
828       NS_ASSERT (n);
829       m_macToNodeIdMap[oss.str ()] = n->GetId ();
830       NS_LOG_INFO ("Added Mac" << oss.str () << " node:" << m_macToNodeIdMap[oss.str ()]);
831     }
832   AnimUidPacketInfoMap * pendingPackets =  ProtocolTypeToPendingPackets (protocolType);
833   OutputWirelessPacketTxInfo (p, pendingPackets->at (gAnimUid), gAnimUid);
834 }
835 
836 void
GenericWirelessRxTrace(std::string context,Ptr<const Packet> p,ProtocolType protocolType)837 AnimationInterface::GenericWirelessRxTrace (std::string context, Ptr<const Packet> p, ProtocolType protocolType)
838 {
839   NS_LOG_FUNCTION (this);
840   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
841   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
842   NS_ASSERT (ndev);
843   UpdatePosition (ndev);
844   uint64_t animUid = GetAnimUidFromPacket (p);
845   NS_LOG_INFO (ProtocolTypeToString (protocolType).c_str () << " for packet:" << animUid);
846   if (!IsPacketPending (animUid, protocolType))
847     {
848       NS_LOG_WARN (ProtocolTypeToString (protocolType).c_str () << " GenericWirelessRxTrace: unknown Uid");
849       return;
850     }
851   AnimUidPacketInfoMap * pendingPackets =  ProtocolTypeToPendingPackets (protocolType);
852   pendingPackets->at (animUid).ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
853   OutputWirelessPacketRxInfo (p, pendingPackets->at (animUid), animUid);
854 }
855 
856 void
UanPhyGenTxTrace(std::string context,Ptr<const Packet> p)857 AnimationInterface::UanPhyGenTxTrace (std::string context, Ptr<const Packet> p)
858 {
859   NS_LOG_FUNCTION (this);
860   return GenericWirelessTxTrace (context, p, AnimationInterface::UAN);
861 }
862 
863 void
UanPhyGenRxTrace(std::string context,Ptr<const Packet> p)864 AnimationInterface::UanPhyGenRxTrace (std::string context, Ptr<const Packet> p)
865 {
866   NS_LOG_FUNCTION (this);
867   return GenericWirelessRxTrace (context, p, AnimationInterface::UAN);
868 }
869 
870 void
WifiPhyTxBeginTrace(std::string context,WifiConstPsduMap psduMap,WifiTxVector txVector,double txPowerW)871 AnimationInterface::WifiPhyTxBeginTrace (std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
872 {
873   NS_LOG_FUNCTION (this);
874   NS_UNUSED (txVector);
875   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
876   Ptr<NetDevice> ndev = GetNetDeviceFromContext (context);
877   NS_ASSERT (ndev);
878   UpdatePosition (ndev);
879 
880   AnimPacketInfo pktInfo (ndev, Simulator::Now ());
881   AnimUidPacketInfoMap * pendingPackets =  ProtocolTypeToPendingPackets (WIFI);
882   for (auto& psdu : psduMap)
883     {
884       for (auto& mpdu : *PeekPointer (psdu.second))
885         {
886           ++gAnimUid;
887           NS_LOG_INFO ("WifiPhyTxTrace for MPDU:" << gAnimUid);
888           AddByteTag (gAnimUid, mpdu->GetPacket ()); //the underlying MSDU/A-MSDU should be handed off
889           AddPendingPacket (WIFI, gAnimUid, pktInfo);
890           OutputWirelessPacketTxInfo (mpdu->GetProtocolDataUnit (), pendingPackets->at (gAnimUid), gAnimUid); //PDU should be considered in order to have header
891         }
892     }
893 
894   Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
895   if (netDevice)
896     {
897       Mac48Address nodeAddr = netDevice->GetMac ()->GetAddress ();
898       std::ostringstream oss;
899       oss << nodeAddr;
900       Ptr<Node> n = netDevice->GetNode ();
901       NS_ASSERT (n);
902       m_macToNodeIdMap[oss.str ()] = n->GetId ();
903       NS_LOG_INFO ("Added Mac" << oss.str () << " node:" << m_macToNodeIdMap[oss.str ()]);
904     }
905   else
906     {
907       NS_ABORT_MSG ("This NetDevice should be a Wi-Fi network device");
908     }
909 }
910 
911 void
WifiPhyRxBeginTrace(std::string context,Ptr<const Packet> p,RxPowerWattPerChannelBand rxPowersW)912 AnimationInterface::WifiPhyRxBeginTrace (std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW)
913 {
914   NS_LOG_FUNCTION (this);
915   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
916   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
917   NS_ASSERT (ndev);
918   UpdatePosition (ndev);
919   uint64_t animUid = GetAnimUidFromPacket (p);
920   NS_LOG_INFO ("Wifi RxBeginTrace for packet: " << animUid);
921   if (!IsPacketPending (animUid, AnimationInterface::WIFI))
922     {
923       NS_ASSERT_MSG (false, "WifiPhyRxBeginTrace: unknown Uid");
924       std::ostringstream oss;
925       WifiMacHeader hdr;
926       if (!p->PeekHeader (hdr))
927         {
928           NS_LOG_WARN ("WifiMacHeader not present");
929           return;
930         }
931       oss << hdr.GetAddr2 ();
932       if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
933         {
934           NS_LOG_WARN ("Transmitter Mac address " << oss.str () << " never seen before. Skipping");
935           return;
936         }
937       Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
938       UpdatePosition (txNode);
939       AnimPacketInfo pktInfo (0, Simulator::Now (), m_macToNodeIdMap[oss.str ()]);
940       AddPendingPacket (AnimationInterface::WIFI, animUid, pktInfo);
941       NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
942     }
943   /// \todo NS_ASSERT (WifiPacketIsPending (animUid) == true);
944   m_pendingWifiPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
945   OutputWirelessPacketRxInfo (p, m_pendingWifiPackets[animUid], animUid);
946 }
947 
948 void
LrWpanPhyTxBeginTrace(std::string context,Ptr<const Packet> p)949 AnimationInterface::LrWpanPhyTxBeginTrace (std::string context,
950                                            Ptr<const Packet> p)
951 {
952   NS_LOG_FUNCTION (this);
953   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
954 
955   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
956   NS_ASSERT (ndev);
957   Ptr<LrWpanNetDevice> netDevice = DynamicCast<LrWpanNetDevice> (ndev);
958 
959   Ptr <Node> n = ndev->GetNode ();
960   NS_ASSERT (n);
961 
962   UpdatePosition (n);
963 
964   LrWpanMacHeader hdr;
965   if (!p->PeekHeader (hdr))
966     {
967       NS_LOG_WARN ("LrWpanMacHeader not present");
968       return;
969     }
970 
971   std::ostringstream oss;
972   if (hdr.GetSrcAddrMode () == 2)
973     {
974       Mac16Address nodeAddr = netDevice->GetMac ()->GetShortAddress ();
975       oss << nodeAddr;
976     }
977   else if (hdr.GetSrcAddrMode () == 3)
978     {
979       Mac64Address nodeAddr = netDevice->GetMac ()->GetExtendedAddress ();
980       oss << nodeAddr;
981     }
982   else
983     {
984       NS_LOG_WARN ("LrWpanMacHeader without source address");
985       return;
986     }
987   m_macToNodeIdMap[oss.str ()] = n->GetId ();
988   NS_LOG_INFO ("Added Mac" << oss.str () << " node:" << m_macToNodeIdMap[oss.str ()]);
989 
990   ++gAnimUid;
991   NS_LOG_INFO ("LrWpan TxBeginTrace for packet:" << gAnimUid);
992   AddByteTag (gAnimUid, p);
993 
994   AnimPacketInfo pktInfo (ndev, Simulator::Now ());
995   AddPendingPacket (AnimationInterface::LRWPAN, gAnimUid, pktInfo);
996 
997   OutputWirelessPacketTxInfo (p, m_pendingLrWpanPackets[gAnimUid], gAnimUid);
998 }
999 
1000 void
LrWpanPhyRxBeginTrace(std::string context,Ptr<const Packet> p)1001 AnimationInterface::LrWpanPhyRxBeginTrace (std::string context,
1002                                            Ptr<const Packet> p)
1003 {
1004   NS_LOG_FUNCTION (this);
1005   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1006   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1007   NS_ASSERT (ndev);
1008   Ptr <Node> n = ndev->GetNode ();
1009   NS_ASSERT (n);
1010 
1011   AnimByteTag tag;
1012   if (!p->FindFirstMatchingByteTag (tag))
1013     {
1014       return;
1015     }
1016 
1017   uint64_t animUid = GetAnimUidFromPacket (p);
1018   NS_LOG_INFO ("LrWpan RxBeginTrace for packet:" << animUid);
1019   if (!IsPacketPending (animUid, AnimationInterface::LRWPAN))
1020     {
1021       NS_LOG_WARN ("LrWpanPhyRxBeginTrace: unknown Uid - most probably it's an ACK.");
1022     }
1023 
1024   UpdatePosition (n);
1025   m_pendingLrWpanPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1026   OutputWirelessPacketRxInfo (p, m_pendingLrWpanPackets[animUid], animUid);
1027 }
1028 
1029 void
WavePhyTxBeginTrace(std::string context,Ptr<const Packet> p)1030 AnimationInterface::WavePhyTxBeginTrace (std::string context, Ptr<const Packet> p)
1031 {
1032   NS_LOG_FUNCTION (this);
1033   return GenericWirelessTxTrace (context, p, AnimationInterface::WAVE);
1034 }
1035 
1036 void
WavePhyRxBeginTrace(std::string context,Ptr<const Packet> p)1037 AnimationInterface::WavePhyRxBeginTrace (std::string context, Ptr<const Packet> p)
1038 {
1039   NS_LOG_FUNCTION (this);
1040   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1041   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1042   NS_ASSERT (ndev);
1043   UpdatePosition (ndev);
1044   uint64_t animUid = GetAnimUidFromPacket (p);
1045   NS_LOG_INFO ("Wave RxBeginTrace for packet:" << animUid);
1046   if (!IsPacketPending (animUid, AnimationInterface::WAVE))
1047     {
1048       NS_ASSERT_MSG (false, "WavePhyRxBeginTrace: unknown Uid");
1049       std::ostringstream oss;
1050       WifiMacHeader hdr;
1051       if (!p->PeekHeader (hdr))
1052         {
1053           NS_LOG_WARN ("WaveMacHeader not present");
1054           return;
1055         }
1056       oss << hdr.GetAddr2 ();
1057       if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
1058         {
1059           NS_LOG_WARN ("Transmitter Mac address " << oss.str () << " never seen before. Skipping");
1060           return;
1061         }
1062       Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
1063       UpdatePosition (txNode);
1064       AnimPacketInfo pktInfo (0, Simulator::Now (), m_macToNodeIdMap[oss.str ()]);
1065       AddPendingPacket (AnimationInterface::WAVE, animUid, pktInfo);
1066       NS_LOG_WARN ("WavePhyRxBegin: unknown Uid, but we are adding a wave packet");
1067     }
1068   /// \todo NS_ASSERT (WavePacketIsPending (animUid) == true);
1069   m_pendingWavePackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1070   OutputWirelessPacketRxInfo (p, m_pendingWavePackets[animUid], animUid);
1071 }
1072 
1073 
1074 void
WimaxTxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1075 AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1076 {
1077   NS_LOG_FUNCTION (this);
1078   return GenericWirelessTxTrace (context, p, AnimationInterface::WIMAX);
1079 }
1080 
1081 
1082 void
WimaxRxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1083 AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1084 {
1085   NS_LOG_FUNCTION (this);
1086   return GenericWirelessRxTrace (context, p, AnimationInterface::WIMAX);
1087 }
1088 
1089 void
LteTxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1090 AnimationInterface::LteTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1091 {
1092   NS_LOG_FUNCTION (this);
1093   return GenericWirelessTxTrace (context, p, AnimationInterface::LTE);
1094 }
1095 
1096 void
LteRxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1097 AnimationInterface::LteRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1098 {
1099   NS_LOG_FUNCTION (this);
1100   return GenericWirelessRxTrace (context, p, AnimationInterface::LTE);
1101 }
1102 
1103 void
LteSpectrumPhyTxStart(std::string context,Ptr<const PacketBurst> pb)1104 AnimationInterface::LteSpectrumPhyTxStart (std::string context, Ptr<const PacketBurst> pb)
1105 {
1106   NS_LOG_FUNCTION (this);
1107   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1108   if (!pb)
1109     {
1110       NS_LOG_WARN ("pb == 0. Not yet supported");
1111       return;
1112     }
1113   context = "/" + context;
1114   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1115   NS_ASSERT (ndev);
1116   UpdatePosition (ndev);
1117 
1118   std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1119   for (std::list <Ptr <Packet> >::iterator i  = pbList.begin ();
1120        i != pbList.end ();
1121        ++i)
1122     {
1123       Ptr <Packet> p = *i;
1124       ++gAnimUid;
1125       NS_LOG_INFO ("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
1126       AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1127       AddByteTag (gAnimUid, p);
1128       AddPendingPacket (AnimationInterface::LTE, gAnimUid, pktInfo);
1129       OutputWirelessPacketTxInfo (p, pktInfo, gAnimUid);
1130     }
1131 }
1132 
1133 void
LteSpectrumPhyRxStart(std::string context,Ptr<const PacketBurst> pb)1134 AnimationInterface::LteSpectrumPhyRxStart (std::string context, Ptr<const PacketBurst> pb)
1135 {
1136   NS_LOG_FUNCTION (this);
1137   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1138   if (!pb)
1139     {
1140       NS_LOG_WARN ("pb == 0. Not yet supported");
1141       return;
1142     }
1143   context = "/" + context;
1144   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1145   NS_ASSERT (ndev);
1146   UpdatePosition (ndev);
1147 
1148   std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1149   for (std::list <Ptr <Packet> >::iterator i  = pbList.begin ();
1150        i != pbList.end ();
1151        ++i)
1152     {
1153       Ptr <Packet> p = *i;
1154       uint64_t animUid = GetAnimUidFromPacket (p);
1155       NS_LOG_INFO ("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
1156       if (!IsPacketPending (animUid, AnimationInterface::LTE))
1157         {
1158           NS_LOG_WARN ("LteSpectrumPhyRxTrace: unknown Uid");
1159           return;
1160         }
1161       AnimPacketInfo& pktInfo = m_pendingLtePackets[animUid];
1162       pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1163       OutputWirelessPacketRxInfo (p, pktInfo, animUid);
1164     }
1165 }
1166 
1167 void
CsmaPhyTxBeginTrace(std::string context,Ptr<const Packet> p)1168 AnimationInterface::CsmaPhyTxBeginTrace (std::string context, Ptr<const Packet> p)
1169 {
1170   NS_LOG_FUNCTION (this);
1171   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1172   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1173   NS_ASSERT (ndev);
1174   UpdatePosition (ndev);
1175   ++gAnimUid;
1176   NS_LOG_INFO ("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
1177   AddByteTag (gAnimUid, p);
1178   UpdatePosition (ndev);
1179   AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1180   AddPendingPacket (AnimationInterface::CSMA, gAnimUid, pktInfo);
1181 
1182 
1183 }
1184 
1185 void
CsmaPhyTxEndTrace(std::string context,Ptr<const Packet> p)1186 AnimationInterface::CsmaPhyTxEndTrace (std::string context, Ptr<const Packet> p)
1187 {
1188   NS_LOG_FUNCTION (this);
1189   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1190   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1191   NS_ASSERT (ndev);
1192   UpdatePosition (ndev);
1193   uint64_t animUid = GetAnimUidFromPacket (p);
1194   NS_LOG_INFO ("CsmaPhyTxEndTrace for packet:" << animUid);
1195   if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1196     {
1197       NS_LOG_WARN ("CsmaPhyTxEndTrace: unknown Uid");
1198       NS_FATAL_ERROR ("CsmaPhyTxEndTrace: unknown Uid");
1199       AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1200       AddPendingPacket (AnimationInterface::CSMA, animUid, pktInfo);
1201       NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
1202     }
1203   /// \todo NS_ASSERT (IsPacketPending (AnimUid) == true);
1204   AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1205   pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
1206 }
1207 
1208 void
CsmaPhyRxEndTrace(std::string context,Ptr<const Packet> p)1209 AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
1210 {
1211   NS_LOG_FUNCTION (this);
1212   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1213   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1214   NS_ASSERT (ndev);
1215   UpdatePosition (ndev);
1216   uint64_t animUid = GetAnimUidFromPacket (p);
1217   if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1218     {
1219       NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid");
1220       return;
1221     }
1222   /// \todo NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1223   AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1224   pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1225   NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid);
1226   NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid << " complete");
1227   OutputCsmaPacket (p, pktInfo);
1228 }
1229 
1230 void
CsmaMacRxTrace(std::string context,Ptr<const Packet> p)1231 AnimationInterface::CsmaMacRxTrace (std::string context,
1232                                     Ptr<const Packet> p)
1233 {
1234   NS_LOG_FUNCTION (this);
1235   CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1236   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1237   NS_ASSERT (ndev);
1238   uint64_t animUid = GetAnimUidFromPacket (p);
1239   if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1240     {
1241       NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid");
1242       return;
1243     }
1244   /// \todo NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1245   AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1246   NS_LOG_INFO ("MacRxTrace for packet:" << animUid << " complete");
1247   OutputCsmaPacket (p, pktInfo);
1248 }
1249 
1250 void
OutputWirelessPacketTxInfo(Ptr<const Packet> p,AnimPacketInfo & pktInfo,uint64_t animUid)1251 AnimationInterface::OutputWirelessPacketTxInfo (Ptr<const Packet> p, AnimPacketInfo &pktInfo, uint64_t animUid)
1252 {
1253   CheckMaxPktsPerTraceFile ();
1254   uint32_t nodeId = 0;
1255   if (pktInfo.m_txnd)
1256     {
1257       nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1258     }
1259   else
1260     {
1261       nodeId = pktInfo.m_txNodeId;
1262     }
1263   WriteXmlPRef (animUid, nodeId, pktInfo.m_fbTx, m_enablePacketMetadata ? GetPacketMetadata (p) : "");
1264 }
1265 
1266 void
OutputWirelessPacketRxInfo(Ptr<const Packet> p,AnimPacketInfo & pktInfo,uint64_t animUid)1267 AnimationInterface::OutputWirelessPacketRxInfo (Ptr<const Packet> p, AnimPacketInfo & pktInfo, uint64_t animUid)
1268 {
1269   CheckMaxPktsPerTraceFile ();
1270   uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1271   WriteXmlP (animUid, "wpr", rxId, pktInfo.m_fbRx, pktInfo.m_lbRx);
1272 }
1273 
1274 void
OutputCsmaPacket(Ptr<const Packet> p,AnimPacketInfo & pktInfo)1275 AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo)
1276 {
1277   CheckMaxPktsPerTraceFile ();
1278   NS_ASSERT (pktInfo.m_txnd);
1279   uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1280   uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1281 
1282   WriteXmlP ("p",
1283              nodeId,
1284              pktInfo.m_fbTx,
1285              pktInfo.m_lbTx,
1286              rxId,
1287              pktInfo.m_fbRx,
1288              pktInfo.m_lbRx,
1289              m_enablePacketMetadata ? GetPacketMetadata (p) : "");
1290 }
1291 
1292 void
AddPendingPacket(ProtocolType protocolType,uint64_t animUid,AnimPacketInfo pktInfo)1293 AnimationInterface::AddPendingPacket (ProtocolType protocolType, uint64_t animUid, AnimPacketInfo pktInfo)
1294 {
1295   AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1296   NS_ASSERT (pendingPackets);
1297   pendingPackets->insert (AnimUidPacketInfoMap::value_type (animUid, pktInfo));
1298 }
1299 
1300 bool
IsPacketPending(uint64_t animUid,AnimationInterface::ProtocolType protocolType)1301 AnimationInterface::IsPacketPending (uint64_t animUid, AnimationInterface::ProtocolType protocolType)
1302 {
1303   AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1304   NS_ASSERT (pendingPackets);
1305   return (pendingPackets->find (animUid) != pendingPackets->end ());
1306 }
1307 
1308 void
PurgePendingPackets(AnimationInterface::ProtocolType protocolType)1309 AnimationInterface::PurgePendingPackets (AnimationInterface::ProtocolType protocolType)
1310 {
1311   AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1312   NS_ASSERT (pendingPackets);
1313   if (pendingPackets->empty ())
1314     {
1315       return;
1316     }
1317   std::vector <uint64_t> purgeList;
1318   for (AnimUidPacketInfoMap::iterator i = pendingPackets->begin ();
1319        i != pendingPackets->end ();
1320        ++i)
1321     {
1322 
1323       AnimPacketInfo pktInfo = i->second;
1324       double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
1325       if (delta > PURGE_INTERVAL)
1326         {
1327           purgeList.push_back (i->first);
1328         }
1329     }
1330   for (std::vector <uint64_t>::iterator i = purgeList.begin ();
1331        i != purgeList.end ();
1332        ++i)
1333     {
1334       pendingPackets->erase (*i);
1335     }
1336 }
1337 
1338 AnimationInterface::AnimUidPacketInfoMap *
ProtocolTypeToPendingPackets(AnimationInterface::ProtocolType protocolType)1339 AnimationInterface::ProtocolTypeToPendingPackets (AnimationInterface::ProtocolType protocolType)
1340 {
1341   AnimUidPacketInfoMap * pendingPackets = 0;
1342   switch (protocolType)
1343     {
1344     case AnimationInterface::WIFI:
1345       {
1346         pendingPackets = &m_pendingWifiPackets;
1347         break;
1348       }
1349     case AnimationInterface::UAN:
1350       {
1351         pendingPackets = &m_pendingUanPackets;
1352         break;
1353       }
1354     case AnimationInterface::CSMA:
1355       {
1356         pendingPackets = &m_pendingCsmaPackets;
1357         break;
1358       }
1359     case AnimationInterface::WIMAX:
1360       {
1361         pendingPackets = &m_pendingWimaxPackets;
1362         break;
1363       }
1364     case AnimationInterface::LTE:
1365       {
1366         pendingPackets = &m_pendingLtePackets;
1367         break;
1368       }
1369     case AnimationInterface::LRWPAN:
1370       {
1371         pendingPackets = &m_pendingLrWpanPackets;
1372         break;
1373       }
1374     case AnimationInterface::WAVE:
1375       {
1376         pendingPackets = &m_pendingWavePackets;
1377         break;
1378       }
1379     }
1380   return pendingPackets;
1381 
1382 }
1383 
1384 std::string
ProtocolTypeToString(AnimationInterface::ProtocolType protocolType)1385 AnimationInterface::ProtocolTypeToString (AnimationInterface::ProtocolType protocolType)
1386 {
1387   std::string result = "Unknown";
1388   switch (protocolType)
1389     {
1390     case AnimationInterface::WIFI:
1391       {
1392         result = "WIFI";
1393         break;
1394       }
1395     case AnimationInterface::UAN:
1396       {
1397         result = "UAN";
1398         break;
1399       }
1400     case AnimationInterface::CSMA:
1401       {
1402         result = "CSMA";
1403         break;
1404       }
1405     case AnimationInterface::WIMAX:
1406       {
1407         result = "WIMAX";
1408         break;
1409       }
1410     case AnimationInterface::LTE:
1411       {
1412         result = "LTE";
1413         break;
1414       }
1415     case AnimationInterface::LRWPAN:
1416       {
1417         result = "LRWPAN";
1418         break;
1419       }
1420     case AnimationInterface::WAVE:
1421       {
1422         result = "WAVE";
1423         break;
1424       }
1425     }
1426   return result;
1427 }
1428 
1429 // Counters
1430 
1431 std::string
CounterTypeToString(CounterType counterType)1432 AnimationInterface::CounterTypeToString (CounterType counterType)
1433 {
1434   std::string typeString = "unknown";
1435   switch (counterType)
1436     {
1437     case UINT32_COUNTER:
1438       {
1439         typeString = "UINT32";
1440         break;
1441       }
1442     case DOUBLE_COUNTER:
1443       {
1444         typeString = "DOUBLE";
1445         break;
1446       }
1447     }
1448   return typeString;
1449 }
1450 
1451 // General
1452 
1453 std::string
GetPacketMetadata(Ptr<const Packet> p)1454 AnimationInterface::GetPacketMetadata (Ptr<const Packet> p)
1455 {
1456   std::ostringstream oss;
1457   p->Print (oss);
1458   return oss.str ();
1459 }
1460 
1461 uint64_t
GetTracePktCount()1462 AnimationInterface::GetTracePktCount ()
1463 {
1464   return m_currentPktCount;
1465 }
1466 
1467 void
StopAnimation(bool onlyAnimation)1468 AnimationInterface::StopAnimation (bool onlyAnimation)
1469 {
1470   m_started = false;
1471   NS_LOG_INFO ("Stopping Animation");
1472   ResetAnimWriteCallback ();
1473   if (m_f)
1474     {
1475       // Terminate the anim element
1476       WriteXmlClose ("anim");
1477       std::fclose (m_f);
1478       m_f = 0;
1479     }
1480   if (onlyAnimation)
1481     {
1482       return;
1483     }
1484   if (m_routingF)
1485     {
1486       WriteXmlClose ("anim", true);
1487       std::fclose (m_routingF);
1488       m_routingF = 0;
1489     }
1490 }
1491 
1492 void
StartAnimation(bool restart)1493 AnimationInterface::StartAnimation (bool restart)
1494 {
1495   m_currentPktCount = 0;
1496   m_started = true;
1497   SetOutputFile (m_outputFileName);
1498   WriteXmlAnim ();
1499   WriteNodes ();
1500   WriteNodeColors ();
1501   WriteLinkProperties ();
1502   WriteIpv4Addresses ();
1503   WriteIpv6Addresses ();
1504   WriteNodeSizes ();
1505   WriteNodeEnergies ();
1506   if (!restart)
1507     {
1508       Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
1509       ConnectCallbacks ();
1510     }
1511 }
1512 
1513 void
AddToIpv4AddressNodeIdTable(std::string ipv4Address,uint32_t nodeId)1514 AnimationInterface::AddToIpv4AddressNodeIdTable (std::string ipv4Address, uint32_t nodeId)
1515 {
1516   m_ipv4ToNodeIdMap[ipv4Address] = nodeId;
1517   m_nodeIdIpv4Map.insert (NodeIdIpv4Pair (nodeId, ipv4Address));
1518 }
1519 
1520 void
AddToIpv4AddressNodeIdTable(std::vector<std::string> ipv4Addresses,uint32_t nodeId)1521 AnimationInterface::AddToIpv4AddressNodeIdTable (std::vector<std::string> ipv4Addresses, uint32_t nodeId)
1522 {
1523   for (std::vector<std::string>::const_iterator i = ipv4Addresses.begin ();
1524        i != ipv4Addresses.end ();
1525        ++i)
1526     {
1527       AddToIpv4AddressNodeIdTable (*i, nodeId);
1528     }
1529 }
1530 
1531 void
AddToIpv6AddressNodeIdTable(std::string ipv6Address,uint32_t nodeId)1532 AnimationInterface::AddToIpv6AddressNodeIdTable (std::string ipv6Address, uint32_t nodeId)
1533 {
1534   m_ipv6ToNodeIdMap[ipv6Address] = nodeId;
1535   m_nodeIdIpv6Map.insert (NodeIdIpv6Pair (nodeId, ipv6Address));
1536 }
1537 
1538 void
AddToIpv6AddressNodeIdTable(std::vector<std::string> ipv6Addresses,uint32_t nodeId)1539 AnimationInterface::AddToIpv6AddressNodeIdTable (std::vector<std::string> ipv6Addresses, uint32_t nodeId)
1540 {
1541   for (std::vector<std::string>::const_iterator i = ipv6Addresses.begin ();
1542        i != ipv6Addresses.end ();
1543        ++i)
1544     {
1545       AddToIpv6AddressNodeIdTable (*i, nodeId);
1546     }
1547 }
1548 
1549 // Callbacks
1550 void
ConnectLteEnb(Ptr<Node> n,Ptr<LteEnbNetDevice> nd,uint32_t devIndex)1551 AnimationInterface::ConnectLteEnb (Ptr <Node> n, Ptr <LteEnbNetDevice> nd, uint32_t devIndex)
1552 {
1553 
1554   Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy ();
1555   Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy ();
1556   Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy ();
1557   std::ostringstream oss;
1558   //NodeList/*/DeviceList/*/
1559   oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1560   if (dlPhy)
1561     {
1562       dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1563       dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1564     }
1565   if (ulPhy)
1566     {
1567       ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1568       ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1569     }
1570 }
1571 
1572 
1573 
1574 void
ConnectLteUe(Ptr<Node> n,Ptr<LteUeNetDevice> nd,uint32_t devIndex)1575 AnimationInterface::ConnectLteUe (Ptr <Node> n, Ptr <LteUeNetDevice> nd, uint32_t devIndex)
1576 {
1577 
1578   Ptr<LteUePhy> lteUePhy = nd->GetPhy ();
1579   Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy ();
1580   Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy ();
1581   std::ostringstream oss;
1582   //NodeList/*/DeviceList/*/
1583   oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1584   if (dlPhy)
1585     {
1586       dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1587       dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1588     }
1589   if (ulPhy)
1590     {
1591       ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1592       ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1593     }
1594 }
1595 
1596 void
ConnectLte()1597 AnimationInterface::ConnectLte ()
1598 {
1599 
1600   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1601     {
1602       Ptr<Node> n = *i;
1603       NS_ASSERT (n);
1604       uint32_t nDevices = n->GetNDevices ();
1605       for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
1606         {
1607           Ptr <NetDevice> nd = n->GetDevice (devIndex);
1608           if (!nd)
1609             {
1610               continue;
1611             }
1612           Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice> (nd);
1613           if (lteUeNetDevice)
1614             {
1615               ConnectLteUe (n, lteUeNetDevice, devIndex);
1616               continue;
1617             }
1618           Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice> (nd);
1619           if (lteEnbNetDevice)
1620             {
1621               ConnectLteEnb (n, lteEnbNetDevice, devIndex);
1622             }
1623         }
1624 
1625     }
1626 }
1627 
1628 void
ConnectCallbacks()1629 AnimationInterface::ConnectCallbacks ()
1630 {
1631   // Connect the callbacks
1632   Config::ConnectFailSafe ("/ChannelList/*/TxRxPointToPoint",
1633                            MakeCallback (&AnimationInterface::DevTxTrace, this));
1634   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
1635                            MakeCallback (&AnimationInterface::WifiPhyTxBeginTrace, this));
1636   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
1637                            MakeCallback (&AnimationInterface::WifiPhyRxBeginTrace, this));
1638   Config::ConnectWithoutContextFailSafe ("/NodeList/*/$ns3::MobilityModel/CourseChange",
1639                                          MakeCallback (&AnimationInterface::MobilityCourseChangeTrace, this));
1640   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
1641                            MakeCallback (&AnimationInterface::WimaxTxTrace, this));
1642   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
1643                            MakeCallback (&AnimationInterface::WimaxRxTrace, this));
1644   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
1645                            MakeCallback (&AnimationInterface::LteTxTrace, this));
1646   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
1647                            MakeCallback (&AnimationInterface::LteRxTrace, this));
1648   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
1649                            MakeCallback (&AnimationInterface::CsmaPhyTxBeginTrace, this));
1650   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
1651                            MakeCallback (&AnimationInterface::CsmaPhyTxEndTrace, this));
1652   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
1653                            MakeCallback (&AnimationInterface::CsmaPhyRxEndTrace, this));
1654   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
1655                            MakeCallback (&AnimationInterface::CsmaMacRxTrace, this));
1656   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
1657                            MakeCallback (&AnimationInterface::UanPhyGenTxTrace, this));
1658   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
1659                            MakeCallback (&AnimationInterface::UanPhyGenRxTrace, this));
1660   Config::ConnectFailSafe ("/NodeList/*/$ns3::BasicEnergySource/RemainingEnergy",
1661                            MakeCallback (&AnimationInterface::RemainingEnergyTrace, this));
1662 
1663   ConnectLte ();
1664 
1665   Config::ConnectFailSafe ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
1666                            MakeCallback (&AnimationInterface::Ipv4TxTrace, this));
1667   Config::ConnectFailSafe ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
1668                            MakeCallback (&AnimationInterface::Ipv4RxTrace, this));
1669   Config::ConnectFailSafe ("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
1670                            MakeCallback (&AnimationInterface::Ipv4DropTrace, this));
1671 
1672   // Queue Enqueues
1673 
1674   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Enqueue",
1675                            MakeCallback (&AnimationInterface::EnqueueTrace, this));
1676   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Enqueue",
1677                            MakeCallback (&AnimationInterface::EnqueueTrace, this));
1678   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Enqueue",
1679                            MakeCallback (&AnimationInterface::EnqueueTrace, this));
1680 
1681   // Queue Dequeues
1682 
1683   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Dequeue",
1684                            MakeCallback (&AnimationInterface::DequeueTrace, this));
1685   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Dequeue",
1686                            MakeCallback (&AnimationInterface::DequeueTrace, this));
1687   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Dequeue",
1688                            MakeCallback (&AnimationInterface::DequeueTrace, this));
1689 
1690   // Queue Drops
1691 
1692   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Drop",
1693                            MakeCallback (&AnimationInterface::QueueDropTrace, this));
1694   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Drop",
1695                            MakeCallback (&AnimationInterface::QueueDropTrace, this));
1696   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Drop",
1697                            MakeCallback (&AnimationInterface::QueueDropTrace, this));
1698 
1699 
1700   // Wifi Mac
1701   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
1702                            MakeCallback (&AnimationInterface::WifiMacTxTrace, this));
1703   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTxDrop",
1704                            MakeCallback (&AnimationInterface::WifiMacTxDropTrace, this));
1705   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
1706                            MakeCallback (&AnimationInterface::WifiMacRxTrace, this));
1707   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRxDrop",
1708                            MakeCallback (&AnimationInterface::WifiMacRxDropTrace, this));
1709 
1710   // Wifi Phy
1711   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxDrop",
1712                            MakeCallback (&AnimationInterface::WifiPhyTxDropTrace, this));
1713   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
1714                            MakeCallback (&AnimationInterface::WifiPhyRxDropTrace, this));
1715 
1716   // LrWpan
1717   Config::ConnectFailSafe ("NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Phy/PhyTxBegin",
1718                            MakeCallback (&AnimationInterface::LrWpanPhyTxBeginTrace, this));
1719   Config::ConnectFailSafe ("NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Phy/PhyRxBegin",
1720                            MakeCallback (&AnimationInterface::LrWpanPhyRxBeginTrace, this));
1721   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacTx",
1722                            MakeCallback (&AnimationInterface::LrWpanMacTxTrace, this));
1723   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacTxDrop",
1724                            MakeCallback (&AnimationInterface::LrWpanMacTxDropTrace, this));
1725   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacRx",
1726                            MakeCallback (&AnimationInterface::LrWpanMacRxTrace, this));
1727   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacRxDrop",
1728                            MakeCallback (&AnimationInterface::LrWpanMacRxDropTrace, this));
1729 
1730   // Wave
1731   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/PhyTxBegin",
1732                            MakeCallback (&AnimationInterface::WavePhyTxBeginTrace, this));
1733   Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/PhyRxBegin",
1734                            MakeCallback (&AnimationInterface::WavePhyRxBeginTrace, this));
1735 }
1736 
1737 Vector
UpdatePosition(Ptr<Node> n)1738 AnimationInterface::UpdatePosition (Ptr <Node> n)
1739 {
1740   Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
1741   if (loc)
1742     {
1743       m_nodeLocation[n->GetId ()] = loc->GetPosition ();
1744     }
1745   else
1746     {
1747       NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
1748       Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
1749       x->SetAttribute ("Min", DoubleValue (0));
1750       x->SetAttribute ("Max", DoubleValue (100));
1751       Ptr<UniformRandomVariable> y = CreateObject<UniformRandomVariable> ();
1752       y->SetAttribute ("Min", DoubleValue (0));
1753       y->SetAttribute ("Max", DoubleValue (100));
1754       m_nodeLocation[n->GetId ()] = Vector (int (x->GetValue ()), int (y->GetValue ()), 0);
1755     }
1756   return m_nodeLocation[n->GetId ()];
1757 }
1758 
1759 Vector
UpdatePosition(Ptr<Node> n,Vector v)1760 AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
1761 {
1762   m_nodeLocation[n->GetId ()] = v;
1763   return v;
1764 }
1765 
1766 Vector
UpdatePosition(Ptr<NetDevice> ndev)1767 AnimationInterface::UpdatePosition (Ptr <NetDevice> ndev)
1768 {
1769   Ptr <Node> n = ndev->GetNode ();
1770   NS_ASSERT (n);
1771   return UpdatePosition (n);
1772 }
1773 
1774 Vector
GetPosition(Ptr<Node> n)1775 AnimationInterface::GetPosition (Ptr <Node> n)
1776 {
1777   if (m_nodeLocation.find (n->GetId ()) == m_nodeLocation.end ())
1778     {
1779       NS_FATAL_ERROR ("Node:" << n->GetId () << " not found in Location table");
1780     }
1781   return m_nodeLocation[n->GetId ()];
1782 }
1783 
1784 
1785 std::string
GetMacAddress(Ptr<NetDevice> nd)1786 AnimationInterface::GetMacAddress (Ptr <NetDevice> nd)
1787 {
1788   Address nodeAddr = nd->GetAddress ();
1789   std::ostringstream oss;
1790   oss << nodeAddr;
1791   return oss.str ().substr (6); // Skip the first 6 chars to get the Mac
1792 }
1793 
1794 std::string
GetIpv4Address(Ptr<NetDevice> nd)1795 AnimationInterface::GetIpv4Address (Ptr <NetDevice> nd)
1796 {
1797   Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
1798   if (!ipv4)
1799     {
1800       NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1801       return "0.0.0.0";
1802     }
1803   int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
1804   if (ifIndex == -1)
1805     {
1806       NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1807       return "0.0.0.0";
1808     }
1809   Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, 0);
1810   std::ostringstream oss;
1811   oss << addr.GetLocal ();
1812   return oss.str ();
1813 }
1814 
1815 std::string
GetIpv6Address(Ptr<NetDevice> nd)1816 AnimationInterface::GetIpv6Address (Ptr <NetDevice> nd)
1817 {
1818   Ptr<Ipv6> ipv6 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv6> ();
1819   if (!ipv6)
1820     {
1821       NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1822       return "::";
1823     }
1824   int32_t ifIndex = ipv6->GetInterfaceForDevice (nd);
1825   if (ifIndex == -1)
1826     {
1827       NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1828       return "::";
1829     }
1830   bool nonLinkLocalFound = false;
1831   uint32_t nAddresses = ipv6->GetNAddresses (ifIndex);
1832   Ipv6InterfaceAddress addr;
1833   for (uint32_t addressIndex = 0; addressIndex < nAddresses; ++addressIndex)
1834     {
1835       addr = ipv6->GetAddress (ifIndex, addressIndex);
1836       if (!addr.GetAddress ().IsLinkLocal ())
1837         {
1838           nonLinkLocalFound = true;
1839           break;
1840         }
1841     }
1842   if (!nonLinkLocalFound)
1843     {
1844       addr = ipv6->GetAddress (ifIndex, 0);
1845     }
1846   std::ostringstream oss;
1847   oss << addr.GetAddress ();
1848   return oss.str ();
1849 }
1850 
1851 
1852 
1853 std::vector<std::string>
GetIpv4Addresses(Ptr<NetDevice> nd)1854 AnimationInterface::GetIpv4Addresses (Ptr <NetDevice> nd)
1855 {
1856   std::vector<std::string> ipv4Addresses;
1857   Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
1858   if (!ipv4)
1859     {
1860       NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1861       return ipv4Addresses;
1862     }
1863   int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
1864   if (ifIndex == -1)
1865     {
1866       NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1867       return ipv4Addresses;
1868     }
1869   for (uint32_t index = 0; index < ipv4->GetNAddresses (ifIndex); ++index)
1870     {
1871       Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, index);
1872       std::ostringstream oss;
1873       oss << addr.GetLocal ();
1874       ipv4Addresses.push_back (oss.str ());
1875     }
1876   return ipv4Addresses;
1877 }
1878 
1879 std::vector<std::string>
GetIpv6Addresses(Ptr<NetDevice> nd)1880 AnimationInterface::GetIpv6Addresses (Ptr <NetDevice> nd)
1881 {
1882   std::vector<std::string> ipv6Addresses;
1883   Ptr<Ipv6> ipv6 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv6> ();
1884   if (!ipv6)
1885     {
1886       NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv6 object found");
1887       return ipv6Addresses;
1888     }
1889   int32_t ifIndex = ipv6->GetInterfaceForDevice (nd);
1890   if (ifIndex == -1)
1891     {
1892       NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1893       return ipv6Addresses;
1894     }
1895   for (uint32_t index = 0; index < ipv6->GetNAddresses (ifIndex); ++index)
1896     {
1897       Ipv6InterfaceAddress addr = ipv6->GetAddress (ifIndex, index);
1898       std::ostringstream oss;
1899       oss << addr.GetAddress ();
1900       ipv6Addresses.push_back (oss.str ());
1901     }
1902   return ipv6Addresses;
1903 }
1904 
1905 
1906 void
WriteIpv4Addresses()1907 AnimationInterface::WriteIpv4Addresses ()
1908 {
1909   for (NodeIdIpv4Map::const_iterator i = m_nodeIdIpv4Map.begin ();
1910        i != m_nodeIdIpv4Map.end ();
1911        ++i)
1912     {
1913       std::vector <std::string> ipv4Addresses;
1914       std::pair<NodeIdIpv4Map::const_iterator, NodeIdIpv4Map::const_iterator> iterPair = m_nodeIdIpv4Map.equal_range (i->first);
1915       for (NodeIdIpv4Map::const_iterator it = iterPair.first;
1916            it != iterPair.second;
1917            ++it)
1918         {
1919           ipv4Addresses.push_back (it->second);
1920         }
1921       WriteXmlIpv4Addresses (i->first, ipv4Addresses);
1922     }
1923 }
1924 
1925 void
WriteIpv6Addresses()1926 AnimationInterface::WriteIpv6Addresses ()
1927 {
1928   for (NodeIdIpv6Map::const_iterator i = m_nodeIdIpv6Map.begin ();
1929        i != m_nodeIdIpv6Map.end ();
1930        i = m_nodeIdIpv6Map.upper_bound (i->first))
1931     {
1932       std::vector <std::string> ipv6Addresses;
1933       std::pair<NodeIdIpv6Map::const_iterator, NodeIdIpv6Map::const_iterator> iterPair = m_nodeIdIpv6Map.equal_range (i->first);
1934       for (NodeIdIpv6Map::const_iterator it = iterPair.first;
1935            it != iterPair.second;
1936            ++it)
1937         {
1938           ipv6Addresses.push_back (it->second);
1939         }
1940       WriteXmlIpv6Addresses (i->first, ipv6Addresses);
1941     }
1942 }
1943 
1944 void
WriteLinkProperties()1945 AnimationInterface::WriteLinkProperties ()
1946 {
1947   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1948     {
1949       Ptr<Node> n = *i;
1950       UpdatePosition (n);
1951       uint32_t n1Id = n->GetId ();
1952       uint32_t nDev = n->GetNDevices ();  // Number of devices
1953       for (uint32_t i = 0; i < nDev; ++i)
1954         {
1955           Ptr<NetDevice> dev = n->GetDevice (i);
1956           NS_ASSERT (dev);
1957           Ptr<Channel>   ch = dev->GetChannel ();
1958           std::string channelType = "Unknown channel";
1959           if (ch)
1960             {
1961               channelType = ch->GetInstanceTypeId ().GetName ();
1962             }
1963           NS_LOG_DEBUG ("Got ChannelType" << channelType);
1964 
1965           if (!ch || (channelType != std::string ("ns3::PointToPointChannel")))
1966             {
1967               NS_LOG_DEBUG ("No channel can't be a p2p device");
1968               /*
1969               // Try to see if it is an LTE NetDevice, which does not return a channel
1970               if ((dev->GetInstanceTypeId ().GetName () == "ns3::LteUeNetDevice") ||
1971                   (dev->GetInstanceTypeId ().GetName () == "ns3::LteEnbNetDevice")||
1972                   (dev->GetInstanceTypeId ().GetName () == "ns3::VirtualNetDevice"))
1973                 {
1974                   WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
1975                   AddToIpv4AddressNodeIdTable (GetIpv4Address (dev), n->GetId ());
1976                 }
1977                */
1978               std::vector<std::string> ipv4Addresses = GetIpv4Addresses (dev);
1979               AddToIpv4AddressNodeIdTable (ipv4Addresses, n->GetId ());
1980               std::vector<std::string> ipv6Addresses = GetIpv6Addresses (dev);
1981               AddToIpv6AddressNodeIdTable (ipv6Addresses, n->GetId ());
1982               if (!ipv4Addresses.empty ())
1983                 {
1984                   NS_LOG_INFO ("Writing Ipv4 link");
1985                   WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
1986                 }
1987               else if (!ipv6Addresses.empty ())
1988                 {
1989                   NS_LOG_INFO ("Writing Ipv6 link");
1990                   WriteNonP2pLinkProperties (n->GetId (), GetIpv6Address (dev) + "~" + GetMacAddress (dev), channelType);
1991                 }
1992               continue;
1993             }
1994 
1995           else if (channelType == std::string ("ns3::PointToPointChannel"))
1996             { // Since these are duplex links, we only need to dump
1997               // if srcid < dstid
1998               std::size_t nChDev = ch->GetNDevices ();
1999               for (std::size_t j = 0; j < nChDev; ++j)
2000                 {
2001                   Ptr<NetDevice> chDev = ch->GetDevice (j);
2002                   uint32_t n2Id = chDev->GetNode ()->GetId ();
2003                   if (n1Id < n2Id)
2004                     {
2005 
2006                       std::vector<std::string> ipv4Addresses = GetIpv4Addresses (dev);
2007                       AddToIpv4AddressNodeIdTable (ipv4Addresses, n1Id);
2008                       ipv4Addresses = GetIpv4Addresses (chDev);
2009                       AddToIpv4AddressNodeIdTable (ipv4Addresses, n2Id);
2010                       std::vector<std::string> ipv6Addresses = GetIpv6Addresses (dev);
2011                       AddToIpv6AddressNodeIdTable (ipv6Addresses, n1Id);
2012                       ipv6Addresses = GetIpv6Addresses (chDev);
2013                       AddToIpv6AddressNodeIdTable (ipv6Addresses, n2Id);
2014 
2015                       P2pLinkNodeIdPair p2pPair;
2016                       p2pPair.fromNode = n1Id;
2017                       p2pPair.toNode = n2Id;
2018                       if (!ipv4Addresses.empty ())
2019                         {
2020                           LinkProperties lp = { GetIpv4Address (dev) + "~" + GetMacAddress (dev), GetIpv4Address (chDev) + "~" + GetMacAddress (chDev), "" };
2021                           m_linkProperties[p2pPair] = lp;
2022                         }
2023                       else if (!ipv6Addresses.empty ())
2024                         {
2025                           LinkProperties lp = { GetIpv6Address (dev) + "~" + GetMacAddress (dev), GetIpv6Address (chDev) + "~" + GetMacAddress (chDev), "" };
2026                           m_linkProperties[p2pPair] = lp;
2027                         }
2028                       WriteXmlLink (n1Id, 0, n2Id);
2029                     }
2030                 }
2031             }
2032         }
2033     }
2034   m_linkProperties.clear ();
2035 }
2036 
2037 void
WriteNodes()2038 AnimationInterface::WriteNodes ()
2039 {
2040   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2041     {
2042       Ptr<Node> n = *i;
2043       NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
2044       Vector v = UpdatePosition (n);
2045       WriteXmlNode (n->GetId (), n->GetSystemId (), v.x, v.y);
2046     }
2047 }
2048 
2049 void
WriteNodeColors()2050 AnimationInterface::WriteNodeColors ()
2051 {
2052   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2053     {
2054       Ptr<Node> n = *i;
2055       Rgb rgb = {255, 0, 0};
2056       if (m_nodeColors.find (n->GetId ()) == m_nodeColors.end ())
2057         {
2058           m_nodeColors[n->GetId ()] = rgb;
2059         }
2060       UpdateNodeColor (n, rgb.r, rgb.g, rgb.b);
2061     }
2062 }
2063 
2064 void
WriteNodeSizes()2065 AnimationInterface::WriteNodeSizes ()
2066 {
2067   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2068     {
2069       Ptr<Node> n = *i;
2070       NS_LOG_INFO ("Update Size for Node: " << n->GetId ());
2071       AnimationInterface::NodeSize s = { 1, 1 };
2072       m_nodeSizes[n->GetId ()] = s;
2073       UpdateNodeSize (n->GetId (), s.width, s.height);
2074     }
2075 }
2076 
2077 void
WriteNodeEnergies()2078 AnimationInterface::WriteNodeEnergies ()
2079 {
2080   m_remainingEnergyCounterId = AddNodeCounter ("RemainingEnergy", AnimationInterface::DOUBLE_COUNTER);
2081   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2082     {
2083       Ptr<Node> n = *i;
2084       if (NodeList::GetNode (n->GetId ())->GetObject<EnergySource> ())
2085         {
2086           UpdateNodeCounter (m_remainingEnergyCounterId, n->GetId (), 1);
2087         }
2088     }
2089 }
2090 
2091 bool
IsInTimeWindow()2092 AnimationInterface::IsInTimeWindow ()
2093 {
2094   if ((Simulator::Now () >= m_startTime)
2095       && (Simulator::Now () <= m_stopTime))
2096     {
2097       return true;
2098     }
2099   else
2100     {
2101       return false;
2102     }
2103 }
2104 
2105 void
SetOutputFile(const std::string & fn,bool routing)2106 AnimationInterface::SetOutputFile (const std::string& fn, bool routing)
2107 {
2108   if (!routing && m_f)
2109     {
2110       return;
2111     }
2112   if (routing && m_routingF)
2113     {
2114       NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
2115       return;
2116     }
2117 
2118   NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
2119   FILE * f = 0;
2120   f = std::fopen (fn.c_str (), "w");
2121   if (!f)
2122     {
2123       NS_FATAL_ERROR ("Unable to open output file:" << fn.c_str ());
2124       return; // Can't open output file
2125     }
2126   if (routing)
2127     {
2128       m_routingF = f;
2129       m_routingFileName = fn;
2130     }
2131   else
2132     {
2133       m_f = f;
2134       m_outputFileName = fn;
2135     }
2136   return;
2137 }
2138 
2139 void
CheckMaxPktsPerTraceFile()2140 AnimationInterface::CheckMaxPktsPerTraceFile ()
2141 {
2142   // Start a new trace file if the current packet count exceeded nax packets per file
2143   ++m_currentPktCount;
2144   if (m_currentPktCount <= m_maxPktsPerFile)
2145     {
2146       return;
2147     }
2148   NS_LOG_UNCOND ("Max Packets per trace file exceeded");
2149   StopAnimation (true);
2150 }
2151 
2152 std::string
GetNetAnimVersion()2153 AnimationInterface::GetNetAnimVersion ()
2154 {
2155   return NETANIM_VERSION;
2156 }
2157 
2158 
2159 void
TrackQueueCounters()2160 AnimationInterface::TrackQueueCounters ()
2161 {
2162   if (Simulator::Now () > m_queueCountersStopTime)
2163     {
2164       NS_LOG_INFO ("TrackQueueCounters Completed");
2165       return;
2166     }
2167   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2168     {
2169       uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2170       UpdateNodeCounter (m_queueEnqueueCounterId, nodeId, m_nodeQueueEnqueue[nodeId]);
2171       UpdateNodeCounter (m_queueDequeueCounterId, nodeId, m_nodeQueueDequeue[nodeId]);
2172       UpdateNodeCounter (m_queueDropCounterId, nodeId, m_nodeQueueDrop[nodeId]);
2173     }
2174   Simulator::Schedule (m_queueCountersPollInterval, &AnimationInterface::TrackQueueCounters, this);
2175 }
2176 
2177 void
TrackWifiMacCounters()2178 AnimationInterface::TrackWifiMacCounters ()
2179 {
2180   if (Simulator::Now () > m_wifiMacCountersStopTime)
2181     {
2182       NS_LOG_INFO ("TrackWifiMacCounters Completed");
2183       return;
2184     }
2185   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2186     {
2187       uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2188       UpdateNodeCounter (m_wifiMacTxCounterId, nodeId, m_nodeWifiMacTx[nodeId]);
2189       UpdateNodeCounter (m_wifiMacTxDropCounterId, nodeId, m_nodeWifiMacTxDrop[nodeId]);
2190       UpdateNodeCounter (m_wifiMacRxCounterId, nodeId, m_nodeWifiMacRx[nodeId]);
2191       UpdateNodeCounter (m_wifiMacRxDropCounterId, nodeId, m_nodeWifiMacRxDrop[nodeId]);
2192     }
2193   Simulator::Schedule (m_wifiMacCountersPollInterval, &AnimationInterface::TrackWifiMacCounters, this);
2194 }
2195 
2196 void
TrackWifiPhyCounters()2197 AnimationInterface::TrackWifiPhyCounters ()
2198 {
2199   if (Simulator::Now () > m_wifiPhyCountersStopTime)
2200     {
2201       NS_LOG_INFO ("TrackWifiPhyCounters Completed");
2202       return;
2203     }
2204   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2205     {
2206       uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2207       UpdateNodeCounter (m_wifiPhyTxDropCounterId, nodeId, m_nodeWifiPhyTxDrop[nodeId]);
2208       UpdateNodeCounter (m_wifiPhyRxDropCounterId, nodeId, m_nodeWifiPhyRxDrop[nodeId]);
2209     }
2210   Simulator::Schedule (m_wifiPhyCountersPollInterval, &AnimationInterface::TrackWifiPhyCounters, this);
2211 }
2212 
2213 void
TrackIpv4L3ProtocolCounters()2214 AnimationInterface::TrackIpv4L3ProtocolCounters ()
2215 {
2216   if (Simulator::Now () > m_ipv4L3ProtocolCountersStopTime)
2217     {
2218       NS_LOG_INFO ("TrackIpv4L3ProtocolCounters Completed");
2219       return;
2220     }
2221   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2222     {
2223       uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2224       UpdateNodeCounter (m_ipv4L3ProtocolTxCounterId, nodeId, m_nodeIpv4Tx[nodeId]);
2225       UpdateNodeCounter (m_ipv4L3ProtocolRxCounterId, nodeId, m_nodeIpv4Rx[nodeId]);
2226       UpdateNodeCounter (m_ipv4L3ProtocolDropCounterId, nodeId, m_nodeIpv4Drop[nodeId]);
2227     }
2228   Simulator::Schedule (m_ipv4L3ProtocolCountersPollInterval, &AnimationInterface::TrackIpv4L3ProtocolCounters, this);
2229 }
2230 
2231 
2232 
2233 
2234 
2235 /***** Routing-related *****/
2236 
2237 void
TrackIpv4RoutePaths()2238 AnimationInterface::TrackIpv4RoutePaths ()
2239 {
2240   if (m_ipv4RouteTrackElements.empty ())
2241     {
2242       return;
2243     }
2244   for (std::vector <Ipv4RouteTrackElement>::const_iterator i = m_ipv4RouteTrackElements.begin ();
2245        i != m_ipv4RouteTrackElements.end ();
2246        ++i)
2247     {
2248       Ipv4RouteTrackElement trackElement = *i;
2249       Ptr <Node> fromNode = NodeList::GetNode (trackElement.fromNodeId);
2250       if (!fromNode)
2251         {
2252           NS_FATAL_ERROR ("Node: " << trackElement.fromNodeId << " Not found");
2253           continue;
2254         }
2255       Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
2256       if (!ipv4)
2257         {
2258           NS_LOG_WARN ("ipv4 object not found");
2259           continue;
2260         }
2261       Ptr <Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
2262       if (!rp)
2263         {
2264           NS_LOG_WARN ("Routing protocol object not found");
2265           continue;
2266         }
2267       NS_LOG_INFO ("Begin Track Route for: " << trackElement.destination.c_str () << " From:" << trackElement.fromNodeId);
2268       Ptr<Packet> pkt = Create<Packet> ();
2269       Ipv4Header header;
2270       header.SetDestination (Ipv4Address (trackElement.destination.c_str ()));
2271       Socket::SocketErrno sockerr;
2272       Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
2273       Ipv4RoutePathElements rpElements;
2274       if (!rt)
2275         {
2276           NS_LOG_INFO ("No route to :" << trackElement.destination.c_str ());
2277           Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
2278           rpElements.push_back (elem);
2279           WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
2280           continue;
2281         }
2282       std::ostringstream oss;
2283       oss << rt->GetGateway ();
2284       NS_LOG_INFO ("Node:" << trackElement.fromNodeId << "-->" << rt->GetGateway ());
2285       if (rt->GetGateway () == "0.0.0.0")
2286         {
2287           Ipv4RoutePathElement elem = { trackElement.fromNodeId, "C" };
2288           rpElements.push_back (elem);
2289           if ( m_ipv4ToNodeIdMap.find (trackElement.destination) != m_ipv4ToNodeIdMap.end ())
2290             {
2291               Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[trackElement.destination], "L" };
2292               rpElements.push_back (elem2);
2293             }
2294         }
2295       else if (rt->GetGateway () == "127.0.0.1")
2296         {
2297           Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
2298           rpElements.push_back (elem);
2299         }
2300       else
2301         {
2302           Ipv4RoutePathElement elem = { trackElement.fromNodeId, oss.str () };
2303           rpElements.push_back (elem);
2304         }
2305       RecursiveIpv4RoutePathSearch (oss.str (), trackElement.destination, rpElements);
2306       WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
2307     }
2308 
2309 }
2310 
2311 void
TrackIpv4Route()2312 AnimationInterface::TrackIpv4Route ()
2313 {
2314   if (Simulator::Now () > m_routingStopTime)
2315     {
2316       NS_LOG_INFO ("TrackIpv4Route completed");
2317       return;
2318     }
2319   if (m_routingNc.GetN ())
2320     {
2321       for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
2322         {
2323           Ptr <Node> n = *i;
2324           WriteXmlRouting (n->GetId (), GetIpv4RoutingTable (n));
2325         }
2326     }
2327   else
2328     {
2329       for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2330         {
2331           Ptr <Node> n = *i;
2332           WriteXmlRouting (n->GetId (), GetIpv4RoutingTable (n));
2333         }
2334     }
2335   TrackIpv4RoutePaths ();
2336   Simulator::Schedule (m_routingPollInterval, &AnimationInterface::TrackIpv4Route, this);
2337 }
2338 
2339 std::string
GetIpv4RoutingTable(Ptr<Node> n)2340 AnimationInterface::GetIpv4RoutingTable (Ptr <Node> n)
2341 {
2342 
2343   NS_ASSERT (n);
2344   Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
2345   if (!ipv4)
2346     {
2347       NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
2348       return "";
2349     }
2350   std::stringstream stream;
2351   Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
2352   ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
2353   return stream.str ();
2354 
2355 }
2356 
2357 void
RecursiveIpv4RoutePathSearch(std::string from,std::string to,Ipv4RoutePathElements & rpElements)2358 AnimationInterface::RecursiveIpv4RoutePathSearch (std::string from, std::string to, Ipv4RoutePathElements & rpElements)
2359 {
2360   NS_LOG_INFO ("RecursiveIpv4RoutePathSearch from:" << from.c_str () << " to:" << to.c_str ());
2361   if ((from == "0.0.0.0") || (from == "127.0.0.1"))
2362     {
2363       NS_LOG_INFO ("Got " << from.c_str () << " End recursion");
2364       return;
2365     }
2366   Ptr <Node> fromNode = NodeList::GetNode (m_ipv4ToNodeIdMap[from]);
2367   Ptr <Node> toNode = NodeList::GetNode (m_ipv4ToNodeIdMap[to]);
2368   if (fromNode->GetId () == toNode->GetId ())
2369     {
2370       Ipv4RoutePathElement elem = { fromNode->GetId (), "L" };
2371       rpElements.push_back (elem);
2372       return;
2373     }
2374   if (!fromNode)
2375     {
2376       NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[from] << " Not found");
2377       return;
2378     }
2379   if (!toNode)
2380     {
2381       NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[to] << " Not found");
2382       return;
2383     }
2384   Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
2385   if (!ipv4)
2386     {
2387       NS_LOG_WARN ("ipv4 object not found");
2388       return;
2389     }
2390   Ptr <Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
2391   if (!rp)
2392     {
2393       NS_LOG_WARN ("Routing protocol object not found");
2394       return;
2395     }
2396   Ptr<Packet> pkt = Create<Packet> ();
2397   Ipv4Header header;
2398   header.SetDestination (Ipv4Address (to.c_str ()));
2399   Socket::SocketErrno sockerr;
2400   Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
2401   if (!rt)
2402     {
2403       return;
2404     }
2405   NS_LOG_DEBUG ("Node: " << fromNode->GetId () << " G:" << rt->GetGateway ());
2406   std::ostringstream oss;
2407   oss << rt->GetGateway ();
2408   if (oss.str () == "0.0.0.0" && (sockerr != Socket::ERROR_NOROUTETOHOST))
2409     {
2410       NS_LOG_INFO ("Null gw");
2411       Ipv4RoutePathElement elem = { fromNode->GetId (), "C" };
2412       rpElements.push_back (elem);
2413       if ( m_ipv4ToNodeIdMap.find (to) != m_ipv4ToNodeIdMap.end ())
2414         {
2415           Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[to], "L" };
2416           rpElements.push_back (elem2);
2417         }
2418       return;
2419     }
2420   NS_LOG_INFO ("Node:" << fromNode->GetId () << "-->" << rt->GetGateway ());
2421   Ipv4RoutePathElement elem = { fromNode->GetId (), oss.str () };
2422   rpElements.push_back (elem);
2423   RecursiveIpv4RoutePathSearch (oss.str (), to, rpElements);
2424 
2425 }
2426 
2427 
2428 
2429 /***** WriteXml *****/
2430 
2431 void
WriteXmlAnim(bool routing)2432 AnimationInterface::WriteXmlAnim (bool routing)
2433 {
2434   AnimXmlElement element ("anim");
2435   element.AddAttribute ("ver", GetNetAnimVersion ());
2436   FILE * f = m_f;
2437   if (!routing)
2438     {
2439       element.AddAttribute ("filetype", "animation");
2440     }
2441   else
2442     {
2443       element.AddAttribute ("filetype", "routing");
2444       f = m_routingF;
2445     }
2446   WriteN (element.ToString (false) + ">\n", f);
2447 }
2448 
2449 void
WriteXmlClose(std::string name,bool routing)2450 AnimationInterface::WriteXmlClose (std::string name, bool routing)
2451 {
2452   std::string closeString = "</" + name + ">\n";
2453   if (!routing)
2454     {
2455       WriteN (closeString, m_f);
2456     }
2457   else
2458     {
2459       WriteN (closeString, m_routingF);
2460     }
2461 }
2462 
2463 void
WriteXmlNode(uint32_t id,uint32_t sysId,double locX,double locY)2464 AnimationInterface::WriteXmlNode (uint32_t id, uint32_t sysId, double locX, double locY)
2465 {
2466   AnimXmlElement element ("node");
2467   element.AddAttribute ("id", id);
2468   element.AddAttribute ("sysId", sysId);
2469   element.AddAttribute ("locX", locX);
2470   element.AddAttribute ("locY", locY);
2471   WriteN (element.ToString (), m_f);
2472 }
2473 
2474 void
WriteXmlUpdateLink(uint32_t fromId,uint32_t toId,std::string linkDescription)2475 AnimationInterface::WriteXmlUpdateLink (uint32_t fromId, uint32_t toId, std::string linkDescription)
2476 {
2477   AnimXmlElement element ("linkupdate");
2478   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2479   element.AddAttribute ("fromId", fromId);
2480   element.AddAttribute ("toId", toId);
2481   element.AddAttribute ("ld", linkDescription, true);
2482   WriteN (element.ToString (), m_f);
2483 }
2484 
2485 void
WriteXmlLink(uint32_t fromId,uint32_t toLp,uint32_t toId)2486 AnimationInterface::WriteXmlLink (uint32_t fromId, uint32_t toLp, uint32_t toId)
2487 {
2488   AnimXmlElement element ("link");
2489   element.AddAttribute ("fromId", fromId);
2490   element.AddAttribute ("toId", toId);
2491 
2492   LinkProperties lprop;
2493   lprop.fromNodeDescription = "";
2494   lprop.toNodeDescription = "";
2495   lprop.linkDescription = "";
2496 
2497   P2pLinkNodeIdPair p1 = { fromId, toId };
2498   P2pLinkNodeIdPair p2 = { toId, fromId };
2499   if (m_linkProperties.find (p1) != m_linkProperties.end ())
2500     {
2501       lprop = m_linkProperties[p1];
2502     }
2503   else if (m_linkProperties.find (p2) != m_linkProperties.end ())
2504     {
2505       lprop = m_linkProperties[p2];
2506     }
2507 
2508   element.AddAttribute ("fd", lprop.fromNodeDescription, true);
2509   element.AddAttribute ("td", lprop.toNodeDescription, true);
2510   element.AddAttribute ("ld", lprop.linkDescription, true);
2511   WriteN (element.ToString (), m_f);
2512 }
2513 
2514 void
WriteXmlIpv4Addresses(uint32_t nodeId,std::vector<std::string> ipv4Addresses)2515 AnimationInterface::WriteXmlIpv4Addresses (uint32_t nodeId, std::vector<std::string> ipv4Addresses)
2516 {
2517   AnimXmlElement element ("ip");
2518   element.AddAttribute ("n", nodeId);
2519   for (std::vector<std::string>::const_iterator i = ipv4Addresses.begin ();
2520        i != ipv4Addresses.end ();
2521        ++i)
2522     {
2523       AnimXmlElement valueElement ("address");
2524       valueElement.SetText (*i);
2525       element.AppendChild (valueElement);
2526     }
2527   WriteN (element.ToString (), m_f);
2528 }
2529 
2530 void
WriteXmlIpv6Addresses(uint32_t nodeId,std::vector<std::string> ipv6Addresses)2531 AnimationInterface::WriteXmlIpv6Addresses (uint32_t nodeId, std::vector<std::string> ipv6Addresses)
2532 {
2533   AnimXmlElement element ("ipv6");
2534   element.AddAttribute ("n", nodeId);
2535   for (std::vector<std::string>::const_iterator i = ipv6Addresses.begin ();
2536        i != ipv6Addresses.end ();
2537        ++i)
2538     {
2539       AnimXmlElement valueElement ("address");
2540       valueElement.SetText (*i);
2541       element.AppendChild (valueElement);
2542     }
2543   WriteN (element.ToString (), m_f);
2544 }
2545 
2546 void
WriteXmlRouting(uint32_t nodeId,std::string routingInfo)2547 AnimationInterface::WriteXmlRouting (uint32_t nodeId, std::string routingInfo)
2548 {
2549   AnimXmlElement element ("rt");
2550   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2551   element.AddAttribute ("id", nodeId);
2552   element.AddAttribute ("info", routingInfo.c_str (), true);
2553   WriteN (element.ToString (), m_routingF);
2554 }
2555 
2556 void
WriteXmlRp(uint32_t nodeId,std::string destination,Ipv4RoutePathElements rpElements)2557 AnimationInterface::WriteXmlRp (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
2558 {
2559   std::string tagName = "rp";
2560   AnimXmlElement element (tagName, false);
2561   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2562   element.AddAttribute ("id", nodeId);
2563   element.AddAttribute ("d", destination.c_str ());
2564   element.AddAttribute ("c", rpElements.size ());
2565   for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
2566        i != rpElements.end ();
2567        ++i)
2568     {
2569       Ipv4RoutePathElement rpElement = *i;
2570       AnimXmlElement rpeElement ("rpe");
2571       rpeElement.AddAttribute ("n", rpElement.nodeId);
2572       rpeElement.AddAttribute ("nH", rpElement.nextHop.c_str ());
2573       element.AppendChild (rpeElement);
2574     }
2575   WriteN (element.ToString (),  m_routingF);
2576 }
2577 
2578 
2579 void
WriteXmlPRef(uint64_t animUid,uint32_t fId,double fbTx,std::string metaInfo)2580 AnimationInterface::WriteXmlPRef (uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo)
2581 {
2582   AnimXmlElement element ("pr");
2583   element.AddAttribute ("uId", animUid);
2584   element.AddAttribute ("fId", fId);
2585   element.AddAttribute ("fbTx", fbTx);
2586   if (!metaInfo.empty ())
2587     {
2588       element.AddAttribute ("meta-info", metaInfo.c_str (), true);
2589     }
2590   WriteN (element.ToString (),  m_f);
2591 }
2592 
2593 void
WriteXmlP(uint64_t animUid,std::string pktType,uint32_t tId,double fbRx,double lbRx)2594 AnimationInterface::WriteXmlP (uint64_t animUid, std::string pktType, uint32_t tId, double fbRx, double lbRx)
2595 {
2596   AnimXmlElement element (pktType);
2597   element.AddAttribute ("uId", animUid);
2598   element.AddAttribute ("tId", tId);
2599   element.AddAttribute ("fbRx", fbRx);
2600   element.AddAttribute ("lbRx", lbRx);
2601   WriteN (element.ToString (),  m_f);
2602 }
2603 
2604 void
WriteXmlP(std::string pktType,uint32_t fId,double fbTx,double lbTx,uint32_t tId,double fbRx,double lbRx,std::string metaInfo)2605 AnimationInterface::WriteXmlP (std::string pktType, uint32_t fId, double fbTx, double lbTx,
2606                                uint32_t tId, double fbRx, double lbRx, std::string metaInfo)
2607 {
2608   AnimXmlElement element (pktType);
2609   element.AddAttribute ("fId", fId);
2610   element.AddAttribute ("fbTx", fbTx);
2611   element.AddAttribute ("lbTx", lbTx);
2612   if (!metaInfo.empty ())
2613     {
2614       element.AddAttribute ("meta-info", metaInfo.c_str (), true);
2615     }
2616   element.AddAttribute ("tId", tId);
2617   element.AddAttribute ("fbRx", fbRx);
2618   element.AddAttribute ("lbRx", lbRx);
2619   WriteN (element.ToString (),  m_f);
2620 }
2621 
2622 void
WriteXmlAddNodeCounter(uint32_t nodeCounterId,std::string counterName,CounterType counterType)2623 AnimationInterface::WriteXmlAddNodeCounter (uint32_t nodeCounterId, std::string counterName, CounterType counterType)
2624 {
2625   AnimXmlElement element ("ncs");
2626   element.AddAttribute ("ncId", nodeCounterId);
2627   element.AddAttribute ("n", counterName);
2628   element.AddAttribute ("t", CounterTypeToString (counterType));
2629   WriteN (element.ToString (), m_f);
2630 }
2631 
2632 void
WriteXmlAddResource(uint32_t resourceId,std::string resourcePath)2633 AnimationInterface::WriteXmlAddResource (uint32_t resourceId, std::string resourcePath)
2634 {
2635   AnimXmlElement element ("res");
2636   element.AddAttribute ("rid", resourceId);
2637   element.AddAttribute ("p", resourcePath);
2638   WriteN (element.ToString (), m_f);
2639 }
2640 
2641 void
WriteXmlUpdateNodeImage(uint32_t nodeId,uint32_t resourceId)2642 AnimationInterface::WriteXmlUpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
2643 {
2644   AnimXmlElement element ("nu");
2645   element.AddAttribute ("p", "i");
2646   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2647   element.AddAttribute ("id", nodeId);
2648   element.AddAttribute ("rid", resourceId);
2649   WriteN (element.ToString (), m_f);
2650 }
2651 
2652 void
WriteXmlUpdateNodeSize(uint32_t nodeId,double width,double height)2653 AnimationInterface::WriteXmlUpdateNodeSize (uint32_t nodeId, double width, double height)
2654 {
2655   AnimXmlElement element ("nu");
2656   element.AddAttribute ("p", "s");
2657   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2658   element.AddAttribute ("id", nodeId);
2659   element.AddAttribute ("w", width);
2660   element.AddAttribute ("h", height);
2661   WriteN (element.ToString (),  m_f);
2662 }
2663 
2664 void
WriteXmlUpdateNodePosition(uint32_t nodeId,double x,double y)2665 AnimationInterface::WriteXmlUpdateNodePosition (uint32_t nodeId, double x, double y)
2666 {
2667   AnimXmlElement element ("nu");
2668   element.AddAttribute ("p", "p");
2669   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2670   element.AddAttribute ("id", nodeId);
2671   element.AddAttribute ("x", x);
2672   element.AddAttribute ("y", y);
2673   WriteN (element.ToString (), m_f);
2674 }
2675 
2676 void
WriteXmlUpdateNodeColor(uint32_t nodeId,uint8_t r,uint8_t g,uint8_t b)2677 AnimationInterface::WriteXmlUpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
2678 {
2679   AnimXmlElement element ("nu");
2680   element.AddAttribute ("p", "c");
2681   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2682   element.AddAttribute ("id", nodeId);
2683   element.AddAttribute ("r", (uint32_t) r);
2684   element.AddAttribute ("g", (uint32_t) g);
2685   element.AddAttribute ("b", (uint32_t) b);
2686   WriteN (element.ToString (), m_f);
2687 }
2688 
2689 void
WriteXmlUpdateNodeDescription(uint32_t nodeId)2690 AnimationInterface::WriteXmlUpdateNodeDescription (uint32_t nodeId)
2691 {
2692   AnimXmlElement element ("nu");
2693   element.AddAttribute ("p", "d");
2694   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2695   element.AddAttribute ("id", nodeId);
2696   if (m_nodeDescriptions.find (nodeId) != m_nodeDescriptions.end ())
2697     {
2698       element.AddAttribute ("descr", m_nodeDescriptions[nodeId], true);
2699     }
2700   WriteN (element.ToString (), m_f);
2701 }
2702 
2703 
2704 void
WriteXmlUpdateNodeCounter(uint32_t nodeCounterId,uint32_t nodeId,double counterValue)2705 AnimationInterface::WriteXmlUpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counterValue)
2706 {
2707   AnimXmlElement element ("nc");
2708   element.AddAttribute ("c", nodeCounterId);
2709   element.AddAttribute ("i", nodeId);
2710   element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2711   element.AddAttribute ("v", counterValue);
2712   WriteN (element.ToString (), m_f);
2713 }
2714 
2715 void
WriteXmlUpdateBackground(std::string fileName,double x,double y,double scaleX,double scaleY,double opacity)2716 AnimationInterface::WriteXmlUpdateBackground (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
2717 {
2718   AnimXmlElement element ("bg");
2719   element.AddAttribute ("f", fileName);
2720   element.AddAttribute ("x", x);
2721   element.AddAttribute ("y", y);
2722   element.AddAttribute ("sx", scaleX);
2723   element.AddAttribute ("sy", scaleY);
2724   element.AddAttribute ("o", opacity);
2725   WriteN (element.ToString (), m_f);
2726 }
2727 
2728 void
WriteXmlNonP2pLinkProperties(uint32_t id,std::string ipAddress,std::string channelType)2729 AnimationInterface::WriteXmlNonP2pLinkProperties (uint32_t id, std::string ipAddress, std::string channelType)
2730 {
2731   AnimXmlElement element ("nonp2plinkproperties");
2732   element.AddAttribute ("id", id);
2733   element.AddAttribute ("ipAddress", ipAddress);
2734   element.AddAttribute ("channelType", channelType);
2735   WriteN (element.ToString (), m_f);
2736 }
2737 
2738 
2739 
2740 /***** AnimXmlElement  *****/
2741 
AnimXmlElement(std::string tagName,bool emptyElement)2742 AnimationInterface::AnimXmlElement::AnimXmlElement (std::string tagName, bool emptyElement)
2743   : m_tagName (tagName),
2744     m_text ("")
2745 {
2746 }
2747 
2748 template <typename T>
2749 void
AddAttribute(std::string attribute,T value,bool xmlEscape)2750 AnimationInterface::AnimXmlElement::AddAttribute (std::string attribute, T value, bool xmlEscape)
2751 {
2752   std::ostringstream oss;
2753   oss << std::setprecision (10);
2754   oss << value;
2755   std::string attributeString = attribute.c_str ();
2756   if (xmlEscape)
2757     {
2758       attributeString += "=\"";
2759       std::string valueStr = oss.str ();
2760       for (std::string::iterator it = valueStr.begin (); it != valueStr.end (); ++it)
2761         {
2762           switch (*it)
2763             {
2764             case '&':
2765               attributeString += "&amp;";
2766               break;
2767             case '\"':
2768               attributeString += "&quot;";
2769               break;
2770             case '\'':
2771               attributeString += "&apos;";
2772               break;
2773             case '<':
2774               attributeString += "&lt;";
2775               break;
2776             case '>':
2777               attributeString += "&gt;";
2778               break;
2779             default:
2780               attributeString += *it;
2781               break;
2782             }
2783         }
2784       attributeString += "\" ";
2785     }
2786   else
2787     {
2788       attributeString += "=\"" + oss.str () + "\" ";
2789     }
2790   m_attributes.push_back (attributeString);
2791 }
2792 
2793 void
AppendChild(AnimXmlElement e)2794 AnimationInterface::AnimXmlElement::AppendChild (AnimXmlElement e)
2795 {
2796   m_children.push_back (e.ToString ());
2797 }
2798 
2799 void
SetText(std::string text)2800 AnimationInterface::AnimXmlElement::SetText (std::string text)
2801 {
2802   m_text = text;
2803 }
2804 
2805 std::string
ToString(bool autoClose)2806 AnimationInterface::AnimXmlElement::ToString (bool autoClose)
2807 {
2808   std::string elementString = "<" + m_tagName + " ";
2809 
2810 
2811   for (std::vector<std::string>::const_iterator i = m_attributes.begin ();
2812        i != m_attributes.end ();
2813        ++i)
2814     {
2815       elementString += *i;
2816     }
2817   if (m_children.empty () && m_text.empty ())
2818     {
2819       if (autoClose)
2820         {
2821           elementString += "/>";
2822         }
2823     }
2824   else
2825     {
2826       elementString += ">";
2827       if (!m_text.empty ())
2828         {
2829           elementString += m_text;
2830         }
2831       if (!m_children.empty ())
2832         {
2833           elementString += "\n";
2834           for (std::vector<std::string>::const_iterator i = m_children.begin ();
2835                i != m_children.end ();
2836                ++i)
2837             {
2838               elementString += *i + "\n";
2839             }
2840 
2841         }
2842       if (autoClose)
2843         {
2844           elementString += "</" + m_tagName + ">";
2845         }
2846     }
2847 
2848 
2849   return elementString + ((autoClose) ? "\n" : "");
2850 }
2851 
2852 
2853 
2854 
2855 
2856 /***** AnimByteTag *****/
2857 
2858 TypeId
GetTypeId(void)2859 AnimByteTag::GetTypeId (void)
2860 {
2861   static TypeId tid = TypeId ("ns3::AnimByteTag")
2862     .SetParent<Tag> ()
2863     .SetGroupName ("NetAnim")
2864     .AddConstructor<AnimByteTag> ()
2865   ;
2866   return tid;
2867 }
2868 
2869 TypeId
GetInstanceTypeId(void) const2870 AnimByteTag::GetInstanceTypeId (void) const
2871 {
2872   return GetTypeId ();
2873 }
2874 
2875 uint32_t
GetSerializedSize(void) const2876 AnimByteTag::GetSerializedSize (void) const
2877 {
2878   return sizeof (uint64_t);
2879 }
2880 
2881 void
Serialize(TagBuffer i) const2882 AnimByteTag::Serialize (TagBuffer i) const
2883 {
2884   i.WriteU64 (m_AnimUid);
2885 }
2886 
2887 void
Deserialize(TagBuffer i)2888 AnimByteTag::Deserialize (TagBuffer i)
2889 {
2890   m_AnimUid = i.ReadU64 ();
2891 }
2892 
2893 void
Print(std::ostream & os) const2894 AnimByteTag::Print (std::ostream &os) const
2895 {
2896   os << "AnimUid=" << m_AnimUid;
2897 }
2898 
2899 void
Set(uint64_t AnimUid)2900 AnimByteTag::Set (uint64_t AnimUid)
2901 {
2902   m_AnimUid = AnimUid;
2903 }
2904 
2905 uint64_t
Get(void) const2906 AnimByteTag::Get (void) const
2907 {
2908   return m_AnimUid;
2909 }
2910 
AnimPacketInfo()2911 AnimationInterface::AnimPacketInfo::AnimPacketInfo ()
2912   : m_txnd (0),
2913     m_txNodeId (0),
2914     m_fbTx (0),
2915     m_lbTx (0),
2916     m_lbRx (0)
2917 {
2918 }
2919 
AnimPacketInfo(const AnimPacketInfo & pInfo)2920 AnimationInterface::AnimPacketInfo::AnimPacketInfo (const AnimPacketInfo & pInfo)
2921 {
2922   m_txnd = pInfo.m_txnd;
2923   m_txNodeId = pInfo.m_txNodeId;
2924   m_fbTx = pInfo.m_fbTx;
2925   m_lbTx = pInfo.m_lbTx;
2926   m_lbRx = pInfo.m_lbRx;
2927 }
2928 
AnimPacketInfo(Ptr<const NetDevice> txnd,const Time fbTx,uint32_t txNodeId)2929 AnimationInterface::AnimPacketInfo::AnimPacketInfo (Ptr <const NetDevice> txnd,
2930                                                     const Time fbTx,
2931                                                     uint32_t txNodeId)
2932   : m_txnd (txnd),
2933     m_txNodeId (0),
2934     m_fbTx (fbTx.GetSeconds ()),
2935     m_lbTx (0),
2936     m_lbRx (0)
2937 {
2938   if (!m_txnd)
2939     {
2940       m_txNodeId = txNodeId;
2941     }
2942 }
2943 
2944 void
ProcessRxBegin(Ptr<const NetDevice> nd,const double fbRx)2945 AnimationInterface::AnimPacketInfo::ProcessRxBegin (Ptr<const NetDevice> nd, const double fbRx)
2946 {
2947   Ptr <Node> n = nd->GetNode ();
2948   m_fbRx = fbRx;
2949   m_rxnd = nd;
2950 }
2951 
2952 } // namespace ns3
2953