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