A Discrete-Event Network Simulator
API
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  * Contributions: Eugene Kalishenko <ydginster@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
19  */
20 
21 // Interface between ns-3 and the network animator
22 
23 
24 
25 #include <cstdio>
26 #include <unistd.h>
27 #include <sstream>
28 #include <fstream>
29 #include <string>
30 #include <iomanip>
31 #include <map>
32 
33 // ns3 includes
34 #include "ns3/animation-interface.h"
35 #include "ns3/channel.h"
36 #include "ns3/config.h"
37 #include "ns3/node.h"
38 #include "ns3/mobility-model.h"
39 #include "ns3/packet.h"
40 #include "ns3/simulator.h"
41 #include "ns3/wifi-mac-header.h"
42 #include "ns3/wimax-mac-header.h"
43 #include "ns3/wifi-net-device.h"
44 #include "ns3/wifi-mac.h"
45 #include "ns3/constant-position-mobility-model.h"
46 #include "ns3/lte-ue-phy.h"
47 #include "ns3/lte-enb-phy.h"
48 #include "ns3/uan-net-device.h"
49 #include "ns3/uan-mac.h"
50 #include "ns3/ipv4.h"
51 #include "ns3/ipv4-routing-protocol.h"
52 #include "ns3/energy-source-container.h"
53 
54 namespace ns3 {
55 
56 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
57 
58 // Globals
59 
60 static bool initialized = false;
61 
62 
63 // Public methods
64 
66  : m_f (0),
67  m_routingF (0),
68  m_mobilityPollInterval (Seconds (0.25)),
69  m_outputFileName (fn),
70  gAnimUid (0),
71  m_writeCallback (0),
72  m_started (false),
73  m_enablePacketMetadata (false),
74  m_startTime (Seconds (0)),
75  m_stopTime (Seconds (3600 * 1000)),
76  m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE),
77  m_originalFileName (fn),
78  m_routingStopTime (Seconds (0)),
79  m_routingFileName (""),
80  m_routingPollInterval (Seconds (5)),
81  m_trackPackets (true)
82 {
83  initialized = true;
84  StartAnimation ();
85 }
86 
88 {
89  StopAnimation ();
90 }
91 
92 void
94 {
95  m_trackPackets = false;
96 }
97 
98 void
100 {
102  m_wifiPhyCountersPollInterval = pollInterval;
105  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
106  {
107  Ptr<Node> n = *i;
108  m_nodeWifiPhyTxDrop[n->GetId ()] = 0;
109  m_nodeWifiPhyRxDrop[n->GetId ()] = 0;
112  }
114 
115 }
116 
117 void
119 {
121  m_wifiMacCountersPollInterval = pollInterval;
126  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
127  {
128  Ptr<Node> n = *i;
129  m_nodeWifiMacTx[n->GetId ()] = 0;
130  m_nodeWifiMacTxDrop[n->GetId ()] = 0;
131  m_nodeWifiMacRx[n->GetId ()] = 0;
132  m_nodeWifiMacRxDrop[n->GetId ()] = 0;
137  }
139 }
140 
141 void
143 {
145  m_queueCountersPollInterval = pollInterval;
149  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
150  {
151  Ptr<Node> n = *i;
152  m_nodeQueueEnqueue[n->GetId ()] = 0;
153  m_nodeQueueDequeue[n->GetId ()] = 0;
154  m_nodeQueueDrop[n->GetId ()] = 0;
158  }
160 }
161 
162 void
164 {
170  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
171  {
172  Ptr<Node> n = *i;
173  m_nodeIpv4Tx[n->GetId ()] = 0;
174  m_nodeIpv4Rx[n->GetId ()] = 0;
175  m_nodeIpv4Drop[n->GetId ()] = 0;
179  }
181 }
182 
185 {
186  SetOutputFile (fileName, true);
188  m_routingPollInterval = pollInterval;
189  WriteXmlAnim (true);
191  return *this;
192 }
193 
196 {
197  m_routingNc = nc;
198  return EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
199 }
200 
202 AnimationInterface::AddSourceDestination (uint32_t fromNodeId, std::string ipv4Address)
203 {
204  Ipv4RouteTrackElement element = { ipv4Address, fromNodeId };
205  m_ipv4RouteTrackElements.push_back (element);
206  return *this;
207 }
208 
209 void
211 {
212  m_startTime = t;
213 }
214 
215 void
217 {
218  m_stopTime = t;
219 }
220 
221 void
222 AnimationInterface::SetMaxPktsPerTraceFile (uint64_t maxPacketsPerFile)
223 {
224  m_maxPktsPerFile = maxPacketsPerFile;
225 }
226 
227 uint32_t
228 AnimationInterface::AddNodeCounter (std::string counterName, CounterType counterType)
229 {
230  m_nodeCounters.push_back (counterName);
231  uint32_t counterId = m_nodeCounters.size () - 1; // counter ID is zero-indexed
232  WriteXmlAddNodeCounter (counterId, counterName, counterType);
233  return counterId;
234 }
235 
236 uint32_t
237 AnimationInterface::AddResource (std::string resourcePath)
238 {
239  m_resources.push_back (resourcePath);
240  uint32_t resourceId = m_resources.size () - 1; // resource ID is zero-indexed
241  WriteXmlAddResource (resourceId, resourcePath);
242  return resourceId;
243 }
244 
245 void
247 {
248  m_enablePacketMetadata = enable;
249  if (enable)
250  {
252  }
253 }
254 
255 bool
257 {
258  return initialized;
259 }
260 
261 bool
263 {
264  return m_started;
265 }
266 
267 void
269 {
270  m_writeCallback = cb;
271 }
272 
273 void
275 {
276  m_writeCallback = 0;
277 }
278 
279 void
281 {
283 }
284 
285 
286 void
287 AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
288 {
289  NS_ASSERT (n);
291  if (loc == 0)
292  {
293  loc = CreateObject<ConstantPositionMobilityModel> ();
294  n->AggregateObject (loc);
295  }
296  Vector hubVec (x, y, z);
297  loc->SetPosition (hubVec);
298  NS_LOG_INFO ("Node:" << n->GetId () << " Position set to:(" << x << "," << y << "," << z << ")");
299 
300 }
301 
302 void
303 AnimationInterface::UpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
304 {
305  NS_LOG_INFO ("Setting node image for Node Id:" << nodeId);
306  if (resourceId > (m_resources.size ()-1))
307  {
308  NS_FATAL_ERROR ("Resource Id:" << resourceId << " not found. Did you use AddResource?");
309  }
310  WriteXmlUpdateNodeImage (nodeId, resourceId);
311 }
312 
313 void
314 AnimationInterface::UpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counter)
315 {
316  if (nodeCounterId > (m_nodeCounters.size () - 1))
317  {
318  NS_FATAL_ERROR ("NodeCounter Id:" << nodeCounterId << " not found. Did you use AddNodeCounter?");
319  }
320  WriteXmlUpdateNodeCounter (nodeCounterId, nodeId, counter);
321 }
322 
323 void
324 AnimationInterface::SetBackgroundImage (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
325 {
326  if ((opacity < 0) || (opacity > 1))
327  {
328  NS_FATAL_ERROR ("Opacity must be between 0.0 and 1.0");
329  }
330  WriteXmlUpdateBackground (fileName, x, y, scaleX, scaleY, opacity);
331 }
332 
333 void
334 AnimationInterface::UpdateNodeSize (uint32_t nodeId, double width, double height)
335 {
336  AnimationInterface::NodeSize s = { width, height };
337  m_nodeSizes[nodeId] = s;
338  WriteXmlUpdateNodeSize (nodeId, s.width, s.height);
339 }
340 
341 void
342 AnimationInterface::UpdateNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
343 {
344  UpdateNodeColor (n->GetId (), r, g, b);
345 }
346 
347 void
348 AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
349 {
350  NS_ASSERT (NodeList::GetNode (nodeId));
351  NS_LOG_INFO ("Setting node color for Node Id:" << nodeId);
352  Rgb rgb = {r, g, b};
353  m_nodeColors[nodeId] = rgb;
354  WriteXmlUpdateNodeColor (nodeId, r, g, b);
355 }
356 
357 void
358 AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNode,
359  std::string linkDescription)
360 {
361  WriteXmlUpdateLink (fromNode, toNode, linkDescription);
362 }
363 
364 void
366  std::string linkDescription)
367 {
368  NS_ASSERT (fromNode);
369  NS_ASSERT (toNode);
370  WriteXmlUpdateLink (fromNode->GetId (), toNode->GetId (), linkDescription);
371 }
372 
373 void
375 {
376  UpdateNodeDescription (n->GetId (), descr);
377 }
378 
379 void
380 AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string descr)
381 {
382  NS_ASSERT (NodeList::GetNode (nodeId));
383  m_nodeDescriptions[nodeId] = descr;
385 }
386 
387 // Private methods
388 
389 
390 double
392 {
393  const EnergyFractionMap::const_iterator fractionIter = m_nodeEnergyFraction.find (node->GetId ());
394  NS_ASSERT (fractionIter != m_nodeEnergyFraction.end ());
395  return fractionIter->second;
396 }
397 
398 void
400 {
402  Ptr <Node> n = mobility->GetObject <Node> ();
403  NS_ASSERT (n);
404  Vector v ;
405  if (!mobility)
406  {
407  v = GetPosition (n);
408  }
409  else
410  {
411  v = mobility->GetPosition ();
412  }
413  UpdatePosition (n, v);
414  WriteXmlUpdateNodePosition (n->GetId (), v.x, v.y);
415 }
416 
417 bool
419 {
420  Vector oldLocation = GetPosition (n);
421  bool moved = true;
422  if ((ceil (oldLocation.x) == ceil (newLocation.x)) &&
423  (ceil (oldLocation.y) == ceil (newLocation.y)))
424  {
425  moved = false;
426  }
427  else
428  {
429  moved = true;
430  }
431  return moved;
432 }
433 
434 void
436 {
438  std::vector <Ptr <Node> > MovedNodes = GetMovedNodes ();
439  for (uint32_t i = 0; i < MovedNodes.size (); i++)
440  {
441  Ptr <Node> n = MovedNodes [i];
442  NS_ASSERT (n);
443  Vector v = GetPosition (n);
444  WriteXmlUpdateNodePosition (n->GetId () , v.x, v.y);
445  }
446  if (!Simulator::IsFinished ())
447  {
453  }
454 }
455 
456 std::vector <Ptr <Node> >
458 {
459  std::vector < Ptr <Node> > movedNodes;
460  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
461  {
462  Ptr<Node> n = *i;
463  NS_ASSERT (n);
465  Vector newLocation;
466  if (!mobility)
467  {
468  newLocation = GetPosition (n);
469  }
470  else
471  {
472  newLocation = mobility->GetPosition ();
473  }
474  if (!NodeHasMoved (n, newLocation))
475  {
476  continue; //Location has not changed
477  }
478  else
479  {
480  UpdatePosition (n, newLocation);
481  movedNodes.push_back (n);
482  }
483  }
484  return movedNodes;
485 }
486 
487 int
488 AnimationInterface::WriteN (const std::string& st, FILE * f)
489 {
490  if (!f)
491  {
492  return 0;
493  }
494  if (m_writeCallback)
495  {
496  m_writeCallback (st.c_str ());
497  }
498  return WriteN (st.c_str (), st.length (), f);
499 }
500 
501 int
502 AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
503 {
504  if (!f)
505  {
506  return 0;
507  }
508  // Write count bytes to h from data
509  uint32_t nLeft = count;
510  const char* p = data;
511  uint32_t written = 0;
512  while (nLeft)
513  {
514  int n = std::fwrite (p, 1, nLeft, f);
515  if (n <= 0)
516  {
517  return written;
518  }
519  written += n;
520  nLeft -= n;
521  p += n;
522  }
523  return written;
524 }
525 
526 void
527 AnimationInterface::WriteRoutePath (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
528 {
529  NS_LOG_INFO ("Writing Route Path From :" << nodeId << " To: " << destination.c_str ());
530  WriteXmlRp (nodeId, destination, rpElements);
531  /*for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
532  i != rpElements.end ();
533  ++i)
534  {
535  Ipv4RoutePathElement rpElement = *i;
536  NS_LOG_INFO ("Node:" << rpElement.nodeId << "-->" << rpElement.nextHop.c_str ());
537  WriteN (GetXmlRp (rpElement.node, GetIpv4RoutingTable (n)), m_routingF);
538 
539  }
540  */
541 }
542 
543 void
544 AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
545 {
546  WriteXmlNonP2pLinkProperties (id, ipv4Address, channelType);
547 }
548 
549 const std::vector<std::string>
550 AnimationInterface::GetElementsFromContext (const std::string& context) const
551 {
552  std::vector <std::string> elements;
553  size_t pos1=0, pos2;
554  while (pos1 != context.npos)
555  {
556  pos1 = context.find ("/",pos1);
557  pos2 = context.find ("/",pos1+1);
558  elements.push_back (context.substr (pos1+1,pos2-(pos1+1)));
559  pos1 = pos2;
560  pos2 = context.npos;
561  }
562  return elements;
563 }
564 
566 AnimationInterface::GetNodeFromContext (const std::string& context) const
567 {
568  // Use "NodeList/*/ as reference
569  // where element [1] is the Node Id
570 
571  std::vector <std::string> elements = GetElementsFromContext (context);
572  Ptr <Node> n = NodeList::GetNode (atoi (elements.at (1).c_str ()));
573  NS_ASSERT (n);
574 
575  return n;
576 }
577 
580 {
581  // Use "NodeList/*/DeviceList/*/ as reference
582  // where element [1] is the Node Id
583  // element [2] is the NetDevice Id
584 
585  std::vector <std::string> elements = GetElementsFromContext (context);
586  Ptr <Node> n = GetNodeFromContext (context);
587 
588  return n->GetDevice (atoi (elements.at (3).c_str ()));
589 }
590 
591 uint64_t
593 {
594  AnimByteTag tag;
595  TypeId tid = tag.GetInstanceTypeId ();
597  bool found = false;
598  while (i.HasNext ())
599  {
600  ByteTagIterator::Item item = i.Next ();
601  if (tid == item.GetTypeId ())
602  {
603  item.GetTag (tag);
604  found = true;
605  }
606  }
607  if (found)
608  {
609  return tag.Get ();
610  }
611  else
612  {
613  return 0;
614  }
615 }
616 
617 void
619 {
620  AnimByteTag tag;
621  tag.Set (animUid);
622  p->AddByteTag (tag);
623 }
624 
625 void
626 AnimationInterface::RemainingEnergyTrace (std::string context, double previousEnergy, double currentEnergy)
627 {
629  const Ptr <const Node> node = GetNodeFromContext (context);
630  const uint32_t nodeId = node->GetId ();
631 
632  NS_LOG_INFO ("Remaining energy on one of sources on node " << nodeId << ": " << currentEnergy);
633 
634  const Ptr<EnergySource> energySource = node->GetObject<EnergySource> ();
635 
636  NS_ASSERT (energySource);
637  // Don't call GetEnergyFraction () because of recursion
638  const double energyFraction = currentEnergy / energySource->GetInitialEnergy ();
639 
640  NS_LOG_INFO ("Total energy fraction on node " << nodeId << ": " << energyFraction);
641 
642  m_nodeEnergyFraction[nodeId] = energyFraction;
643  UpdateNodeCounter (m_remainingEnergyCounterId, nodeId, energyFraction);
644 }
645 
646 void
648 {
649  const Ptr <const Node> node = GetNodeFromContext (context);
650  ++m_nodeWifiPhyTxDrop[node->GetId ()];
651 }
652 
653 void
655 {
656  const Ptr <const Node> node = GetNodeFromContext (context);
657  ++m_nodeWifiPhyRxDrop[node->GetId ()];
658 }
659 
660 void
662 {
663  const Ptr <const Node> node = GetNodeFromContext (context);
664  ++m_nodeWifiMacTx[node->GetId ()];
665 }
666 
667 void
669 {
670  const Ptr <const Node> node = GetNodeFromContext (context);
671  ++m_nodeWifiMacTxDrop[node->GetId ()];
672 }
673 
674 void
676 {
677  const Ptr <const Node> node = GetNodeFromContext (context);
678  ++m_nodeWifiMacRx[node->GetId ()];
679 }
680 
681 void
683 {
684  const Ptr <const Node> node = GetNodeFromContext (context);
685  ++m_nodeWifiMacRxDrop[node->GetId ()];
686 }
687 
688 void
689 AnimationInterface::Ipv4TxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
690 {
691  const Ptr <const Node> node = GetNodeFromContext (context);
692  ++m_nodeIpv4Tx[node->GetId ()];
693 }
694 
695 void
696 AnimationInterface::Ipv4RxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
697 {
698  const Ptr <const Node> node = GetNodeFromContext (context);
699  ++m_nodeIpv4Rx[node->GetId ()];
700 }
701 
702 void
703 AnimationInterface::Ipv4DropTrace (std::string context,
704  const Ipv4Header & ipv4Header,
706  Ipv4L3Protocol::DropReason dropReason,
707  Ptr<Ipv4> ipv4,
708  uint32_t)
709 {
710  const Ptr <const Node> node = GetNodeFromContext (context);
711  ++m_nodeIpv4Drop[node->GetId ()];
712 }
713 
714 void
715 AnimationInterface::EnqueueTrace (std::string context,
717 {
718  const Ptr <const Node> node = GetNodeFromContext (context);
719  ++m_nodeQueueEnqueue[node->GetId ()];
720 }
721 
722 void
723 AnimationInterface::DequeueTrace (std::string context,
725 {
726  const Ptr <const Node> node = GetNodeFromContext (context);
727  ++m_nodeQueueDequeue[node->GetId ()];
728 }
729 
730 void
733 {
734  const Ptr <const Node> node = GetNodeFromContext (context);
735  ++m_nodeQueueDrop[node->GetId ()];
736 }
737 
738 void
739 AnimationInterface::DevTxTrace (std::string context,
741  Ptr<NetDevice> tx,
742  Ptr<NetDevice> rx,
743  Time txTime,
744  Time rxTime)
745 {
746  NS_LOG_FUNCTION (this);
748  NS_ASSERT (tx);
749  NS_ASSERT (rx);
750  Time now = Simulator::Now ();
751  double fbTx = now.GetSeconds ();
752  double lbTx = (now + txTime).GetSeconds ();
753  double fbRx = (now + rxTime - txTime).GetSeconds ();
754  double lbRx = (now + rxTime).GetSeconds ();
756  WriteXmlP ("p",
757  tx->GetNode ()->GetId (),
758  fbTx,
759  lbTx,
760  rx->GetNode ()->GetId (),
761  fbRx,
762  lbRx,
764 }
765 
766 void
768 {
769  NS_LOG_FUNCTION (this);
771  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
772  NS_ASSERT (ndev);
773  UpdatePosition (ndev);
774 
775  ++gAnimUid;
776  NS_LOG_INFO (ProtocolTypeToString (protocolType).c_str () << " GenericWirelessTxTrace for packet:" << gAnimUid);
777  AddByteTag (gAnimUid, p);
778  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
779  AddPendingPacket (protocolType, gAnimUid, pktInfo);
780 
781  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
782  if (netDevice)
783  {
784  Mac48Address nodeAddr = netDevice->GetMac ()->GetAddress ();
785  std::ostringstream oss;
786  oss << nodeAddr;
787  Ptr <Node> n = netDevice->GetNode ();
788  NS_ASSERT (n);
789  m_macToNodeIdMap[oss.str ()] = n->GetId ();
790  NS_LOG_INFO ("Added Mac" << oss.str () << " node:" <<m_macToNodeIdMap[oss.str ()]);
791  }
792  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
793  OutputWirelessPacketTxInfo (p, pendingPackets->at (gAnimUid), gAnimUid);
794 }
795 
796 void
798 {
799  NS_LOG_FUNCTION (this);
801  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
802  NS_ASSERT (ndev);
803  UpdatePosition (ndev);
804  uint64_t animUid = GetAnimUidFromPacket (p);
805  NS_LOG_INFO (ProtocolTypeToString (protocolType).c_str () << " for packet:" << animUid);
806  if (!IsPacketPending (animUid, protocolType))
807  {
808  NS_LOG_WARN (ProtocolTypeToString (protocolType).c_str () << " GenericWirelessRxTrace: unknown Uid");
809  return;
810  }
811  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
812  pendingPackets->at (animUid).ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
813  OutputWirelessPacketRxInfo (p, pendingPackets->at (animUid), animUid);
814 }
815 
816 void
818 {
819  NS_LOG_FUNCTION (this);
820  return GenericWirelessTxTrace (context, p, AnimationInterface::UAN);
821 }
822 
823 void
825 {
826  NS_LOG_FUNCTION (this);
827  return GenericWirelessRxTrace (context, p, AnimationInterface::UAN);
828 }
829 
830 void
832 {
833  NS_LOG_FUNCTION (this);
835 }
836 
837 void
839 {
840  NS_LOG_FUNCTION (this);
842  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
843  NS_ASSERT (ndev);
844  UpdatePosition (ndev);
845  uint64_t animUid = GetAnimUidFromPacket (p);
846  NS_LOG_INFO ("Wifi RxBeginTrace for packet:" << animUid);
848  {
849  NS_ASSERT (0);
850  NS_LOG_WARN ("WifiPhyRxBeginTrace: unknown Uid");
851  std::ostringstream oss;
852  WifiMacHeader hdr;
853  if (!p->PeekHeader (hdr))
854  {
855  NS_LOG_WARN ("WifiMacHeader not present");
856  return;
857  }
858  oss << hdr.GetAddr2 ();
859  if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
860  {
861  NS_LOG_WARN ("Transmitter Mac address " << oss.str () << " never seen before. Skipping");
862  return;
863  }
864  Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
865  UpdatePosition (txNode);
866  AnimPacketInfo pktInfo (0, Simulator::Now (), m_macToNodeIdMap[oss.str ()]);
867  AddPendingPacket (AnimationInterface::WIFI, animUid, pktInfo);
868  NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
869  }
871  m_pendingWifiPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
872  OutputWirelessPacketRxInfo (p, m_pendingWifiPackets[animUid], animUid);
873 }
874 
875 void
877 {
878  NS_LOG_FUNCTION (this);
880 }
881 
882 
883 void
885 {
886  NS_LOG_FUNCTION (this);
888 }
889 
890 void
892 {
893  NS_LOG_FUNCTION (this);
894  return GenericWirelessTxTrace (context, p, AnimationInterface::LTE);
895 }
896 
897 void
899 {
900  NS_LOG_FUNCTION (this);
901  return GenericWirelessRxTrace (context, p, AnimationInterface::LTE);
902 }
903 
904 void
906 {
907  NS_LOG_FUNCTION (this);
909  if (!pb)
910  {
911  NS_LOG_WARN ("pb == 0. Not yet supported");
912  return;
913  }
914  context = "/" + context;
915  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
916  NS_ASSERT (ndev);
917  UpdatePosition (ndev);
918 
919  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
920  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
921  i != pbList.end ();
922  ++i)
923  {
924  Ptr <Packet> p = *i;
925  ++gAnimUid;
926  NS_LOG_INFO ("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
927  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
928  AddByteTag (gAnimUid, p);
930  OutputWirelessPacketTxInfo (p, pktInfo, gAnimUid);
931  }
932 }
933 
934 void
936 {
937  NS_LOG_FUNCTION (this);
939  if (!pb)
940  {
941  NS_LOG_WARN ("pb == 0. Not yet supported");
942  return;
943  }
944  context = "/" + context;
945  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
946  NS_ASSERT (ndev);
947  UpdatePosition (ndev);
948 
949  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
950  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
951  i != pbList.end ();
952  ++i)
953  {
954  Ptr <Packet> p = *i;
955  uint64_t animUid = GetAnimUidFromPacket (p);
956  NS_LOG_INFO ("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
958  {
959  NS_LOG_WARN ("LteSpectrumPhyRxTrace: unknown Uid");
960  return;
961  }
962  AnimPacketInfo& pktInfo = m_pendingLtePackets[animUid];
963  pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
964  OutputWirelessPacketRxInfo (p, pktInfo, animUid);
965  }
966 }
967 
968 void
970 {
971  NS_LOG_FUNCTION (this);
973  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
974  NS_ASSERT (ndev);
975  UpdatePosition (ndev);
976  ++gAnimUid;
977  NS_LOG_INFO ("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
978  AddByteTag (gAnimUid, p);
979  UpdatePosition (ndev);
980  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
982 
983 
984 }
985 
986 void
988 {
989  NS_LOG_FUNCTION (this);
991  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
992  NS_ASSERT (ndev);
993  UpdatePosition (ndev);
994  uint64_t animUid = GetAnimUidFromPacket (p);
995  NS_LOG_INFO ("CsmaPhyTxEndTrace for packet:" << animUid);
997  {
998  NS_LOG_WARN ("CsmaPhyTxEndTrace: unknown Uid");
999  NS_FATAL_ERROR ("CsmaPhyTxEndTrace: unknown Uid");
1000  AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1001  AddPendingPacket (AnimationInterface::CSMA, animUid, pktInfo);
1002  NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
1003  }
1005  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1006  pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
1007 }
1008 
1009 void
1011 {
1012  NS_LOG_FUNCTION (this);
1014  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1015  NS_ASSERT (ndev);
1016  UpdatePosition (ndev);
1017  uint64_t animUid = GetAnimUidFromPacket (p);
1018  if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1019  {
1020  NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid");
1021  return;
1022  }
1024  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1025  pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1026  NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid);
1027  NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid << " complete");
1028  OutputCsmaPacket (p, pktInfo);
1029 }
1030 
1031 void
1034 {
1035  NS_LOG_FUNCTION (this);
1037  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1038  NS_ASSERT (ndev);
1039  uint64_t animUid = GetAnimUidFromPacket (p);
1040  if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1041  {
1042  NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid");
1043  return;
1044  }
1046  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1047  NS_LOG_INFO ("MacRxTrace for packet:" << animUid << " complete");
1048  OutputCsmaPacket (p, pktInfo);
1049 }
1050 
1051 void
1053 {
1055  uint32_t nodeId = 0;
1056  if (pktInfo.m_txnd)
1057  {
1058  nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1059  }
1060  else
1061  {
1062  nodeId = pktInfo.m_txNodeId;
1063  }
1064  WriteXmlPRef (animUid, nodeId, pktInfo.m_fbTx, m_enablePacketMetadata? GetPacketMetadata (p):"");
1065 }
1066 
1067 void
1069 {
1071  uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1072  WriteXmlP (animUid, "wpr", rxId, pktInfo.m_fbRx, pktInfo.m_lbRx);
1073 }
1074 
1075 void
1077 {
1079  NS_ASSERT (pktInfo.m_txnd);
1080  uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1081  uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1082 
1083  WriteXmlP ("p",
1084  nodeId,
1085  pktInfo.m_fbTx,
1086  pktInfo.m_lbTx,
1087  rxId,
1088  pktInfo.m_fbRx,
1089  pktInfo.m_lbRx,
1091 }
1092 
1093 void
1094 AnimationInterface::AddPendingPacket (ProtocolType protocolType, uint64_t animUid, AnimPacketInfo pktInfo)
1095 {
1096  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1097  NS_ASSERT (pendingPackets);
1098  pendingPackets->insert (AnimUidPacketInfoMap::value_type (animUid, pktInfo));
1099 }
1100 
1101 bool
1103 {
1104  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1105  NS_ASSERT (pendingPackets);
1106  return (pendingPackets->find (animUid) != pendingPackets->end ());
1107 }
1108 
1109 void
1111 {
1112  AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1113  NS_ASSERT (pendingPackets);
1114  if (pendingPackets->empty ())
1115  {
1116  return;
1117  }
1118  std::vector <uint64_t> purgeList;
1119  for (AnimUidPacketInfoMap::iterator i = pendingPackets->begin ();
1120  i != pendingPackets->end ();
1121  ++i)
1122  {
1123 
1124  AnimPacketInfo pktInfo = i->second;
1125  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
1126  if (delta > PURGE_INTERVAL)
1127  {
1128  purgeList.push_back (i->first);
1129  }
1130  }
1131  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
1132  i != purgeList.end ();
1133  ++i)
1134  {
1135  pendingPackets->erase (*i);
1136  }
1137 }
1138 
1141 {
1142  AnimUidPacketInfoMap * pendingPackets = 0;
1143  switch (protocolType)
1144  {
1146  {
1147  pendingPackets = &m_pendingWifiPackets;
1148  break;
1149  }
1151  {
1152  pendingPackets = &m_pendingUanPackets;
1153  break;
1154  }
1156  {
1157  pendingPackets = &m_pendingCsmaPackets;
1158  break;
1159  }
1161  {
1162  pendingPackets = &m_pendingWimaxPackets;
1163  break;
1164  }
1166  {
1167  pendingPackets = &m_pendingLtePackets;
1168  break;
1169  }
1170  }
1171  return pendingPackets;
1172 
1173 }
1174 
1175 std::string
1177 {
1178  std::string result = "Unknown";
1179  switch (protocolType)
1180  {
1182  {
1183  result = "WIFI";
1184  break;
1185  }
1187  {
1188  result = "UAN";
1189  break;
1190  }
1192  {
1193  result = "CSMA";
1194  break;
1195  }
1197  {
1198  result = "WIMAX";
1199  break;
1200  }
1202  {
1203  result = "LTE";
1204  break;
1205  }
1206  }
1207  return result;
1208 }
1209 
1210 // Counters
1211 
1212 std::string
1214 {
1215  std::string typeString = "unknown";
1216  switch (counterType)
1217  {
1218  case UINT32_COUNTER:
1219  {
1220  typeString = "UINT32";
1221  break;
1222  }
1223  case DOUBLE_COUNTER:
1224  {
1225  typeString = "DOUBLE";
1226  break;
1227  }
1228  }
1229  return typeString;
1230 }
1231 
1232 // General
1233 
1234 std::string
1236 {
1237  std::ostringstream oss;
1238  p->Print (oss);
1239  return oss.str ();
1240 }
1241 
1242 uint64_t
1244 {
1245  return m_currentPktCount;
1246 }
1247 
1248 void
1250 {
1251  m_started = false;
1252  NS_LOG_INFO ("Stopping Animation");
1254  if (m_f)
1255  {
1256  // Terminate the anim element
1257  WriteXmlClose ("anim");
1258  std::fclose (m_f);
1259  m_f = 0;
1260  }
1261  if (onlyAnimation)
1262  {
1263  return;
1264  }
1265  if (m_routingF)
1266  {
1267  WriteXmlClose ("anim", true);
1268  std::fclose (m_routingF);
1269  m_routingF = 0;
1270  }
1271 }
1272 
1273 void
1275 {
1276  m_currentPktCount = 0;
1277  m_started = true;
1279  WriteXmlAnim ();
1280  WriteNodes ();
1281  WriteNodeColors ();
1283  WriteNodeSizes ();
1284  WriteNodeEnergies ();
1285  if (!restart)
1286  {
1288  ConnectCallbacks ();
1289  }
1290 }
1291 
1292 void
1293 AnimationInterface::AddToIpv4AddressNodeIdTable (std::string ipv4Address, uint32_t nodeId)
1294 {
1295  m_ipv4ToNodeIdMap[ipv4Address] = nodeId;
1296 }
1297 
1298 
1299 // Callbacks
1300 void
1302 {
1303 
1304  Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy ();
1305  Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy ();
1306  Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy ();
1307  std::ostringstream oss;
1308  //NodeList/*/DeviceList/*/
1309  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1310  if (dlPhy)
1311  {
1312  dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1313  dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1314  }
1315  if (ulPhy)
1316  {
1317  ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1318  ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1319  }
1320 }
1321 
1322 
1323 
1324 void
1326 {
1327 
1328  Ptr<LteUePhy> lteUePhy = nd->GetPhy ();
1329  Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy ();
1330  Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy ();
1331  std::ostringstream oss;
1332  //NodeList/*/DeviceList/*/
1333  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1334  if (dlPhy)
1335  {
1336  dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1337  dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1338  }
1339  if (ulPhy)
1340  {
1341  ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1342  ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1343  }
1344 }
1345 
1346 void
1348 {
1349 
1350  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1351  {
1352  Ptr<Node> n = *i;
1353  NS_ASSERT (n);
1354  uint32_t nDevices = n->GetNDevices ();
1355  for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
1356  {
1357  Ptr <NetDevice> nd = n->GetDevice (devIndex);
1358  if (!nd)
1359  continue;
1360  Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice> (nd);
1361  if (lteUeNetDevice)
1362  {
1363  ConnectLteUe (n, lteUeNetDevice, devIndex);
1364  continue;
1365  }
1366  Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice> (nd);
1367  if (lteEnbNetDevice)
1368  ConnectLteEnb (n, lteEnbNetDevice, devIndex);
1369  }
1370 
1371  }
1372 }
1373 
1374 void
1376 {
1377  // Connect the callbacks
1378  Config::Connect ("/ChannelList/*/TxRxPointToPoint",
1380  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
1382  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
1384  Config::ConnectWithoutContext ("/NodeList/*/$ns3::MobilityModel/CourseChange",
1386  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
1388  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
1390  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
1392  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
1394  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
1396  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
1398  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
1400  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
1402  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
1404  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
1406  Config::Connect ("/NodeList/*/$ns3::BasicEnergySource/RemainingEnergy",
1408 
1409  ConnectLte ();
1410 
1411  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
1413  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
1415  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
1417 
1418  // Queue Enqueues
1419 
1420  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Enqueue",
1422  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Enqueue",
1424  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Enqueue",
1426 
1427  // Queue Dequeues
1428 
1429  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Dequeue",
1431  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Dequeue",
1433  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Dequeue",
1435 
1436  // Queue Drops
1437 
1438  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Drop",
1440  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Drop",
1442  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Drop",
1444 
1445 
1446  // Wifi Mac
1447  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
1449  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTxDrop",
1451  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
1453  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRxDrop",
1455 
1456  // Wifi Phy
1457  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxDrop",
1459  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
1461 }
1462 
1463 Vector
1465 {
1467  if (loc)
1468  {
1469  m_nodeLocation[n->GetId ()] = loc->GetPosition ();
1470  }
1471  else
1472  {
1473  NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
1474  m_nodeLocation[n->GetId ()] = Vector (0, 0, 0);
1475  }
1476  return m_nodeLocation[n->GetId ()];
1477 }
1478 
1479 Vector
1481 {
1482  m_nodeLocation[n->GetId ()] = v;
1483  return v;
1484 }
1485 
1486 Vector
1488 {
1489  Ptr <Node> n = ndev->GetNode ();
1490  NS_ASSERT (n);
1491  return UpdatePosition (n);
1492 }
1493 
1494 Vector
1496 {
1497  if (m_nodeLocation.find (n->GetId ()) == m_nodeLocation.end ())
1498  {
1499  NS_FATAL_ERROR ("Node:" <<n->GetId () << " not found in Location table");
1500  }
1501  return m_nodeLocation[n->GetId ()];
1502 }
1503 
1504 
1505 std::string
1507 {
1508  Address nodeAddr = nd->GetAddress ();
1509  std::ostringstream oss;
1510  oss << nodeAddr;
1511  return oss.str ().substr (6); // Skip the first 6 chars to get the Mac
1512 }
1513 
1514 std::string
1516 {
1517  Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
1518  if (!ipv4)
1519  {
1520  NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1521  return "0.0.0.0";
1522  }
1523  int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
1524  if (ifIndex == -1)
1525  {
1526  NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1527  return "0.0.0.0";
1528  }
1529  Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, 0);
1530  std::ostringstream oss;
1531  oss << addr.GetLocal ();
1532  return oss.str ();
1533 }
1534 
1535 void
1537 {
1538  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1539  {
1540  Ptr<Node> n = *i;
1541  UpdatePosition (n);
1542  uint32_t n1Id = n->GetId ();
1543  uint32_t nDev = n->GetNDevices (); // Number of devices
1544  for (uint32_t i = 0; i < nDev; ++i)
1545  {
1546  Ptr<NetDevice> dev = n->GetDevice (i);
1547  NS_ASSERT (dev);
1548  Ptr<Channel> ch = dev->GetChannel ();
1549  if (!ch)
1550  {
1551  NS_LOG_DEBUG ("No channel can't be a p2p device");
1552  // Try to see if it is an LTE NetDevice, which does not return a channel
1553  if ((dev->GetInstanceTypeId ().GetName () == "ns3::LteUeNetDevice") ||
1554  (dev->GetInstanceTypeId ().GetName () == "ns3::LteEnbNetDevice")||
1555  (dev->GetInstanceTypeId ().GetName () == "ns3::VirtualNetDevice"))
1556  {
1557  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), dev->GetInstanceTypeId ().GetName ());
1559  }
1560  continue;
1561  }
1562  std::string channelType = ch->GetInstanceTypeId ().GetName ();
1563  NS_LOG_DEBUG ("Got ChannelType" << channelType);
1564  if (channelType == std::string ("ns3::PointToPointChannel"))
1565  { // Since these are duplex links, we only need to dump
1566  // if srcid < dstid
1567  uint32_t nChDev = ch->GetNDevices ();
1568  for (uint32_t j = 0; j < nChDev; ++j)
1569  {
1570  Ptr<NetDevice> chDev = ch->GetDevice (j);
1571  uint32_t n2Id = chDev->GetNode ()->GetId ();
1572  if (n1Id < n2Id)
1573  {
1574  // ouptut the p2p link
1575  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << ":" << GetMacAddress (dev) << "----" << GetIpv4Address (chDev) << ":" << GetMacAddress (chDev));
1578  P2pLinkNodeIdPair p2pPair;
1579  p2pPair.fromNode = n1Id;
1580  p2pPair.toNode = n2Id;
1581  LinkProperties lp = {GetIpv4Address (dev) + "~" + GetMacAddress (dev), GetIpv4Address (chDev) + "~" + GetMacAddress (chDev), ""};
1582  m_linkProperties[p2pPair] = lp;
1583  WriteXmlLink (n1Id, 0, n2Id);
1584  }
1585  }
1586  }
1587  else
1588  {
1589  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << " Channel Type:" << channelType << " Mac: " << GetMacAddress (dev));
1590  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
1592  }
1593  }
1594  }
1595  m_linkProperties.clear ();
1596 }
1597 
1598 void
1600 {
1601  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1602  {
1603  Ptr<Node> n = *i;
1604  NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
1605  Vector v = UpdatePosition (n);
1606  WriteXmlNode (n->GetId (), n->GetSystemId (), v.x, v.y);
1607  }
1608 }
1609 
1610 void
1612 {
1613  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1614  {
1615  Ptr<Node> n = *i;
1616  Rgb rgb = {255, 0, 0};
1617  if (m_nodeColors.find (n->GetId ()) == m_nodeColors.end ())
1618  {
1619  m_nodeColors[n->GetId ()] = rgb;
1620  }
1621  UpdateNodeColor (n, rgb.r, rgb.g, rgb.b);
1622  }
1623 }
1624 
1625 void
1627 {
1628  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1629  {
1630  Ptr<Node> n = *i;
1631  NS_LOG_INFO ("Update Size for Node: " << n->GetId ());
1632  AnimationInterface::NodeSize s = { 1, 1 };
1633  m_nodeSizes[n->GetId ()] = s;
1634  UpdateNodeSize (n->GetId (), s.width, s.height);
1635  }
1636 }
1637 
1638 void
1640 {
1642  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1643  {
1644  Ptr<Node> n = *i;
1645  if (NodeList::GetNode (n->GetId ())->GetObject<EnergySource> ())
1646  {
1648  }
1649  }
1650 }
1651 
1652 bool
1654 {
1655  if ((Simulator::Now () >= m_startTime) &&
1656  (Simulator::Now () <= m_stopTime))
1657  return true;
1658  else
1659  return false;
1660 }
1661 
1662 void
1663 AnimationInterface::SetOutputFile (const std::string& fn, bool routing)
1664 {
1665  if (!routing && m_f)
1666  {
1667  return;
1668  }
1669  if (routing && m_routingF)
1670  {
1671  NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
1672  return;
1673  }
1674 
1675  NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
1676  FILE * f = 0;
1677  f = std::fopen (fn.c_str (), "w");
1678  if (!f)
1679  {
1680  NS_FATAL_ERROR ("Unable to open output file:" << fn.c_str ());
1681  return; // Can't open output file
1682  }
1683  if (routing)
1684  {
1685  m_routingF = f;
1686  m_routingFileName = fn;
1687  }
1688  else
1689  {
1690  m_f = f;
1691  m_outputFileName = fn;
1692  }
1693  return;
1694 }
1695 
1696 void
1698 {
1699  // Start a new trace file if the current packet count exceeded nax packets per file
1702  {
1703  return;
1704  }
1705  NS_LOG_UNCOND ("Max Packets per trace file exceeded");
1706  StopAnimation (true);
1707 }
1708 
1709 std::string
1711 {
1712  return NETANIM_VERSION;
1713 }
1714 
1715 
1716 void
1718 {
1720  {
1721  NS_LOG_INFO ("TrackQueueCounters Completed");
1722  return;
1723  }
1724  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1725  {
1726  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1730  }
1732 }
1733 
1734 void
1736 {
1738  {
1739  NS_LOG_INFO ("TrackWifiMacCounters Completed");
1740  return;
1741  }
1742  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1743  {
1744  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1749  }
1751 }
1752 
1753 void
1755 {
1757  {
1758  NS_LOG_INFO ("TrackWifiPhyCounters Completed");
1759  return;
1760  }
1761  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1762  {
1763  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1766  }
1768 }
1769 
1770 void
1772 {
1774  {
1775  NS_LOG_INFO ("TrackIpv4L3ProtocolCounters Completed");
1776  return;
1777  }
1778  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1779  {
1780  uint32_t nodeId = Ptr <Node> (*i)->GetId ();
1784  }
1786 }
1787 
1788 
1789 
1790 
1791 
1792 /***** Routing-related *****/
1793 
1794 void
1796 {
1797  if (m_ipv4RouteTrackElements.empty ())
1798  {
1799  return;
1800  }
1801  for (std::vector <Ipv4RouteTrackElement>::const_iterator i = m_ipv4RouteTrackElements.begin ();
1802  i != m_ipv4RouteTrackElements.end ();
1803  ++i)
1804  {
1805  Ipv4RouteTrackElement trackElement = *i;
1806  Ptr <Node> fromNode = NodeList::GetNode (trackElement.fromNodeId);
1807  if (!fromNode)
1808  {
1809  NS_FATAL_ERROR ("Node: " << trackElement.fromNodeId << " Not found");
1810  continue;
1811  }
1812  Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
1813  if (!ipv4)
1814  {
1815  NS_LOG_WARN ("ipv4 object not found");
1816  continue;
1817  }
1819  if (!rp)
1820  {
1821  NS_LOG_WARN ("Routing protocol object not found");
1822  continue;
1823  }
1824  NS_LOG_INFO ("Begin Track Route for: " << trackElement.destination.c_str () << " From:" << trackElement.fromNodeId);
1825  Ptr<Packet> pkt = Create<Packet> ();
1826  Ipv4Header header;
1827  header.SetDestination (Ipv4Address (trackElement.destination.c_str ()));
1828  Socket::SocketErrno sockerr;
1829  Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
1830  Ipv4RoutePathElements rpElements;
1831  if (!rt)
1832  {
1833  NS_LOG_INFO ("No route to :" << trackElement.destination.c_str ());
1834  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
1835  rpElements.push_back (elem);
1836  WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
1837  continue;
1838  }
1839  std::ostringstream oss;
1840  oss << rt->GetGateway ();
1841  NS_LOG_INFO ("Node:" << trackElement.fromNodeId << "-->" << rt->GetGateway ());
1842  if (rt->GetGateway () == "0.0.0.0")
1843  {
1844  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "C" };
1845  rpElements.push_back (elem);
1846  if ( m_ipv4ToNodeIdMap.find (trackElement.destination) != m_ipv4ToNodeIdMap.end ())
1847  {
1848  Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[trackElement.destination], "L" };
1849  rpElements.push_back (elem2);
1850  }
1851  }
1852  else if (rt->GetGateway () == "127.0.0.1")
1853  {
1854  Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
1855  rpElements.push_back (elem);
1856  }
1857  else
1858  {
1859  Ipv4RoutePathElement elem = { trackElement.fromNodeId, oss.str () };
1860  rpElements.push_back (elem);
1861  }
1862  RecursiveIpv4RoutePathSearch (oss.str (), trackElement.destination, rpElements);
1863  WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
1864  }
1865 
1866 }
1867 
1868 void
1870 {
1872  {
1873  NS_LOG_INFO ("TrackIpv4Route completed");
1874  return;
1875  }
1876  if (m_routingNc.GetN ())
1877  {
1878  for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
1879  {
1880  Ptr <Node> n = *i;
1882  }
1883  }
1884  else
1885  {
1886  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1887  {
1888  Ptr <Node> n = *i;
1890  }
1891  }
1894 }
1895 
1896 std::string
1898 {
1899 
1900  NS_ASSERT (n);
1901  Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
1902  if (!ipv4)
1903  {
1904  NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
1905  return "";
1906  }
1907  std::stringstream stream;
1908  Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
1909  ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
1910  return stream.str ();
1911 
1912 }
1913 
1914 void
1915 AnimationInterface::RecursiveIpv4RoutePathSearch (std::string from, std::string to, Ipv4RoutePathElements & rpElements)
1916 {
1917  NS_LOG_INFO ("RecursiveIpv4RoutePathSearch from:" << from.c_str () << " to:" << to.c_str ());
1918  if ((from == "0.0.0.0") || (from == "127.0.0.1"))
1919  {
1920  NS_LOG_INFO ("Got " << from.c_str () << " End recursion");
1921  return;
1922  }
1923  Ptr <Node> fromNode = NodeList::GetNode (m_ipv4ToNodeIdMap[from]);
1925  if (fromNode->GetId () == toNode->GetId ())
1926  {
1927  Ipv4RoutePathElement elem = { fromNode->GetId (), "L" };
1928  rpElements.push_back (elem);
1929  return;
1930  }
1931  if (!fromNode)
1932  {
1933  NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[from] << " Not found");
1934  return;
1935  }
1936  if (!toNode)
1937  {
1938  NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[to] << " Not found");
1939  return;
1940  }
1941  Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
1942  if (!ipv4)
1943  {
1944  NS_LOG_WARN ("ipv4 object not found");
1945  return;
1946  }
1948  if (!rp)
1949  {
1950  NS_LOG_WARN ("Routing protocol object not found");
1951  return;
1952  }
1953  Ptr<Packet> pkt = Create<Packet> ();
1954  Ipv4Header header;
1955  header.SetDestination (Ipv4Address (to.c_str ()));
1956  Socket::SocketErrno sockerr;
1957  Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
1958  if (!rt)
1959  {
1960  return;
1961  }
1962  NS_LOG_DEBUG ("Node: " << fromNode->GetId () << " G:" << rt->GetGateway ());
1963  std::ostringstream oss;
1964  oss << rt->GetGateway ();
1965  if (oss.str () == "0.0.0.0" && (sockerr != Socket::ERROR_NOROUTETOHOST))
1966  {
1967  NS_LOG_INFO ("Null gw");
1968  Ipv4RoutePathElement elem = { fromNode->GetId (), "C" };
1969  rpElements.push_back (elem);
1970  if ( m_ipv4ToNodeIdMap.find (to) != m_ipv4ToNodeIdMap.end ())
1971  {
1972  Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[to], "L" };
1973  rpElements.push_back (elem2);
1974  }
1975  return;
1976  }
1977  NS_LOG_INFO ("Node:" << fromNode->GetId () << "-->" << rt->GetGateway ());
1978  Ipv4RoutePathElement elem = { fromNode->GetId (), oss.str () };
1979  rpElements.push_back (elem);
1980  RecursiveIpv4RoutePathSearch (oss.str (), to, rpElements);
1981 
1982 }
1983 
1984 
1985 
1986 /***** WriteXml *****/
1987 
1988 void
1990 {
1991  AnimXmlElement element ("anim");
1992  element.AddAttribute ("ver", GetNetAnimVersion ());
1993  FILE * f = m_f;
1994  if (!routing)
1995  {
1996  element.AddAttribute ("filetype", "animation");
1997  }
1998  else
1999  {
2000  element.AddAttribute ("filetype", "routing");
2001  f = m_routingF;
2002  }
2003  element.Close ();
2004  WriteN (element.GetElementString (), f);
2005 }
2006 
2007 void
2008 AnimationInterface::WriteXmlClose (std::string name, bool routing)
2009 {
2010  std::string closeString = "</" + name + ">\n";
2011  if (!routing)
2012  {
2013  WriteN (closeString, m_f);
2014  }
2015  else
2016  {
2017  WriteN (closeString, m_routingF);
2018  }
2019 }
2020 
2021 void
2022 AnimationInterface::WriteXmlNode (uint32_t id, uint32_t sysId, double locX, double locY)
2023 {
2024  AnimXmlElement element ("node");
2025  element.AddAttribute ("id", id);
2026  element.AddAttribute ("sysId", sysId);
2027  element.AddAttribute ("locX", locX);
2028  element.AddAttribute ("locY", locY);
2029  element.CloseElement ();
2030  WriteN (element.GetElementString (), m_f);
2031 }
2032 
2033 void
2034 AnimationInterface::WriteXmlUpdateLink (uint32_t fromId, uint32_t toId, std::string linkDescription)
2035 {
2036  AnimXmlElement element ("linkupdate");
2037  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2038  element.AddAttribute ("fromId", fromId);
2039  element.AddAttribute ("toId", toId);
2040  element.AddAttribute ("ld", linkDescription, true);
2041  element.CloseElement ();
2042  WriteN (element.GetElementString (), m_f);
2043 }
2044 
2045 void
2046 AnimationInterface::WriteXmlLink (uint32_t fromId, uint32_t toLp, uint32_t toId)
2047 {
2048  AnimXmlElement element ("link");
2049  element.AddAttribute ("fromId", fromId);
2050  element.AddAttribute ("toId", toId);
2051 
2052  LinkProperties lprop ;
2053  lprop.fromNodeDescription = "";
2054  lprop.toNodeDescription = "";
2055  lprop.linkDescription = "";
2056 
2057  P2pLinkNodeIdPair p1 = { fromId, toId };
2058  P2pLinkNodeIdPair p2 = { toId, fromId };
2059  if (m_linkProperties.find (p1) != m_linkProperties.end ())
2060  {
2061  lprop = m_linkProperties[p1];
2062  }
2063  else if (m_linkProperties.find (p2) != m_linkProperties.end ())
2064  {
2065  lprop = m_linkProperties[p2];
2066  }
2067 
2068  element.AddAttribute ("fd", lprop.fromNodeDescription, true);
2069  element.AddAttribute ("td", lprop.toNodeDescription, true);
2070  element.AddAttribute ("ld", lprop.linkDescription, true);
2071  element.CloseElement ();
2072  WriteN (element.GetElementString (), m_f);
2073 }
2074 
2075 void
2076 AnimationInterface::WriteXmlRouting (uint32_t nodeId, std::string routingInfo)
2077 {
2078  AnimXmlElement element ("rt");
2079  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2080  element.AddAttribute ("id", nodeId);
2081  element.AddAttribute ("info", routingInfo.c_str (), true);
2082  element.CloseElement ();
2083  WriteN (element.GetElementString (), m_routingF);
2084 }
2085 
2086 void
2087 AnimationInterface::WriteXmlRp (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
2088 {
2089  std::string tagName = "rp";
2090  AnimXmlElement element (tagName, false);
2091  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2092  element.AddAttribute ("id", nodeId);
2093  element.AddAttribute ("d", destination.c_str ());
2094  element.AddAttribute ("c", rpElements.size ());
2095  element.CloseTag ();
2096  element.AddLineBreak ();
2097  for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
2098  i != rpElements.end ();
2099  ++i)
2100  {
2101  Ipv4RoutePathElement rpElement = *i;
2102  AnimXmlElement rpeElement ("rpe");
2103  rpeElement.AddAttribute ("n", rpElement.nodeId);
2104  rpeElement.AddAttribute ("nH", rpElement.nextHop.c_str ());
2105  rpeElement.CloseElement ();
2106  element.Add (rpeElement);
2107  }
2108  element.CloseElement ();
2109  WriteN (element.GetElementString (), m_routingF);
2110 }
2111 
2112 
2113 void
2114 AnimationInterface::WriteXmlPRef (uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo)
2115 {
2116  AnimXmlElement element ("pr");
2117  element.AddAttribute ("uId", animUid);
2118  element.AddAttribute ("fId", fId);
2119  element.AddAttribute ("fbTx", fbTx);
2120  if (!metaInfo.empty ())
2121  {
2122  element.AddAttribute ("meta-info", metaInfo.c_str (), true);
2123  }
2124  element.CloseElement ();
2125  WriteN (element.GetElementString (), m_f);
2126 }
2127 
2128 void
2129 AnimationInterface::WriteXmlP (uint64_t animUid, std::string pktType, uint32_t tId, double fbRx, double lbRx)
2130 {
2131  AnimXmlElement element (pktType);
2132  element.AddAttribute ("uId", animUid);
2133  element.AddAttribute ("tId", tId);
2134  element.AddAttribute ("fbRx", fbRx);
2135  element.AddAttribute ("lbRx", lbRx);
2136  element.CloseElement ();
2137  WriteN (element.GetElementString (), m_f);
2138 }
2139 
2140 void
2141 AnimationInterface::WriteXmlP (std::string pktType, uint32_t fId, double fbTx, double lbTx,
2142  uint32_t tId, double fbRx, double lbRx, std::string metaInfo)
2143 {
2144  AnimXmlElement element (pktType);
2145  element.AddAttribute ("fId", fId);
2146  element.AddAttribute ("fbTx", fbTx);
2147  element.AddAttribute ("lbTx", lbTx);
2148  if (!metaInfo.empty ())
2149  {
2150  element.AddAttribute ("meta-info", metaInfo.c_str (), true);
2151  }
2152  element.AddAttribute ("tId", tId);
2153  element.AddAttribute ("fbRx", fbRx);
2154  element.AddAttribute ("lbRx", lbRx);
2155  element.CloseElement ();
2156  WriteN (element.GetElementString (), m_f);
2157 }
2158 
2159 void
2160 AnimationInterface::WriteXmlAddNodeCounter (uint32_t nodeCounterId, std::string counterName, CounterType counterType)
2161 {
2162  AnimXmlElement element ("ncs");
2163  element.AddAttribute ("ncId", nodeCounterId);
2164  element.AddAttribute ("n", counterName);
2165  element.AddAttribute ("t", CounterTypeToString (counterType));
2166  element.CloseElement ();
2167  WriteN (element.GetElementString (), m_f);
2168 }
2169 
2170 void
2171 AnimationInterface::WriteXmlAddResource (uint32_t resourceId, std::string resourcePath)
2172 {
2173  AnimXmlElement element ("res");
2174  element.AddAttribute ("rid", resourceId);
2175  element.AddAttribute ("p", resourcePath);
2176  element.CloseElement ();
2177  WriteN (element.GetElementString (), m_f);
2178 }
2179 
2180 void
2181 AnimationInterface::WriteXmlUpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
2182 {
2183  AnimXmlElement element ("nu");
2184  element.AddAttribute ("p", "i");
2185  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2186  element.AddAttribute ("id", nodeId);
2187  element.AddAttribute ("rid", resourceId);
2188  element.CloseElement ();
2189  WriteN (element.GetElementString (), m_f);
2190 }
2191 
2192 void
2193 AnimationInterface::WriteXmlUpdateNodeSize (uint32_t nodeId, double width, double height)
2194 {
2195  AnimXmlElement element ("nu");
2196  element.AddAttribute ("p", "s");
2197  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2198  element.AddAttribute ("id", nodeId);
2199  element.AddAttribute ("w", width);
2200  element.AddAttribute ("h", height);
2201  element.CloseElement ();
2202  WriteN (element.GetElementString (), m_f);
2203 }
2204 
2205 void
2206 AnimationInterface::WriteXmlUpdateNodePosition (uint32_t nodeId, double x, double y)
2207 {
2208  AnimXmlElement element ("nu");
2209  element.AddAttribute ("p", "p");
2210  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2211  element.AddAttribute ("id", nodeId);
2212  element.AddAttribute ("x", x);
2213  element.AddAttribute ("y", y);
2214  element.CloseElement ();
2215  WriteN (element.GetElementString (), m_f);
2216 }
2217 
2218 void
2219 AnimationInterface::WriteXmlUpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
2220 {
2221  AnimXmlElement element ("nu");
2222  element.AddAttribute ("p", "c");
2223  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2224  element.AddAttribute ("id", nodeId);
2225  element.AddAttribute ("r", (uint32_t) r);
2226  element.AddAttribute ("g", (uint32_t) g);
2227  element.AddAttribute ("b", (uint32_t) b);
2228  element.CloseElement ();
2229  WriteN (element.GetElementString (), m_f);
2230 }
2231 
2232 void
2234 {
2235  AnimXmlElement element ("nu");
2236  element.AddAttribute ("p", "d");
2237  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2238  element.AddAttribute ("id", nodeId);
2239  if (m_nodeDescriptions.find (nodeId) != m_nodeDescriptions.end ())
2240  {
2241  element.AddAttribute ("descr", m_nodeDescriptions[nodeId], true);
2242  }
2243  element.CloseElement ();
2244  WriteN (element.GetElementString (), m_f);
2245 }
2246 
2247 
2248 void
2249 AnimationInterface::WriteXmlUpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counterValue)
2250 {
2251  AnimXmlElement element ("nc");
2252  element.AddAttribute ("c", nodeCounterId);
2253  element.AddAttribute ("i", nodeId);
2254  element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2255  element.AddAttribute ("v", counterValue);
2256  element.CloseElement ();
2257  WriteN (element.GetElementString (), m_f);
2258 }
2259 
2260 void
2261 AnimationInterface::WriteXmlUpdateBackground (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
2262 {
2263  AnimXmlElement element ("bg");
2264  element.AddAttribute ("f", fileName);
2265  element.AddAttribute ("x", x);
2266  element.AddAttribute ("y", y);
2267  element.AddAttribute ("sx", scaleX);
2268  element.AddAttribute ("sy", scaleY);
2269  element.AddAttribute ("o", opacity);
2270  element.CloseElement ();
2271  WriteN (element.GetElementString (), m_f);
2272 }
2273 
2274 void
2275 AnimationInterface::WriteXmlNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
2276 {
2277  AnimXmlElement element ("nonp2plinkproperties");
2278  element.AddAttribute ("id", id);
2279  element.AddAttribute ("ipv4Address", ipv4Address);
2280  element.AddAttribute ("channelType", channelType);
2281  element.CloseElement ();
2282  WriteN (element.GetElementString (), m_f);
2283 }
2284 
2285 
2286 
2287 /***** AnimXmlElement *****/
2288 
2289 AnimationInterface::AnimXmlElement::AnimXmlElement (std::string tagName, bool emptyElement):
2290  m_tagName (tagName),
2291  m_emptyElement (emptyElement)
2292 {
2293  m_elementString = "<" + tagName + " ";
2294 }
2295 
2296 template <typename T>
2297 void
2298 AnimationInterface::AnimXmlElement::AddAttribute (std::string attribute, T value, bool xmlEscape)
2299 {
2300  std::ostringstream oss;
2301  oss << std::setprecision (10);
2302  oss << value;
2303  m_elementString += attribute.c_str ();
2304  if (xmlEscape)
2305  {
2306  m_elementString += "=\"";
2307  std::string valueStr = oss.str ();
2308  for (std::string::iterator it = valueStr.begin (); it != valueStr.end (); ++it)
2309  {
2310  switch (*it)
2311  {
2312  case '&':
2313  m_elementString += "&amp;";
2314  break;
2315  case '\"':
2316  m_elementString += "&quot;";
2317  break;
2318  case '\'':
2319  m_elementString += "&apos;";
2320  break;
2321  case '<':
2322  m_elementString += "&lt;";
2323  break;
2324  case '>':
2325  m_elementString += "&gt;";
2326  break;
2327  default:
2328  m_elementString += *it;
2329  break;
2330  }
2331  }
2332  m_elementString += "\" ";
2333  }
2334  else
2335  {
2336  m_elementString += "=\"" + oss.str () + "\" ";
2337  }
2338 }
2339 
2340 void
2342 {
2343  m_elementString += ">\n";
2344 }
2345 
2346 void
2348 {
2349  if (m_emptyElement)
2350  {
2351  m_elementString += "/>\n";
2352  }
2353  else
2354  {
2355  m_elementString += "</" + m_tagName + ">\n";
2356  }
2357 }
2358 
2359 void
2361 {
2362  m_elementString += ">";
2363 }
2364 
2365 void
2367 {
2368  m_elementString += "\n";
2369 }
2370 
2371 void
2373 {
2374  m_elementString += e.GetElementString ();
2375 }
2376 
2377 std::string
2379 {
2380  return m_elementString;
2381 }
2382 
2383 
2384 
2385 
2386 /***** AnimByteTag *****/
2387 
2388 TypeId
2390 {
2391  static TypeId tid = TypeId ("ns3::AnimByteTag")
2392  .SetParent<Tag> ()
2393  .SetGroupName ("NetAnim")
2394  .AddConstructor<AnimByteTag> ()
2395  ;
2396  return tid;
2397 }
2398 
2399 TypeId
2401 {
2402  return GetTypeId ();
2403 }
2404 
2405 uint32_t
2407 {
2408  return sizeof (uint64_t);
2409 }
2410 
2411 void
2413 {
2414  i.WriteU64 (m_AnimUid);
2415 }
2416 
2417 void
2419 {
2420  m_AnimUid = i.ReadU64 ();
2421 }
2422 
2423 void
2424 AnimByteTag::Print (std::ostream &os) const
2425 {
2426  os << "AnimUid=" << m_AnimUid;
2427 }
2428 
2429 void
2430 AnimByteTag::Set (uint64_t AnimUid)
2431 {
2432  m_AnimUid = AnimUid;
2433 }
2434 
2435 uint64_t
2436 AnimByteTag::Get (void) const
2437 {
2438  return m_AnimUid;
2439 }
2440 
2442  : m_txnd (0),
2443  m_txNodeId (0),
2444  m_fbTx (0),
2445  m_lbTx (0),
2446  m_lbRx (0)
2447 {
2448 }
2449 
2451 {
2452  m_txnd = pInfo.m_txnd;
2453  m_txNodeId = pInfo.m_txNodeId;
2454  m_fbTx = pInfo.m_fbTx;
2455  m_lbTx = pInfo.m_lbTx;
2456  m_lbRx = pInfo.m_lbRx;
2457 }
2458 
2460  const Time fbTx,
2461  uint32_t txNodeId)
2462  : m_txnd (txnd),
2463  m_txNodeId (0),
2464  m_fbTx (fbTx.GetSeconds ()),
2465  m_lbTx (0),
2466  m_lbRx (0)
2467 {
2468  if (!m_txnd)
2469  m_txNodeId = txNodeId;
2470 }
2471 
2472 void
2474 {
2475  Ptr <Node> n = nd->GetNode ();
2476  m_fbRx = fbRx;
2477  m_rxnd = nd;
2478 }
2479 
2480 } // 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)
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:462
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)
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
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
virtual Ptr< Node > GetNode(void) const =0
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)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
NodeCounterMap64 m_nodeWifiPhyTxDrop
#define CHECK_STARTED_INTIMEWINDOW
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 &)
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:412
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:121
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.
#define CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS
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 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.
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:33
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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:61
void RemainingEnergyTrace(std::string context, double previousEnergy, double currentEnergy)
tuple mobility
Definition: third.py:101
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
void WifiMacRxDropTrace(std::string context, Ptr< const Packet >)
void WriteXmlClose(std::string name, bool routing=false)
void GenericWirelessTxTrace(std::string context, Ptr< const Packet >, ProtocolType protocolType)
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:535
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:142
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
ByteTagIterator GetByteTagIterator(void) const
Returns an iterator over the set of byte tags included in this packet.
Definition: packet.cc:801
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:824
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.
AnimXmlElement(std::string tagName, bool emptyElement=true)
std::map< uint32_t, NodeSize > m_nodeSizes
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:835
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:150
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:278
double f(double x, void *params)
Definition: 80211b.c:60
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:54
#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:224
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
std::string ProtocolTypeToString(ProtocolType protocolType)
void AddByteTag(uint64_t animUid, Ptr< const Packet > p)
A network Node.
Definition: node.h:56
#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:895
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)
DropReason
Reason why a packet has been dropped.
void GenericWirelessRxTrace(std::string context, Ptr< const Packet >, ProtocolType protocolType)
static bool IsFinished(void)
Check if the simulation should finish.
Definition: simulator.cc:194
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.
void AddAttribute(std::string attribute, T value, bool xmlEscape=false)
void WifiPhyRxDropTrace(std::string context, Ptr< const Packet >)
Vector GetPosition(Ptr< Node > n)
a unique identifier for an interface.
Definition: type-id.h:58
NodeCounterMap64 m_nodeWifiMacTxDrop
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
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:791