A Discrete-Event Network Simulator
API
animation-interface.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indeni * This program is free software; you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License version 2 as
3  * published by the Free Software Foundation;
4  *
5  * This program is distributed in the hope that it will be useful,
6  * but WITHOUT ANY WARRANTY; without even the implied warranty of
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8  * GNU General Public License for more details.
9  *
10  * You should have received a copy of the GNU General Public License
11  * along with this program; if not, write to the Free Software
12  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13  *
14  * Author: George F. Riley<riley@ece.gatech.edu>
15  * Modified by: John Abraham <john.abraham@gatech.edu>
16  * Contributions: Eugene Kalishenko <ydginster@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
17  */
18 
19 // Interface between ns-3 and the network animator
20 
21 
22 
23 #include <cstdio>
24 #include <unistd.h>
25 #include <sstream>
26 #include <fstream>
27 #include <string>
28 #include <iomanip>
29 #include <map>
30 
31 // ns3 includes
32 #include "ns3/animation-interface.h"
33 #include "ns3/channel.h"
34 #include "ns3/config.h"
35 #include "ns3/node.h"
36 #include "ns3/mobility-model.h"
37 #include "ns3/packet.h"
38 #include "ns3/simulator.h"
39 #include "ns3/wifi-mac-header.h"
40 #include "ns3/wimax-mac-header.h"
41 #include "ns3/wifi-net-device.h"
42 #include "ns3/wifi-mac.h"
43 #include "ns3/constant-position-mobility-model.h"
44 #include "ns3/lte-ue-phy.h"
45 #include "ns3/lte-enb-phy.h"
46 #include "ns3/uan-net-device.h"
47 #include "ns3/uan-mac.h"
48 #include "ns3/ipv4.h"
49 #include "ns3/ipv4-routing-protocol.h"
50 #include "ns3/energy-source-container.h"
51 
52 namespace ns3 {
53 
54 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
55 
56 // Globals
57 
58 static bool initialized = false;
59 
60 
61 // Public methods
62 
64  : m_f (0),
65  m_routingF (0),
66  m_mobilityPollInterval (Seconds (0.25)),
67  m_outputFileName (fn),
68  gAnimUid (0),
69  m_writeCallback (0),
70  m_started (false),
71  m_enablePacketMetadata (false),
72  m_startTime (Seconds (0)),
73  m_stopTime (Seconds (3600 * 1000)),
74  m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE),
75  m_originalFileName (fn),
76  m_routingStopTime (Seconds (0)),
77  m_routingFileName (""),
78  m_routingPollInterval (Seconds (5)),
79  m_trackPackets (true)
80 {
81  initialized = true;
82  StartAnimation ();
83 }
84 
86 {
87  StopAnimation ();
88 }
89 
90 void
92 {
93  m_trackPackets = false;
94 }
95 
96 void
98 {
100  m_wifiPhyCountersPollInterval = pollInterval;
103  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
104  {
105  Ptr<Node> n = *i;
106  m_nodeWifiPhyTxDrop[n->GetId ()] = 0;
107  m_nodeWifiPhyRxDrop[n->GetId ()] = 0;
110  }
112 
113 }
114 
115 void
117 {
119  m_wifiMacCountersPollInterval = pollInterval;
124  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
125  {
126  Ptr<Node> n = *i;
127  m_nodeWifiMacTx[n->GetId ()] = 0;
128  m_nodeWifiMacTxDrop[n->GetId ()] = 0;
129  m_nodeWifiMacRx[n->GetId ()] = 0;
130  m_nodeWifiMacRxDrop[n->GetId ()] = 0;
135  }
137 }
138 
139 void
141 {
143  m_queueCountersPollInterval = pollInterval;
147  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
148  {
149  Ptr<Node> n = *i;
150  m_nodeQueueEnqueue[n->GetId ()] = 0;
151  m_nodeQueueDequeue[n->GetId ()] = 0;
152  m_nodeQueueDrop[n->GetId ()] = 0;
156  }
158 }
159 
160 void
162 {
168  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
169  {
170  Ptr<Node> n = *i;
171  m_nodeIpv4Tx[n->GetId ()] = 0;
172  m_nodeIpv4Rx[n->GetId ()] = 0;
173  m_nodeIpv4Drop[n->GetId ()] = 0;
177  }
179 }
180 
183 {
184  SetOutputFile (fileName, true);
186  m_routingPollInterval = pollInterval;
187  WriteXmlAnim (true);
189  return *this;
190 }
191 
194 {
195  m_routingNc = nc;
196  return EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
197 }
198 
200 AnimationInterface::AddSourceDestination (uint32_t fromNodeId, std::string ipv4Address)
201 {
202  Ipv4RouteTrackElement element = { ipv4Address, fromNodeId };
203  m_ipv4RouteTrackElements.push_back (element);
204  return *this;
205 }
206 
207 void
209 {
210  m_startTime = t;
211 }
212 
213 void
215 {
216  m_stopTime = t;
217 }
218 
219 void
220 AnimationInterface::SetMaxPktsPerTraceFile (uint64_t maxPacketsPerFile)
221 {
222  m_maxPktsPerFile = maxPacketsPerFile;
223 }
224 
225 uint32_t
226 AnimationInterface::AddNodeCounter (std::string counterName, CounterType counterType)
227 {
228  m_nodeCounters.push_back (counterName);
229  uint32_t counterId = m_nodeCounters.size () - 1; // counter ID is zero-indexed
230  WriteXmlAddNodeCounter (counterId, counterName, counterType);
231  return counterId;
232 }
233 
234 uint32_t
235 AnimationInterface::AddResource (std::string resourcePath)
236 {
237  m_resources.push_back (resourcePath);
238  uint32_t resourceId = m_resources.size () - 1; // resource ID is zero-indexed
239  WriteXmlAddResource (resourceId, resourcePath);
240  return resourceId;
241 }
242 
243 void
245 {
246  m_enablePacketMetadata = enable;
247  if (enable)
248  {
250  }
251 }
252 
253 bool
255 {
256  return initialized;
257 }
258 
259 bool
261 {
262  return m_started;
263 }
264 
265 void
267 {
268  m_writeCallback = cb;
269 }
270 
271 void
273 {
274  m_writeCallback = 0;
275 }
276 
277 void
279 {
281 }
282 
283 
284 void
285 AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
286 {
287  NS_ASSERT (n);
289  if (loc == 0)
290  {
291  loc = CreateObject<ConstantPositionMobilityModel> ();
292  n->AggregateObject (loc);
293  }
294  Vector hubVec (x, y, z);
295  loc->SetPosition (hubVec);
296  NS_LOG_INFO ("Node:" << n->GetId () << " Position set to:(" << x << "," << y << "," << z << ")");
297 
298 }
299 
300 void
301 AnimationInterface::UpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
302 {
303  NS_LOG_INFO ("Setting node image for Node Id:" << nodeId);
304  if (resourceId > (m_resources.size ()-1))
305  {
306  NS_FATAL_ERROR ("Resource Id:" << resourceId << " not found. Did you use AddResource?");
307  }
308  WriteXmlUpdateNodeImage (nodeId, resourceId);
309 }
310 
311 void
312 AnimationInterface::UpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counter)
313 {
314  if (nodeCounterId > (m_nodeCounters.size () - 1))
315  {
316  NS_FATAL_ERROR ("NodeCounter Id:" << nodeCounterId << " not found. Did you use AddNodeCounter?");
317  }
318  WriteXmlUpdateNodeCounter (nodeCounterId, nodeId, counter);
319 }
320 
321 void
322 AnimationInterface::SetBackgroundImage (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
323 {
324  if ((opacity < 0) || (opacity > 1))
325  {
326  NS_FATAL_ERROR ("Opacity must be between 0.0 and 1.0");
327  }
328  WriteXmlUpdateBackground (fileName, x, y, scaleX, scaleY, opacity);
329 }
330 
331 void
332 AnimationInterface::UpdateNodeSize (uint32_t nodeId, double width, double height)
333 {
334  AnimationInterface::NodeSize s = { width, height };
335  m_nodeSizes[nodeId] = s;
336  WriteXmlUpdateNodeSize (nodeId, s.width, s.height);
337 }
338 
339 void
340 AnimationInterface::UpdateNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
341 {
342  UpdateNodeColor (n->GetId (), r, g, b);
343 }
344 
345 void
346 AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
347 {
348  NS_ASSERT (NodeList::GetNode (nodeId));
349  NS_LOG_INFO ("Setting node color for Node Id:" << nodeId);
350  Rgb rgb = {r, g, b};
351  m_nodeColors[nodeId] = rgb;
352  WriteXmlUpdateNodeColor (nodeId, r, g, b);
353 }
354 
355 void
356 AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNode,
357  std::string linkDescription)
358 {
359  WriteXmlUpdateLink (fromNode, toNode, linkDescription);
360 }
361 
362 void
364  std::string linkDescription)
365 {
366  NS_ASSERT (fromNode);
367  NS_ASSERT (toNode);
368  WriteXmlUpdateLink (fromNode->GetId (), toNode->GetId (), linkDescription);
369 }
370 
371 void
373 {
374  UpdateNodeDescription (n->GetId (), descr);
375 }
376 
377 void
378 AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string descr)
379 {
380  NS_ASSERT (NodeList::GetNode (nodeId));
381  m_nodeDescriptions[nodeId] = descr;
383 }
384 
385 // Private methods
386 
387 
388 double
390 {
391  const EnergyFractionMap::const_iterator fractionIter = m_nodeEnergyFraction.find (node->GetId ());
392  NS_ASSERT (fractionIter != m_nodeEnergyFraction.end ());
393  return fractionIter->second;
394 }
395 
396 void
398 {
399  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
400  return;
401  Ptr <Node> n = mobility->GetObject <Node> ();
402  NS_ASSERT (n);
403  Vector v ;
404  if (!mobility)
405  {
406  v = GetPosition (n);
407  }
408  else
409  {
410  v = mobility->GetPosition ();
411  }
412  UpdatePosition (n, v);
413  WriteXmlUpdateNodePosition (n->GetId (), v.x, v.y);
414 }
415 
416 bool
418 {
419  Vector oldLocation = GetPosition (n);
420  if ((ceil (oldLocation.x) == ceil (newLocation.x)) &&
421  (ceil (oldLocation.y) == ceil (newLocation.y)))
422  {
423  return false;
424  }
425  else
426  {
427  return true;
428  }
429 }
430 
431 void
433 {
434  if (!m_started || !IsInTimeWindow ())
435  return;
436  std::vector <Ptr <Node> > MovedNodes = GetMovedNodes ();
437  for (uint32_t i = 0; i < MovedNodes.size (); i++)
438  {
439  Ptr <Node> n = MovedNodes [i];
440  NS_ASSERT (n);
441  Vector v = GetPosition (n);
442  WriteXmlUpdateNodePosition (n->GetId () , v.x, v.y);
443  }
444  if (!Simulator::IsFinished ())
445  {
451  }
452 }
453 
454 std::vector <Ptr <Node> >
456 {
457  std::vector < Ptr <Node> > movedNodes;
458  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
459  {
460  Ptr<Node> n = *i;
461  NS_ASSERT (n);
462  Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
463  Vector newLocation;
464  if (!mobility)
465  {
466  newLocation = GetPosition (n);
467  }
468  else
469  {
470  newLocation = mobility->GetPosition ();
471  }
472  if (!NodeHasMoved (n, newLocation))
473  {
474  continue; //Location has not changed
475  }
476  else
477  {
478  UpdatePosition (n, newLocation);
479  movedNodes.push_back (n);
480  }
481  }
482  return movedNodes;
483 }
484 
485 int
486 AnimationInterface::WriteN (const std::string& st, FILE * f)
487 {
488  if (!f)
489  return 0;
490  if (m_writeCallback)
491  {
492  m_writeCallback (st.c_str ());
493  }
494  return WriteN (st.c_str (), st.length (), f);
495 }
496 
497 int
498 AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
499 {
500  if (!f)
501  return 0;
502  // Write count bytes to h from data
503  uint32_t nLeft = count;
504  const char* p = data;
505  uint32_t written = 0;
506  while (nLeft)
507  {
508  int n = std::fwrite (p, 1, nLeft, f);
509  if (n <= 0)
510  {
511  return written;
512  }
513  written += n;
514  nLeft -= n;
515  p += n;
516  }
517  return written;
518 }
519 
520 void
521 AnimationInterface::WriteRoutePath (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
522 {
523  NS_LOG_INFO ("Writing Route Path From :" << nodeId << " To: " << destination.c_str ());
524  WriteXmlRp (nodeId, destination, rpElements);
525  /*for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
526  i != rpElements.end ();
527  ++i)
528  {
529  Ipv4RoutePathElement rpElement = *i;
530  NS_LOG_INFO ("Node:" << rpElement.nodeId << "-->" << rpElement.nextHop.c_str ());
531  WriteN (GetXmlRp (rpElement.node, GetIpv4RoutingTable (n)), m_routingF);
532 
533  }
534  */
535 }
536 
537 void
538 AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
539 {
540  WriteXmlNonP2pLinkProperties (id, ipv4Address, channelType);
541 }
542 
543 const std::vector<std::string>
544 AnimationInterface::GetElementsFromContext (const std::string& context) const
545 {
546  std::vector <std::string> elements;
547  size_t pos1=0, pos2;
548  while (pos1 != context.npos)
549  {
550  pos1 = context.find ("/",pos1);
551  pos2 = context.find ("/",pos1+1);
552  elements.push_back (context.substr (pos1+1,pos2-(pos1+1)));
553  pos1 = pos2;
554  pos2 = context.npos;
555  }
556  return elements;
557 }
558 
560 AnimationInterface::GetNodeFromContext (const std::string& context) const
561 {
562  // Use "NodeList/*/ as reference
563  // where element [1] is the Node Id
564 
565  std::vector <std::string> elements = GetElementsFromContext (context);
566  Ptr <Node> n = NodeList::GetNode (atoi (elements.at (1).c_str ()));
567  NS_ASSERT (n);
568 
569  return n;
570 }
571 
574 {
575  // Use "NodeList/*/DeviceList/*/ as reference
576  // where element [1] is the Node Id
577  // element [2] is the NetDevice Id
578 
579  std::vector <std::string> elements = GetElementsFromContext (context);
580  Ptr <Node> n = GetNodeFromContext (context);
581 
582  return n->GetDevice (atoi (elements.at (3).c_str ()));
583 }
584 
585 uint64_t
587 {
588  AnimByteTag tag;
589  TypeId tid = tag.GetInstanceTypeId ();
591  bool found = false;
592  while (i.HasNext ())
593  {
594  ByteTagIterator::Item item = i.Next ();
595  if (tid == item.GetTypeId ())
596  {
597  item.GetTag (tag);
598  found = true;
599  }
600  }
601  if (found)
602  {
603  return tag.Get ();
604  }
605  else
606  {
607  return 0;
608  }
609 }
610 
611 void
613 {
614  AnimByteTag tag;
615  tag.Set (animUid);
616  p->AddByteTag (tag);
617 }
618 
619 void
620 AnimationInterface::RemainingEnergyTrace (std::string context, double previousEnergy, double currentEnergy)
621 {
622  if (!m_started || !IsInTimeWindow ())
623  return;
624 
625  const Ptr <const Node> node = GetNodeFromContext (context);
626  const uint32_t nodeId = node->GetId ();
627 
628  NS_LOG_INFO ("Remaining energy on one of sources on node " << nodeId << ": " << currentEnergy);
629 
630  const Ptr<EnergySource> energySource = node->GetObject<EnergySource> ();
631 
632  NS_ASSERT (energySource);
633  // Don't call GetEnergyFraction () because of recursion
634  const double energyFraction = currentEnergy / energySource->GetInitialEnergy ();
635 
636  NS_LOG_INFO ("Total energy fraction on node " << nodeId << ": " << energyFraction);
637 
638  m_nodeEnergyFraction[nodeId] = energyFraction;
639  UpdateNodeCounter (m_remainingEnergyCounterId, nodeId, energyFraction);
640 }
641 
642 void
644 {
645  const Ptr <const Node> node = GetNodeFromContext (context);
646  ++m_nodeWifiPhyTxDrop[node->GetId ()];
647 }
648 
649 void
651 {
652  const Ptr <const Node> node = GetNodeFromContext (context);
653  ++m_nodeWifiPhyRxDrop[node->GetId ()];
654 }
655 
656 void
658 {
659  const Ptr <const Node> node = GetNodeFromContext (context);
660  ++m_nodeWifiMacTx[node->GetId ()];
661 }
662 
663 void
665 {
666  const Ptr <const Node> node = GetNodeFromContext (context);
667  ++m_nodeWifiMacTxDrop[node->GetId ()];
668 }
669 
670 void
672 {
673  const Ptr <const Node> node = GetNodeFromContext (context);
674  ++m_nodeWifiMacRx[node->GetId ()];
675 }
676 
677 void
679 {
680  const Ptr <const Node> node = GetNodeFromContext (context);
681  ++m_nodeWifiMacRxDrop[node->GetId ()];
682 }
683 
684 void
685 AnimationInterface::Ipv4TxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
686 {
687  const Ptr <const Node> node = GetNodeFromContext (context);
688  ++m_nodeIpv4Tx[node->GetId ()];
689 }
690 
691 void
692 AnimationInterface::Ipv4RxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
693 {
694  const Ptr <const Node> node = GetNodeFromContext (context);
695  ++m_nodeIpv4Rx[node->GetId ()];
696 }
697 
698 void
699 AnimationInterface::Ipv4DropTrace (std::string context,
700  const Ipv4Header & ipv4Header,
702  Ipv4L3Protocol::DropReason dropReason,
703  Ptr<Ipv4> ipv4,
704  uint32_t)
705 {
706  const Ptr <const Node> node = GetNodeFromContext (context);
707  ++m_nodeIpv4Drop[node->GetId ()];
708 }
709 
710 void
711 AnimationInterface::EnqueueTrace (std::string context,
713 {
714  const Ptr <const Node> node = GetNodeFromContext (context);
715  ++m_nodeQueueEnqueue[node->GetId ()];
716 }
717 
718 void
719 AnimationInterface::DequeueTrace (std::string context,
721 {
722  const Ptr <const Node> node = GetNodeFromContext (context);
723  ++m_nodeQueueDequeue[node->GetId ()];
724 }
725 
726 void
729 {
730  const Ptr <const Node> node = GetNodeFromContext (context);
731  ++m_nodeQueueDrop[node->GetId ()];
732 }
733 
734 void
735 AnimationInterface::DevTxTrace (std::string context,
737  Ptr<NetDevice> tx,
738  Ptr<NetDevice> rx,
739  Time txTime,
740  Time rxTime)
741 {
742  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
743  return;
744  NS_ASSERT (tx);
745  NS_ASSERT (rx);
746  Time now = Simulator::Now ();
747  double fbTx = now.GetSeconds ();
748  double lbTx = (now + txTime).GetSeconds ();
749  double fbRx = (now + rxTime - txTime).GetSeconds ();
750  double lbRx = (now + rxTime).GetSeconds ();
752  WriteXmlP ("p",
753  tx->GetNode ()->GetId (),
754  fbTx,
755  lbTx,
756  rx->GetNode ()->GetId (),
757  fbRx,
758  lbRx,
760 }
761 
762 void
764 {
765  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
766  return;
767  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
768  NS_ASSERT (ndev);
769  Ptr <Node> n = ndev->GetNode ();
770  NS_ASSERT (n);
771  ++gAnimUid;
772  NS_LOG_INFO ("Uan TxBeginTrace for packet:" << gAnimUid);
773  AddByteTag (gAnimUid, p);
774  UpdatePosition (n);
775  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
778 }
779 
780 void
782 {
783  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
784  return;
785  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
786  NS_ASSERT (ndev);
787  Ptr <Node> n = ndev->GetNode ();
788  NS_ASSERT (n);
789  uint64_t animUid = GetAnimUidFromPacket (p);
790  NS_LOG_INFO ("UanPhyGenRxTrace for packet:" << animUid);
792  {
793  NS_LOG_WARN ("UanPhyGenRxBeginTrace: unknown Uid");
794  return;
795  }
796  UpdatePosition (n);
797  m_pendingUanPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
798  OutputWirelessPacketRxInfo (p, m_pendingUanPackets[animUid], animUid);
799 }
800 
801 
802 void
805 {
806  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
807  return;
808  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
809  NS_ASSERT (ndev);
810  Ptr <Node> n = ndev->GetNode ();
811  NS_ASSERT (n);
812  ++gAnimUid;
813  NS_LOG_INFO ("Wifi TxBeginTrace for packet:" << gAnimUid);
814  AddByteTag (gAnimUid, p);
815  UpdatePosition (n);
816  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
818  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
819  Mac48Address nodeAddr = netDevice->GetMac ()->GetAddress ();
820  std::ostringstream oss;
821  oss << nodeAddr;
822  m_macToNodeIdMap[oss.str ()] = n->GetId ();
823  NS_LOG_INFO ("Added Mac" << oss.str () << " node:" <<m_macToNodeIdMap[oss.str ()]);
825 }
826 
827 void
830 {
831  //NS_LOG_UNCOND ("Context:" << context.c_str ());
832  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
833  return;
834  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
835  NS_ASSERT (ndev);
836  Ptr <Node> n = ndev->GetNode ();
837  NS_ASSERT (n);
838  uint64_t animUid = GetAnimUidFromPacket (p);
839  NS_LOG_INFO ("Wifi RxBeginTrace for packet:" << animUid);
841  {
842  NS_ASSERT (0);
843  NS_LOG_WARN ("WifiPhyRxBeginTrace: unknown Uid");
844  std::ostringstream oss;
845  WifiMacHeader hdr;
846  if (!p->PeekHeader (hdr))
847  {
848  NS_LOG_WARN ("WifiMacHeader not present");
849  return;
850  }
851  oss << hdr.GetAddr2 ();
852  if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
853  {
854  NS_LOG_WARN ("Transmitter Mac address " << oss.str () << " never seen before. Skipping");
855  return;
856  }
857  Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
858  UpdatePosition (txNode);
859  AnimPacketInfo pktInfo (0, Simulator::Now (), m_macToNodeIdMap[oss.str ()]);
860  AddPendingPacket (AnimationInterface::WIFI, animUid, pktInfo);
861  NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
862  }
864  UpdatePosition (n);
865  m_pendingWifiPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
866  OutputWirelessPacketRxInfo (p, m_pendingWifiPackets[animUid], animUid);
867 }
868 
869 void
871 {
872  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
873  return;
874  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
875  NS_ASSERT (ndev);
876  Ptr <Node> n = ndev->GetNode ();
877  NS_ASSERT (n);
878  ++gAnimUid;
879  NS_LOG_INFO ("WimaxTxTrace for packet:" << gAnimUid);
880  UpdatePosition (n);
881  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
882  AddByteTag (gAnimUid, p);
884  OutputWirelessPacketTxInfo (p, pktInfo, gAnimUid);
885 }
886 
887 
888 void
890 {
891  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
892  return;
893  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
894  NS_ASSERT (ndev);
895  Ptr <Node> n = ndev->GetNode ();
896  NS_ASSERT (n);
897  uint64_t animUid = GetAnimUidFromPacket (p);
898  NS_LOG_INFO ("WimaxRxTrace for packet:" << animUid);
900  AnimPacketInfo& pktInfo = m_pendingWimaxPackets[animUid];
901  UpdatePosition (n);
902  pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
903  OutputWirelessPacketRxInfo (p, pktInfo, animUid);
904 }
905 
906 void
908 {
909  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
910  return;
911  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
912  NS_ASSERT (ndev);
913  Ptr <Node> n = ndev->GetNode ();
914  NS_ASSERT (n);
915  ++gAnimUid;
916  NS_LOG_INFO ("LteTxTrace for packet:" << gAnimUid);
917  UpdatePosition (n);
918  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
919  AddByteTag (gAnimUid, p);
921  OutputWirelessPacketTxInfo (p, pktInfo, gAnimUid);
922 }
923 
924 
925 void
927 {
928  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
929  return;
930  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
931  NS_ASSERT (ndev);
932  Ptr <Node> n = ndev->GetNode ();
933  NS_ASSERT (n);
934  uint64_t animUid = GetAnimUidFromPacket (p);
935  NS_LOG_INFO ("LteRxTrace for packet:" << gAnimUid);
937  {
938  NS_LOG_WARN ("LteRxTrace: unknown Uid");
939  return;
940  }
941  AnimPacketInfo& pktInfo = m_pendingLtePackets[animUid];
942  UpdatePosition (n);
943  pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
944  OutputWirelessPacketRxInfo (p, pktInfo, animUid);
945 }
946 
947 void
949 {
950  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
951  return;
952  if (!pb)
953  {
954  NS_LOG_WARN ("pb == 0. Not yet supported");
955  return;
956  }
957  context = "/" + context;
958  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
959  NS_ASSERT (ndev);
960  Ptr <Node> n = ndev->GetNode ();
961  NS_ASSERT (n);
962 
963  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
964  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
965  i != pbList.end ();
966  ++i)
967  {
968  Ptr <Packet> p = *i;
969  ++gAnimUid;
970  NS_LOG_INFO ("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
971  UpdatePosition (n);
972  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
973  AddByteTag (gAnimUid, p);
975  OutputWirelessPacketTxInfo (p, pktInfo, gAnimUid);
976  }
977 }
978 
979 void
981 {
982  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
983  return;
984  if (!pb)
985  {
986  NS_LOG_WARN ("pb == 0. Not yet supported");
987  return;
988  }
989  context = "/" + context;
990  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
991  NS_ASSERT (ndev);
992  Ptr <Node> n = ndev->GetNode ();
993  NS_ASSERT (n);
994 
995  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
996  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
997  i != pbList.end ();
998  ++i)
999  {
1000  Ptr <Packet> p = *i;
1001  uint64_t animUid = GetAnimUidFromPacket (p);
1002  NS_LOG_INFO ("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
1003  if (!IsPacketPending (animUid, AnimationInterface::LTE))
1004  {
1005  NS_LOG_WARN ("LteSpectrumPhyRxTrace: unknown Uid");
1006  return;
1007  }
1008  AnimPacketInfo& pktInfo = m_pendingLtePackets[animUid];
1009  UpdatePosition (n);
1010  pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1011  OutputWirelessPacketRxInfo (p, pktInfo, animUid);
1012  }
1013 }
1014 
1015 void
1017 {
1018  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
1019  return;
1020  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1021  NS_ASSERT (ndev);
1022  Ptr <Node> n = ndev->GetNode ();
1023  NS_ASSERT (n);
1024  ++gAnimUid;
1025  NS_LOG_INFO ("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
1026  AddByteTag (gAnimUid, p);
1027  UpdatePosition (n);
1028  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1030 
1031 }
1032 
1033 void
1035 {
1036  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
1037  return;
1038  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1039  NS_ASSERT (ndev);
1040  Ptr <Node> n = ndev->GetNode ();
1041  NS_ASSERT (n);
1042  uint64_t animUid = GetAnimUidFromPacket (p);
1043  NS_LOG_INFO ("CsmaPhyTxEndTrace for packet:" << animUid);
1044  if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1045  {
1046  NS_LOG_WARN ("CsmaPhyTxEndTrace: unknown Uid");
1047  NS_FATAL_ERROR ("CsmaPhyTxEndTrace: unknown Uid");
1048  UpdatePosition (n);
1049  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1050  AddPendingPacket (AnimationInterface::CSMA, animUid, pktInfo);
1051  NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
1052  }
1054  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1055  pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
1056 }
1057 
1058 void
1060 {
1061  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
1062  return;
1063  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1064  NS_ASSERT (ndev);
1065  Ptr <Node> n = ndev->GetNode ();
1066  NS_ASSERT (n);
1067  uint64_t animUid = GetAnimUidFromPacket (p);
1068  if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1069  {
1070  NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid");
1071  return;
1072  }
1074  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1075  UpdatePosition (n);
1076  pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1077  NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid);
1078  NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid << " complete");
1079  OutputCsmaPacket (p, pktInfo);
1080 }
1081 
1082 void
1085 {
1086  if (!m_started || !IsInTimeWindow () || !m_trackPackets)
1087  return;
1088  NS_LOG_FUNCTION (this);
1089  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1090  NS_ASSERT (ndev);
1091  Ptr <Node> n = ndev->GetNode ();
1092  NS_ASSERT (n);
1093  uint64_t animUid = GetAnimUidFromPacket (p);
1094  if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1095  {
1096  NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid");
1097  return;
1098  }
1100  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1101  NS_LOG_INFO ("MacRxTrace for packet:" << animUid << " complete");
1102  OutputCsmaPacket (p, pktInfo);
1103 }
1104 
1105 void
1107 {
1109  uint32_t nodeId = 0;
1110  if (pktInfo.m_txnd)
1111  nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1112  else
1113  nodeId = pktInfo.m_txNodeId;
1114  WriteXmlPRef (animUid, nodeId, pktInfo.m_fbTx, m_enablePacketMetadata? GetPacketMetadata (p):"");
1115 
1116 }
1117 
1118 void
1120 {
1122  uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1123  WriteXmlP (animUid, "wpr", rxId, pktInfo.m_fbRx, pktInfo.m_lbRx);
1124 }
1125 
1126 void
1128 {
1130  NS_ASSERT (pktInfo.m_txnd);
1131  uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1132  uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1133 
1134  WriteXmlP ("p",
1135  nodeId,
1136  pktInfo.m_fbTx,
1137  pktInfo.m_lbTx,
1138  rxId,
1139  pktInfo.m_fbRx,
1140  pktInfo.m_lbRx,
1142 }
1143 
1144 void
1145 AnimationInterface::AddPendingPacket (ProtocolType protocolType, uint64_t animUid, AnimPacketInfo pktInfo)
1146 {
1147  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1148  NS_ASSERT (pendingPackets);
1149  pendingPackets->insert (AnimUidPacketInfoMap::value_type (animUid, pktInfo));
1150 }
1151 
1152 bool
1154 {
1155  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1156  NS_ASSERT (pendingPackets);
1157  return (pendingPackets->find (animUid) != pendingPackets->end ());
1158 }
1159 
1160 void
1162 {
1163  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1164  NS_ASSERT (pendingPackets);
1165  if (pendingPackets->empty ())
1166  return;
1167  std::vector <uint64_t> purgeList;
1168  for (AnimUidPacketInfoMap::iterator i = pendingPackets->begin ();
1169  i != pendingPackets->end ();
1170  ++i)
1171  {
1172 
1173  AnimPacketInfo pktInfo = i->second;
1174  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
1175  if (delta > PURGE_INTERVAL)
1176  {
1177  purgeList.push_back (i->first);
1178  }
1179  }
1180  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
1181  i != purgeList.end ();
1182  ++i)
1183  {
1184  pendingPackets->erase (*i);
1185  }
1186 }
1187 
1190 {
1191  AnimUidPacketInfoMap * pendingPackets = 0;
1192  switch (protocolType)
1193  {
1195  {
1196  pendingPackets = &m_pendingWifiPackets;
1197  break;
1198  }
1200  {
1201  pendingPackets = &m_pendingUanPackets;
1202  break;
1203  }
1205  {
1206  pendingPackets = &m_pendingCsmaPackets;
1207  break;
1208  }
1210  {
1211  pendingPackets = &m_pendingWimaxPackets;
1212  break;
1213  }
1215  {
1216  pendingPackets = &m_pendingLtePackets;
1217  break;
1218  }
1219  }
1220  return pendingPackets;
1221 
1222 }
1223 
1224 // Counters
1225 
1226 std::string
1228 {
1229  std::string typeString = "unknown";
1230  switch (counterType)
1231  {
1232  case UINT32_COUNTER:
1233  {
1234  typeString = "UINT32";
1235  break;
1236  }
1237  case DOUBLE_COUNTER:
1238  {
1239  typeString = "DOUBLE";
1240  break;
1241  }
1242  }
1243  return typeString;
1244 }
1245 
1246 // General
1247 
1248 std::string
1250 {
1251  std::ostringstream oss;
1252  p->Print (oss);
1253  return oss.str ();
1254 }
1255 
1256 uint64_t
1258 {
1259  return m_currentPktCount;
1260 }
1261 
1262 void
1264 {
1265  m_started = false;
1266  NS_LOG_INFO ("Stopping Animation");
1268  if (m_f)
1269  {
1270  // Terminate the anim element
1271  WriteXmlClose ("anim");
1272  std::fclose (m_f);
1273  m_f = 0;
1274  }
1275  if (onlyAnimation)
1276  {
1277  return;
1278  }
1279  if (m_routingF)
1280  {
1281  WriteXmlClose ("anim", true);
1282  std::fclose (m_routingF);
1283  m_routingF = 0;
1284  }
1285 }
1286 
1287 void
1289 {
1290  m_currentPktCount = 0;
1291  m_started = true;
1293  WriteXmlAnim ();
1294  WriteNodes ();
1295  WriteNodeColors ();
1297  WriteNodeSizes ();
1298  WriteNodeEnergies ();
1299  if (!restart)
1300  {
1302  ConnectCallbacks ();
1303  }
1304 }
1305 
1306 void
1307 AnimationInterface::AddToIpv4AddressNodeIdTable (std::string ipv4Address, uint32_t nodeId)
1308 {
1309  m_ipv4ToNodeIdMap[ipv4Address] = nodeId;
1310 }
1311 
1312 
1313 // Callbacks
1314 void
1316 {
1317 
1318  Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy ();
1319  Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy ();
1320  Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy ();
1321  std::ostringstream oss;
1322  //NodeList/*/DeviceList/*/
1323  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1324  if (dlPhy)
1325  {
1326  dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1327  dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1328  }
1329  if (ulPhy)
1330  {
1331  ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1332  ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1333  }
1334 }
1335 
1336 
1337 
1338 void
1340 {
1341 
1342  Ptr<LteUePhy> lteUePhy = nd->GetPhy ();
1343  Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy ();
1344  Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy ();
1345  std::ostringstream oss;
1346  //NodeList/*/DeviceList/*/
1347  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1348  if (dlPhy)
1349  {
1350  dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1351  dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1352  }
1353  if (ulPhy)
1354  {
1355  ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1356  ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1357  }
1358 }
1359 
1360 void
1362 {
1363 
1364  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1365  {
1366  Ptr<Node> n = *i;
1367  NS_ASSERT (n);
1368  uint32_t nDevices = n->GetNDevices ();
1369  for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
1370  {
1371  Ptr <NetDevice> nd = n->GetDevice (devIndex);
1372  if (!nd)
1373  continue;
1374  Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice> (nd);
1375  if (lteUeNetDevice)
1376  {
1377  ConnectLteUe (n, lteUeNetDevice, devIndex);
1378  continue;
1379  }
1380  Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice> (nd);
1381  if (lteEnbNetDevice)
1382  ConnectLteEnb (n, lteEnbNetDevice, devIndex);
1383  }
1384 
1385  }
1386 }
1387 
1388 void
1390 {
1391  // Connect the callbacks
1392  Config::Connect ("/ChannelList/*/TxRxPointToPoint",
1394  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
1396  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
1398  Config::ConnectWithoutContext ("/NodeList/*/$ns3::MobilityModel/CourseChange",
1400  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
1402  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
1404  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
1406  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
1408  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
1410  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
1412  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
1414  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
1416  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
1418  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
1420  Config::Connect ("/NodeList/*/$ns3::BasicEnergySource/RemainingEnergy",
1422 
1423  ConnectLte ();
1424 
1425  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
1427  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
1429  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
1431 
1432  // Queue Enqueues
1433 
1434  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Enqueue",
1436  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Enqueue",
1438  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Enqueue",
1440 
1441  // Queue Dequeues
1442 
1443  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Dequeue",
1445  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Dequeue",
1447  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Dequeue",
1449 
1450  // Queue Drops
1451 
1452  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Drop",
1454  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Drop",
1456  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Drop",
1458 
1459 
1460  // Wifi Mac
1461  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
1463  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTxDrop",
1465  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
1467  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRxDrop",
1469 
1470  // Wifi Phy
1471  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxDrop",
1473  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
1475 }
1476 
1477 Vector
1479 {
1481  if (loc)
1482  {
1483  m_nodeLocation[n->GetId ()] = loc->GetPosition ();
1484  }
1485  else
1486  {
1487  NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
1488  m_nodeLocation[n->GetId ()] = Vector (0, 0, 0);
1489  }
1490  return m_nodeLocation[n->GetId ()];
1491 }
1492 
1493 Vector
1495 {
1496  m_nodeLocation[n->GetId ()] = v;
1497  return v;
1498 }
1499 
1500 Vector
1502 {
1503  if (m_nodeLocation.find (n->GetId ()) == m_nodeLocation.end ())
1504  {
1505  NS_FATAL_ERROR ("Node:" <<n->GetId () << " not found in Location table");
1506  }
1507  return m_nodeLocation[n->GetId ()];
1508 }
1509 
1510 
1511 std::string
1513 {
1514  Address nodeAddr = nd->GetAddress ();
1515  std::ostringstream oss;
1516  oss << nodeAddr;
1517  return oss.str ().substr (6); // Skip the first 6 chars to get the Mac
1518 }
1519 
1520 std::string
1522 {
1523  Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
1524  if (!ipv4)
1525  {
1526  NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1527  return "0.0.0.0";
1528  }
1529  int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
1530  if (ifIndex == -1)
1531  {
1532  NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1533  return "0.0.0.0";
1534  }
1535  Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, 0);
1536  std::ostringstream oss;
1537  oss << addr.GetLocal ();
1538  return oss.str ();
1539 }
1540 
1541 void
1543 {
1544  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1545  {
1546  Ptr<Node> n = *i;
1547  UpdatePosition (n);
1548  uint32_t n1Id = n->GetId ();
1549  uint32_t nDev = n->GetNDevices (); // Number of devices
1550  for (uint32_t i = 0; i < nDev; ++i)
1551  {
1552  Ptr<NetDevice> dev = n->GetDevice (i);
1553  NS_ASSERT (dev);
1554  Ptr<Channel> ch = dev->GetChannel ();
1555  if (!ch)
1556  {
1557  NS_LOG_DEBUG ("No channel can't be a p2p device");
1558  // Try to see if it is an LTE NetDevice, which does not return a channel
1559  if ((dev->GetInstanceTypeId ().GetName () == "ns3::LteUeNetDevice") ||
1560  (dev->GetInstanceTypeId ().GetName () == "ns3::LteEnbNetDevice")||
1561  (dev->GetInstanceTypeId ().GetName () == "ns3::VirtualNetDevice"))
1562  {
1563  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), dev->GetInstanceTypeId ().GetName ());
1565  }
1566  continue;
1567  }
1568  std::string channelType = ch->GetInstanceTypeId ().GetName ();
1569  NS_LOG_DEBUG ("Got ChannelType" << channelType);
1570  if (channelType == std::string ("ns3::PointToPointChannel"))
1571  { // Since these are duplex links, we only need to dump
1572  // if srcid < dstid
1573  uint32_t nChDev = ch->GetNDevices ();
1574  for (uint32_t j = 0; j < nChDev; ++j)
1575  {
1576  Ptr<NetDevice> chDev = ch->GetDevice (j);
1577  uint32_t n2Id = chDev->GetNode ()->GetId ();
1578  if (n1Id < n2Id)
1579  {
1580  // ouptut the p2p link
1581  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << ":" << GetMacAddress (dev) << "----" << GetIpv4Address (chDev) << ":" << GetMacAddress (chDev));
1584  P2pLinkNodeIdPair p2pPair;
1585  p2pPair.fromNode = n1Id;
1586  p2pPair.toNode = n2Id;
1587  LinkProperties lp = {GetIpv4Address (dev) + "~" + GetMacAddress (dev), GetIpv4Address (chDev) + "~" + GetMacAddress (chDev), ""};
1588  m_linkProperties[p2pPair] = lp;
1589  WriteXmlLink (n1Id, 0, n2Id);
1590  }
1591  }
1592  }
1593  else
1594  {
1595  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << " Channel Type:" << channelType << " Mac: " << GetMacAddress (dev));
1596  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
1598  }
1599  }
1600  }
1601  m_linkProperties.clear ();
1602 }
1603 
1604 void
1606 {
1607  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1608  {
1609  Ptr<Node> n = *i;
1610  NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
1611  Vector v = UpdatePosition (n);
1612  WriteXmlNode (n->GetId (), n->GetSystemId (), v.x, v.y);
1613  }
1614 }
1615 
1616 void
1618 {
1619  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1620  {
1621  Ptr<Node> n = *i;
1622  Rgb rgb = {255, 0, 0};
1623  if (m_nodeColors.find (n->GetId ()) == m_nodeColors.end ())
1624  {
1625  m_nodeColors[n->GetId ()] = rgb;
1626  }
1627  UpdateNodeColor (n, rgb.r, rgb.g, rgb.b);
1628  }
1629 }
1630 
1631 void
1633 {
1634  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1635  {
1636  Ptr<Node> n = *i;
1637  NS_LOG_INFO ("Update Size for Node: " << n->GetId ());
1638  AnimationInterface::NodeSize s = { 1, 1 };
1639  m_nodeSizes[n->GetId ()] = s;
1640  UpdateNodeSize (n->GetId (), s.width, s.height);
1641  }
1642 }
1643 
1644 void
1646 {
1648  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1649  {
1650  Ptr<Node> n = *i;
1651  if (NodeList::GetNode (n->GetId ())->GetObject<EnergySource> ())
1652  {
1654  }
1655  }
1656 }
1657 
1658 bool
1660 {
1661  if ((Simulator::Now () >= m_startTime) &&
1662  (Simulator::Now () <= m_stopTime))
1663  return true;
1664  else
1665  return false;
1666 }
1667 
1668 void
1669 AnimationInterface::SetOutputFile (const std::string& fn, bool routing)
1670 {
1671  if (!routing && m_f)
1672  {
1673  return;
1674  }
1675  if (routing && m_routingF)
1676  {
1677  NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
1678  return;
1679  }
1680 
1681  NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
1682  FILE * f = 0;
1683  f = std::fopen (fn.c_str (), "w");
1684  if (!f)
1685  {
1686  NS_FATAL_ERROR ("Unable to open output file:" << fn.c_str ());
1687  return; // Can't open output file
1688  }
1689  if (routing)
1690  {
1691  m_routingF = f;
1692  m_routingFileName = fn;
1693  }
1694  else
1695  {
1696  m_f = f;
1697  m_outputFileName = fn;
1698  }
1699  return;
1700 }
1701 
1702 void
1704 {
1705  // Start a new trace file if the current packet count exceeded nax packets per file
1708  {
1709  return;
1710  }
1711  NS_LOG_UNCOND ("Max Packets per trace file exceeded");
1712  StopAnimation (true);
1713 }
1714 
1715 std::string
1717 {
1718  return NETANIM_VERSION;
1719 }
1720 
1721 
1722 // Routing
1723 
1724 void
1726 {
1727  if (m_ipv4RouteTrackElements.empty ())
1728  {
1729  return;
1730  }
1731  for (std::vector <Ipv4RouteTrackElement>::const_iterator i = m_ipv4RouteTrackElements.begin ();
1732  i != m_ipv4RouteTrackElements.end ();
1733  ++i)
1734  {
1735  Ipv4RouteTrackElement trackElement = *i;
1736  Ptr <Node> fromNode = NodeList::GetNode (trackElement.fromNodeId);
1737  if (!fromNode)
1738  {
1739  NS_FATAL_ERROR ("Node: " << trackElement.fromNodeId << " Not found");
1740  continue;
1741  }
1742  Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
1743  if (!ipv4)
1744  {
1745  NS_LOG_WARN ("ipv4 object not found");
1746  continue;
1747  }
1749  if (!rp)
1750  {
1751  NS_LOG_WARN ("Routing protocol object not found");
1752  continue;
1753  }
1754  NS_LOG_INFO ("Begin Track Route for: " << trackElement.destination.c_str () << " From:" << trackElement.fromNodeId);
1755  Ptr<Packet> pkt = Create<Packet> ();
1756  Ipv4Header header;
1757  header.SetDestination (Ipv4Address (trackElement.destination.c_str ()));
1758  Socket::SocketErrno sockerr;
1759  Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
1760  Ipv4RoutePathElements rpElements;
1761  if (!rt)
1762  {
1763  NS_LOG_INFO ("No route to :" << trackElement.destination.c_str ());
1764  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
1765  rpElements.push_back (elem);
1766  WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
1767  continue;
1768  }
1769  std::ostringstream oss;
1770  oss << rt->GetGateway ();
1771  NS_LOG_INFO ("Node:" << trackElement.fromNodeId << "-->" << rt->GetGateway ());
1772  if (rt->GetGateway () == "0.0.0.0")
1773  {
1774  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "C" };
1775  rpElements.push_back (elem);
1776  if ( m_ipv4ToNodeIdMap.find (trackElement.destination) != m_ipv4ToNodeIdMap.end ())
1777  {
1778  Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[trackElement.destination], "L" };
1779  rpElements.push_back (elem2);
1780  }
1781  }
1782  else if (rt->GetGateway () == "127.0.0.1")
1783  {
1784  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
1785  rpElements.push_back (elem);
1786  }
1787  else
1788  {
1789  Ipv4RoutePathElement elem = { trackElement.fromNodeId, oss.str () };
1790  rpElements.push_back (elem);
1791  }
1792  RecursiveIpv4RoutePathSearch (oss.str (), trackElement.destination, rpElements);
1793  WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
1794  }
1795 
1796 }
1797 
1798 void
1800 {
1802  {
1803  NS_LOG_INFO ("TrackQueueCounters Completed");
1804  return;
1805  }
1806  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1807  {
1808  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1812  }
1814 }
1815 
1816 void
1818 {
1820  {
1821  NS_LOG_INFO ("TrackWifiMacCounters Completed");
1822  return;
1823  }
1824  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1825  {
1826  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1831  }
1833 }
1834 
1835 void
1837 {
1839  {
1840  NS_LOG_INFO ("TrackWifiPhyCounters Completed");
1841  return;
1842  }
1843  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1844  {
1845  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1848  }
1850 }
1851 
1852 void
1854 {
1856  {
1857  NS_LOG_INFO ("TrackIpv4L3ProtocolCounters Completed");
1858  return;
1859  }
1860  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1861  {
1862  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1866  }
1868 }
1869 
1870 void
1872 {
1874  {
1875  NS_LOG_INFO ("TrackIpv4Route completed");
1876  return;
1877  }
1878  if (m_routingNc.GetN ())
1879  {
1880  for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
1881  {
1882  Ptr <Node> n = *i;
1884  }
1885  }
1886  else
1887  {
1888  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1889  {
1890  Ptr <Node> n = *i;
1892  }
1893  }
1896 }
1897 
1898 std::string
1900 {
1901 
1902  NS_ASSERT (n);
1903  Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
1904  if (!ipv4)
1905  {
1906  NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
1907  return "";
1908  }
1909  std::stringstream stream;
1910  Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
1911  ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
1912  return stream.str ();
1913 
1914 }
1915 
1916 void
1917 AnimationInterface::RecursiveIpv4RoutePathSearch (std::string from, std::string to, Ipv4RoutePathElements & rpElements)
1918 {
1919  NS_LOG_INFO ("RecursiveIpv4RoutePathSearch from:" << from.c_str () << " to:" << to.c_str ());
1920  if ((from == "0.0.0.0") || (from == "127.0.0.1"))
1921  {
1922  NS_LOG_INFO ("Got " << from.c_str () << " End recursion");
1923  return;
1924  }
1925  Ptr <Node> fromNode = NodeList::GetNode (m_ipv4ToNodeIdMap[from]);
1927  if (fromNode->GetId () == toNode->GetId ())
1928  {
1929  Ipv4RoutePathElement elem = { fromNode->GetId (), "L" };
1930  rpElements.push_back (elem);
1931  return;
1932  }
1933  if (!fromNode)
1934  {
1935  NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[from] << " Not found");
1936  return;
1937  }
1938  if (!toNode)
1939  {
1940  NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[to] << " Not found");
1941  return;
1942  }
1943  Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
1944  if (!ipv4)
1945  {
1946  NS_LOG_WARN ("ipv4 object not found");
1947  return;
1948  }
1950  if (!rp)
1951  {
1952  NS_LOG_WARN ("Routing protocol object not found");
1953  return;
1954  }
1955  Ptr<Packet> pkt = Create<Packet> ();
1956  Ipv4Header header;
1957  header.SetDestination (Ipv4Address (to.c_str ()));
1958  Socket::SocketErrno sockerr;
1959  Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
1960  if (!rt)
1961  {
1962  return;
1963  }
1964  NS_LOG_DEBUG ("Node: " << fromNode->GetId () << " G:" << rt->GetGateway ());
1965  std::ostringstream oss;
1966  oss << rt->GetGateway ();
1967  if (oss.str () == "0.0.0.0" && (sockerr != Socket::ERROR_NOROUTETOHOST))
1968  {
1969  NS_LOG_INFO ("Null gw");
1970  Ipv4RoutePathElement elem = { fromNode->GetId (), "C" };
1971  rpElements.push_back (elem);
1972  if ( m_ipv4ToNodeIdMap.find (to) != m_ipv4ToNodeIdMap.end ())
1973  {
1974  Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[to], "L" };
1975  rpElements.push_back (elem2);
1976  }
1977  return;
1978  }
1979  NS_LOG_INFO ("Node:" << fromNode->GetId () << "-->" << rt->GetGateway ());
1980  Ipv4RoutePathElement elem = { fromNode->GetId (), oss.str () };
1981  rpElements.push_back (elem);
1982  RecursiveIpv4RoutePathSearch (oss.str (), to, rpElements);
1983 
1984 }
1985 
1986 
1987 // XML
1988 
1990  m_tagName (tagName)
1991 {
1992  m_elementString = "<" + tagName + " ";
1993 }
1994 
1995 template <typename T>
1996 void
1998 {
1999  std::ostringstream oss;
2000  oss << std::setprecision (10);
2001  oss << value;
2002  m_elementString += attribute.c_str ();
2003  m_elementString += "=\"" + oss.str () + "\" ";
2004 }
2005 
2006 void
2008 {
2009  m_elementString += ">\n";
2010 }
2011 
2012 void
2014 {
2015  m_elementString += ">";
2016 }
2017 
2018 void
2020 {
2021  m_elementString += "\n";
2022 }
2023 
2024 void
2026 {
2027  m_elementString += e.GetElementString ();
2028 }
2029 
2030 std::string
2032 {
2033  return m_elementString;
2034 }
2035 
2036 
2037 void
2039 {
2040  AnimXmlElement element ("anim");
2041  element.AddAttribute ("ver", GetNetAnimVersion ());
2042  FILE * f = m_f;
2043  if (!routing)
2044  {
2045  element.AddAttribute ("filetype", "animation");
2046  }
2047  else
2048  {
2049  element.AddAttribute ("filetype", "routing");
2050  f = m_routingF;
2051  }
2052  element.Close ();
2053  WriteN (element.GetElementString (), f);
2054 }
2055 
2056 void
2057 AnimationInterface::WriteXmlClose (std::string name, bool routing)
2058 {
2059  std::string closeString = "</" + name + ">\n";
2060  if (!routing)
2061  {
2062  WriteN (closeString, m_f);
2063  }
2064  else
2065  {
2066  WriteN (closeString, m_routingF);
2067  }
2068 }
2069 
2070 void
2071 AnimationInterface::WriteXmlNode (uint32_t id, uint32_t sysId, double locX, double locY)
2072 {
2073  AnimXmlElement element ("node");
2074  element.AddAttribute ("id", id);
2075  element.AddAttribute ("sysId", sysId);
2076  element.AddAttribute ("locX", locX);
2077  element.AddAttribute ("locY", locY);
2078  element.Close ();
2079  WriteN (element.GetElementString (), m_f);
2080 }
2081 
2082 void
2083 AnimationInterface::WriteXmlUpdateLink (uint32_t fromId, uint32_t toId, std::string linkDescription)
2084 {
2085  AnimXmlElement element ("linkupdate");
2086  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2087  element.AddAttribute ("fromId", fromId);
2088  element.AddAttribute ("toId", toId);
2089  element.AddAttribute ("ld", linkDescription);
2090  element.Close ();
2091  WriteN (element.GetElementString (), m_f);
2092 }
2093 
2094 void
2095 AnimationInterface::WriteXmlLink (uint32_t fromId, uint32_t toLp, uint32_t toId)
2096 {
2097  AnimXmlElement element ("link");
2098  element.AddAttribute ("fromId", fromId);
2099  element.AddAttribute ("toId", toId);
2100 
2101  LinkProperties lprop ;
2102  lprop.fromNodeDescription = "";
2103  lprop.toNodeDescription = "";
2104  lprop.linkDescription = "";
2105 
2106  P2pLinkNodeIdPair p1 = { fromId, toId };
2107  P2pLinkNodeIdPair p2 = { toId, fromId };
2108  if (m_linkProperties.find (p1) != m_linkProperties.end ())
2109  {
2110  lprop = m_linkProperties[p1];
2111  }
2112  else if (m_linkProperties.find (p2) != m_linkProperties.end ())
2113  {
2114  lprop = m_linkProperties[p2];
2115  }
2116 
2117  element.AddAttribute ("fd", lprop.fromNodeDescription);
2118  element.AddAttribute ("td", lprop.toNodeDescription);
2119  element.AddAttribute ("ld", lprop.linkDescription);
2120  element.Close ();
2121  WriteN (element.GetElementString (), m_f);
2122 }
2123 
2124 void
2125 AnimationInterface::WriteXmlRouting (uint32_t nodeId, std::string routingInfo)
2126 {
2127  AnimXmlElement element ("rt");
2128  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2129  element.AddAttribute ("id", nodeId);
2130  element.AddAttribute ("info", routingInfo.c_str ());
2131  element.Close ();
2132  WriteN (element.GetElementString (), m_routingF);
2133 }
2134 
2135 void
2136 AnimationInterface::WriteXmlRp (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
2137 {
2138  AnimXmlElement element ("rp");
2139  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2140  element.AddAttribute ("id", nodeId);
2141  element.AddAttribute ("d", destination.c_str ());
2142  element.AddAttribute ("c", rpElements.size ());
2143  element.CloseTag ();
2144  element.AddLineBreak ();
2145  for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
2146  i != rpElements.end ();
2147  ++i)
2148  {
2149  Ipv4RoutePathElement rpElement = *i;
2150  AnimXmlElement rpeElement ("rpe");
2151  rpeElement.AddAttribute ("n", rpElement.nodeId);
2152  rpeElement.AddAttribute ("nH", rpElement.nextHop.c_str ());
2153  rpeElement.Close ();
2154  element.Add (rpeElement);
2155  }
2156  WriteN (element.GetElementString (), m_routingF);
2157 }
2158 
2159 
2160 void
2161 AnimationInterface::WriteXmlPRef (uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo)
2162 {
2163  AnimXmlElement element ("pr");
2164  element.AddAttribute ("uId", animUid);
2165  element.AddAttribute ("fId", fId);
2166  element.AddAttribute ("fbTx", fbTx);
2167  if (!metaInfo.empty ())
2168  {
2169  element.AddAttribute ("meta-info", metaInfo.c_str ());
2170  }
2171  element.Close ();
2172  WriteN (element.GetElementString (), m_f);
2173 }
2174 
2175 void
2176 AnimationInterface::WriteXmlP (uint64_t animUid, std::string pktType, uint32_t tId, double fbRx, double lbRx)
2177 {
2178  AnimXmlElement element (pktType);
2179  element.AddAttribute ("uId", animUid);
2180  element.AddAttribute ("tId", tId);
2181  element.AddAttribute ("fbRx", fbRx);
2182  element.AddAttribute ("lbRx", lbRx);
2183  element.Close ();
2184  WriteN (element.GetElementString (), m_f);
2185 }
2186 
2187 void
2188 AnimationInterface::WriteXmlP (std::string pktType, uint32_t fId, double fbTx, double lbTx,
2189  uint32_t tId, double fbRx, double lbRx, std::string metaInfo)
2190 {
2191  AnimXmlElement element (pktType);
2192  element.AddAttribute ("fId", fId);
2193  element.AddAttribute ("fbTx", fbTx);
2194  element.AddAttribute ("lbTx", lbTx);
2195  if (!metaInfo.empty ())
2196  {
2197  element.AddAttribute ("meta-info", metaInfo.c_str ());
2198  }
2199  element.AddAttribute ("tId", tId);
2200  element.AddAttribute ("fbRx", fbRx);
2201  element.AddAttribute ("lbRx", lbRx);
2202  element.Close ();
2203  WriteN (element.GetElementString (), m_f);
2204 }
2205 
2206 void
2207 AnimationInterface::WriteXmlAddNodeCounter (uint32_t nodeCounterId, std::string counterName, CounterType counterType)
2208 {
2209  AnimXmlElement element ("ncs");
2210  element.AddAttribute ("ncId", nodeCounterId);
2211  element.AddAttribute ("n", counterName);
2212  element.AddAttribute ("t", CounterTypeToString (counterType));
2213  element.Close ();
2214  WriteN (element.GetElementString (), m_f);
2215 }
2216 
2217 void
2218 AnimationInterface::WriteXmlAddResource (uint32_t resourceId, std::string resourcePath)
2219 {
2220  AnimXmlElement element ("res");
2221  element.AddAttribute ("rid", resourceId);
2222  element.AddAttribute ("p", resourcePath);
2223  element.Close ();
2224  WriteN (element.GetElementString (), m_f);
2225 }
2226 
2227 void
2228 AnimationInterface::WriteXmlUpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
2229 {
2230  AnimXmlElement element ("nu");
2231  element.AddAttribute ("p", "i");
2232  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2233  element.AddAttribute ("id", nodeId);
2234  element.AddAttribute ("rid", resourceId);
2235  element.Close ();
2236  WriteN (element.GetElementString (), m_f);
2237 }
2238 
2239 void
2240 AnimationInterface::WriteXmlUpdateNodeSize (uint32_t nodeId, double width, double height)
2241 {
2242  AnimXmlElement element ("nu");
2243  element.AddAttribute ("p", "s");
2244  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2245  element.AddAttribute ("id", nodeId);
2246  element.AddAttribute ("w", width);
2247  element.AddAttribute ("h", height);
2248  element.Close ();
2249  WriteN (element.GetElementString (), m_f);
2250 }
2251 
2252 void
2253 AnimationInterface::WriteXmlUpdateNodePosition (uint32_t nodeId, double x, double y)
2254 {
2255  AnimXmlElement element ("nu");
2256  element.AddAttribute ("p", "p");
2257  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2258  element.AddAttribute ("id", nodeId);
2259  element.AddAttribute ("x", x);
2260  element.AddAttribute ("y", y);
2261  element.Close ();
2262  WriteN (element.GetElementString (), m_f);
2263 }
2264 
2265 void
2266 AnimationInterface::WriteXmlUpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
2267 {
2268  AnimXmlElement element ("nu");
2269  element.AddAttribute ("p", "c");
2270  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2271  element.AddAttribute ("id", nodeId);
2272  element.AddAttribute ("r", (uint32_t) r);
2273  element.AddAttribute ("g", (uint32_t) g);
2274  element.AddAttribute ("b", (uint32_t) b);
2275  element.Close ();
2276  WriteN (element.GetElementString (), m_f);
2277 }
2278 
2279 void
2281 {
2282  AnimXmlElement element ("nu");
2283  element.AddAttribute ("p", "d");
2284  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2285  element.AddAttribute ("id", nodeId);
2286  if (m_nodeDescriptions.find (nodeId) != m_nodeDescriptions.end ())
2287  {
2288  element.AddAttribute ("descr", m_nodeDescriptions[nodeId]);
2289  }
2290  element.Close ();
2291  WriteN (element.GetElementString (), m_f);
2292 }
2293 
2294 
2295 void
2296 AnimationInterface::WriteXmlUpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counterValue)
2297 {
2298  AnimXmlElement element ("nc");
2299  element.AddAttribute ("c", nodeCounterId);
2300  element.AddAttribute ("i", nodeId);
2301  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2302  element.AddAttribute ("v", counterValue);
2303  element.Close ();
2304  WriteN (element.GetElementString (), m_f);
2305 }
2306 
2307 void
2308 AnimationInterface::WriteXmlUpdateBackground (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
2309 {
2310  AnimXmlElement element ("bg");
2311  element.AddAttribute ("f", fileName);
2312  element.AddAttribute ("x", x);
2313  element.AddAttribute ("y", y);
2314  element.AddAttribute ("sx", scaleX);
2315  element.AddAttribute ("sy", scaleY);
2316  element.AddAttribute ("o", opacity);
2317  element.Close ();
2318  WriteN (element.GetElementString (), m_f);
2319 }
2320 
2321 void
2322 AnimationInterface::WriteXmlNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
2323 {
2324  AnimXmlElement element ("nonp2plinkproperties");
2325  element.AddAttribute ("id", id);
2326  element.AddAttribute ("ipv4Address", ipv4Address);
2327  element.AddAttribute ("channelType", channelType);
2328  element.Close ();
2329  WriteN (element.GetElementString (), m_f);
2330 }
2331 
2332 TypeId
2334 {
2335  static TypeId tid = TypeId ("ns3::AnimByteTag")
2336  .SetParent<Tag> ()
2337  .SetGroupName ("NetAnim")
2338  .AddConstructor<AnimByteTag> ()
2339  ;
2340  return tid;
2341 }
2342 
2343 TypeId
2345 {
2346  return GetTypeId ();
2347 }
2348 
2349 uint32_t
2351 {
2352  return sizeof (uint64_t);
2353 }
2354 
2355 void
2357 {
2358  i.WriteU64 (m_AnimUid);
2359 }
2360 
2361 void
2363 {
2364  m_AnimUid = i.ReadU64 ();
2365 }
2366 
2367 void
2368 AnimByteTag::Print (std::ostream &os) const
2369 {
2370  os << "AnimUid=" << m_AnimUid;
2371 }
2372 
2373 void
2374 AnimByteTag::Set (uint64_t AnimUid)
2375 {
2376  m_AnimUid = AnimUid;
2377 }
2378 
2379 uint64_t
2380 AnimByteTag::Get (void) const
2381 {
2382  return m_AnimUid;
2383 }
2384 
2386  : m_txnd (0),
2387  m_txNodeId (0),
2388  m_fbTx (0),
2389  m_lbTx (0),
2390  m_lbRx (0)
2391 {
2392 }
2393 
2395 {
2396  m_txnd = pInfo.m_txnd;
2397  m_txNodeId = pInfo.m_txNodeId;
2398  m_fbTx = pInfo.m_fbTx;
2399  m_lbTx = pInfo.m_lbTx;
2400  m_lbRx = pInfo.m_lbRx;
2401 }
2402 
2404  const Time fbTx,
2405  uint32_t txNodeId)
2406  : m_txnd (txnd),
2407  m_txNodeId (0),
2408  m_fbTx (fbTx.GetSeconds ()),
2409  m_lbTx (0),
2410  m_lbRx (0)
2411 {
2412  if (!m_txnd)
2413  m_txNodeId = txNodeId;
2414 }
2415 
2416 void
2418 {
2419  Ptr <Node> n = nd->GetNode ();
2420  m_fbRx = fbRx;
2421  m_rxnd = nd;
2422 }
2423 
2424 } // namespace ns3
bool HasNext(void) const
Definition: packet.cc:65
uint64_t GetAnimUidFromPacket(Ptr< const Packet >)
void Set(uint64_t AnimUid)
Set global Uid in tag.
uint64_t GetTracePktCount()
Get trace file packet count (This used only for testing)
void AddToIpv4AddressNodeIdTable(std::string, uint32_t)
void UpdateNodeImage(uint32_t nodeId, uint32_t resourceId)
Helper function to update the image of a node.
void WriteXmlRp(uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
void AddPendingPacket(ProtocolType protocolType, uint64_t animUid, AnimPacketInfo pktInfo)
void CsmaMacRxTrace(std::string context, Ptr< const Packet > p)
void WriteXmlNonP2pLinkProperties(uint32_t id, std::string ipv4Address, std::string channelType)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
NodeCounterMap64 m_nodeQueueDequeue
void WifiMacRxTrace(std::string context, Ptr< const Packet >)
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Ipv4Address GetLocal(void) const
Get the local address.
std::string GetIpv4Address(Ptr< NetDevice > nd)
std::string CounterTypeToString(CounterType counterType)
void WriteU64(uint64_t v)
Definition: tag-buffer.cc:102
AnimationInterface(const std::string filename)
Constructor.
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
AnimationInterface & AddSourceDestination(uint32_t fromNodeId, std::string destinationIpv4Address)
Helper function to print the routing path from a source node to destination IP.
void WriteXmlUpdateNodeImage(uint32_t nodeId, uint32_t resourceId)
static TypeId GetTypeId(void)
Get Type Id.
Introspection did not find any typical Config paths.
Definition: energy-source.h:81
void CsmaPhyTxBeginTrace(std::string context, Ptr< const Packet > p)
Ptr< LteEnbPhy > GetPhy(void) const
Mobility model for which the current position does not change once it has been set and until it is se...
AnimUidPacketInfoMap m_pendingWifiPackets
void WriteXmlUpdateNodePosition(uint32_t nodeId, double x, double y)
NodeDescriptionsMap m_nodeDescriptions
static bool IsInitialized(void)
Check if AnimationInterface is initialized.
void PurgePendingPackets(ProtocolType protocolType)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void QueueDropTrace(std::string context, Ptr< const Packet >)
#define NETANIM_VERSION
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
std::map< std::string, uint32_t > m_macToNodeIdMap
void LteSpectrumPhyRxStart(std::string context, Ptr< const PacketBurst > pb)
Ptr< NetDevice > GetNetDeviceFromContext(std::string context)
Vector GetPosition(void) const
void WifiPhyTxBeginTrace(std::string context, Ptr< const Packet > p)
void EnableWifiPhyCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Wifi Phy Counters such as TxDrop, RxDrop.
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
void WriteXmlAnim(bool routing=false)
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
NodeCounterMap64 m_nodeWifiPhyTxDrop
void LteTxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &)
void WimaxRxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &)
std::map< std::string, uint32_t > m_ipv4ToNodeIdMap
void RecursiveIpv4RoutePathSearch(std::string fromIpv4, std::string toIpv4, Ipv4RoutePathElements &)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
void UpdateNodeSize(uint32_t nodeId, double width, double height)
Helper function to update the size of a node.
virtual void Deserialize(TagBuffer i)
Deserialize function.
void WriteXmlAddNodeCounter(uint32_t counterId, std::string counterName, CounterType counterType)
void ProcessRxBegin(Ptr< const NetDevice > nd, const double fbRx)
void ConnectLteEnb(Ptr< Node > n, Ptr< LteEnbNetDevice > nd, uint32_t devIndex)
std::string GetIpv4RoutingTable(Ptr< Node > n)
void WriteXmlUpdateNodeSize(uint32_t nodeId, double width, double height)
void Print(std::ostream &os) const
Print the packet contents.
Definition: packet.cc:424
void WriteXmlUpdateNodeColor(uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
void SetStartTime(Time t)
Specify the time at which capture should start.
void SetStopTime(Time t)
Specify the time at which capture should stop.
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(void) const =0
Get the routing protocol to be used by this Ipv4 stack.
std::vector< Ptr< Node > > GetMovedNodes()
LinkPropertiesMap m_linkProperties
uint32_t GetSystemId(void) const
Definition: node.cc:114
void WifiPhyRxBeginTrace(std::string context, Ptr< const Packet > p)
void Ipv4TxTrace(std::string context, Ptr< const Packet >, Ptr< Ipv4 >, uint32_t)
void UpdateNodeColor(Ptr< Node > n, uint8_t r, uint8_t g, uint8_t b)
Helper function to update the node color.
double stopTime
void WriteXmlAddResource(uint32_t resourceId, std::string resourcePath)
void ResetAnimWriteCallback()
Reset the write callback function.
NodeCounterMap64 m_nodeWifiMacTx
AnimWriteCallback m_writeCallback
a polymophic address class
Definition: address.h:90
void AddAttribute(std::string attribute, T value)
void UanPhyGenTxTrace(std::string context, Ptr< const Packet >)
static void SetConstantPosition(Ptr< Node > n, double x, double y, double z=0)
Helper function to set Constant Position for a given node.
void WriteXmlUpdateLink(uint32_t fromId, uint32_t toId, std::string)
uint32_t GetN(void) const
Get the number of Ptr stored in this container.
DropReason
Reason why a packet has been dropped.
void ConnectLteUe(Ptr< Node > n, Ptr< LteUeNetDevice > nd, uint32_t devIndex)
std::map< uint32_t, Vector > m_nodeLocation
virtual void Print(std::ostream &os) const
Print tag info.
Keep track of the current position and velocity of an object.
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:334
void SetBackgroundImage(std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
Helper function to set the background image.
void CsmaPhyRxEndTrace(std::string context, Ptr< const Packet > p)
Identifies a byte tag and a set of bytes within a packet to which the tag applies.
Definition: packet.h:60
void RemainingEnergyTrace(std::string context, double previousEnergy, double currentEnergy)
void WifiMacRxDropTrace(std::string context, Ptr< const Packet >)
void WriteXmlClose(std::string name, bool routing=false)
void OutputWirelessPacketTxInfo(Ptr< const Packet > p, AnimPacketInfo &pktInfo, uint64_t animUid)
void EnableWifiMacCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Wifi Mac Counters such as Tx, TxDrop, Rx, RxDrop.
static void EnablePrinting(void)
Enable printing packets metadata.
Definition: packet.cc:547
void UpdateNodeCounter(uint32_t nodeCounterId, uint32_t nodeId, double counter)
Helper function to update a node's counter referenced by the nodeCounterId.
uint32_t AddNodeCounter(std::string counterName, CounterType counterType)
Setup a node counter.
~AnimationInterface()
Destructor for the animator interface.
AnimUidPacketInfoMap m_pendingWimaxPackets
EnergyFractionMap m_nodeEnergyFraction
void SkipPacketTracing()
Do not trace packets.
double startTime
static Iterator End(void)
Definition: node-list.cc:235
uint8_t data[writeSize]
double GetNodeEnergyFraction(Ptr< const Node > node) const
Get node's energy fraction (This used only for testing)
Ptr< Node > GetNodeFromContext(const std::string &context) const
void DequeueTrace(std::string context, Ptr< const Packet >)
NodeCounterMap64 m_nodeIpv4Drop
void UanPhyGenRxTrace(std::string context, Ptr< const Packet >)
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:135
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1296
ByteTagIterator GetByteTagIterator(void) const
Retiurns an iterator over the set of byte tags included in this packet.
Definition: packet.cc:813
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:733
void WriteXmlP(std::string pktType, uint32_t fId, double fbTx, double lbTx, uint32_t tId, double fbRx, double lbRx, std::string metaInfo="")
Item Next(void)
Definition: packet.cc:70
void WifiMacTxTrace(std::string context, Ptr< const Packet >)
void StartAnimation(bool restart=false)
void WriteXmlNode(uint32_t id, uint32_t sysId, double locX, double locY)
std::vector< Ipv4RoutePathElement > Ipv4RoutePathElements
AnimationInterface & EnableIpv4RouteTracking(std::string fileName, Time startTime, Time stopTime, Time pollInterval=Seconds(5))
Enable tracking of the Ipv4 routing table for all Nodes.
std::map< uint32_t, NodeSize > m_nodeSizes
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:246
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:744
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
#define list
void CsmaPhyTxEndTrace(std::string context, Ptr< const Packet > p)
std::string GetPacketMetadata(Ptr< const Packet > p)
std::vector< std::string > m_resources
int WriteN(const char *, uint32_t, FILE *f)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
void DevTxTrace(std::string context, Ptr< const Packet > p, Ptr< NetDevice > tx, Ptr< NetDevice > rx, Time txTime, Time rxTime)
uint32_t GetNDevices(void) const
Definition: node.cc:143
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
tag a set of bytes in a packet
Definition: tag.h:36
void WriteXmlRouting(uint32_t id, std::string routingInfo)
void Ipv4RxTrace(std::string context, Ptr< const Packet >, Ptr< Ipv4 >, uint32_t)
void WriteXmlPRef(uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo="")
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void UpdateLinkDescription(uint32_t fromNode, uint32_t toNode, std::string linkDescription)
Helper function to update the description for a link.
uint64_t ReadU64(void)
Definition: tag-buffer.cc:134
uint32_t AddResource(std::string resourcePath)
Add a resource such as the path to an image file.
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Definition: node-list.h:44
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
void SetMaxPktsPerTraceFile(uint64_t maxPktsPerFile)
Set Max packets per trace file.
bool NodeHasMoved(Ptr< Node > n, Vector newLocation)
Iterator over the set of byte tags in a packet.
Definition: packet.h:53
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionaly.
an EUI-48 address
Definition: mac48-address.h:43
NodeCounterMap64 m_nodeQueueDrop
AnimUidPacketInfoMap m_pendingLtePackets
void EnablePacketMetadata(bool enable=true)
Enable Packet metadata.
std::map< uint64_t, AnimPacketInfo > AnimUidPacketInfoMap
TypeId GetTypeId(void) const
Definition: packet.cc:34
virtual void Serialize(TagBuffer i) const
Serialize function.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
const std::vector< std::string > GetElementsFromContext(const std::string &context) const
void WriteXmlUpdateNodeDescription(uint32_t nodeId)
void EnqueueTrace(std::string context, Ptr< const Packet >)
Byte tag using by Anim to uniquely identify packets.
virtual TypeId GetInstanceTypeId(void) const
Get Instance Type Id.
void StopAnimation(bool onlyAnimation=false)
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition: packet.cc:49
void WriteXmlUpdateNodeCounter(uint32_t counterId, uint32_t nodeId, double value)
Vector UpdatePosition(Ptr< Node > n)
uint64_t Get(void) const
Get Uid in tag.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
std::vector< Ipv4RouteTrackElement > m_ipv4RouteTrackElements
NodeCounterMap64 m_nodeWifiMacRxDrop
void WifiMacTxDropTrace(std::string context, Ptr< const Packet >)
void MobilityCourseChangeTrace(Ptr< const MobilityModel > mob)
read and write tag data
Definition: tag-buffer.h:51
NodeCounterMap64 m_nodeWifiPhyRxDrop
bool IsPacketPending(uint64_t animUid, ProtocolType protocolType)
uint32_t GetId(void) const
Definition: node.cc:107
a class to store IPv4 address information on an interface
static bool initialized
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
std::string GetMacAddress(Ptr< NetDevice > nd)
static Iterator Begin(void)
Definition: node-list.cc:229
NodeCounterMap64 m_nodeWifiMacRx
AnimUidPacketInfoMap m_pendingUanPackets
#define MAX_PKTS_PER_TRACE_FILE
void AddByteTag(uint64_t animUid, Ptr< const Packet > p)
A network Node.
Definition: node.h:55
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:866
void WriteXmlUpdateBackground(std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
virtual uint32_t GetSerializedSize(void) const
Get Serialized Size.
Interface to network animator.
void WriteNonP2pLinkProperties(uint32_t id, std::string ipv4Address, std::string channelType)
void OutputWirelessPacketRxInfo(Ptr< const Packet > p, AnimPacketInfo &pktInfo, uint64_t animUid)
static bool IsFinished(void)
Check if the simulation should finish.
Definition: simulator.cc:193
void SetAnimWriteCallback(AnimWriteCallback cb)
Set a callback function to listen to AnimationInterface write events.
void SetMobilityPollInterval(Time t)
Set mobility poll interval:WARNING: setting a low interval can cause slowness.
void Ipv4DropTrace(std::string context, const Ipv4Header &, Ptr< const Packet >, Ipv4L3Protocol::DropReason, Ptr< Ipv4 >, uint32_t)
NodeCounterMap64 m_nodeQueueEnqueue
void WriteRoutePath(uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
bool IsStarted(void)
Is AnimationInterface started.
void EnableIpv4L3ProtocolCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Ipv4 L3 Protocol Counters such as Tx, Rx, Drop.
AnimUidPacketInfoMap * ProtocolTypeToPendingPackets(ProtocolType protocolType)
void EnableQueueCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Queue Counters such as Enqueue, Dequeue, Queue Drops.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
void WifiPhyRxDropTrace(std::string context, Ptr< const Packet >)
Vector GetPosition(Ptr< Node > n)
a unique identifier for an interface.
Definition: type-id.h:57
NodeCounterMap64 m_nodeWifiMacTxDrop
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638
std::vector< std::string > m_nodeCounters
void WifiPhyTxDropTrace(std::string context, Ptr< const Packet >)
void LteRxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &)
void UpdateNodeDescription(Ptr< Node > n, std::string descr)
Helper function to update the description for a given node.
void OutputCsmaPacket(Ptr< const Packet > p, AnimPacketInfo &pktInfo)
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
#define PURGE_INTERVAL
void SetOutputFile(const std::string &fn, bool routing=false)
void LteSpectrumPhyTxStart(std::string context, Ptr< const PacketBurst > pb)
AnimUidPacketInfoMap m_pendingCsmaPackets
void WriteXmlLink(uint32_t fromId, uint32_t toLp, uint32_t toId)
void WimaxTxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &)
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:803