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