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