A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
animation-interface.cc
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  */
19 
20 // Interface between ns3 and the network animator
21 
22 
23 // ns3 includes
24 #include "ns3/animation-interface.h"
25 #include "ns3/channel.h"
26 #include "ns3/config.h"
27 #include "ns3/node.h"
28 #include "ns3/mobility-model.h"
29 #include "ns3/packet.h"
30 #include "ns3/simulator.h"
31 #include "ns3/animation-interface-helper.h"
32 #include "ns3/wifi-mac-header.h"
33 #include "ns3/wimax-mac-header.h"
34 #include "ns3/wifi-net-device.h"
35 #include "ns3/wifi-mac.h"
36 #include "ns3/constant-position-mobility-model.h"
37 #include "ns3/lte-ue-phy.h"
38 #include "ns3/lte-enb-phy.h"
39 #include "ns3/uan-net-device.h"
40 #include "ns3/uan-mac.h"
41 #include "ns3/ipv4.h"
42 #include "ns3/ipv4-routing-protocol.h"
43 
44 #include <cstdio>
45 #include <unistd.h>
46 #include <sstream>
47 #include <fstream>
48 #include <string>
49 #include <iomanip>
50 #include <map>
51 
52 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
53 
54 namespace ns3 {
55 
56 #define PURGE_INTERVAL 5
57 
58 static bool initialized = false;
59 std::map <uint32_t, std::string> AnimationInterface::nodeDescriptions;
60 std::map <uint32_t, Rgb> AnimationInterface::nodeColors;
61 std::map <P2pLinkNodeIdPair, LinkProperties, LinkPairCompare> AnimationInterface::linkProperties;
62 
63 
64 AnimationInterface::AnimationInterface (const std::string fn, uint64_t maxPktsPerFile, bool usingXML)
65  : m_routingF (0), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)),
66  m_outputFileName (fn),
67  m_outputFileSet (false), gAnimUid (0), m_randomPosition (true),
68  m_writeCallback (0), m_started (false),
69  m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
70  m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn),
71  m_routingStopTime (Seconds (0)), m_routingFileName (""),
72  m_routingPollInterval (Seconds (5))
73 {
74  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
75  initialized = true;
76  StartAnimation ();
77 }
78 
80 {
81  StopAnimation ();
82 }
83 
84 AnimationInterface & AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, Time pollInterval)
85 {
86  m_routingFileName = fileName;
87  SetRoutingOutputFile (m_routingFileName);
88  m_routingStopTime = stopTime;
89  m_routingPollInterval = pollInterval;
90  WriteN (GetXMLOpen_anim (0), m_routingF);
91  Simulator::Schedule (startTime, &AnimationInterface::TrackIpv4Route, this);
92  return *this;
93 }
94 
95 AnimationInterface & AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, NodeContainer nc, Time pollInterval)
96 {
97  m_routingNc = nc;
98  return EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
99 }
100 
101 std::string AnimationInterface::GetIpv4RoutingTable (Ptr <Node> n)
102 {
103 
104  NS_ASSERT (n);
105  Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
106  if (!ipv4)
107  {
108  NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
109  return "";
110  }
111  std::stringstream stream;
112  Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
113  ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
114  return stream.str();
115 
116 }
117 
118 void AnimationInterface::RecursiveIpv4RoutePathSearch (std::string from, std::string to, Ipv4RoutePathElements & rpElements)
119 {
120  NS_LOG_INFO ("RecursiveIpv4RoutePathSearch from:" << from.c_str () << " to:" << to.c_str ());
121  if ((from == "0.0.0.0") || (from == "127.0.0.1"))
122  {
123  NS_LOG_INFO ("Got " << from.c_str () << " End recursion");
124  return;
125  }
126  Ptr <Node> fromNode = NodeList::GetNode (m_ipv4ToNodeIdMap[from]);
127  Ptr <Node> toNode = NodeList::GetNode (m_ipv4ToNodeIdMap[to]);
128  if (fromNode->GetId () == toNode->GetId ())
129  {
130  Ipv4RoutePathElement elem = { fromNode->GetId (), "L" };
131  rpElements.push_back (elem);
132  return;
133  }
134  if (!fromNode)
135  {
136  NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[from] << " Not found");
137  return;
138  }
139  if (!toNode)
140  {
141  NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[to] << " Not found");
142  return;
143  }
144  Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
145  if (!ipv4)
146  {
147  NS_LOG_WARN ("ipv4 object not found");
148  return;
149  }
150  Ptr <Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
151  if (!rp)
152  {
153  NS_LOG_WARN ("Routing protocol object not found");
154  return;
155  }
156  Ptr<Packet> pkt = 0;
157  Ipv4Header header;
158  header.SetDestination (Ipv4Address (to.c_str ()));
159  Socket::SocketErrno sockerr;
160  Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
161  if (!rt)
162  {
163  return;
164  }
165  NS_LOG_UNCOND ("Node: " << fromNode->GetId () << " G:" << rt->GetGateway ());
166  std::ostringstream oss;
167  oss << rt->GetGateway ();
168  if (oss.str () == "0.0.0.0" && (sockerr != Socket::ERROR_NOROUTETOHOST))
169  {
170  NS_LOG_INFO ("Null gw");
171  Ipv4RoutePathElement elem = { fromNode->GetId (), "C" };
172  rpElements.push_back (elem);
173  if ( m_ipv4ToNodeIdMap.find (to) != m_ipv4ToNodeIdMap.end ())
174  {
175  Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[to], "L" };
176  rpElements.push_back (elem2);
177  }
178  return;
179  }
180  NS_LOG_INFO ("Node:" << fromNode->GetId () << "-->" << rt->GetGateway ());
181  Ipv4RoutePathElement elem = { fromNode->GetId (), oss.str () };
182  rpElements.push_back (elem);
183  RecursiveIpv4RoutePathSearch (oss.str (), to, rpElements);
184 
185 }
186 
187 void AnimationInterface::TrackIpv4RoutePaths ()
188 {
189  if (m_ipv4RouteTrackElements.empty ())
190  {
191  return;
192  }
193  for (std::vector <Ipv4RouteTrackElement>::const_iterator i = m_ipv4RouteTrackElements.begin ();
194  i != m_ipv4RouteTrackElements.end ();
195  ++i)
196  {
197  Ipv4RouteTrackElement trackElement = *i;
198  Ptr <Node> fromNode = NodeList::GetNode (trackElement.fromNodeId);
199  if (!fromNode)
200  {
201  NS_FATAL_ERROR ("Node: " << trackElement.fromNodeId << " Not found");
202  continue;
203  }
204  Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
205  if (!ipv4)
206  {
207  NS_LOG_WARN ("ipv4 object not found");
208  continue;
209  }
210  Ptr <Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
211  if (!rp)
212  {
213  NS_LOG_WARN ("Routing protocol object not found");
214  continue;
215  }
216  NS_LOG_INFO ("Begin Track Route for: " << trackElement.destination.c_str () << " From:" << trackElement.fromNodeId);
217  Ptr<Packet> pkt = 0;
218  Ipv4Header header;
219  header.SetDestination (Ipv4Address (trackElement.destination.c_str ()));
220  Socket::SocketErrno sockerr;
221  Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
222  if (!rt)
223  {
224  NS_LOG_INFO ("No route to :" << trackElement.destination.c_str ());
225  }
226  std::ostringstream oss;
227  oss << rt->GetGateway ();
228  NS_LOG_INFO ("Node:" << trackElement.fromNodeId << "-->" << rt->GetGateway ());
229  Ipv4RoutePathElements rpElements;
230  if (rt->GetGateway () == "0.0.0.0")
231  {
232  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "C" };
233  rpElements.push_back (elem);
234  if ( m_ipv4ToNodeIdMap.find (trackElement.destination) != m_ipv4ToNodeIdMap.end ())
235  {
236  Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[trackElement.destination], "L" };
237  rpElements.push_back (elem2);
238  }
239  }
240  else if (rt->GetGateway () == "127.0.0.1")
241  {
242  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
243  rpElements.push_back (elem);
244  }
245  else
246  {
247  Ipv4RoutePathElement elem = { trackElement.fromNodeId, oss.str () };
248  rpElements.push_back (elem);
249  }
250  RecursiveIpv4RoutePathSearch (oss.str (), trackElement.destination, rpElements);
251  WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
252  }
253 
254 }
255 
256 void AnimationInterface::TrackIpv4Route ()
257 {
258  if (Simulator::Now () > m_routingStopTime)
259  {
260  NS_LOG_INFO ("TrackIpv4Route completed");
261  return;
262  }
263  if (m_routingNc.GetN ())
264  {
265  for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
266  {
267  Ptr <Node> n = *i;
268  WriteN (GetXMLOpenClose_routing (n->GetId (), GetIpv4RoutingTable (n)), m_routingF);
269  }
270  }
271  else
272  {
273  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
274  {
275  Ptr <Node> n = *i;
276  WriteN (GetXMLOpenClose_routing (n->GetId (), GetIpv4RoutingTable (n)), m_routingF);
277  }
278  }
279  TrackIpv4RoutePaths ();
280  Simulator::Schedule (m_routingPollInterval, &AnimationInterface::TrackIpv4Route, this);
281 }
282 
284 {
285  NS_LOG_INFO ("XML output set");
286  m_xml = true;
287 }
288 
289 
290 void AnimationInterface::StartNewTraceFile ()
291 {
292  static int i = 0;
293  std::ostringstream oss;
294  oss << i;
295  ++m_currentPktCount;
296  if (m_currentPktCount <= m_maxPktsPerFile)
297  {
298  return;
299  }
300  StopAnimation (true);
301  m_outputFileName = m_originalFileName + "-" + oss.str ();
302  StartAnimation (true);
303  ++i;
304 
305 }
306 
307 std::string AnimationInterface::GetNetAnimVersion ()
308 {
309  return "netanim-3.103";
310 }
311 
313 {
314  m_startTime = t;
315 }
316 
318 {
319  m_stopTime = t;
320 }
321 
322 bool AnimationInterface::SetOutputFile (const std::string& fn)
323 {
324  if (m_outputFileSet)
325  {
326  return true;
327  }
328  NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
329  m_f = std::fopen (fn.c_str (), "w");
330  if (!m_f)
331  {
332  NS_FATAL_ERROR ("Unable to open Animation output file");
333  return false; // Can't open
334  }
335  m_outputFileName = fn;
336  m_outputFileSet = true;
337  return true;
338 }
339 
340 bool AnimationInterface::SetRoutingOutputFile (const std::string& fn)
341 {
342  if (m_routingF)
343  {
344  NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
345  return false;
346  }
347  m_routingF = std::fopen (fn.c_str (), "w");
348  if (!m_routingF)
349  {
350  NS_FATAL_ERROR ("Unable to open Animation Routing output file");
351  return false;
352  }
353  return true;
354 }
355 
357 {
358  m_enablePacketMetadata = enable;
359  if (enable)
361 }
362 
364 {
365  return initialized;
366 }
367 
369 {
370  return m_started;
371 
372 }
373 
374 void AnimationInterface::SetAnimWriteCallback (AnimWriteCallback cb)
375 {
376  m_writeCallback = cb;
377 }
378 
380 {
381  m_writeCallback = 0;
382 }
383 
384 bool AnimationInterface::IsInTimeWindow ()
385 {
386  if ((Simulator::Now () >= m_startTime) &&
387  (Simulator::Now () <= m_stopTime))
388  return true;
389  else
390  return false;
391 }
392 
393 bool AnimationInterface::UanPacketIsPending (uint64_t AnimUid)
394 {
395  return (m_pendingUanPackets.find (AnimUid) != m_pendingUanPackets.end ());
396 }
397 
398 bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
399 {
400  return (m_pendingWifiPackets.find (AnimUid) != m_pendingWifiPackets.end ());
401 }
402 
403 bool AnimationInterface::CsmaPacketIsPending (uint64_t AnimUid)
404 {
405  return (m_pendingCsmaPackets.find (AnimUid) != m_pendingCsmaPackets.end ());
406 }
407 
408 
409 bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
410 {
411  return (m_pendingWimaxPackets.find (AnimUid) != m_pendingWimaxPackets.end ());
412 }
413 
414 bool AnimationInterface::LtePacketIsPending (uint64_t AnimUid)
415 {
416  return (m_pendingLtePackets.find (AnimUid) != m_pendingLtePackets.end ());
417 }
418 
420 {
421  m_mobilityPollInterval = t;
422 }
423 
425 {
426  m_randomPosition = setRandPos;
427 }
428 
429 Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
430 {
432  if (loc)
433  {
434  m_nodeLocation[n->GetId ()] = loc->GetPosition ();
435  }
436  else
437  {
438  NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
439  Vector deterministicVector (100,100,0);
440  Vector randomVector (m_uniformRandomVariable->GetValue (0, m_topoMaxX - m_topoMinX), m_uniformRandomVariable->GetValue (0, m_topoMaxY - m_topoMinY), 0);
441  if (m_randomPosition)
442  {
443  m_nodeLocation[n->GetId ()] = randomVector;
444  }
445  else
446  {
447  m_nodeLocation[n->GetId ()] = deterministicVector;
448  }
449  }
450  return m_nodeLocation[n->GetId ()];
451 }
452 
453 Vector AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
454 {
455  m_nodeLocation[n->GetId ()] = v;
456  return v;
457 }
458 
459 Vector AnimationInterface::GetPosition (Ptr <Node> n)
460 {
461  #ifdef NS_LOG
462  if (m_nodeLocation.find (n->GetId()) == m_nodeLocation.end ())
463  {
464  NS_FATAL_ERROR ("Node:" <<n->GetId() << " not found in Location table");
465  }
466  #endif
467  return m_nodeLocation[n->GetId ()];
468 }
469 
470 void AnimationInterface::PurgePendingWifi ()
471 {
472  if (m_pendingWifiPackets.empty ())
473  return;
474  std::vector <uint64_t> purgeList;
475  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWifiPackets.begin ();
476  i != m_pendingWifiPackets.end ();
477  ++i)
478  {
479 
480  AnimPacketInfo pktInfo = i->second;
481  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
482  if (delta > PURGE_INTERVAL)
483  {
484  purgeList.push_back (i->first);
485  }
486  }
487 
488  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
489  i != purgeList.end ();
490  ++i)
491  {
492  m_pendingWifiPackets.erase (*i);
493  }
494 
495 }
496 
497 void AnimationInterface::PurgePendingWimax ()
498 {
499  if (m_pendingWimaxPackets.empty ())
500  return;
501  std::vector <uint64_t> purgeList;
502  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWimaxPackets.begin ();
503  i != m_pendingWimaxPackets.end ();
504  ++i)
505  {
506 
507  AnimPacketInfo pktInfo = i->second;
508  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
509  if (delta > PURGE_INTERVAL)
510  {
511  purgeList.push_back (i->first);
512  }
513  }
514 
515  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
516  i != purgeList.end ();
517  ++i)
518  {
519  m_pendingWimaxPackets.erase (*i);
520  }
521 
522 }
523 
524 
525 void AnimationInterface::PurgePendingLte ()
526 {
527  if (m_pendingLtePackets.empty ())
528  return;
529  std::vector <uint64_t> purgeList;
530  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingLtePackets.begin ();
531  i != m_pendingLtePackets.end ();
532  ++i)
533  {
534 
535  AnimPacketInfo pktInfo = i->second;
536  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
537  if (delta > PURGE_INTERVAL)
538  {
539  purgeList.push_back (i->first);
540  }
541  }
542 
543  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
544  i != purgeList.end ();
545  ++i)
546  {
547  m_pendingLtePackets.erase (*i);
548  }
549 }
550 
551 void AnimationInterface::PurgePendingCsma ()
552 {
553  if (m_pendingCsmaPackets.empty ())
554  return;
555  std::vector <uint64_t> purgeList;
556  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingCsmaPackets.begin ();
557  i != m_pendingCsmaPackets.end ();
558  ++i)
559  {
560 
561  AnimPacketInfo pktInfo = i->second;
562  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
563  if (delta > PURGE_INTERVAL)
564  {
565  purgeList.push_back (i->first);
566  }
567  }
568 
569  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
570  i != purgeList.end ();
571  ++i)
572  {
573  m_pendingCsmaPackets.erase (*i);
574  }
575 
576 }
577 
578 std::string AnimationInterface::GetMacAddress (Ptr <NetDevice> nd)
579 {
580  Address nodeAddr = nd->GetAddress();
581  std::ostringstream oss;
582  oss << nodeAddr;
583  return oss.str ().substr (6); // Skip the first 6 chars to get the Mac
584 }
585 
586 std::string AnimationInterface::GetIpv4Address (Ptr <NetDevice> nd)
587 {
588  Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
589  if (!ipv4)
590  {
591  NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
592  return "0.0.0.0";
593  }
594  int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
595  if (ifIndex == -1)
596  {
597  NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
598  return "0.0.0.0";
599  }
600  Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, 0);
601  std::ostringstream oss;
602  oss << addr.GetLocal ();
603  return oss.str ();
604 }
605 
607 {
608  m_currentPktCount = 0;
609  m_started = true;
610  SetOutputFile (m_outputFileName);
611 
612  // Find the min/max x/y for the xml topology element
613  m_topoMinX = -2;
614  m_topoMinY = -2;
615  m_topoMaxX = 2;
616  m_topoMaxY = 2;
617  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
618  {
619  Ptr<Node> n = *i;
620  NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
621  Vector v = UpdatePosition (n);
622  m_topoMinX = std::min (m_topoMinX, v.x);
623  m_topoMinY = std::min (m_topoMinY, v.y);
624  m_topoMaxX = std::max (m_topoMaxX, v.x);
625  m_topoMaxY = std::max (m_topoMaxY, v.y);
626  struct Rgb rgb = {255, 0, 0};
627  if (nodeColors.find (n->GetId ()) == nodeColors.end ())
628  {
629  nodeColors[n->GetId ()] = rgb;
630  }
631  }
632 
633 
634  std::ostringstream oss;
635  oss << GetXMLOpen_anim (0);
636  oss << GetPreamble ();
637  oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
638  WriteN (oss.str (), m_f);
639  NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
640  // Dump the topology
641  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
642  {
643  Ptr<Node> n = *i;
644  std::ostringstream oss;
645  Vector v = GetPosition (n);
646  struct Rgb rgb = nodeColors[n->GetId ()];
647  oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, rgb);
648  WriteN (oss.str (), m_f);
649  }
650  NS_LOG_INFO ("Setting p2p links");
651  // Now dump the p2p links
652  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
653  {
654  Ptr<Node> n = *i;
655  uint32_t n1Id = n->GetId ();
656  uint32_t nDev = n->GetNDevices (); // Number of devices
657  for (uint32_t i = 0; i < nDev; ++i)
658  {
659  Ptr<NetDevice> dev = n->GetDevice (i);
660  NS_ASSERT (dev);
661  Ptr<Channel> ch = dev->GetChannel ();
662  if (!ch)
663  {
664  NS_LOG_DEBUG ("No channel can't be a p2p device");
665  // Try to see if it is an LTE NetDevice, which does not return a channel
666  if ((dev->GetInstanceTypeId ().GetName () == "ns3::LteUeNetDevice") ||
667  (dev->GetInstanceTypeId ().GetName () == "ns3::LteEnbNetDevice")||
668  (dev->GetInstanceTypeId ().GetName () == "ns3::VirtualNetDevice"))
669  {
670  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), dev->GetInstanceTypeId ().GetName ());
671  AddToIpv4AddressNodeIdTable (GetIpv4Address (dev), n->GetId ());
672  }
673  continue;
674  }
675  std::string channelType = ch->GetInstanceTypeId ().GetName ();
676  NS_LOG_DEBUG ("Got ChannelType" << channelType);
677  if (channelType == std::string ("ns3::PointToPointChannel"))
678  { // Since these are duplex links, we only need to dump
679  // if srcid < dstid
680  uint32_t nChDev = ch->GetNDevices ();
681  for (uint32_t j = 0; j < nChDev; ++j)
682  {
683  Ptr<NetDevice> chDev = ch->GetDevice (j);
684  uint32_t n2Id = chDev->GetNode ()->GetId ();
685  if (n1Id < n2Id)
686  {
687  // ouptut the p2p link
688  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << ":" << GetMacAddress (dev) << "----" << GetIpv4Address (chDev) << ":" << GetMacAddress (chDev) );
689  SetLinkDescription (n1Id, n2Id, "", GetIpv4Address (dev) + "~" + GetMacAddress (dev), GetIpv4Address (chDev) + "~" + GetMacAddress (chDev));
690  AddToIpv4AddressNodeIdTable (GetIpv4Address (dev), n1Id);
691  AddToIpv4AddressNodeIdTable (GetIpv4Address (chDev), n2Id);
692  std::ostringstream oss;
693  if (m_xml)
694  {
695  oss << GetXMLOpenClose_link (0, n1Id, 0, n2Id);
696  }
697  else
698  {
699  oss << "0.0 L " << n1Id << " " << n2Id << std::endl;
700  }
701  WriteN (oss.str (), m_f);
702  }
703  }
704  }
705  else
706  {
707  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << " Channel Type:" << channelType << " Mac: " << GetMacAddress (dev));
708  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
709  AddToIpv4AddressNodeIdTable (GetIpv4Address (dev), n->GetId ());
710  }
711  }
712  }
713  linkProperties.clear ();
714  if (m_xml && !restart)
715  {
716  WriteN (GetXMLClose ("topology"), m_f);
717  Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
718  }
719  if (!restart)
720  ConnectCallbacks ();
721 }
722 
723 void AnimationInterface::AddToIpv4AddressNodeIdTable (std::string ipv4Address, uint32_t nodeId)
724 {
725  m_ipv4ToNodeIdMap[ipv4Address] = nodeId;
726 }
727 
728 AnimationInterface & AnimationInterface::AddSourceDestination (uint32_t fromNodeId, std::string ipv4Address)
729 {
730  Ipv4RouteTrackElement element = { ipv4Address, fromNodeId };
731  m_ipv4RouteTrackElements.push_back (element);
732  return *this;
733 }
734 
735 
736 void AnimationInterface::ConnectLteEnb (Ptr <Node> n, Ptr <LteEnbNetDevice> nd, uint32_t devIndex)
737 {
738 
739  Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy ();
740  Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy ();
741  Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy ();
742  std::ostringstream oss;
743  //NodeList/*/DeviceList/*/
744  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
745  if (dlPhy)
746  {
747  dlPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
748  dlPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
749  }
750  if (ulPhy)
751  {
752  ulPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
753  ulPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
754  }
755 }
756 
757 
758 
759 void AnimationInterface::ConnectLteUe (Ptr <Node> n, Ptr <LteUeNetDevice> nd, uint32_t devIndex)
760 {
761 
762  Ptr<LteUePhy> lteUePhy = nd->GetPhy ();
763  Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy ();
764  Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy ();
765  std::ostringstream oss;
766  //NodeList/*/DeviceList/*/
767  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
768  if (dlPhy)
769  {
770  dlPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
771  dlPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
772  }
773  if (ulPhy)
774  {
775  ulPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
776  ulPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
777  }
778 }
779 
780 void AnimationInterface::ConnectLte ()
781 {
782 
783  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
784  {
785  Ptr<Node> n = *i;
786  NS_ASSERT (n);
787  uint32_t nDevices = n->GetNDevices ();
788  for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
789  {
790  Ptr <NetDevice> nd = n->GetDevice(devIndex);
791  if (!nd)
792  continue;
793  Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice> (nd);
794  if (lteUeNetDevice)
795  {
796  ConnectLteUe (n, lteUeNetDevice, devIndex);
797  continue;
798  }
799  Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice> (nd);
800  if (lteEnbNetDevice)
801  ConnectLteEnb (n, lteEnbNetDevice, devIndex);
802  }
803 
804  }
805 }
806 
807 void AnimationInterface::ConnectCallbacks ()
808 {
809  // Connect the callbacks
810  Config::Connect ("/ChannelList/*/TxRxPointToPoint",
811  MakeCallback (&AnimationInterface::DevTxTrace, this));
812  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
813  MakeCallback (&AnimationInterface::WifiPhyTxBeginTrace, this));
814  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
815  MakeCallback (&AnimationInterface::WifiPhyRxBeginTrace, this));
816  Config::ConnectWithoutContext ("/NodeList/*/$ns3::MobilityModel/CourseChange",
817  MakeCallback (&AnimationInterface::MobilityCourseChangeTrace, this));
818  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
819  MakeCallback (&AnimationInterface::WimaxTxTrace, this));
820  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
821  MakeCallback (&AnimationInterface::WimaxRxTrace, this));
822  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
823  MakeCallback (&AnimationInterface::LteTxTrace, this));
824  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
825  MakeCallback (&AnimationInterface::LteRxTrace, this));
826  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
827  MakeCallback (&AnimationInterface::CsmaPhyTxBeginTrace, this));
828  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
829  MakeCallback (&AnimationInterface::CsmaPhyTxEndTrace, this));
830  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
831  MakeCallback (&AnimationInterface::CsmaPhyRxEndTrace, this));
832  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
833  MakeCallback (&AnimationInterface::CsmaMacRxTrace, this));
834  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
835  MakeCallback (&AnimationInterface::UanPhyGenTxTrace, this));
836  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
837  MakeCallback (&AnimationInterface::UanPhyGenRxTrace, this));
838 
839  ConnectLte ();
840 
841 }
842 
843 
844 void AnimationInterface::StopAnimation (bool onlyAnimation)
845 {
846  m_started = false;
847  NS_LOG_INFO ("Stopping Animation");
849  if (m_f)
850  {
851  if (m_xml)
852  { // Terminate the anim element
853  WriteN (GetXMLClose ("anim"), m_f);
854  }
855  std::fclose (m_f);
856  }
857  m_outputFileSet = false;
858  if (onlyAnimation)
859  {
860  return;
861  }
862  if (m_routingF)
863  {
864  WriteN (GetXMLClose ("anim"), m_routingF);
865  std::fclose (m_routingF);
866  }
867 }
868 
869 int AnimationInterface::WriteN (const std::string& st, FILE * f)
870 {
871  if (m_writeCallback)
872  {
873  m_writeCallback (st.c_str ());
874  }
875  return WriteN (st.c_str (), st.length (), f);
876 }
877 
878 std::vector <Ptr <Node> > AnimationInterface::RecalcTopoBounds ()
879 {
880  std::vector < Ptr <Node> > MovedNodes;
881  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
882  {
883  Ptr<Node> n = *i;
884  NS_ASSERT (n);
885  Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
886  Vector newLocation;
887  if (!mobility)
888  {
889  newLocation = GetPosition (n);
890  }
891  else
892  {
893  newLocation = mobility->GetPosition ();
894  }
895  if (!NodeHasMoved (n, newLocation))
896  {
897  continue; //Location has not changed
898  }
899  else
900  {
901  UpdatePosition (n, newLocation);
902  RecalcTopoBounds (newLocation);
903  MovedNodes.push_back (n);
904  }
905  }
906  return MovedNodes;
907 }
908 
909 void AnimationInterface::RecalcTopoBounds (Vector v)
910 {
911  m_topoMinX = std::min (m_topoMinX, v.x);
912  m_topoMinY = std::min (m_topoMinY, v.y);
913  m_topoMaxX = std::max (m_topoMaxX, v.x);
914  m_topoMaxY = std::max (m_topoMaxY, v.y);
915 
916 }
917 
918 int AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
919 {
920  // Write count bytes to h from data
921  uint32_t nLeft = count;
922  const char* p = data;
923  uint32_t written = 0;
924  while (nLeft)
925  {
926  int n = std::fwrite (p, 1, nLeft, f);
927  if (n <= 0)
928  {
929  return written;
930  }
931  written += n;
932  nLeft -= n;
933  p += n;
934  }
935  return written;
936 }
937 
938 void AnimationInterface::WriteDummyPacket ()
939 {
940  Time now = Simulator::Now ();
941  std::ostringstream oss;
942  double fbTx = now.GetSeconds ();
943  double lbTx = now.GetSeconds ();
944  double fbRx = now.GetSeconds ();
945  double lbRx = now.GetSeconds ();
946  oss << GetXMLOpenClose_p ("p", 0, fbTx, lbTx, 0, fbRx, lbRx, "", "DummyPktIgnoreThis");
947  WriteN (oss.str (), m_f);
948 
949 
950 }
951 
952 void AnimationInterface::WriteRoutePath (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
953 {
954  NS_LOG_INFO ("Writing Route Path From :" << nodeId << " To: " << destination.c_str ());
955  WriteN (GetXMLOpenClose_rp (nodeId, destination, rpElements), m_routingF);
956  /*for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
957  i != rpElements.end ();
958  ++i)
959  {
960  Ipv4RoutePathElement rpElement = *i;
961  NS_LOG_INFO ("Node:" << rpElement.nodeId << "-->" << rpElement.nextHop.c_str ());
962  WriteN (GetXMLOpenClose_rp (rpElement.node, GetIpv4RoutingTable (n)), m_routingF);
963 
964  }
965  */
966 }
967 
968 void AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
969 {
970  std::ostringstream oss;
971  oss << GetXMLOpenClose_NonP2pLinkProperties (id, ipv4Address, channelType);
972  WriteN (oss.str (), m_f);
973 }
974 
975 void AnimationInterface::DevTxTrace (std::string context, Ptr<const Packet> p,
976  Ptr<NetDevice> tx, Ptr<NetDevice> rx,
977  Time txTime, Time rxTime)
978 {
979  if (!m_started || !IsInTimeWindow ())
980  return;
981  NS_ASSERT (tx);
982  NS_ASSERT (rx);
983  Time now = Simulator::Now ();
984  std::ostringstream oss;
985  double fbTx = now.GetSeconds ();
986  double lbTx = (now + txTime).GetSeconds ();
987  double fbRx = (now + rxTime - txTime).GetSeconds ();
988  double lbRx = (now + rxTime).GetSeconds ();
989  if (m_xml)
990  {
991  oss << GetXMLOpenClose_p ("p", tx->GetNode ()->GetId (), fbTx, lbTx, rx->GetNode ()->GetId (),
992  fbRx, lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
993  StartNewTraceFile ();
994  ++m_currentPktCount;
995  }
996  else
997  {
998  oss << std::setprecision (10);
999  oss << now.GetSeconds () << " P "
1000  << tx->GetNode ()->GetId () << " "
1001  << rx->GetNode ()->GetId () << " "
1002  << (now + txTime).GetSeconds () << " " // last bit tx time
1003  << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time
1004  << (now + rxTime).GetSeconds () << std::endl; // last bit rx time
1005  }
1006  WriteN (oss.str (), m_f);
1007 }
1008 
1009 
1010 Ptr <NetDevice>
1011 AnimationInterface::GetNetDeviceFromContext (std::string context)
1012 {
1013  // Use "NodeList/*/DeviceList/*/ as reference
1014  // where element [1] is the Node Id
1015  // element [2] is the NetDevice Id
1016 
1017  std::vector <std::string> elements = GetElementsFromContext (context);
1018  Ptr <Node> n = NodeList::GetNode (atoi (elements[1].c_str ()));
1019  NS_ASSERT (n);
1020  return n->GetDevice (atoi (elements[3].c_str ()));
1021 }
1022 
1023 void AnimationInterface::AddPendingUanPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
1024 {
1025  m_pendingUanPackets[AnimUid] = pktinfo;
1026 }
1027 
1028 
1029 void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
1030 {
1031  m_pendingWifiPackets[AnimUid] = pktinfo;
1032 }
1033 
1034 void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
1035 {
1036  NS_ASSERT (pktinfo.m_txnd);
1037  m_pendingWimaxPackets[AnimUid] = pktinfo;
1038 }
1039 
1040 void AnimationInterface::AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
1041 {
1042  NS_ASSERT (pktinfo.m_txnd);
1043  m_pendingLtePackets[AnimUid] = pktinfo;
1044 }
1045 
1046 void AnimationInterface::AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
1047 {
1048  NS_ASSERT (pktinfo.m_txnd);
1049  m_pendingCsmaPackets[AnimUid] = pktinfo;
1050 }
1051 
1052 uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
1053 {
1054  AnimByteTag tag;
1055  TypeId tid = tag.GetInstanceTypeId ();
1056  ByteTagIterator i = p->GetByteTagIterator ();
1057  bool found = false;
1058  while (i.HasNext ())
1059  {
1060  ByteTagIterator::Item item = i.Next ();
1061  if (tid == item.GetTypeId ())
1062  {
1063  item.GetTag (tag);
1064  found = true;
1065  }
1066  }
1067  if (found)
1068  {
1069  return tag.Get ();
1070  }
1071  else
1072  {
1073  return 0;
1074  }
1075 }
1076 
1077 void AnimationInterface::UanPhyGenTxTrace (std::string context, Ptr<const Packet> p)
1078 {
1079  if (!m_started || !IsInTimeWindow ())
1080  return;
1081  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1082  NS_ASSERT (ndev);
1083  Ptr <Node> n = ndev->GetNode ();
1084  NS_ASSERT (n);
1085  gAnimUid++;
1086  NS_LOG_INFO ("Uan TxBeginTrace for packet:" << gAnimUid);
1087  AnimByteTag tag;
1088  tag.Set (gAnimUid);
1089  p->AddByteTag (tag);
1090  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1091  AddPendingUanPacket (gAnimUid, pktinfo);
1092 
1093 
1094 }
1095 
1096 void AnimationInterface::UanPhyGenRxTrace (std::string context, Ptr<const Packet> p)
1097 {
1098  if (!m_started || !IsInTimeWindow ())
1099  return;
1100  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1101  NS_ASSERT (ndev);
1102  Ptr <Node> n = ndev->GetNode ();
1103  NS_ASSERT (n);
1104  uint64_t AnimUid = GetAnimUidFromPacket (p);
1105  NS_LOG_INFO ("UanPhyGenRxTrace for packet:" << AnimUid);
1106  if (!UanPacketIsPending (AnimUid))
1107  {
1108  NS_LOG_WARN ("UanPhyGenRxBeginTrace: unknown Uid");
1109  return;
1110  }
1111  m_pendingUanPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
1112  m_pendingUanPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1113  OutputWirelessPacket (p, m_pendingUanPackets[AnimUid], m_pendingUanPackets[AnimUid].GetRxInfo (ndev));
1114 
1115 }
1116 
1117 
1118 void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
1119  Ptr<const Packet> p)
1120 {
1121  if (!m_started || !IsInTimeWindow ())
1122  return;
1123  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1124  NS_ASSERT (ndev);
1125  Ptr <Node> n = ndev->GetNode ();
1126  NS_ASSERT (n);
1127  // Add a new pending wireless
1128  gAnimUid++;
1129  NS_LOG_INFO ("Wifi TxBeginTrace for packet:" << gAnimUid);
1130  AnimByteTag tag;
1131  tag.Set (gAnimUid);
1132  p->AddByteTag (tag);
1133  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1134  AddPendingWifiPacket (gAnimUid, pktinfo);
1135  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
1136  Mac48Address nodeAddr = netDevice->GetMac()->GetAddress();
1137  std::ostringstream oss;
1138  oss << nodeAddr;
1139  m_macToNodeIdMap[oss.str ()] = n->GetId ();
1140  NS_LOG_INFO ("Added Mac" << oss.str () << " node:" <<m_macToNodeIdMap[oss.str ()]);
1141 }
1142 
1143 void AnimationInterface::WifiPhyTxEndTrace (std::string context,
1144  Ptr<const Packet> p)
1145 {
1146 }
1147 
1148 void AnimationInterface::WifiPhyTxDropTrace (std::string context,
1149  Ptr<const Packet> p)
1150 {
1151  if (!m_started || !IsInTimeWindow ())
1152  return;
1153  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1154  NS_ASSERT (ndev);
1155  // Erase pending wifi
1156  uint64_t AnimUid = GetAnimUidFromPacket (p);
1157  NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
1158  NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1159  m_pendingWifiPackets.erase (m_pendingWifiPackets.find (AnimUid));
1160 }
1161 
1162 
1163 void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
1164  Ptr<const Packet> p)
1165 {
1166  if (!m_started || !IsInTimeWindow ())
1167  return;
1168  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1169  NS_ASSERT (ndev);
1170  Ptr <Node> n = ndev->GetNode ();
1171  NS_ASSERT (n);
1172  uint64_t AnimUid = GetAnimUidFromPacket (p);
1173  NS_LOG_INFO ("Wifi RxBeginTrace for packet:" << AnimUid);
1174  if (!WifiPacketIsPending (AnimUid))
1175  {
1176  NS_LOG_WARN ("WifiPhyRxBeginTrace: unknown Uid");
1177  std::ostringstream oss;
1178  WifiMacHeader hdr;
1179  if(!p->PeekHeader (hdr))
1180  {
1181  NS_LOG_WARN ("WifiMacHeader not present");
1182  return;
1183  }
1184  oss << hdr.GetAddr2 ();
1185  if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
1186  {
1187  //NS_LOG_UNCOND (oss.str ());
1188  return;
1189  }
1190  Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
1191  AnimPacketInfo pktinfo (0, Simulator::Now (), Simulator::Now (), UpdatePosition (txNode), m_macToNodeIdMap[oss.str ()]);
1192  AddPendingWifiPacket (AnimUid, pktinfo);
1193  NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
1194  }
1195  // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1196  m_pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
1197  m_pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1198  OutputWirelessPacket (p, m_pendingWifiPackets[AnimUid], m_pendingWifiPackets[AnimUid].GetRxInfo (ndev));
1199 }
1200 
1201 
1202 void AnimationInterface::WifiPhyRxEndTrace (std::string context,
1203  Ptr<const Packet> p)
1204 {
1205  if (!m_started || !IsInTimeWindow ())
1206  return;
1207  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1208  NS_ASSERT (ndev);
1209  Ptr <Node> n = ndev->GetNode ();
1210  NS_ASSERT (n);
1211  uint64_t AnimUid = GetAnimUidFromPacket (p);
1212  if (!WifiPacketIsPending (AnimUid))
1213  {
1214  NS_LOG_WARN ("WifiPhyRxEndTrace: unknown Uid");
1215  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1216  AddPendingWifiPacket (AnimUid, pktinfo);
1217  }
1218  // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1219  AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
1220  pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1221  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1222  if (pktrxInfo.IsPhyRxComplete ())
1223  {
1224  NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
1225  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1226  }
1227 }
1228 
1229 void AnimationInterface::WifiMacRxTrace (std::string context,
1230  Ptr<const Packet> p)
1231 {
1232  if (!m_started || !IsInTimeWindow ())
1233  return;
1234  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1235  NS_ASSERT (ndev);
1236  Ptr <Node> n = ndev->GetNode ();
1237  NS_ASSERT (n);
1238  uint64_t AnimUid = GetAnimUidFromPacket (p);
1239  if (!WifiPacketIsPending (AnimUid))
1240  {
1241  NS_LOG_WARN ("WifiMacRxTrace: unknown Uid");
1242  return;
1243  }
1244  // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1245  AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
1246  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1247  if (pktrxInfo.IsPhyRxComplete ())
1248  {
1249  NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
1250  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1251  }
1252 
1253 }
1254 void AnimationInterface::WifiPhyRxDropTrace (std::string context,
1255  Ptr<const Packet> p)
1256 {
1257 }
1258 
1259 void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1260 {
1261  if (!m_started || !IsInTimeWindow ())
1262  return;
1263  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1264  NS_ASSERT (ndev);
1265  Ptr <Node> n = ndev->GetNode ();
1266  NS_ASSERT (n);
1267  gAnimUid++;
1268  NS_LOG_INFO ("WimaxTxTrace for packet:" << gAnimUid);
1269  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1270  //TODO 0.0001 is used until Wimax implements TxBegin and TxEnd traces
1271  AnimByteTag tag;
1272  tag.Set (gAnimUid);
1273  p->AddByteTag (tag);
1274  AddPendingWimaxPacket (gAnimUid, pktinfo);
1275 }
1276 
1277 
1278 void AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1279 {
1280  if (!m_started || !IsInTimeWindow ())
1281  return;
1282  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1283  NS_ASSERT (ndev);
1284  Ptr <Node> n = ndev->GetNode ();
1285  NS_ASSERT (n);
1286  uint64_t AnimUid = GetAnimUidFromPacket (p);
1287  NS_LOG_INFO ("WimaxRxTrace for packet:" << AnimUid);
1288  NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
1289  AnimPacketInfo& pktInfo = m_pendingWimaxPackets[AnimUid];
1290  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
1291  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1292  //TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
1293  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1294  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1295 }
1296 
1297 void AnimationInterface::LteTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1298 {
1299  if (!m_started || !IsInTimeWindow ())
1300  return;
1301  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1302  NS_ASSERT (ndev);
1303  Ptr <Node> n = ndev->GetNode ();
1304  NS_ASSERT (n);
1305  gAnimUid++;
1306  NS_LOG_INFO ("LteTxTrace for packet:" << gAnimUid);
1307  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1308  //TODO 0.0001 is used until Lte implements TxBegin and TxEnd traces
1309  AnimByteTag tag;
1310  tag.Set (gAnimUid);
1311  p->AddByteTag (tag);
1312  AddPendingLtePacket (gAnimUid, pktinfo);
1313 }
1314 
1315 
1316 void AnimationInterface::LteRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1317 {
1318  if (!m_started || !IsInTimeWindow ())
1319  return;
1320  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1321  NS_ASSERT (ndev);
1322  Ptr <Node> n = ndev->GetNode ();
1323  NS_ASSERT (n);
1324  uint64_t AnimUid = GetAnimUidFromPacket (p);
1325  NS_LOG_INFO ("LteRxTrace for packet:" << gAnimUid);
1326  if (!LtePacketIsPending (AnimUid))
1327  {
1328  NS_LOG_WARN ("LteRxTrace: unknown Uid");
1329  return;
1330  }
1331  AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
1332  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
1333  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1334  //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
1335  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1336  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1337 }
1338 
1339 void AnimationInterface::LteSpectrumPhyTxStart (std::string context, Ptr<const PacketBurst> pb)
1340 {
1341  if (!m_started || !IsInTimeWindow ())
1342  return;
1343  if (!pb)
1344  {
1345  NS_LOG_WARN ("pb == 0. Not yet supported");
1346  return;
1347  }
1348  context = "/" + context;
1349  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1350  NS_ASSERT (ndev);
1351  Ptr <Node> n = ndev->GetNode ();
1352  NS_ASSERT (n);
1353 
1354  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1355  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
1356  i != pbList.end ();
1357  ++i)
1358  {
1359  Ptr <Packet> p = *i;
1360  gAnimUid++;
1361  NS_LOG_INFO ("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
1362  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1363  //TODO 0.0001 is used until Lte implements TxBegin and TxEnd traces
1364  AnimByteTag tag;
1365  tag.Set (gAnimUid);
1366  p->AddByteTag (tag);
1367  AddPendingLtePacket (gAnimUid, pktinfo);
1368  }
1369 }
1370 
1371 void AnimationInterface::LteSpectrumPhyRxStart (std::string context, Ptr<const PacketBurst> pb)
1372 {
1373  if (!m_started || !IsInTimeWindow ())
1374  return;
1375  if (!pb)
1376  {
1377  NS_LOG_WARN ("pb == 0. Not yet supported");
1378  return;
1379  }
1380  context = "/" + context;
1381  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1382  NS_ASSERT (ndev);
1383  Ptr <Node> n = ndev->GetNode ();
1384  NS_ASSERT (n);
1385 
1386  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1387  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
1388  i != pbList.end ();
1389  ++i)
1390  {
1391  Ptr <Packet> p = *i;
1392  uint64_t AnimUid = GetAnimUidFromPacket (p);
1393  NS_LOG_INFO ("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
1394  if (!LtePacketIsPending (AnimUid))
1395  {
1396  NS_LOG_WARN ("LteSpectrumPhyRxTrace: unknown Uid");
1397  return;
1398  }
1399  AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
1400  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
1401  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1402  //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
1403  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1404  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1405  }
1406 }
1407 
1408 void AnimationInterface::CsmaPhyTxBeginTrace (std::string context, Ptr<const Packet> p)
1409 {
1410  if (!m_started || !IsInTimeWindow ())
1411  return;
1412  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1413  NS_ASSERT (ndev);
1414  Ptr <Node> n = ndev->GetNode ();
1415  NS_ASSERT (n);
1416  gAnimUid++;
1417  NS_LOG_INFO ("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
1418  AnimByteTag tag;
1419  tag.Set (gAnimUid);
1420  p->AddByteTag (tag);
1421  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1422  AddPendingCsmaPacket (gAnimUid, pktinfo);
1423 
1424 }
1425 
1426 void AnimationInterface::CsmaPhyTxEndTrace (std::string context, Ptr<const Packet> p)
1427 {
1428  if (!m_started || !IsInTimeWindow ())
1429  return;
1430  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1431  NS_ASSERT (ndev);
1432  Ptr <Node> n = ndev->GetNode ();
1433  NS_ASSERT (n);
1434  uint64_t AnimUid = GetAnimUidFromPacket (p);
1435  NS_LOG_INFO ("CsmaPhyTxEndTrace for packet:" << AnimUid);
1436  if (!CsmaPacketIsPending (AnimUid))
1437  {
1438  NS_LOG_WARN ("CsmaPhyTxEndTrace: unknown Uid");
1439  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1440  AddPendingCsmaPacket (AnimUid, pktinfo);
1441  NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
1442  }
1443  // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1444  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
1445  pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
1446 }
1447 
1448 void AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
1449 {
1450  if (!m_started || !IsInTimeWindow ())
1451  return;
1452  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1453  NS_ASSERT (ndev);
1454  Ptr <Node> n = ndev->GetNode ();
1455  NS_ASSERT (n);
1456  uint64_t AnimUid = GetAnimUidFromPacket (p);
1457  if (!CsmaPacketIsPending (AnimUid))
1458  {
1459  NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid");
1460  return;
1461  }
1462  // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1463  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
1464  m_pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
1465  pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1466  NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << AnimUid);
1467 }
1468 
1469 
1470 void AnimationInterface::CsmaMacRxTrace (std::string context,
1471  Ptr<const Packet> p)
1472 {
1473  if (!m_started || !IsInTimeWindow ())
1474  return;
1475  NS_LOG_FUNCTION (this);
1476  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1477  NS_ASSERT (ndev);
1478  Ptr <Node> n = ndev->GetNode ();
1479  NS_ASSERT (n);
1480  uint64_t AnimUid = GetAnimUidFromPacket (p);
1481  if (!CsmaPacketIsPending (AnimUid))
1482  {
1483  NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid");
1484  return;
1485  }
1486  // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1487  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
1488  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1489  if (pktrxInfo.IsPhyRxComplete ())
1490  {
1491  NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
1492  OutputCsmaPacket (p, pktInfo, pktrxInfo);
1493  }
1494 }
1495 
1496 
1497 void AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
1498 
1499 {
1500  if (!m_started || !IsInTimeWindow ())
1501  return;
1502  Ptr <Node> n = mobility->GetObject <Node> ();
1503  NS_ASSERT (n);
1504  Vector v ;
1505  if (!mobility)
1506  {
1507  v = GetPosition (n);
1508  }
1509  else
1510  {
1511  v = mobility->GetPosition ();
1512  }
1513  UpdatePosition (n,v);
1514  RecalcTopoBounds (v);
1515  std::ostringstream oss;
1516  oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
1517  oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, nodeColors[n->GetId ()]);
1518  oss << GetXMLClose ("topology");
1519  WriteN (oss.str (), m_f);
1520  WriteDummyPacket ();
1521 }
1522 
1523 bool AnimationInterface::NodeHasMoved (Ptr <Node> n, Vector newLocation)
1524 {
1525  Vector oldLocation = GetPosition (n);
1526  if ((ceil (oldLocation.x) == ceil (newLocation.x)) &&
1527  (ceil (oldLocation.y) == ceil (newLocation.y)))
1528  {
1529 
1530  return false;
1531  }
1532  else
1533  {
1534  return true;
1535  }
1536 }
1537 
1538 void AnimationInterface::MobilityAutoCheck ()
1539 {
1540  if (!m_started || !IsInTimeWindow ())
1541  return;
1542  std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
1543  std::ostringstream oss;
1544  oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
1545  for (uint32_t i = 0; i < MovedNodes.size (); i++)
1546  {
1547  Ptr <Node> n = MovedNodes [i];
1548  NS_ASSERT (n);
1549  Vector v = GetPosition (n);
1550  oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
1551  }
1552  oss << GetXMLClose ("topology");
1553  WriteN (oss.str (), m_f);
1554  WriteDummyPacket ();
1555  if (!Simulator::IsFinished ())
1556  {
1557  PurgePendingWifi ();
1558  PurgePendingWimax ();
1559  PurgePendingLte ();
1560  PurgePendingCsma ();
1561  Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
1562  }
1563 }
1564 
1565 std::string AnimationInterface::GetPacketMetadata (Ptr<const Packet> p)
1566 {
1567  std::ostringstream oss;
1568  p->Print (oss);
1569  return oss.str ();
1570 }
1571 
1573 {
1574  return m_currentPktCount;
1575 }
1576 
1577 int64_t
1579 {
1580  NS_LOG_FUNCTION (this << stream);
1582  return 1;
1583 }
1584 
1585 // Helper to output a wireless packet.
1586 // For now, only the XML interface is supported
1587 
1588 
1589 std::string AnimationInterface::GetPreamble ()
1590 {
1591  std::string s =
1592  "<information><!-- \n\
1593  Description of attributes:\n\
1594  =========================\n\
1595  anim\n\
1596  * ver = Current version\n\
1597  topology\n\
1598  * minX = minimum X coordinate of the canvas\n\
1599  * minY = minimum Y coordinate of the canvas\n\
1600  * maxX = maximum X coordinate of the canvas\n\
1601  * maxY = maximum Y coordinate of the canvas\n\
1602  node\n\
1603  * id = Node Id\n\
1604  * locX = X coordinate\n\
1605  * locY = Y coordinate\n\
1606  * r = Red component\n\
1607  * g = Green component\n\
1608  * b = Blue component\n\
1609  link\n\
1610  * fromId = From Node Id\n\
1611  * toId = To Node Id\n\
1612  * fd = From Node description (for IP Address)\n\
1613  * td = To Node description (for IP Address)\n\
1614  * ld = Link description (for Bandwidth, delay etc)\n\
1615  linkupdate\n\
1616  * t = Simulation time\n\
1617  * ld = Link description (for Bandwidth, delay etc)\n\
1618  nodeupdate\n\
1619  * t = Simulation time\n\
1620  * descr = Node description\n\
1621  * r = Red component\n\
1622  * g = Green component\n\
1623  * b = Blue component\n\
1624  * visible = Node visibility\n\
1625  p\n\
1626  * fId = From Node Id\n\
1627  * fbTx = First bit transmit time\n\
1628  * lbTx = Last bit transmit time\n\
1629  * tId = To Node Id\n\
1630  * fbRx = First bit Rx Time\n\
1631  * lbRx = Last bit Rx\n\
1632  * meta-info = Packet meta data\n\
1633  wp\n\
1634  * fId = From Node Id\n\
1635  * fbTx = First bit transmit time\n\
1636  * lbTx = Last bit transmit time\n\
1637  * range = Reception range\n\
1638  * tId = To Node Id\n\
1639  * fbRx = First bit Rx time\n\
1640  * meta-info = Packet meta data\n\
1641  * lbRx = Last bit Rx time-->\n\
1642  </information>\n";
1643 return s;
1644 }
1645 
1646 void AnimationInterface::OutputWirelessPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
1647 {
1648  StartNewTraceFile ();
1649  NS_ASSERT (m_xml);
1650  std::ostringstream oss;
1651  uint32_t nodeId = 0;
1652  if (pktInfo.m_txnd)
1653  nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1654  else
1655  nodeId = pktInfo.m_txNodeId;
1656 
1657  double lbTx = pktInfo.firstlastbitDelta + pktInfo.m_fbTx;
1658  uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId ();
1659 
1660  oss << GetXMLOpenClose_p ("wp", nodeId, pktInfo.m_fbTx, lbTx, rxId,
1661  pktrxInfo.m_fbRx, pktrxInfo.m_lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
1662  WriteN (oss.str (), m_f);
1663 }
1664 
1665 void AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
1666 {
1667  StartNewTraceFile ();
1668  NS_ASSERT (m_xml);
1669  std::ostringstream oss;
1670  NS_ASSERT (pktInfo.m_txnd);
1671  uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1672  uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId ();
1673 
1674  oss << GetXMLOpenClose_p ("p", nodeId, pktInfo.m_fbTx, pktInfo.m_lbTx, rxId,
1675  pktrxInfo.m_fbRx, pktrxInfo.m_lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
1676  WriteN (oss.str (), m_f);
1677 }
1678 
1679 void AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
1680 {
1681  NS_ASSERT (n);
1683  if (hubLoc == 0)
1684  {
1685  hubLoc = CreateObject<ConstantPositionMobilityModel> ();
1686  n->AggregateObject (hubLoc);
1687  }
1688  Vector hubVec (x, y, z);
1689  hubLoc->SetPosition (hubVec);
1690  NS_LOG_INFO ("Node:" << n->GetId () << " Position set to:(" << x << "," << y << "," << z << ")");
1691 
1692 }
1693 
1694 void AnimationInterface::SetNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
1695 {
1696  if (initialized)
1697  NS_FATAL_ERROR ("SetNodeColor must be used prior to creating the AnimationInterface object");
1698  NS_ASSERT (n);
1699  NS_LOG_INFO ("Setting node color for Node Id:" << n->GetId ());
1700  struct Rgb rgb = {r, g, b};
1701  nodeColors[n->GetId ()] = rgb;
1702 }
1703 
1704 void AnimationInterface::ShowNode (uint32_t nodeId, bool show)
1705 {
1706  NS_ASSERT (NodeList::GetNode (nodeId));
1707  NS_LOG_INFO ("Setting node visibility for Node Id:" << nodeId);
1708  std::ostringstream oss;
1709  oss << GetXMLOpenClose_nodeupdate (nodeId, show);
1710  WriteN (oss.str (), m_f);
1711 
1712 }
1713 
1715 {
1716  ShowNode (n, show);
1717 }
1718 
1719 void AnimationInterface::UpdateNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
1720 {
1721  UpdateNodeColor (n->GetId (), r, g, b);
1722 }
1723 
1724 void AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
1725 {
1726  NS_ASSERT (NodeList::GetNode (nodeId));
1727  NS_LOG_INFO ("Setting node color for Node Id:" << nodeId);
1728  struct Rgb rgb = {r, g, b};
1729  nodeColors[nodeId] = rgb;
1730  std::ostringstream oss;
1731  oss << GetXMLOpenClose_nodeupdate (nodeId);
1732  WriteN (oss.str (), m_f);
1733 }
1734 
1735 
1736 
1737 void AnimationInterface::SetNodeColor (NodeContainer nc, uint8_t r, uint8_t g, uint8_t b)
1738 {
1739  for (uint32_t i = 0; i < nc.GetN (); ++i)
1740  {
1741  Ptr <Node> n = nc.Get (i);
1742  NS_ASSERT (n);
1743  SetNodeColor (n, r, g, b);
1744  }
1745 }
1746 
1747 
1748 void AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNode,
1749  std::string linkDescription)
1750 {
1751  std::ostringstream oss;
1752  oss << GetXMLOpenClose_linkupdate (fromNode, toNode, linkDescription);
1753  WriteN (oss.str (), m_f);
1754 }
1755 
1757  std::string linkDescription)
1758 {
1759  NS_ASSERT (fromNode);
1760  NS_ASSERT (toNode);
1761  std::ostringstream oss;
1762  oss << GetXMLOpenClose_linkupdate (fromNode->GetId (), toNode->GetId (), linkDescription);
1763  WriteN (oss.str (), m_f);
1764 }
1765 
1766 void AnimationInterface::SetLinkDescription (uint32_t fromNode, uint32_t toNode,
1767  std::string linkDescription,
1768  std::string fromNodeDescription,
1769  std::string toNodeDescription)
1770 {
1771 
1772  P2pLinkNodeIdPair p2pPair;
1773  p2pPair.fromNode = fromNode;
1774  p2pPair.toNode = toNode;
1775  LinkProperties lp = { fromNodeDescription, toNodeDescription, linkDescription };
1776  linkProperties[p2pPair] = lp;
1777  /* DEBUG */
1778  /*
1779  for (std::map <P2pLinkNodeIdPair, LinkProperties>::const_iterator i = linkProperties.begin ();
1780  i != linkProperties.end(); ++i)
1781  {
1782  P2pLinkNodeIdPair ppair = i->first;
1783  LinkProperties l = i->second;
1784  NS_LOG_UNCOND ("A:" << ppair.fromNode << " B:" << ppair.toNode << " ad:" << l.fromNodeDescription << " bd:" << l.toNodeDescription << " ld:" << l.linkDescription);
1785 
1786  }
1787  */
1788 }
1789 
1791  std::string linkDescription,
1792  std::string fromNodeDescription,
1793  std::string toNodeDescription)
1794 {
1795  NS_ASSERT (fromNode);
1796  NS_ASSERT (toNode);
1797  SetLinkDescription (fromNode->GetId (), toNode->GetId (), linkDescription, fromNodeDescription, toNodeDescription);
1798 }
1799 
1800 
1802 {
1803  if (initialized)
1804  NS_FATAL_ERROR ("SetNodeDescription must be used prior to creating the AnimationInterface object");
1805  NS_ASSERT (n);
1806  nodeDescriptions[n->GetId ()] = descr;
1807 }
1808 
1810 {
1811  UpdateNodeDescription (n->GetId (), descr);
1812 }
1813 
1814 void AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string descr)
1815 {
1816  NS_ASSERT (NodeList::GetNode (nodeId));
1817  nodeDescriptions[nodeId] = descr;
1818  std::ostringstream oss;
1819  oss << GetXMLOpenClose_nodeupdate (nodeId);
1820  WriteN (oss.str (), m_f);
1821 }
1822 
1823 
1824 
1826 {
1827  if (initialized)
1828  NS_FATAL_ERROR ("SetNodeDescription must be used prior to creating the AnimationInterface object");
1829  for (uint32_t i = 0; i < nc.GetN (); ++i)
1830  {
1831  Ptr <Node> n = nc.Get (i);
1832  NS_ASSERT (n);
1833  nodeDescriptions[n->GetId ()] = descr;
1834  }
1835 }
1836 
1837 
1838 // XML Private Helpers
1839 
1840 std::string AnimationInterface::GetXMLOpen_anim (uint32_t lp)
1841 {
1842  std::ostringstream oss;
1843  oss <<"<anim ver=\"" << GetNetAnimVersion () << "\">\n";
1844  return oss.str ();
1845 }
1846 std::string AnimationInterface::GetXMLOpen_topology (double minX, double minY, double maxX, double maxY)
1847 {
1848  std::ostringstream oss;
1849  oss << "<topology minX = \"" << minX << "\" minY = \"" << minY
1850  << "\" maxX = \"" << maxX << "\" maxY = \"" << maxY
1851  << "\">" << std::endl;
1852  return oss.str ();
1853 
1854 }
1855 
1856 std::string AnimationInterface::GetXMLOpenClose_nodeupdate (uint32_t id, bool visible)
1857 {
1858  struct Rgb rgb = nodeColors[id];
1859  uint8_t r = rgb.r;
1860  uint8_t g = rgb.g;
1861  uint8_t b = rgb.b;
1862  std::ostringstream oss;
1863  oss << "<nodeupdate id=\"" << id << "\"";
1864  oss << " t=\"" << Simulator::Now ().GetSeconds () << "\"";
1865  if (visible)
1866  oss << " visible=\"" << 1 << "\"";
1867  else
1868  oss << " visible=\"" << 0 << "\"";
1869  if (nodeDescriptions.find (id) != nodeDescriptions.end ())
1870  {
1871  oss << " descr=\""<< nodeDescriptions[id] << "\"";
1872  }
1873  else
1874  {
1875  oss << " descr=\"\"";
1876  }
1877  oss << " r=\"" << (uint32_t)r << "\" "
1878  << " g=\"" << (uint32_t)g << "\" b=\"" << (uint32_t)b <<"\"/>\n";
1879  return oss.str ();
1880 
1881 }
1882 
1883 std::string AnimationInterface::GetXMLOpenClose_node (uint32_t lp, uint32_t id, double locX, double locY)
1884 {
1885  std::ostringstream oss;
1886  oss <<"<node id=\"" << id << "\"";
1887  if (nodeDescriptions.find (id) != nodeDescriptions.end ())
1888  {
1889  oss << " descr=\""<< nodeDescriptions[id] << "\"";
1890  }
1891  else
1892  {
1893  oss << " descr=\"\"";
1894  }
1895  oss << " locX = \"" << locX << "\" " << "locY = \"" << locY << "\" />\n";
1896  return oss.str ();
1897 }
1898 
1899 std::string AnimationInterface::GetXMLOpenClose_node (uint32_t lp, uint32_t id, double locX, double locY, struct Rgb rgb)
1900 {
1901  uint8_t r = rgb.r;
1902  uint8_t g = rgb.g;
1903  uint8_t b = rgb.b;
1904  std::ostringstream oss;
1905  oss <<"<node id = \"" << id << "\"";
1906  if (nodeDescriptions.find (id) != nodeDescriptions.end ())
1907  {
1908  oss << " descr=\""<< nodeDescriptions[id] << "\"";
1909  }
1910  else
1911  {
1912  oss << " descr=\"\"";
1913  }
1914  oss << " locX=\"" << locX << "\" " << "locY=\"" << locY << "\"" << " r=\"" << (uint32_t)r << "\" "
1915  << " g=\"" << (uint32_t)g << "\" b=\"" << (uint32_t)b <<"\"/>\n";
1916  return oss.str ();
1917 }
1918 
1919 std::string AnimationInterface::GetXMLOpenClose_linkupdate (uint32_t fromId, uint32_t toId, std::string linkDescription)
1920 {
1921  std::ostringstream oss;
1922  oss << "<linkupdate t=\"" << Simulator::Now ().GetSeconds () << "\""
1923  << " fromId=\"" << fromId
1924  << "\" toId=\"" << toId
1925  << "\" ";
1926 
1927  oss << " ld=\"" << linkDescription << "\""
1928  << " />\n";
1929  return oss.str ();
1930 
1931 }
1932 
1933 std::string AnimationInterface::GetXMLOpenClose_link (uint32_t fromLp, uint32_t fromId, uint32_t toLp, uint32_t toId)
1934 {
1935  std::ostringstream oss;
1936  oss << "<link fromId=\"" << fromId
1937  << "\" toId=\"" << toId
1938  << "\" ";
1939 
1940  LinkProperties lprop ;
1941  lprop.fromNodeDescription = "";
1942  lprop.toNodeDescription = "";
1943  lprop.linkDescription = "";
1944 
1945  P2pLinkNodeIdPair p1 = { fromId, toId };
1946  P2pLinkNodeIdPair p2 = { toId, fromId };
1947  if (linkProperties.find (p1) != linkProperties.end())
1948  {
1949  lprop = linkProperties[p1];
1950  }
1951  else if (linkProperties.find (p2) != linkProperties.end())
1952  {
1953  lprop = linkProperties[p2];
1954  }
1955 
1956  oss << " fd=\"" << lprop.fromNodeDescription << "\""
1957  << " td=\"" << lprop.toNodeDescription << "\""
1958  << " ld=\"" << lprop.linkDescription << "\""
1959  << " />\n";
1960  return oss.str ();
1961 }
1962 
1963 
1964 std::string AnimationInterface::GetXMLOpen_packet (uint32_t fromLp, uint32_t fromId, double fbTx, double lbTx, std::string auxInfo)
1965 {
1966  std::ostringstream oss;
1967  oss << std::setprecision (10);
1968  oss << "<p fId=\"" << fromId
1969  << "\" fbTx=\"" << fbTx
1970  << "\" lbTx=\"" << lbTx
1971  << (auxInfo.empty()?"":"\" aux=\"") << auxInfo.c_str () << "\">";
1972  return oss.str ();
1973 }
1974 
1975 std::string AnimationInterface::GetXMLOpenClose_routing (uint32_t nodeId, std::string routingInfo)
1976 {
1977  std::ostringstream oss;
1978  oss << "<" << "rt" << " t=\"" << Simulator::Now ().GetSeconds () << "\""
1979  << " id=\"" << nodeId << "\""
1980  << " info=\"" << routingInfo.c_str () << "\""
1981  << "/>" << std::endl;
1982  return oss.str ();
1983 }
1984 
1985 std::string AnimationInterface::GetXMLOpenClose_rp (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
1986 {
1987  std::ostringstream oss;
1988  oss << "<" << "rp" << " t =\"" << Simulator::Now ().GetSeconds () << "\""
1989  << " id=\"" << nodeId << "\"" << " d=\"" << destination.c_str () << "\""
1990  << " c=\"" << rpElements.size () << "\"" << ">" << std::endl;
1991  for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
1992  i != rpElements.end ();
1993  ++i)
1994  {
1995  Ipv4RoutePathElement rpElement = *i;
1996  oss << "<rpe" << " n=\"" << rpElement.nodeId << "\"" << " nH=\"" << rpElement.nextHop.c_str () << "\"" << "/>" << std::endl;
1997  }
1998  oss << "<rp/>" << std::endl;
1999  return oss.str ();
2000 }
2001 
2002 
2003 std::string AnimationInterface::GetXMLOpenClose_p (std::string pktType, uint32_t fId, double fbTx, double lbTx,
2004  uint32_t tId, double fbRx, double lbRx, std::string metaInfo,
2005  std::string auxInfo)
2006 {
2007  std::ostringstream oss;
2008  oss << std::setprecision (10);
2009  oss << "<" << pktType << " fId=\"" << fId
2010  << "\" fbTx=\"" << fbTx
2011  << "\" lbTx=\"" << lbTx << "\"";
2012  if (!auxInfo.empty ())
2013  {
2014  oss << " aux=\"" << auxInfo.c_str () << "\"";
2015  }
2016  if (!metaInfo.empty ())
2017  {
2018  oss << " meta-info=\"" << metaInfo.c_str () << "\"";
2019  }
2020  oss << " tId=\"" << tId << "\" fbRx=\"" << fbRx << "\" lbRx=\"" << lbRx << "\">" << std::endl;
2021  return oss.str ();
2022 }
2023 
2024 
2025 
2026 std::string AnimationInterface::GetXMLOpen_wpacket (uint32_t fromLp, uint32_t fromId, double fbTx, double lbTx, double range)
2027 {
2028  std::ostringstream oss;
2029  oss << std::setprecision (10);
2030  oss << "<wpacket fromId=\"" << fromId
2031  << "\" fbTx=\"" << fbTx
2032  << "\" lbTx=\"" << lbTx
2033  << "\" range=\"" << range << "\">" << std::endl;
2034  return oss.str ();
2035 
2036 }
2037 
2038 std::string AnimationInterface::GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx)
2039 {
2040  std::ostringstream oss;
2041  oss << std::setprecision (10);
2042  oss << "<rx toId=\"" << toId
2043  << "\" fbRx=\"" << fbRx
2044  << "\" lbRx=\"" << lbRx
2045  << "\"/>" << std::endl;
2046  return oss.str ();
2047 }
2048 
2049 std::string AnimationInterface::GetXMLOpenClose_meta (std::string metaInfo)
2050 {
2051  std::ostringstream oss;
2052  oss << "<meta info=\""
2053  << metaInfo << "\" />" << std::endl;
2054  return oss.str ();
2055 }
2056 
2057 
2058 std::string AnimationInterface::GetXMLOpenClose_NonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
2059 {
2060  std::ostringstream oss;
2061  oss << "<nonp2plinkproperties id=\""
2062  << id << "\""
2063  << " ipv4Address=\"" << ipv4Address << "\""
2064  << " channelType=\"" << channelType << "\""
2065  << "/>" << std::endl;
2066  return oss.str ();
2067 }
2068 
2069 
2070 std::vector<std::string> AnimationInterface::GetElementsFromContext (std::string context)
2071 {
2072  std::vector <std::string> elements;
2073  size_t pos1=0, pos2;
2074  while (pos1 != context.npos)
2075  {
2076  pos1 = context.find ("/",pos1);
2077  pos2 = context.find ("/",pos1+1);
2078  elements.push_back (context.substr (pos1+1,pos2-(pos1+1)));
2079  pos1 = pos2;
2080  pos2 = context.npos;
2081  }
2082  return elements;
2083 }
2084 
2085 TypeId
2087 {
2088  static TypeId tid = TypeId ("ns3::AnimByteTag")
2089  .SetParent<Tag> ()
2090  .AddConstructor<AnimByteTag> ()
2091  ;
2092  return tid;
2093 }
2094 TypeId
2096 {
2097  return GetTypeId ();
2098 }
2099 
2100 uint32_t
2102 {
2103  return sizeof (uint64_t);
2104 }
2105 void
2107 {
2108  i.WriteU64 (m_AnimUid);
2109 }
2110 void
2112 {
2113  m_AnimUid = i.ReadU64 ();
2114 }
2115 void
2116 AnimByteTag::Print (std::ostream &os) const
2117 {
2118  os << "AnimUid=" << m_AnimUid;
2119 }
2120 void
2121 AnimByteTag::Set (uint64_t AnimUid)
2122 {
2123  m_AnimUid = AnimUid;
2124 }
2125 
2126 uint64_t
2127 AnimByteTag::Get (void) const
2128 {
2129  return m_AnimUid;
2130 }
2131 
2132 
2133 } // namespace ns3
void Set(uint64_t AnimUid)
Set global Uid in tag.
uint64_t GetTracePktCount()
Get trace file packet count (This used only for testing)
double x
Definition: vector.h:49
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
static uint32_t GetNNodes(void)
Definition: node-list.cc:198
void WriteU64(uint64_t v)
Definition: tag-buffer.cc:102
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:192
AnimationInterface & AddSourceDestination(uint32_t fromNodeId, std::string destinationIpv4Address)
Helper function to print the routing path from a source node to destination IP.
void EnablePacketMetadata(bool enable)
Enable Packet metadata.
static TypeId GetTypeId(void)
Get Type Id.
static void SetNodeColor(Ptr< Node > n, uint8_t r, uint8_t g, uint8_t b)
Helper function to set the node color.
Mobility model for which the current position does not change once it has been set and until it is se...
static bool IsInitialized(void)
Check if AnimationInterface is initialized.
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
Vector GetPosition(void) const
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
#define NS_LOG_INFO(msg)
Definition: log.h:264
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual void Deserialize(TagBuffer i)
Deserialize function.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:728
void SetStartTime(Time t)
Specify the time at which capture should start.
void SetStopTime(Time t)
Specify the time at which capture should stop.
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(void) const =0
Get the routing protocol to be used by this Ipv4 stack.
a 3d vector
Definition: vector.h:31
void UpdateNodeColor(Ptr< Node > n, uint8_t r, uint8_t g, uint8_t b)
Helper function to update the node color.
void ResetAnimWriteCallback()
Reset the write callback function.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
static void SetConstantPosition(Ptr< Node > n, double x, double y, double z=0)
Helper function to set Constant Position for a given node.
uint32_t GetN(void) const
Get the number of Ptr<Node> stored in this container.
virtual void Print(std::ostream &os) const
Print tag info.
Keep track of the current position and velocity of an object.
static void SetLinkDescription(uint32_t fromNode, uint32_t toNode, std::string linkDescription, std::string fromNodeDescription="", std::string toNodeDescription="")
Helper function to set the description for a link.
void SetXMLOutput()
Specify that animation commands are to be written in XML format.
double GetSeconds(void) const
Definition: nstime.h:262
static void EnablePrinting(void)
Definition: packet.cc:575
void SetRandomPosition(bool setRandPos)
Set random position if a Mobility Model does not exists for the node.
~AnimationInterface()
Destructor for the animator interface.
static Iterator End(void)
Definition: node-list.cc:186
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
static void SetNodeDescription(Ptr< Node > n, std::string descr)
Helper function to set a brief description for a given node.
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:133
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
void StartAnimation(bool restart=false)
Writes the topology information and sets up the appropriate animation packet tx callback.
int64_t AssignStreams(int64_t stream)
AnimationInterface & EnableIpv4RouteTracking(std::string fileName, Time startTime, Time stopTime, Time pollInterval=Seconds(5))
Enable tracking of the Ipv4 routing table for all Nodes.
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
uint32_t GetNDevices(void) const
Definition: node.cc:141
tag a set of bytes in a packet
Definition: tag.h:36
keep track of a set of node pointers.
void UpdateLinkDescription(uint32_t fromNode, uint32_t toNode, std::string linkDescription)
Helper function to update the description for a link.
uint64_t ReadU64(void)
Definition: tag-buffer.cc:134
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
#define NS_LOG_UNCOND(msg)
Definition: log.h:343
double y
Definition: vector.h:53
virtual void Serialize(TagBuffer i) const
Serialize function.
static Time Now(void)
Definition: simulator.cc:179
bool SetOutputFile(const std::string &fn)
Specify that animation commands are to be written to the specified output file.
virtual TypeId GetInstanceTypeId(void) const
Get Instance Type Id.
void StopAnimation(bool onlyAnimation=false)
Closes the interface to the animator.
uint64_t Get(void) const
Get Uid in tag.
read and write tag data
Definition: tag-buffer.h:51
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
uint32_t GetId(void) const
Definition: node.cc:105
#define NS_LOG_WARN(msg)
Definition: log.h:246
static Iterator Begin(void)
Definition: node-list.cc:180
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
AnimationInterface(const std::string filename, uint64_t maxPktsPerFile=MAX_PKTS_PER_TRACE_FILE, bool usingXML=true)
Constructor.
virtual uint32_t GetSerializedSize(void) const
Get Serialized Size.
Interface to network animator.
static bool IsFinished(void)
Definition: simulator.cc:150
void SetAnimWriteCallback(AnimWriteCallback cb)
Set a callback function to listen to AnimationInterface write events.
void SetMobilityPollInterval(Time t)
Set mobility poll interval:WARNING: setting a low interval can cause slowness.
A structure to store red, blue and green components for entities such as nodes.
void ShowNode(uint32_t nodeId, bool show=true)
Helper function to show/hide a node.
bool IsStarted(void)
Is AnimationInterface started.
Ptr< T > GetObject(void) const
Definition: object.h:332
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void UpdateNodeDescription(Ptr< Node > n, std::string descr)
Helper function to update the description for a given node.
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:717