A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
animation-interface.cc
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation;
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 *
15 * Author: George F. Riley<riley@ece.gatech.edu>
16 * Modified by: John Abraham <john.abraham@gatech.edu>
17 * Contributions: Eugene Kalishenko <ydginster@gmail.com> (Open Source and Linux Laboratory
18 * http://wiki.osll.ru/doku.php/start) Tommaso Pecorella <tommaso.pecorella@unifi.it> Pavel Vasilyev
19 * <pavel.vasilyev@sredasolutions.com>
20 */
21
22// Interface between ns-3 and the network animator
23
24#include <cstdio>
25#ifndef WIN32
26#include <unistd.h>
27#endif
28#include <fstream>
29#include <iomanip>
30#include <map>
31#include <sstream>
32#include <string>
33
34// ns3 includes
35#ifdef __WIN32__
36#include "ns3/bs-net-device.h"
37#include "ns3/csma-net-device.h"
38#endif
39#include "animation-interface.h"
40
41#include "ns3/channel.h"
42#include "ns3/config.h"
43#include "ns3/constant-position-mobility-model.h"
44#include "ns3/double.h"
45#include "ns3/energy-source-container.h"
46#include "ns3/ipv4-routing-protocol.h"
47#include "ns3/ipv4.h"
48#include "ns3/ipv6.h"
49#include "ns3/lr-wpan-mac-header.h"
50#include "ns3/lr-wpan-net-device.h"
51#include "ns3/lte-enb-phy.h"
52#include "ns3/lte-ue-phy.h"
53#include "ns3/mobility-model.h"
54#include "ns3/node.h"
55#include "ns3/packet.h"
56#include "ns3/simulator.h"
57#include "ns3/uan-mac.h"
58#include "ns3/uan-net-device.h"
59#include "ns3/wifi-mac-header.h"
60#include "ns3/wifi-mac.h"
61#include "ns3/wifi-net-device.h"
62#include "ns3/wifi-psdu.h"
63#include "ns3/wimax-mac-header.h"
64
65namespace ns3
66{
67
68NS_LOG_COMPONENT_DEFINE("AnimationInterface");
69
70// Globals
71
72static bool initialized = false; //!< Initialization flag
73
74// Public methods
75
77 : m_f(nullptr),
78 m_routingF(nullptr),
79 m_mobilityPollInterval(Seconds(0.25)),
80 m_outputFileName(fn),
81 gAnimUid(0),
82 m_writeCallback(nullptr),
83 m_started(false),
84 m_enablePacketMetadata(false),
85 m_startTime(Seconds(0)),
86 m_stopTime(Seconds(3600 * 1000)),
87 m_maxPktsPerFile(MAX_PKTS_PER_TRACE_FILE),
88 m_originalFileName(fn),
89 m_routingStopTime(Seconds(0)),
90 m_routingFileName(""),
91 m_routingPollInterval(Seconds(5)),
92 m_trackPackets(true)
93{
94 initialized = true;
96
97#ifdef __WIN32__
98 /**
99 * Shared libraries are handled differently on Windows and
100 * need to be explicitly loaded via LoadLibrary("library.dll").
101 *
102 * Otherwise, static import libraries .dll.a/.lib (MinGW/MSVC)
103 * can be linked to the executables to perform the loading of
104 * their respective .dll implicitly during static initialization.
105 *
106 * The .dll.a/.lib however, only gets linked if we instantiate at
107 * least one symbol exported by the .dll.
108 *
109 * To ensure TypeIds from the Csma, Uan, Wifi and Wimax
110 * modules are registered during runtime, we need to instantiate
111 * at least one symbol exported by each of these module libraries.
112 */
113 static BaseStationNetDevice b;
114 static CsmaNetDevice c;
115 static WifiNetDevice w;
116 static UanNetDevice u;
117#endif
118}
119
121{
123}
124
125void
127{
128 m_trackPackets = false;
129}
130
131void
133{
135 m_wifiPhyCountersPollInterval = pollInterval;
138 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
139 {
140 Ptr<Node> n = *i;
141 m_nodeWifiPhyTxDrop[n->GetId()] = 0;
142 m_nodeWifiPhyRxDrop[n->GetId()] = 0;
145 }
147}
148
149void
151{
153 m_wifiMacCountersPollInterval = pollInterval;
158 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
159 {
160 Ptr<Node> n = *i;
161 m_nodeWifiMacTx[n->GetId()] = 0;
162 m_nodeWifiMacTxDrop[n->GetId()] = 0;
163 m_nodeWifiMacRx[n->GetId()] = 0;
164 m_nodeWifiMacRxDrop[n->GetId()] = 0;
169 }
171}
172
173void
175{
177 m_queueCountersPollInterval = pollInterval;
181 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
182 {
183 Ptr<Node> n = *i;
184 m_nodeQueueEnqueue[n->GetId()] = 0;
185 m_nodeQueueDequeue[n->GetId()] = 0;
186 m_nodeQueueDrop[n->GetId()] = 0;
190 }
192}
193
194void
196{
202 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
203 {
204 Ptr<Node> n = *i;
205 m_nodeIpv4Tx[n->GetId()] = 0;
206 m_nodeIpv4Rx[n->GetId()] = 0;
207 m_nodeIpv4Drop[n->GetId()] = 0;
211 }
213}
214
217 Time startTime,
219 Time pollInterval)
220{
221 SetOutputFile(fileName, true);
223 m_routingPollInterval = pollInterval;
224 WriteXmlAnim(true);
226 return *this;
227}
228
231 Time startTime,
233 NodeContainer nc,
234 Time pollInterval)
235{
236 m_routingNc = nc;
237 return EnableIpv4RouteTracking(fileName, startTime, stopTime, pollInterval);
238}
239
241AnimationInterface::AddSourceDestination(uint32_t fromNodeId, std::string ipv4Address)
242{
243 Ipv4RouteTrackElement element = {ipv4Address, fromNodeId};
244 m_ipv4RouteTrackElements.push_back(element);
245 return *this;
246}
247
248void
250{
251 m_startTime = t;
252}
253
254void
256{
257 m_stopTime = t;
258}
259
260void
262{
263 m_maxPktsPerFile = maxPacketsPerFile;
264}
265
267AnimationInterface::AddNodeCounter(std::string counterName, CounterType counterType)
268{
269 m_nodeCounters.push_back(counterName);
270 uint32_t counterId = m_nodeCounters.size() - 1; // counter ID is zero-indexed
271 WriteXmlAddNodeCounter(counterId, counterName, counterType);
272 return counterId;
273}
274
276AnimationInterface::AddResource(std::string resourcePath)
277{
278 m_resources.push_back(resourcePath);
279 uint32_t resourceId = m_resources.size() - 1; // resource ID is zero-indexed
280 WriteXmlAddResource(resourceId, resourcePath);
281 return resourceId;
282}
283
284void
286{
287 m_enablePacketMetadata = enable;
288 if (enable)
289 {
291 }
292}
293
294bool
296{
297 return initialized;
298}
299
300bool
302{
303 return m_started;
304}
305
306void
308{
309 m_writeCallback = cb;
310}
311
312void
314{
315 m_writeCallback = nullptr;
316}
317
318void
320{
322}
323
324void
326{
327 NS_ASSERT(n);
329 if (!loc)
330 {
331 loc = CreateObject<ConstantPositionMobilityModel>();
332 n->AggregateObject(loc);
333 }
334 Vector hubVec(x, y, z);
335 loc->SetPosition(hubVec);
336 NS_LOG_INFO("Node:" << n->GetId() << " Position set to:(" << x << "," << y << "," << z << ")");
337}
338
339void
341{
342 NS_LOG_INFO("Setting node image for Node Id:" << nodeId);
343 if (resourceId > (m_resources.size() - 1))
344 {
345 NS_FATAL_ERROR("Resource Id:" << resourceId << " not found. Did you use AddResource?");
346 }
347 WriteXmlUpdateNodeImage(nodeId, resourceId);
348}
349
350void
351AnimationInterface::UpdateNodeCounter(uint32_t nodeCounterId, uint32_t nodeId, double counter)
352{
353 if (nodeCounterId > (m_nodeCounters.size() - 1))
354 {
355 NS_FATAL_ERROR("NodeCounter Id:" << nodeCounterId
356 << " not found. Did you use AddNodeCounter?");
357 }
358 WriteXmlUpdateNodeCounter(nodeCounterId, nodeId, counter);
359}
360
361void
363 double x,
364 double y,
365 double scaleX,
366 double scaleY,
367 double opacity)
368{
369 if ((opacity < 0) || (opacity > 1))
370 {
371 NS_FATAL_ERROR("Opacity must be between 0.0 and 1.0");
372 }
373 WriteXmlUpdateBackground(fileName, x, y, scaleX, scaleY, opacity);
374}
375
376void
377AnimationInterface::UpdateNodeSize(Ptr<Node> n, double width, double height)
378{
379 UpdateNodeSize(n->GetId(), width, height);
380}
381
382void
383AnimationInterface::UpdateNodeSize(uint32_t nodeId, double width, double height)
384{
385 AnimationInterface::NodeSize s = {width, height};
386 m_nodeSizes[nodeId] = s;
387 WriteXmlUpdateNodeSize(nodeId, s.width, s.height);
388}
389
390void
391AnimationInterface::UpdateNodeColor(Ptr<Node> n, uint8_t r, uint8_t g, uint8_t b)
392{
393 UpdateNodeColor(n->GetId(), r, g, b);
394}
395
396void
397AnimationInterface::UpdateNodeColor(uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
398{
400 NS_LOG_INFO("Setting node color for Node Id:" << nodeId);
401 Rgb rgb = {r, g, b};
402 m_nodeColors[nodeId] = rgb;
403 WriteXmlUpdateNodeColor(nodeId, r, g, b);
404}
405
406void
408 uint32_t toNode,
409 std::string linkDescription)
410{
411 WriteXmlUpdateLink(fromNode, toNode, linkDescription);
412}
413
414void
416 Ptr<Node> toNode,
417 std::string linkDescription)
418{
419 NS_ASSERT(fromNode);
420 NS_ASSERT(toNode);
421 WriteXmlUpdateLink(fromNode->GetId(), toNode->GetId(), linkDescription);
422}
423
424void
426{
427 UpdateNodeDescription(n->GetId(), descr);
428}
429
430void
432{
434 m_nodeDescriptions[nodeId] = descr;
436}
437
438// Private methods
439
440double
442{
443 const auto fractionIter = m_nodeEnergyFraction.find(node->GetId());
444 NS_ASSERT(fractionIter != m_nodeEnergyFraction.end());
445 return fractionIter->second;
446}
447
448void
450{
452 Ptr<Node> n = mobility->GetObject<Node>();
453 NS_ASSERT(n);
454 Vector v;
455 if (!mobility)
456 {
457 v = GetPosition(n);
458 }
459 else
460 {
461 v = mobility->GetPosition();
462 }
463 UpdatePosition(n, v);
464 WriteXmlUpdateNodePosition(n->GetId(), v.x, v.y);
465}
466
467bool
469{
470 Vector oldLocation = GetPosition(n);
471 bool moved = !((ceil(oldLocation.x) == ceil(newLocation.x)) &&
472 (ceil(oldLocation.y) == ceil(newLocation.y)));
473 return moved;
474}
475
476void
478{
480 std::vector<Ptr<Node>> MovedNodes = GetMovedNodes();
481 for (uint32_t i = 0; i < MovedNodes.size(); i++)
482 {
483 Ptr<Node> n = MovedNodes[i];
484 NS_ASSERT(n);
485 Vector v = GetPosition(n);
486 WriteXmlUpdateNodePosition(n->GetId(), v.x, v.y);
487 }
489 {
496 }
497}
498
499std::vector<Ptr<Node>>
501{
502 std::vector<Ptr<Node>> movedNodes;
503 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
504 {
505 Ptr<Node> n = *i;
506 NS_ASSERT(n);
507 Ptr<MobilityModel> mobility = n->GetObject<MobilityModel>();
508 Vector newLocation;
509 if (!mobility)
510 {
511 newLocation = GetPosition(n);
512 }
513 else
514 {
515 newLocation = mobility->GetPosition();
516 }
517 if (!NodeHasMoved(n, newLocation))
518 {
519 continue; // Location has not changed
520 }
521 else
522 {
523 UpdatePosition(n, newLocation);
524 movedNodes.push_back(n);
525 }
526 }
527 return movedNodes;
528}
529
530int
531AnimationInterface::WriteN(const std::string& st, FILE* f)
532{
533 if (!f)
534 {
535 return 0;
536 }
537 if (m_writeCallback)
538 {
539 m_writeCallback(st.c_str());
540 }
541 return WriteN(st.c_str(), st.length(), f);
542}
543
544int
545AnimationInterface::WriteN(const char* data, uint32_t count, FILE* f)
546{
547 if (!f)
548 {
549 return 0;
550 }
551 // Write count bytes to h from data
552 uint32_t nLeft = count;
553 const char* p = data;
554 uint32_t written = 0;
555 while (nLeft)
556 {
557 int n = std::fwrite(p, 1, nLeft, f);
558 if (n <= 0)
559 {
560 return written;
561 }
562 written += n;
563 nLeft -= n;
564 p += n;
565 }
566 return written;
567}
568
569void
571 std::string destination,
572 Ipv4RoutePathElements rpElements)
573{
574 NS_LOG_INFO("Writing Route Path From :" << nodeId << " To: " << destination);
575 WriteXmlRp(nodeId, destination, rpElements);
576 /*
577 for (auto i = rpElements.begin (); i != rpElements.end (); ++i)
578 {
579 Ipv4RoutePathElement rpElement = *i;
580 NS_LOG_INFO ("Node:" << rpElement.nodeId << "-->" << rpElement.nextHop.c_str ());
581 WriteN (GetXmlRp (rpElement.node, GetIpv4RoutingTable (n)), m_routingF);
582
583 }
584 */
585}
586
587void
589 std::string ipv4Address,
590 std::string channelType)
591{
592 WriteXmlNonP2pLinkProperties(id, ipv4Address, channelType);
593}
594
595const std::vector<std::string>
596AnimationInterface::GetElementsFromContext(const std::string& context) const
597{
598 std::vector<std::string> elements;
599 std::size_t pos1 = 0;
600 std::size_t pos2;
601 while (pos1 != std::string::npos)
602 {
603 pos1 = context.find('/', pos1);
604 pos2 = context.find('/', pos1 + 1);
605 elements.push_back(context.substr(pos1 + 1, pos2 - (pos1 + 1)));
606 pos1 = pos2;
607 pos2 = std::string::npos;
608 }
609 return elements;
610}
611
613AnimationInterface::GetNodeFromContext(const std::string& context) const
614{
615 // Use "NodeList/*/ as reference
616 // where element [1] is the Node Id
617
618 std::vector<std::string> elements = GetElementsFromContext(context);
619 Ptr<Node> n = NodeList::GetNode(std::stoi(elements.at(1)));
620 NS_ASSERT(n);
621
622 return n;
623}
624
627{
628 // Use "NodeList/*/DeviceList/*/ as reference
629 // where element [1] is the Node Id
630 // element [2] is the NetDevice Id
631
632 std::vector<std::string> elements = GetElementsFromContext(context);
633 Ptr<Node> n = GetNodeFromContext(context);
634
635 return n->GetDevice(std::stoi(elements.at(3)));
636}
637
638uint64_t
640{
641 AnimByteTag tag;
642 TypeId tid = tag.GetInstanceTypeId();
643 ByteTagIterator i = p->GetByteTagIterator();
644 bool found = false;
645 while (i.HasNext())
646 {
647 ByteTagIterator::Item item = i.Next();
648 if (tid == item.GetTypeId())
649 {
650 item.GetTag(tag);
651 found = true;
652 }
653 }
654 if (found)
655 {
656 return tag.Get();
657 }
658 else
659 {
660 return 0;
661 }
662}
663
664void
666{
667 AnimByteTag tag;
668 tag.Set(animUid);
669 p->AddByteTag(tag);
670}
671
672void
674 double previousEnergy,
675 double currentEnergy)
676{
678 const Ptr<const Node> node = GetNodeFromContext(context);
679 const uint32_t nodeId = node->GetId();
680
681 NS_LOG_INFO("Remaining energy on one of sources on node " << nodeId << ": " << currentEnergy);
682
683 const Ptr<EnergySource> energySource = node->GetObject<EnergySource>();
684
685 NS_ASSERT(energySource);
686 // Don't call GetEnergyFraction () because of recursion
687 const double energyFraction = currentEnergy / energySource->GetInitialEnergy();
688
689 NS_LOG_INFO("Total energy fraction on node " << nodeId << ": " << energyFraction);
690
691 m_nodeEnergyFraction[nodeId] = energyFraction;
692 UpdateNodeCounter(m_remainingEnergyCounterId, nodeId, energyFraction);
693}
694
695void
697{
698 const Ptr<const Node> node = GetNodeFromContext(context);
699 ++m_nodeWifiPhyTxDrop[node->GetId()];
700}
701
702void
706{
707 const Ptr<const Node> node = GetNodeFromContext(context);
708 ++m_nodeWifiPhyRxDrop[node->GetId()];
709}
710
711void
713{
714 const Ptr<const Node> node = GetNodeFromContext(context);
715 ++m_nodeWifiMacTx[node->GetId()];
716}
717
718void
720{
721 const Ptr<const Node> node = GetNodeFromContext(context);
722 ++m_nodeWifiMacTxDrop[node->GetId()];
723}
724
725void
727{
728 const Ptr<const Node> node = GetNodeFromContext(context);
729 ++m_nodeWifiMacRx[node->GetId()];
730}
731
732void
734{
735 const Ptr<const Node> node = GetNodeFromContext(context);
736 ++m_nodeWifiMacRxDrop[node->GetId()];
737}
738
739void
741{
742 const Ptr<const Node> node = GetNodeFromContext(context);
743 ++m_nodeLrWpanMacTx[node->GetId()];
744}
745
746void
748{
749 const Ptr<const Node> node = GetNodeFromContext(context);
750 ++m_nodeLrWpanMacTxDrop[node->GetId()];
751}
752
753void
755{
756 const Ptr<const Node> node = GetNodeFromContext(context);
757 ++m_nodeLrWpanMacRx[node->GetId()];
758}
759
760void
762{
763 const Ptr<const Node> node = GetNodeFromContext(context);
764 ++m_nodeLrWpanMacRxDrop[node->GetId()];
765}
766
767void
770 Ptr<Ipv4> ipv4,
771 uint32_t interfaceIndex)
772{
773 const Ptr<const Node> node = GetNodeFromContext(context);
774 ++m_nodeIpv4Tx[node->GetId()];
775}
776
777void
780 Ptr<Ipv4> ipv4,
781 uint32_t interfaceIndex)
782{
783 const Ptr<const Node> node = GetNodeFromContext(context);
784 ++m_nodeIpv4Rx[node->GetId()];
785}
786
787void
789 const Ipv4Header& ipv4Header,
792 Ptr<Ipv4> ipv4,
793 uint32_t)
794{
795 const Ptr<const Node> node = GetNodeFromContext(context);
796 ++m_nodeIpv4Drop[node->GetId()];
797}
798
799void
801{
802 const Ptr<const Node> node = GetNodeFromContext(context);
803 ++m_nodeQueueEnqueue[node->GetId()];
804}
805
806void
808{
809 const Ptr<const Node> node = GetNodeFromContext(context);
810 ++m_nodeQueueDequeue[node->GetId()];
811}
812
813void
815{
816 const Ptr<const Node> node = GetNodeFromContext(context);
817 ++m_nodeQueueDrop[node->GetId()];
818}
819
820void
825 Time txTime,
826 Time rxTime)
827{
828 NS_LOG_FUNCTION(this);
830 NS_ASSERT(tx);
831 NS_ASSERT(rx);
832 Time now = Simulator::Now();
833 double fbTx = now.GetSeconds();
834 double lbTx = (now + txTime).GetSeconds();
835 double fbRx = (now + rxTime - txTime).GetSeconds();
836 double lbRx = (now + rxTime).GetSeconds();
838 WriteXmlP("p",
839 tx->GetNode()->GetId(),
840 fbTx,
841 lbTx,
842 rx->GetNode()->GetId(),
843 fbRx,
844 lbRx,
846}
847
848void
851 ProtocolType protocolType)
852{
853 NS_LOG_FUNCTION(this);
856 NS_ASSERT(ndev);
857 UpdatePosition(ndev);
858
859 ++gAnimUid;
861 << " GenericWirelessTxTrace for packet:" << gAnimUid);
863 AnimPacketInfo pktInfo(ndev, Simulator::Now());
864 AddPendingPacket(protocolType, gAnimUid, pktInfo);
865
866 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(ndev);
867 if (netDevice)
868 {
869 Mac48Address nodeAddr = netDevice->GetMac()->GetAddress();
870 std::ostringstream oss;
871 oss << nodeAddr;
872 Ptr<Node> n = netDevice->GetNode();
873 NS_ASSERT(n);
874 m_macToNodeIdMap[oss.str()] = n->GetId();
875 NS_LOG_INFO("Added Mac" << oss.str() << " node:" << m_macToNodeIdMap[oss.str()]);
876 }
877 AnimUidPacketInfoMap* pendingPackets = ProtocolTypeToPendingPackets(protocolType);
878 OutputWirelessPacketTxInfo(p, pendingPackets->at(gAnimUid), gAnimUid);
879}
880
881void
884 ProtocolType protocolType)
885{
886 NS_LOG_FUNCTION(this);
889 NS_ASSERT(ndev);
890 UpdatePosition(ndev);
891 uint64_t animUid = GetAnimUidFromPacket(p);
892 NS_LOG_INFO(ProtocolTypeToString(protocolType) << " for packet:" << animUid);
893 if (!IsPacketPending(animUid, protocolType))
894 {
895 NS_LOG_WARN(ProtocolTypeToString(protocolType) << " GenericWirelessRxTrace: unknown Uid");
896 return;
897 }
898 AnimUidPacketInfoMap* pendingPackets = ProtocolTypeToPendingPackets(protocolType);
899 pendingPackets->at(animUid).ProcessRxBegin(ndev, Simulator::Now().GetSeconds());
900 OutputWirelessPacketRxInfo(p, pendingPackets->at(animUid), animUid);
901}
902
903void
905{
906 NS_LOG_FUNCTION(this);
908}
909
910void
912{
913 NS_LOG_FUNCTION(this);
915}
916
917void
919 WifiConstPsduMap psduMap,
920 WifiTxVector /* txVector */,
921 double /* txPowerW */)
922{
923 NS_LOG_FUNCTION(this);
926 NS_ASSERT(ndev);
927 UpdatePosition(ndev);
928
929 AnimPacketInfo pktInfo(ndev, Simulator::Now());
931 for (auto& psdu : psduMap)
932 {
933 for (auto& mpdu : *PeekPointer(psdu.second))
934 {
935 ++gAnimUid;
936 NS_LOG_INFO("WifiPhyTxTrace for MPDU:" << gAnimUid);
938 mpdu->GetPacket()); // the underlying MSDU/A-MSDU should be handed off
939 AddPendingPacket(WIFI, gAnimUid, pktInfo);
941 mpdu->GetProtocolDataUnit(),
942 pendingPackets->at(gAnimUid),
943 gAnimUid); // PDU should be considered in order to have header
944 }
945 }
946
947 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(ndev);
948 if (netDevice)
949 {
950 Mac48Address nodeAddr = netDevice->GetMac()->GetAddress();
951 std::ostringstream oss;
952 oss << nodeAddr;
953 Ptr<Node> n = netDevice->GetNode();
954 NS_ASSERT(n);
955 m_macToNodeIdMap[oss.str()] = n->GetId();
956 NS_LOG_INFO("Added Mac" << oss.str() << " node:" << m_macToNodeIdMap[oss.str()]);
957 }
958 else
959 {
960 NS_ABORT_MSG("This NetDevice should be a Wi-Fi network device");
961 }
962}
963
964void
968{
969 NS_LOG_FUNCTION(this);
972 NS_ASSERT(ndev);
973 UpdatePosition(ndev);
974 uint64_t animUid = GetAnimUidFromPacket(p);
975 NS_LOG_INFO("Wifi RxBeginTrace for packet: " << animUid);
977 {
978 NS_ASSERT_MSG(false, "WifiPhyRxBeginTrace: unknown Uid");
979 std::ostringstream oss;
980 WifiMacHeader hdr;
981 if (!p->PeekHeader(hdr))
982 {
983 NS_LOG_WARN("WifiMacHeader not present");
984 return;
985 }
986 oss << hdr.GetAddr2();
987 if (m_macToNodeIdMap.find(oss.str()) == m_macToNodeIdMap.end())
988 {
989 NS_LOG_WARN("Transmitter Mac address " << oss.str() << " never seen before. Skipping");
990 return;
991 }
992 Ptr<Node> txNode = NodeList::GetNode(m_macToNodeIdMap[oss.str()]);
993 UpdatePosition(txNode);
994 AnimPacketInfo pktInfo(nullptr, Simulator::Now(), m_macToNodeIdMap[oss.str()]);
996 NS_LOG_WARN("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
997 }
998 /// \todo NS_ASSERT (WifiPacketIsPending (animUid) == true);
999 m_pendingWifiPackets[animUid].ProcessRxBegin(ndev, Simulator::Now().GetSeconds());
1001}
1002
1003void
1005{
1006 NS_LOG_FUNCTION(this);
1008
1010 NS_ASSERT(ndev);
1011 Ptr<lrwpan::LrWpanNetDevice> netDevice = DynamicCast<lrwpan::LrWpanNetDevice>(ndev);
1012
1013 Ptr<Node> n = ndev->GetNode();
1014 NS_ASSERT(n);
1015
1016 UpdatePosition(n);
1017
1019 if (!p->PeekHeader(hdr))
1020 {
1021 NS_LOG_WARN("LrWpanMacHeader not present");
1022 return;
1023 }
1024
1025 std::ostringstream oss;
1026 if (hdr.GetSrcAddrMode() == 2)
1027 {
1028 Mac16Address nodeAddr = netDevice->GetMac()->GetShortAddress();
1029 oss << nodeAddr;
1030 }
1031 else if (hdr.GetSrcAddrMode() == 3)
1032 {
1033 Mac64Address nodeAddr = netDevice->GetMac()->GetExtendedAddress();
1034 oss << nodeAddr;
1035 }
1036 else
1037 {
1038 NS_LOG_WARN("LrWpanMacHeader without source address");
1039 return;
1040 }
1041 m_macToNodeIdMap[oss.str()] = n->GetId();
1042 NS_LOG_INFO("Added Mac" << oss.str() << " node:" << m_macToNodeIdMap[oss.str()]);
1043
1044 ++gAnimUid;
1045 NS_LOG_INFO("LrWpan TxBeginTrace for packet:" << gAnimUid);
1046 AddByteTag(gAnimUid, p);
1047
1048 AnimPacketInfo pktInfo(ndev, Simulator::Now());
1050
1052}
1053
1054void
1056{
1057 NS_LOG_FUNCTION(this);
1060 NS_ASSERT(ndev);
1061 Ptr<Node> n = ndev->GetNode();
1062 NS_ASSERT(n);
1063
1064 AnimByteTag tag;
1065 if (!p->FindFirstMatchingByteTag(tag))
1066 {
1067 return;
1068 }
1069
1070 uint64_t animUid = GetAnimUidFromPacket(p);
1071 NS_LOG_INFO("LrWpan RxBeginTrace for packet:" << animUid);
1073 {
1074 NS_LOG_WARN("LrWpanPhyRxBeginTrace: unknown Uid - most probably it's an ACK.");
1075 }
1076
1077 UpdatePosition(n);
1078 m_pendingLrWpanPackets[animUid].ProcessRxBegin(ndev, Simulator::Now().GetSeconds());
1080}
1081
1082void
1084{
1085 NS_LOG_FUNCTION(this);
1087}
1088
1089void
1091{
1092 NS_LOG_FUNCTION(this);
1094}
1095
1096void
1098{
1099 NS_LOG_FUNCTION(this);
1101}
1102
1103void
1105{
1106 NS_LOG_FUNCTION(this);
1108}
1109
1110void
1112{
1113 NS_LOG_FUNCTION(this);
1115 if (!pb)
1116 {
1117 NS_LOG_WARN("pb == 0. Not yet supported");
1118 return;
1119 }
1120 context = "/" + context;
1122 NS_ASSERT(ndev);
1123 UpdatePosition(ndev);
1124
1125 std::list<Ptr<Packet>> pbList = pb->GetPackets();
1126 for (auto i = pbList.begin(); i != pbList.end(); ++i)
1127 {
1128 Ptr<Packet> p = *i;
1129 ++gAnimUid;
1130 NS_LOG_INFO("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
1131 AnimPacketInfo pktInfo(ndev, Simulator::Now());
1132 AddByteTag(gAnimUid, p);
1135 }
1136}
1137
1138void
1140{
1141 NS_LOG_FUNCTION(this);
1143 if (!pb)
1144 {
1145 NS_LOG_WARN("pb == 0. Not yet supported");
1146 return;
1147 }
1148 context = "/" + context;
1150 NS_ASSERT(ndev);
1151 UpdatePosition(ndev);
1152
1153 std::list<Ptr<Packet>> pbList = pb->GetPackets();
1154 for (auto i = pbList.begin(); i != pbList.end(); ++i)
1155 {
1156 Ptr<Packet> p = *i;
1157 uint64_t animUid = GetAnimUidFromPacket(p);
1158 NS_LOG_INFO("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
1160 {
1161 NS_LOG_WARN("LteSpectrumPhyRxTrace: unknown Uid");
1162 return;
1163 }
1164 AnimPacketInfo& pktInfo = m_pendingLtePackets[animUid];
1165 pktInfo.ProcessRxBegin(ndev, Simulator::Now().GetSeconds());
1166 OutputWirelessPacketRxInfo(p, pktInfo, animUid);
1167 }
1168}
1169
1170void
1172{
1173 NS_LOG_FUNCTION(this);
1176 NS_ASSERT(ndev);
1177 UpdatePosition(ndev);
1178 ++gAnimUid;
1179 NS_LOG_INFO("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
1180 AddByteTag(gAnimUid, p);
1181 UpdatePosition(ndev);
1182 AnimPacketInfo pktInfo(ndev, Simulator::Now());
1184}
1185
1186void
1188{
1189 NS_LOG_FUNCTION(this);
1192 NS_ASSERT(ndev);
1193 UpdatePosition(ndev);
1194 uint64_t animUid = GetAnimUidFromPacket(p);
1195 NS_LOG_INFO("CsmaPhyTxEndTrace for packet:" << animUid);
1197 {
1198 NS_LOG_WARN("CsmaPhyTxEndTrace: unknown Uid");
1199 NS_FATAL_ERROR("CsmaPhyTxEndTrace: unknown Uid");
1200 AnimPacketInfo pktInfo(ndev, Simulator::Now());
1201 AddPendingPacket(AnimationInterface::CSMA, animUid, pktInfo);
1202 NS_LOG_WARN("Unknown Uid, but adding Csma Packet anyway");
1203 }
1204 /// \todo NS_ASSERT (IsPacketPending (AnimUid) == true);
1205 AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1206 pktInfo.m_lbTx = Simulator::Now().GetSeconds();
1207}
1208
1209void
1211{
1212 NS_LOG_FUNCTION(this);
1215 NS_ASSERT(ndev);
1216 UpdatePosition(ndev);
1217 uint64_t animUid = GetAnimUidFromPacket(p);
1219 {
1220 NS_LOG_WARN("CsmaPhyRxEndTrace: unknown Uid");
1221 return;
1222 }
1223 /// \todo NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1224 AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1225 pktInfo.ProcessRxBegin(ndev, Simulator::Now().GetSeconds());
1226 NS_LOG_INFO("CsmaPhyRxEndTrace for packet:" << animUid);
1227 NS_LOG_INFO("CsmaPhyRxEndTrace for packet:" << animUid << " complete");
1228 OutputCsmaPacket(p, pktInfo);
1229}
1230
1231void
1233{
1234 NS_LOG_FUNCTION(this);
1237 NS_ASSERT(ndev);
1238 uint64_t animUid = GetAnimUidFromPacket(p);
1240 {
1241 NS_LOG_WARN("CsmaMacRxTrace: unknown Uid");
1242 return;
1243 }
1244 /// \todo NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1245 AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1246 NS_LOG_INFO("MacRxTrace for packet:" << animUid << " complete");
1247 OutputCsmaPacket(p, pktInfo);
1248}
1249
1250void
1252 AnimPacketInfo& pktInfo,
1253 uint64_t animUid)
1254{
1256 uint32_t nodeId = 0;
1257 if (pktInfo.m_txnd)
1258 {
1259 nodeId = pktInfo.m_txnd->GetNode()->GetId();
1260 }
1261 else
1262 {
1263 nodeId = pktInfo.m_txNodeId;
1264 }
1265 WriteXmlPRef(animUid,
1266 nodeId,
1267 pktInfo.m_fbTx,
1269}
1270
1271void
1273 AnimPacketInfo& pktInfo,
1274 uint64_t animUid)
1275{
1277 uint32_t rxId = pktInfo.m_rxnd->GetNode()->GetId();
1278 WriteXmlP(animUid, "wpr", rxId, pktInfo.m_fbRx, pktInfo.m_lbRx);
1279}
1280
1281void
1283{
1285 NS_ASSERT(pktInfo.m_txnd);
1286 uint32_t nodeId = pktInfo.m_txnd->GetNode()->GetId();
1287 uint32_t rxId = pktInfo.m_rxnd->GetNode()->GetId();
1288
1289 WriteXmlP("p",
1290 nodeId,
1291 pktInfo.m_fbTx,
1292 pktInfo.m_lbTx,
1293 rxId,
1294 pktInfo.m_fbRx,
1295 pktInfo.m_lbRx,
1297}
1298
1299void
1301 uint64_t animUid,
1302 AnimPacketInfo pktInfo)
1303{
1304 AnimUidPacketInfoMap* pendingPackets = ProtocolTypeToPendingPackets(protocolType);
1305 NS_ASSERT(pendingPackets);
1306 pendingPackets->insert(AnimUidPacketInfoMap::value_type(animUid, pktInfo));
1307}
1308
1309bool
1311{
1312 AnimUidPacketInfoMap* pendingPackets = ProtocolTypeToPendingPackets(protocolType);
1313 NS_ASSERT(pendingPackets);
1314 return (pendingPackets->find(animUid) != pendingPackets->end());
1315}
1316
1317void
1319{
1320 AnimUidPacketInfoMap* pendingPackets = ProtocolTypeToPendingPackets(protocolType);
1321 NS_ASSERT(pendingPackets);
1322 if (pendingPackets->empty())
1323 {
1324 return;
1325 }
1326 std::vector<uint64_t> purgeList;
1327 for (auto i = pendingPackets->begin(); i != pendingPackets->end(); ++i)
1328 {
1329 AnimPacketInfo pktInfo = i->second;
1330 double delta = (Simulator::Now().GetSeconds() - pktInfo.m_fbTx);
1331 if (delta > PURGE_INTERVAL)
1332 {
1333 purgeList.push_back(i->first);
1334 }
1335 }
1336 for (auto i = purgeList.begin(); i != purgeList.end(); ++i)
1337 {
1338 pendingPackets->erase(*i);
1339 }
1340}
1341
1344{
1345 AnimUidPacketInfoMap* pendingPackets = nullptr;
1346 switch (protocolType)
1347 {
1349 pendingPackets = &m_pendingWifiPackets;
1350 break;
1351 }
1353 pendingPackets = &m_pendingUanPackets;
1354 break;
1355 }
1357 pendingPackets = &m_pendingCsmaPackets;
1358 break;
1359 }
1361 pendingPackets = &m_pendingWimaxPackets;
1362 break;
1363 }
1365 pendingPackets = &m_pendingLtePackets;
1366 break;
1367 }
1369 pendingPackets = &m_pendingLrWpanPackets;
1370 break;
1371 }
1372 }
1373 return pendingPackets;
1374}
1375
1376std::string
1378{
1379 std::string result = "Unknown";
1380 switch (protocolType)
1381 {
1383 result = "WIFI";
1384 break;
1385 }
1387 result = "UAN";
1388 break;
1389 }
1391 result = "CSMA";
1392 break;
1393 }
1395 result = "WIMAX";
1396 break;
1397 }
1399 result = "LTE";
1400 break;
1401 }
1403 result = "LRWPAN";
1404 break;
1405 }
1406 }
1407 return result;
1408}
1409
1410// Counters
1411
1412std::string
1414{
1415 std::string typeString = "unknown";
1416 switch (counterType)
1417 {
1418 case UINT32_COUNTER: {
1419 typeString = "UINT32";
1420 break;
1421 }
1422 case DOUBLE_COUNTER: {
1423 typeString = "DOUBLE";
1424 break;
1425 }
1426 }
1427 return typeString;
1428}
1429
1430// General
1431
1432std::string
1434{
1435 std::ostringstream oss;
1436 p->Print(oss);
1437 return oss.str();
1438}
1439
1440uint64_t
1442{
1443 return m_currentPktCount;
1444}
1445
1446void
1448{
1449 m_started = false;
1450 NS_LOG_INFO("Stopping Animation");
1452 if (m_f)
1453 {
1454 // Terminate the anim element
1455 WriteXmlClose("anim");
1456 std::fclose(m_f);
1457 m_f = nullptr;
1458 }
1459 if (onlyAnimation)
1460 {
1461 return;
1462 }
1463 if (m_routingF)
1464 {
1465 WriteXmlClose("anim", true);
1466 std::fclose(m_routingF);
1467 m_routingF = nullptr;
1468 }
1469}
1470
1471void
1473{
1475 m_started = true;
1477 WriteXmlAnim();
1478 WriteNodes();
1485 if (!restart)
1486 {
1489 }
1490}
1491
1492void
1494{
1495 m_ipv4ToNodeIdMap[ipv4Address] = nodeId;
1496 m_nodeIdIpv4Map.insert(NodeIdIpv4Pair(nodeId, ipv4Address));
1497}
1498
1499void
1500AnimationInterface::AddToIpv4AddressNodeIdTable(std::vector<std::string> ipv4Addresses,
1501 uint32_t nodeId)
1502{
1503 for (auto i = ipv4Addresses.begin(); i != ipv4Addresses.end(); ++i)
1504 {
1505 AddToIpv4AddressNodeIdTable(*i, nodeId);
1506 }
1507}
1508
1509void
1511{
1512 m_ipv6ToNodeIdMap[ipv6Address] = nodeId;
1513 m_nodeIdIpv6Map.insert(NodeIdIpv6Pair(nodeId, ipv6Address));
1514}
1515
1516void
1517AnimationInterface::AddToIpv6AddressNodeIdTable(std::vector<std::string> ipv6Addresses,
1518 uint32_t nodeId)
1519{
1520 for (auto i = ipv6Addresses.begin(); i != ipv6Addresses.end(); ++i)
1521 {
1522 AddToIpv6AddressNodeIdTable(*i, nodeId);
1523 }
1524}
1525
1526// Callbacks
1527void
1529{
1530 Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy();
1531 Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy();
1532 Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy();
1533 std::ostringstream oss;
1534 // NodeList/*/DeviceList/*/
1535 oss << "NodeList/" << n->GetId() << "/DeviceList/" << devIndex << "/";
1536 if (dlPhy)
1537 {
1538 dlPhy->TraceConnect("TxStart",
1539 oss.str(),
1541 dlPhy->TraceConnect("RxStart",
1542 oss.str(),
1544 }
1545 if (ulPhy)
1546 {
1547 ulPhy->TraceConnect("TxStart",
1548 oss.str(),
1550 ulPhy->TraceConnect("RxStart",
1551 oss.str(),
1553 }
1554}
1555
1556void
1558{
1559 Ptr<LteUePhy> lteUePhy = nd->GetPhy();
1560 Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy();
1561 Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy();
1562 std::ostringstream oss;
1563 // NodeList/*/DeviceList/*/
1564 oss << "NodeList/" << n->GetId() << "/DeviceList/" << devIndex << "/";
1565 if (dlPhy)
1566 {
1567 dlPhy->TraceConnect("TxStart",
1568 oss.str(),
1570 dlPhy->TraceConnect("RxStart",
1571 oss.str(),
1573 }
1574 if (ulPhy)
1575 {
1576 ulPhy->TraceConnect("TxStart",
1577 oss.str(),
1579 ulPhy->TraceConnect("RxStart",
1580 oss.str(),
1582 }
1583}
1584
1585void
1587{
1588 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
1589 {
1590 Ptr<Node> n = *i;
1591 NS_ASSERT(n);
1592 uint32_t nDevices = n->GetNDevices();
1593 for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
1594 {
1595 Ptr<NetDevice> nd = n->GetDevice(devIndex);
1596 if (!nd)
1597 {
1598 continue;
1599 }
1600 Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice>(nd);
1601 if (lteUeNetDevice)
1602 {
1603 ConnectLteUe(n, lteUeNetDevice, devIndex);
1604 continue;
1605 }
1606 Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice>(nd);
1607 if (lteEnbNetDevice)
1608 {
1609 ConnectLteEnb(n, lteEnbNetDevice, devIndex);
1610 }
1611 }
1612 }
1613}
1614
1615void
1617{
1618 // Connect the callbacks
1619 Config::ConnectFailSafe("/ChannelList/*/TxRxPointToPoint",
1621 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
1623 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
1626 "/NodeList/*/$ns3::MobilityModel/CourseChange",
1628 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
1630 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
1632 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
1634 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
1636 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
1638 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
1640 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
1642 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
1644 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
1646 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
1648 Config::ConnectFailSafe("/NodeList/*/$ns3::BasicEnergySource/RemainingEnergy",
1650
1651 ConnectLte();
1652
1653 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
1655 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
1657 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
1659
1660 // Queue Enqueues
1661
1662 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Enqueue",
1664 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Enqueue",
1666 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Enqueue",
1668
1669 // Queue Dequeues
1670
1671 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Dequeue",
1673 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Dequeue",
1675 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Dequeue",
1677
1678 // Queue Drops
1679
1680 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Drop",
1682 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Drop",
1684 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Drop",
1686
1687 // Wifi Mac
1688 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
1690 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTxDrop",
1692 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
1694 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRxDrop",
1696
1697 // Wifi Phy
1698 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxDrop",
1700 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
1702
1703 // LrWpan
1704 Config::ConnectFailSafe("NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Phy/PhyTxBegin",
1706 Config::ConnectFailSafe("NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Phy/PhyRxBegin",
1708 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacTx",
1710 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacTxDrop",
1712 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacRx",
1714 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacRxDrop",
1716}
1717
1718Vector
1720{
1721 Ptr<MobilityModel> loc = n->GetObject<MobilityModel>();
1722 if (loc)
1723 {
1724 m_nodeLocation[n->GetId()] = loc->GetPosition();
1725 }
1726 else
1727 {
1729 "AnimationInterface WARNING:Node:"
1730 << n->GetId()
1731 << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
1732 Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable>();
1733 x->SetAttribute("Min", DoubleValue(0));
1734 x->SetAttribute("Max", DoubleValue(100));
1735 Ptr<UniformRandomVariable> y = CreateObject<UniformRandomVariable>();
1736 y->SetAttribute("Min", DoubleValue(0));
1737 y->SetAttribute("Max", DoubleValue(100));
1738 m_nodeLocation[n->GetId()] = Vector(int(x->GetValue()), int(y->GetValue()), 0);
1739 }
1740 return m_nodeLocation[n->GetId()];
1741}
1742
1743Vector
1745{
1746 m_nodeLocation[n->GetId()] = v;
1747 return v;
1748}
1749
1750Vector
1752{
1753 Ptr<Node> n = ndev->GetNode();
1754 NS_ASSERT(n);
1755 return UpdatePosition(n);
1756}
1757
1758Vector
1760{
1761 if (m_nodeLocation.find(n->GetId()) == m_nodeLocation.end())
1762 {
1763 NS_FATAL_ERROR("Node:" << n->GetId() << " not found in Location table");
1764 }
1765 return m_nodeLocation[n->GetId()];
1766}
1767
1768std::string
1770{
1771 Address nodeAddr = nd->GetAddress();
1772 std::ostringstream oss;
1773 oss << nodeAddr;
1774 return oss.str().substr(6); // Skip the first 6 chars to get the Mac
1775}
1776
1777std::string
1779{
1780 Ptr<Ipv4> ipv4 = NodeList::GetNode(nd->GetNode()->GetId())->GetObject<Ipv4>();
1781 if (!ipv4)
1782 {
1783 NS_LOG_WARN("Node: " << nd->GetNode()->GetId() << " No ipv4 object found");
1784 return "0.0.0.0";
1785 }
1786 int32_t ifIndex = ipv4->GetInterfaceForDevice(nd);
1787 if (ifIndex == -1)
1788 {
1789 NS_LOG_WARN("Node :" << nd->GetNode()->GetId() << " Could not find index of NetDevice");
1790 return "0.0.0.0";
1791 }
1792 Ipv4InterfaceAddress addr = ipv4->GetAddress(ifIndex, 0);
1793 std::ostringstream oss;
1794 oss << addr.GetLocal();
1795 return oss.str();
1796}
1797
1798std::string
1800{
1801 Ptr<Ipv6> ipv6 = NodeList::GetNode(nd->GetNode()->GetId())->GetObject<Ipv6>();
1802 if (!ipv6)
1803 {
1804 NS_LOG_WARN("Node: " << nd->GetNode()->GetId() << " No ipv4 object found");
1805 return "::";
1806 }
1807 int32_t ifIndex = ipv6->GetInterfaceForDevice(nd);
1808 if (ifIndex == -1)
1809 {
1810 NS_LOG_WARN("Node :" << nd->GetNode()->GetId() << " Could not find index of NetDevice");
1811 return "::";
1812 }
1813 bool nonLinkLocalFound = false;
1814 uint32_t nAddresses = ipv6->GetNAddresses(ifIndex);
1816 for (uint32_t addressIndex = 0; addressIndex < nAddresses; ++addressIndex)
1817 {
1818 addr = ipv6->GetAddress(ifIndex, addressIndex);
1819 if (!addr.GetAddress().IsLinkLocal())
1820 {
1821 nonLinkLocalFound = true;
1822 break;
1823 }
1824 }
1825 if (!nonLinkLocalFound)
1826 {
1827 addr = ipv6->GetAddress(ifIndex, 0);
1828 }
1829 std::ostringstream oss;
1830 oss << addr.GetAddress();
1831 return oss.str();
1832}
1833
1834std::vector<std::string>
1836{
1837 std::vector<std::string> ipv4Addresses;
1838 Ptr<Ipv4> ipv4 = NodeList::GetNode(nd->GetNode()->GetId())->GetObject<Ipv4>();
1839 if (!ipv4)
1840 {
1841 NS_LOG_WARN("Node: " << nd->GetNode()->GetId() << " No ipv4 object found");
1842 return ipv4Addresses;
1843 }
1844 int32_t ifIndex = ipv4->GetInterfaceForDevice(nd);
1845 if (ifIndex == -1)
1846 {
1847 NS_LOG_WARN("Node :" << nd->GetNode()->GetId() << " Could not find index of NetDevice");
1848 return ipv4Addresses;
1849 }
1850 for (uint32_t index = 0; index < ipv4->GetNAddresses(ifIndex); ++index)
1851 {
1852 Ipv4InterfaceAddress addr = ipv4->GetAddress(ifIndex, index);
1853 std::ostringstream oss;
1854 oss << addr.GetLocal();
1855 ipv4Addresses.push_back(oss.str());
1856 }
1857 return ipv4Addresses;
1858}
1859
1860std::vector<std::string>
1862{
1863 std::vector<std::string> ipv6Addresses;
1864 Ptr<Ipv6> ipv6 = NodeList::GetNode(nd->GetNode()->GetId())->GetObject<Ipv6>();
1865 if (!ipv6)
1866 {
1867 NS_LOG_WARN("Node: " << nd->GetNode()->GetId() << " No ipv6 object found");
1868 return ipv6Addresses;
1869 }
1870 int32_t ifIndex = ipv6->GetInterfaceForDevice(nd);
1871 if (ifIndex == -1)
1872 {
1873 NS_LOG_WARN("Node :" << nd->GetNode()->GetId() << " Could not find index of NetDevice");
1874 return ipv6Addresses;
1875 }
1876 for (uint32_t index = 0; index < ipv6->GetNAddresses(ifIndex); ++index)
1877 {
1878 Ipv6InterfaceAddress addr = ipv6->GetAddress(ifIndex, index);
1879 std::ostringstream oss;
1880 oss << addr.GetAddress();
1881 ipv6Addresses.push_back(oss.str());
1882 }
1883 return ipv6Addresses;
1884}
1885
1886void
1888{
1889 for (auto i = m_nodeIdIpv4Map.begin(); i != m_nodeIdIpv4Map.end(); ++i)
1890 {
1891 std::vector<std::string> ipv4Addresses;
1892 auto iterPair = m_nodeIdIpv4Map.equal_range(i->first);
1893 for (auto it = iterPair.first; it != iterPair.second; ++it)
1894 {
1895 ipv4Addresses.push_back(it->second);
1896 }
1897 WriteXmlIpv4Addresses(i->first, ipv4Addresses);
1898 }
1899}
1900
1901void
1903{
1904 for (auto i = m_nodeIdIpv6Map.begin(); i != m_nodeIdIpv6Map.end();
1905 i = m_nodeIdIpv6Map.upper_bound(i->first))
1906 {
1907 std::vector<std::string> ipv6Addresses;
1908 auto iterPair = m_nodeIdIpv6Map.equal_range(i->first);
1909 for (auto it = iterPair.first; it != iterPair.second; ++it)
1910 {
1911 ipv6Addresses.push_back(it->second);
1912 }
1913 WriteXmlIpv6Addresses(i->first, ipv6Addresses);
1914 }
1915}
1916
1917void
1919{
1920 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
1921 {
1922 Ptr<Node> n = *i;
1923 UpdatePosition(n);
1924 uint32_t n1Id = n->GetId();
1925 uint32_t nDev = n->GetNDevices(); // Number of devices
1926 for (uint32_t i = 0; i < nDev; ++i)
1927 {
1928 Ptr<NetDevice> dev = n->GetDevice(i);
1929 NS_ASSERT(dev);
1930 Ptr<Channel> ch = dev->GetChannel();
1931 std::string channelType = "Unknown channel";
1932 if (ch)
1933 {
1934 channelType = ch->GetInstanceTypeId().GetName();
1935 }
1936 NS_LOG_DEBUG("Got ChannelType" << channelType);
1937
1938 if (!ch || (channelType != "ns3::PointToPointChannel"))
1939 {
1940 NS_LOG_DEBUG("No channel can't be a p2p device");
1941 /*
1942 // Try to see if it is an LTE NetDevice, which does not return a channel
1943 if ((dev->GetInstanceTypeId ().GetName () == "ns3::LteUeNetDevice") ||
1944 (dev->GetInstanceTypeId ().GetName () == "ns3::LteEnbNetDevice")||
1945 (dev->GetInstanceTypeId ().GetName () == "ns3::VirtualNetDevice"))
1946 {
1947 WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" +
1948 GetMacAddress (dev), channelType); AddToIpv4AddressNodeIdTable (GetIpv4Address
1949 (dev), n->GetId ());
1950 }
1951 */
1952 std::vector<std::string> ipv4Addresses = GetIpv4Addresses(dev);
1953 AddToIpv4AddressNodeIdTable(ipv4Addresses, n->GetId());
1954 std::vector<std::string> ipv6Addresses = GetIpv6Addresses(dev);
1955 AddToIpv6AddressNodeIdTable(ipv6Addresses, n->GetId());
1956 if (!ipv4Addresses.empty())
1957 {
1958 NS_LOG_INFO("Writing Ipv4 link");
1959 WriteNonP2pLinkProperties(n->GetId(),
1960 GetIpv4Address(dev) + "~" + GetMacAddress(dev),
1961 channelType);
1962 }
1963 else if (!ipv6Addresses.empty())
1964 {
1965 NS_LOG_INFO("Writing Ipv6 link");
1966 WriteNonP2pLinkProperties(n->GetId(),
1967 GetIpv6Address(dev) + "~" + GetMacAddress(dev),
1968 channelType);
1969 }
1970 continue;
1971 }
1972
1973 else if (channelType == "ns3::PointToPointChannel")
1974 { // Since these are duplex links, we only need to dump
1975 // if srcid < dstid
1976 std::size_t nChDev = ch->GetNDevices();
1977 for (std::size_t j = 0; j < nChDev; ++j)
1978 {
1979 Ptr<NetDevice> chDev = ch->GetDevice(j);
1980 uint32_t n2Id = chDev->GetNode()->GetId();
1981 if (n1Id < n2Id)
1982 {
1983 std::vector<std::string> ipv4Addresses = GetIpv4Addresses(dev);
1984 AddToIpv4AddressNodeIdTable(ipv4Addresses, n1Id);
1985 ipv4Addresses = GetIpv4Addresses(chDev);
1986 AddToIpv4AddressNodeIdTable(ipv4Addresses, n2Id);
1987 std::vector<std::string> ipv6Addresses = GetIpv6Addresses(dev);
1988 AddToIpv6AddressNodeIdTable(ipv6Addresses, n1Id);
1989 ipv6Addresses = GetIpv6Addresses(chDev);
1990 AddToIpv6AddressNodeIdTable(ipv6Addresses, n2Id);
1991
1992 P2pLinkNodeIdPair p2pPair;
1993 p2pPair.fromNode = n1Id;
1994 p2pPair.toNode = n2Id;
1995 if (!ipv4Addresses.empty())
1996 {
1997 LinkProperties lp = {GetIpv4Address(dev) + "~" + GetMacAddress(dev),
1998 GetIpv4Address(chDev) + "~" + GetMacAddress(chDev),
1999 ""};
2000 m_linkProperties[p2pPair] = lp;
2001 }
2002 else if (!ipv6Addresses.empty())
2003 {
2004 LinkProperties lp = {GetIpv6Address(dev) + "~" + GetMacAddress(dev),
2005 GetIpv6Address(chDev) + "~" + GetMacAddress(chDev),
2006 ""};
2007 m_linkProperties[p2pPair] = lp;
2008 }
2009 WriteXmlLink(n1Id, 0, n2Id);
2010 }
2011 }
2012 }
2013 }
2014 }
2015 m_linkProperties.clear();
2016}
2017
2018void
2020{
2021 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2022 {
2023 Ptr<Node> n = *i;
2024 NS_LOG_INFO("Update Position for Node: " << n->GetId());
2025 Vector v = UpdatePosition(n);
2026 WriteXmlNode(n->GetId(), n->GetSystemId(), v.x, v.y);
2027 }
2028}
2029
2030void
2032{
2033 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2034 {
2035 Ptr<Node> n = *i;
2036 Rgb rgb = {255, 0, 0};
2037 if (m_nodeColors.find(n->GetId()) == m_nodeColors.end())
2038 {
2039 m_nodeColors[n->GetId()] = rgb;
2040 }
2041 UpdateNodeColor(n, rgb.r, rgb.g, rgb.b);
2042 }
2043}
2044
2045void
2047{
2048 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2049 {
2050 Ptr<Node> n = *i;
2051 NS_LOG_INFO("Update Size for Node: " << n->GetId());
2053 m_nodeSizes[n->GetId()] = s;
2054 UpdateNodeSize(n->GetId(), s.width, s.height);
2055 }
2056}
2057
2058void
2060{
2063 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2064 {
2065 Ptr<Node> n = *i;
2066 if (NodeList::GetNode(n->GetId())->GetObject<EnergySource>())
2067 {
2069 }
2070 }
2071}
2072
2073bool
2075{
2077}
2078
2079void
2080AnimationInterface::SetOutputFile(const std::string& fn, bool routing)
2081{
2082 if (!routing && m_f)
2083 {
2084 return;
2085 }
2086 if (routing && m_routingF)
2087 {
2088 NS_FATAL_ERROR("SetRoutingOutputFile already used once");
2089 return;
2090 }
2091
2092 NS_LOG_INFO("Creating new trace file:" << fn);
2093 FILE* f = nullptr;
2094 f = std::fopen(fn.c_str(), "w");
2095 if (!f)
2096 {
2097 NS_FATAL_ERROR("Unable to open output file:" << fn);
2098 return; // Can't open output file
2099 }
2100 if (routing)
2101 {
2102 m_routingF = f;
2103 m_routingFileName = fn;
2104 }
2105 else
2106 {
2107 m_f = f;
2108 m_outputFileName = fn;
2109 }
2110}
2111
2112void
2114{
2115 // Start a new trace file if the current packet count exceeded max packets per file
2118 {
2119 return;
2120 }
2121 NS_LOG_UNCOND("Max Packets per trace file exceeded");
2122 StopAnimation(true);
2123}
2124
2125std::string
2127{
2128 return NETANIM_VERSION;
2129}
2130
2131void
2133{
2135 {
2136 NS_LOG_INFO("TrackQueueCounters Completed");
2137 return;
2138 }
2139 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2140 {
2141 uint32_t nodeId = Ptr<Node>(*i)->GetId();
2145 }
2147}
2148
2149void
2151{
2153 {
2154 NS_LOG_INFO("TrackWifiMacCounters Completed");
2155 return;
2156 }
2157 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2158 {
2159 uint32_t nodeId = Ptr<Node>(*i)->GetId();
2164 }
2167 this);
2168}
2169
2170void
2172{
2174 {
2175 NS_LOG_INFO("TrackWifiPhyCounters Completed");
2176 return;
2177 }
2178 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2179 {
2180 uint32_t nodeId = Ptr<Node>(*i)->GetId();
2183 }
2186 this);
2187}
2188
2189void
2191{
2193 {
2194 NS_LOG_INFO("TrackIpv4L3ProtocolCounters Completed");
2195 return;
2196 }
2197 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2198 {
2199 uint32_t nodeId = Ptr<Node>(*i)->GetId();
2203 }
2206 this);
2207}
2208
2209/***** Routing-related *****/
2210
2211void
2213{
2214 if (m_ipv4RouteTrackElements.empty())
2215 {
2216 return;
2217 }
2218 for (auto i = m_ipv4RouteTrackElements.begin(); i != m_ipv4RouteTrackElements.end(); ++i)
2219 {
2220 Ipv4RouteTrackElement trackElement = *i;
2221 Ptr<Node> fromNode = NodeList::GetNode(trackElement.fromNodeId);
2222 if (!fromNode)
2223 {
2224 NS_FATAL_ERROR("Node: " << trackElement.fromNodeId << " Not found");
2225 continue;
2226 }
2227 Ptr<ns3::Ipv4> ipv4 = fromNode->GetObject<ns3::Ipv4>();
2228 if (!ipv4)
2229 {
2230 NS_LOG_WARN("ipv4 object not found");
2231 continue;
2232 }
2233 Ptr<Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol();
2234 if (!rp)
2235 {
2236 NS_LOG_WARN("Routing protocol object not found");
2237 continue;
2238 }
2239 NS_LOG_INFO("Begin Track Route for: " << trackElement.destination
2240 << " From:" << trackElement.fromNodeId);
2241 Ptr<Packet> pkt = Create<Packet>();
2242 Ipv4Header header;
2243 header.SetDestination(Ipv4Address(trackElement.destination.c_str()));
2244 Socket::SocketErrno sockerr;
2245 Ptr<Ipv4Route> rt = rp->RouteOutput(pkt, header, nullptr, sockerr);
2246 Ipv4RoutePathElements rpElements;
2247 if (!rt)
2248 {
2249 NS_LOG_INFO("No route to :" << trackElement.destination);
2250 Ipv4RoutePathElement elem = {trackElement.fromNodeId, "-1"};
2251 rpElements.push_back(elem);
2252 WriteRoutePath(trackElement.fromNodeId, trackElement.destination, rpElements);
2253 continue;
2254 }
2255 std::ostringstream oss;
2256 oss << rt->GetGateway();
2257 NS_LOG_INFO("Node:" << trackElement.fromNodeId << "-->" << rt->GetGateway());
2258 if (rt->GetGateway() == "0.0.0.0")
2259 {
2260 Ipv4RoutePathElement elem = {trackElement.fromNodeId, "C"};
2261 rpElements.push_back(elem);
2262 if (m_ipv4ToNodeIdMap.find(trackElement.destination) != m_ipv4ToNodeIdMap.end())
2263 {
2264 Ipv4RoutePathElement elem2 = {m_ipv4ToNodeIdMap[trackElement.destination], "L"};
2265 rpElements.push_back(elem2);
2266 }
2267 }
2268 else if (rt->GetGateway() == "127.0.0.1")
2269 {
2270 Ipv4RoutePathElement elem = {trackElement.fromNodeId, "-1"};
2271 rpElements.push_back(elem);
2272 }
2273 else
2274 {
2275 Ipv4RoutePathElement elem = {trackElement.fromNodeId, oss.str()};
2276 rpElements.push_back(elem);
2277 }
2278 RecursiveIpv4RoutePathSearch(oss.str(), trackElement.destination, rpElements);
2279 WriteRoutePath(trackElement.fromNodeId, trackElement.destination, rpElements);
2280 }
2281}
2282
2283void
2285{
2287 {
2288 NS_LOG_INFO("TrackIpv4Route completed");
2289 return;
2290 }
2291 if (m_routingNc.GetN())
2292 {
2293 for (auto i = m_routingNc.Begin(); i != m_routingNc.End(); ++i)
2294 {
2295 Ptr<Node> n = *i;
2296 WriteXmlRouting(n->GetId(), GetIpv4RoutingTable(n));
2297 }
2298 }
2299 else
2300 {
2301 for (auto i = NodeList::Begin(); i != NodeList::End(); ++i)
2302 {
2303 Ptr<Node> n = *i;
2304 WriteXmlRouting(n->GetId(), GetIpv4RoutingTable(n));
2305 }
2306 }
2309}
2310
2311std::string
2313{
2314 NS_ASSERT(n);
2315 Ptr<ns3::Ipv4> ipv4 = n->GetObject<ns3::Ipv4>();
2316 if (!ipv4)
2317 {
2318 NS_LOG_WARN("Node " << n->GetId() << " Does not have an Ipv4 object");
2319 return "";
2320 }
2321 std::stringstream stream;
2322 Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper>(&stream);
2323 ipv4->GetRoutingProtocol()->PrintRoutingTable(routingstream);
2324 return stream.str();
2325}
2326
2327void
2329 std::string to,
2330 Ipv4RoutePathElements& rpElements)
2331{
2332 NS_LOG_INFO("RecursiveIpv4RoutePathSearch from:" << from << " to:" << to);
2333 if (from == "0.0.0.0" || from == "127.0.0.1")
2334 {
2335 NS_LOG_INFO("Got " << from << " End recursion");
2336 return;
2337 }
2340 if (fromNode->GetId() == toNode->GetId())
2341 {
2342 Ipv4RoutePathElement elem = {fromNode->GetId(), "L"};
2343 rpElements.push_back(elem);
2344 return;
2345 }
2346 if (!fromNode)
2347 {
2348 NS_FATAL_ERROR("Node: " << m_ipv4ToNodeIdMap[from] << " Not found");
2349 return;
2350 }
2351 if (!toNode)
2352 {
2353 NS_FATAL_ERROR("Node: " << m_ipv4ToNodeIdMap[to] << " Not found");
2354 return;
2355 }
2356 Ptr<ns3::Ipv4> ipv4 = fromNode->GetObject<ns3::Ipv4>();
2357 if (!ipv4)
2358 {
2359 NS_LOG_WARN("ipv4 object not found");
2360 return;
2361 }
2362 Ptr<Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol();
2363 if (!rp)
2364 {
2365 NS_LOG_WARN("Routing protocol object not found");
2366 return;
2367 }
2368 Ptr<Packet> pkt = Create<Packet>();
2369 Ipv4Header header;
2370 header.SetDestination(Ipv4Address(to.c_str()));
2371 Socket::SocketErrno sockerr;
2372 Ptr<Ipv4Route> rt = rp->RouteOutput(pkt, header, nullptr, sockerr);
2373 if (!rt)
2374 {
2375 return;
2376 }
2377 NS_LOG_DEBUG("Node: " << fromNode->GetId() << " G:" << rt->GetGateway());
2378 std::ostringstream oss;
2379 oss << rt->GetGateway();
2380 if (oss.str() == "0.0.0.0" && (sockerr != Socket::ERROR_NOROUTETOHOST))
2381 {
2382 NS_LOG_INFO("Null gw");
2383 Ipv4RoutePathElement elem = {fromNode->GetId(), "C"};
2384 rpElements.push_back(elem);
2385 if (m_ipv4ToNodeIdMap.find(to) != m_ipv4ToNodeIdMap.end())
2386 {
2387 Ipv4RoutePathElement elem2 = {m_ipv4ToNodeIdMap[to], "L"};
2388 rpElements.push_back(elem2);
2389 }
2390 return;
2391 }
2392 NS_LOG_INFO("Node:" << fromNode->GetId() << "-->" << rt->GetGateway());
2393 Ipv4RoutePathElement elem = {fromNode->GetId(), oss.str()};
2394 rpElements.push_back(elem);
2395 RecursiveIpv4RoutePathSearch(oss.str(), to, rpElements);
2396}
2397
2398/***** WriteXml *****/
2399
2400void
2402{
2403 AnimXmlElement element("anim");
2404 element.AddAttribute("ver", GetNetAnimVersion());
2405 FILE* f = m_f;
2406 if (!routing)
2407 {
2408 element.AddAttribute("filetype", "animation");
2409 }
2410 else
2411 {
2412 element.AddAttribute("filetype", "routing");
2413 f = m_routingF;
2414 }
2415 WriteN(element.ToString(false) + ">\n", f);
2416}
2417
2418void
2419AnimationInterface::WriteXmlClose(std::string name, bool routing)
2420{
2421 std::string closeString = "</" + name + ">\n";
2422 if (!routing)
2423 {
2424 WriteN(closeString, m_f);
2425 }
2426 else
2427 {
2428 WriteN(closeString, m_routingF);
2429 }
2430}
2431
2432void
2433AnimationInterface::WriteXmlNode(uint32_t id, uint32_t sysId, double locX, double locY)
2434{
2435 AnimXmlElement element("node");
2436 element.AddAttribute("id", id);
2437 element.AddAttribute("sysId", sysId);
2438 element.AddAttribute("locX", locX);
2439 element.AddAttribute("locY", locY);
2440 WriteN(element.ToString(), m_f);
2441}
2442
2443void
2444AnimationInterface::WriteXmlUpdateLink(uint32_t fromId, uint32_t toId, std::string linkDescription)
2445{
2446 AnimXmlElement element("linkupdate");
2447 element.AddAttribute("t", Simulator::Now().GetSeconds());
2448 element.AddAttribute("fromId", fromId);
2449 element.AddAttribute("toId", toId);
2450 element.AddAttribute("ld", linkDescription, true);
2451 WriteN(element.ToString(), m_f);
2452}
2453
2454void
2456{
2457 AnimXmlElement element("link");
2458 element.AddAttribute("fromId", fromId);
2459 element.AddAttribute("toId", toId);
2460
2461 LinkProperties lprop;
2462 lprop.fromNodeDescription = "";
2463 lprop.toNodeDescription = "";
2464 lprop.linkDescription = "";
2465
2466 P2pLinkNodeIdPair p1 = {fromId, toId};
2467 P2pLinkNodeIdPair p2 = {toId, fromId};
2468 if (m_linkProperties.find(p1) != m_linkProperties.end())
2469 {
2470 lprop = m_linkProperties[p1];
2471 }
2472 else if (m_linkProperties.find(p2) != m_linkProperties.end())
2473 {
2474 lprop = m_linkProperties[p2];
2475 }
2476
2477 element.AddAttribute("fd", lprop.fromNodeDescription, true);
2478 element.AddAttribute("td", lprop.toNodeDescription, true);
2479 element.AddAttribute("ld", lprop.linkDescription, true);
2480 WriteN(element.ToString(), m_f);
2481}
2482
2483void
2484AnimationInterface::WriteXmlIpv4Addresses(uint32_t nodeId, std::vector<std::string> ipv4Addresses)
2485{
2486 AnimXmlElement element("ip");
2487 element.AddAttribute("n", nodeId);
2488 for (auto i = ipv4Addresses.begin(); i != ipv4Addresses.end(); ++i)
2489 {
2490 AnimXmlElement valueElement("address");
2491 valueElement.SetText(*i);
2492 element.AppendChild(valueElement);
2493 }
2494 WriteN(element.ToString(), m_f);
2495}
2496
2497void
2498AnimationInterface::WriteXmlIpv6Addresses(uint32_t nodeId, std::vector<std::string> ipv6Addresses)
2499{
2500 AnimXmlElement element("ipv6");
2501 element.AddAttribute("n", nodeId);
2502 for (auto i = ipv6Addresses.begin(); i != ipv6Addresses.end(); ++i)
2503 {
2504 AnimXmlElement valueElement("address");
2505 valueElement.SetText(*i);
2506 element.AppendChild(valueElement);
2507 }
2508 WriteN(element.ToString(), m_f);
2509}
2510
2511void
2512AnimationInterface::WriteXmlRouting(uint32_t nodeId, std::string routingInfo)
2513{
2514 AnimXmlElement element("rt");
2515 element.AddAttribute("t", Simulator::Now().GetSeconds());
2516 element.AddAttribute("id", nodeId);
2517 element.AddAttribute("info", routingInfo.c_str(), true);
2518 WriteN(element.ToString(), m_routingF);
2519}
2520
2521void
2523 std::string destination,
2524 Ipv4RoutePathElements rpElements)
2525{
2526 std::string tagName = "rp";
2527 AnimXmlElement element(tagName, false);
2528 element.AddAttribute("t", Simulator::Now().GetSeconds());
2529 element.AddAttribute("id", nodeId);
2530 element.AddAttribute("d", destination.c_str());
2531 element.AddAttribute("c", rpElements.size());
2532 for (auto i = rpElements.begin(); i != rpElements.end(); ++i)
2533 {
2534 Ipv4RoutePathElement rpElement = *i;
2535 AnimXmlElement rpeElement("rpe");
2536 rpeElement.AddAttribute("n", rpElement.nodeId);
2537 rpeElement.AddAttribute("nH", rpElement.nextHop.c_str());
2538 element.AppendChild(rpeElement);
2539 }
2540 WriteN(element.ToString(), m_routingF);
2541}
2542
2543void
2544AnimationInterface::WriteXmlPRef(uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo)
2545{
2546 AnimXmlElement element("pr");
2547 element.AddAttribute("uId", animUid);
2548 element.AddAttribute("fId", fId);
2549 element.AddAttribute("fbTx", fbTx);
2550 if (!metaInfo.empty())
2551 {
2552 element.AddAttribute("meta-info", metaInfo.c_str(), true);
2553 }
2554 WriteN(element.ToString(), m_f);
2555}
2556
2557void
2559 std::string pktType,
2560 uint32_t tId,
2561 double fbRx,
2562 double lbRx)
2563{
2564 AnimXmlElement element(pktType);
2565 element.AddAttribute("uId", animUid);
2566 element.AddAttribute("tId", tId);
2567 element.AddAttribute("fbRx", fbRx);
2568 element.AddAttribute("lbRx", lbRx);
2569 WriteN(element.ToString(), m_f);
2570}
2571
2572void
2574 uint32_t fId,
2575 double fbTx,
2576 double lbTx,
2577 uint32_t tId,
2578 double fbRx,
2579 double lbRx,
2580 std::string metaInfo)
2581{
2582 AnimXmlElement element(pktType);
2583 element.AddAttribute("fId", fId);
2584 element.AddAttribute("fbTx", fbTx);
2585 element.AddAttribute("lbTx", lbTx);
2586 if (!metaInfo.empty())
2587 {
2588 element.AddAttribute("meta-info", metaInfo.c_str(), true);
2589 }
2590 element.AddAttribute("tId", tId);
2591 element.AddAttribute("fbRx", fbRx);
2592 element.AddAttribute("lbRx", lbRx);
2593 WriteN(element.ToString(), m_f);
2594}
2595
2596void
2598 std::string counterName,
2599 CounterType counterType)
2600{
2601 AnimXmlElement element("ncs");
2602 element.AddAttribute("ncId", nodeCounterId);
2603 element.AddAttribute("n", counterName);
2604 element.AddAttribute("t", CounterTypeToString(counterType));
2605 WriteN(element.ToString(), m_f);
2606}
2607
2608void
2609AnimationInterface::WriteXmlAddResource(uint32_t resourceId, std::string resourcePath)
2610{
2611 AnimXmlElement element("res");
2612 element.AddAttribute("rid", resourceId);
2613 element.AddAttribute("p", resourcePath);
2614 WriteN(element.ToString(), m_f);
2615}
2616
2617void
2619{
2620 AnimXmlElement element("nu");
2621 element.AddAttribute("p", "i");
2622 element.AddAttribute("t", Simulator::Now().GetSeconds());
2623 element.AddAttribute("id", nodeId);
2624 element.AddAttribute("rid", resourceId);
2625 WriteN(element.ToString(), m_f);
2626}
2627
2628void
2629AnimationInterface::WriteXmlUpdateNodeSize(uint32_t nodeId, double width, double height)
2630{
2631 AnimXmlElement element("nu");
2632 element.AddAttribute("p", "s");
2633 element.AddAttribute("t", Simulator::Now().GetSeconds());
2634 element.AddAttribute("id", nodeId);
2635 element.AddAttribute("w", width);
2636 element.AddAttribute("h", height);
2637 WriteN(element.ToString(), m_f);
2638}
2639
2640void
2642{
2643 AnimXmlElement element("nu");
2644 element.AddAttribute("p", "p");
2645 element.AddAttribute("t", Simulator::Now().GetSeconds());
2646 element.AddAttribute("id", nodeId);
2647 element.AddAttribute("x", x);
2648 element.AddAttribute("y", y);
2649 WriteN(element.ToString(), m_f);
2650}
2651
2652void
2653AnimationInterface::WriteXmlUpdateNodeColor(uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
2654{
2655 AnimXmlElement element("nu");
2656 element.AddAttribute("p", "c");
2657 element.AddAttribute("t", Simulator::Now().GetSeconds());
2658 element.AddAttribute("id", nodeId);
2659 element.AddAttribute("r", (uint32_t)r);
2660 element.AddAttribute("g", (uint32_t)g);
2661 element.AddAttribute("b", (uint32_t)b);
2662 WriteN(element.ToString(), m_f);
2663}
2664
2665void
2667{
2668 AnimXmlElement element("nu");
2669 element.AddAttribute("p", "d");
2670 element.AddAttribute("t", Simulator::Now().GetSeconds());
2671 element.AddAttribute("id", nodeId);
2672 if (m_nodeDescriptions.find(nodeId) != m_nodeDescriptions.end())
2673 {
2674 element.AddAttribute("descr", m_nodeDescriptions[nodeId], true);
2675 }
2676 WriteN(element.ToString(), m_f);
2677}
2678
2679void
2681 uint32_t nodeId,
2682 double counterValue)
2683{
2684 AnimXmlElement element("nc");
2685 element.AddAttribute("c", nodeCounterId);
2686 element.AddAttribute("i", nodeId);
2687 element.AddAttribute("t", Simulator::Now().GetSeconds());
2688 element.AddAttribute("v", counterValue);
2689 WriteN(element.ToString(), m_f);
2690}
2691
2692void
2694 double x,
2695 double y,
2696 double scaleX,
2697 double scaleY,
2698 double opacity)
2699{
2700 AnimXmlElement element("bg");
2701 element.AddAttribute("f", fileName);
2702 element.AddAttribute("x", x);
2703 element.AddAttribute("y", y);
2704 element.AddAttribute("sx", scaleX);
2705 element.AddAttribute("sy", scaleY);
2706 element.AddAttribute("o", opacity);
2707 WriteN(element.ToString(), m_f);
2708}
2709
2710void
2712 std::string ipAddress,
2713 std::string channelType)
2714{
2715 AnimXmlElement element("nonp2plinkproperties");
2716 element.AddAttribute("id", id);
2717 element.AddAttribute("ipAddress", ipAddress);
2718 element.AddAttribute("channelType", channelType);
2719 WriteN(element.ToString(), m_f);
2720}
2721
2722/***** AnimXmlElement *****/
2723
2724AnimationInterface::AnimXmlElement::AnimXmlElement(std::string tagName, bool emptyElement)
2725 : m_tagName(tagName),
2726 m_text("")
2727{
2728}
2729
2730template <typename T>
2731void
2732AnimationInterface::AnimXmlElement::AddAttribute(std::string attribute, T value, bool xmlEscape)
2733{
2734 std::ostringstream oss;
2735 oss << std::setprecision(10);
2736 oss << value;
2737 std::string attributeString = attribute;
2738 if (xmlEscape)
2739 {
2740 attributeString += "=\"";
2741 std::string valueStr = oss.str();
2742 for (auto it = valueStr.begin(); it != valueStr.end(); ++it)
2743 {
2744 switch (*it)
2745 {
2746 case '&':
2747 attributeString += "&amp;";
2748 break;
2749 case '\"':
2750 attributeString += "&quot;";
2751 break;
2752 case '\'':
2753 attributeString += "&apos;";
2754 break;
2755 case '<':
2756 attributeString += "&lt;";
2757 break;
2758 case '>':
2759 attributeString += "&gt;";
2760 break;
2761 default:
2762 attributeString += *it;
2763 break;
2764 }
2765 }
2766 attributeString += "\" ";
2767 }
2768 else
2769 {
2770 attributeString += "=\"" + oss.str() + "\" ";
2771 }
2772 m_attributes.push_back(attributeString);
2773}
2774
2775void
2777{
2778 m_children.push_back(e.ToString());
2779}
2780
2781void
2783{
2784 m_text = text;
2785}
2786
2787std::string
2789{
2790 std::string elementString = "<" + m_tagName + " ";
2791
2792 for (auto i = m_attributes.begin(); i != m_attributes.end(); ++i)
2793 {
2794 elementString += *i;
2795 }
2796 if (m_children.empty() && m_text.empty())
2797 {
2798 if (autoClose)
2799 {
2800 elementString += "/>";
2801 }
2802 }
2803 else
2804 {
2805 elementString += ">";
2806 if (!m_text.empty())
2807 {
2808 elementString += m_text;
2809 }
2810 if (!m_children.empty())
2811 {
2812 elementString += "\n";
2813 for (auto i = m_children.begin(); i != m_children.end(); ++i)
2814 {
2815 elementString += *i + "\n";
2816 }
2817 }
2818 if (autoClose)
2819 {
2820 elementString += "</" + m_tagName + ">";
2821 }
2822 }
2823
2824 return elementString + ((autoClose) ? "\n" : "");
2825}
2826
2827/***** AnimByteTag *****/
2828
2829TypeId
2831{
2832 static TypeId tid = TypeId("ns3::AnimByteTag")
2833 .SetParent<Tag>()
2834 .SetGroupName("NetAnim")
2835 .AddConstructor<AnimByteTag>();
2836 return tid;
2837}
2838
2839TypeId
2841{
2842 return GetTypeId();
2843}
2844
2847{
2848 return sizeof(uint64_t);
2849}
2850
2851void
2853{
2854 i.WriteU64(m_AnimUid);
2855}
2856
2857void
2859{
2860 m_AnimUid = i.ReadU64();
2861}
2862
2863void
2864AnimByteTag::Print(std::ostream& os) const
2865{
2866 os << "AnimUid=" << m_AnimUid;
2867}
2868
2869void
2870AnimByteTag::Set(uint64_t AnimUid)
2871{
2872 m_AnimUid = AnimUid;
2873}
2874
2875uint64_t
2877{
2878 return m_AnimUid;
2879}
2880
2882 : m_txnd(nullptr),
2883 m_txNodeId(0),
2884 m_fbTx(0),
2885 m_lbTx(0),
2886 m_lbRx(0)
2887{
2888}
2889
2891{
2892 m_txnd = pInfo.m_txnd;
2893 m_txNodeId = pInfo.m_txNodeId;
2894 m_fbTx = pInfo.m_fbTx;
2895 m_lbTx = pInfo.m_lbTx;
2896 m_lbRx = pInfo.m_lbRx;
2897}
2898
2900 const Time fbTx,
2901 uint32_t txNodeId)
2902 : m_txnd(txnd),
2903 m_txNodeId(0),
2904 m_fbTx(fbTx.GetSeconds()),
2905 m_lbTx(0),
2906 m_lbRx(0)
2907{
2908 if (!m_txnd)
2909 {
2910 m_txNodeId = txNodeId;
2911 }
2912}
2913
2914void
2916{
2917 Ptr<Node> n = nd->GetNode();
2918 m_fbRx = fbRx;
2919 m_rxnd = nd;
2920}
2921
2922} // namespace ns3
#define NETANIM_VERSION
#define MAX_PKTS_PER_TRACE_FILE
#define CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS
#define CHECK_STARTED_INTIMEWINDOW
#define PURGE_INTERVAL
a polymophic address class
Definition: address.h:101
Byte tag using by Anim to uniquely identify packets.
TypeId GetInstanceTypeId() const override
Get Instance Type Id.
void Serialize(TagBuffer i) const override
Serialize function.
void Print(std::ostream &os) const override
Print tag info.
uint32_t GetSerializedSize() const override
Get Serialized Size.
uint64_t Get() const
Get Uid in tag.
static TypeId GetTypeId()
Get Type Id.
void Deserialize(TagBuffer i) override
Deserialize function.
void Set(uint64_t AnimUid)
Set global Uid in tag.
Ptr< const NetDevice > m_txnd
transmit device
void ProcessRxBegin(Ptr< const NetDevice > nd, const double fbRx)
Process receive begin.
Ptr< const NetDevice > m_rxnd
receive device
void AppendChild(AnimXmlElement e)
Append child function.
void SetText(std::string text)
Set text function.
std::string ToString(bool autoClose=true)
Get text for the element function.
AnimXmlElement(std::string tagName, bool emptyElement=true)
Constructor.
void AddAttribute(std::string attribute, T value, bool xmlEscape=false)
Add attribute function.
Interface to network animator.
FILE * m_f
File handle for output (0 if none)
Time m_wifiMacCountersPollInterval
wifi MAC counters poll interval
void CsmaPhyRxEndTrace(std::string context, Ptr< const Packet > p)
CSMA Phy receive end trace function.
void WriteNodeSizes()
Write node sizes function.
uint32_t AddNodeCounter(std::string counterName, CounterType counterType)
Setup a node counter.
void TrackQueueCounters()
Track queue counters function.
void SetMobilityPollInterval(Time t)
Set mobility poll interval:WARNING: setting a low interval can cause slowness.
uint32_t m_wifiMacRxCounterId
wifi MAC receive counter ID
bool IsPacketPending(uint64_t animUid, ProtocolType protocolType)
Is packet pending function.
bool NodeHasMoved(Ptr< Node > n, Vector newLocation)
Node has moved function.
void LrWpanPhyTxBeginTrace(std::string context, Ptr< const Packet > p)
LR-WPAN Phy receive begin trace function.
uint32_t m_queueDropCounterId
queue drop counter ID
void WimaxTxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &m)
WIMax transmit trace function.
void LrWpanPhyRxBeginTrace(std::string context, Ptr< const Packet > p)
LR-WPAN Phy receive begin trace function.
Time m_routingPollInterval
routing poll interval
void OutputCsmaPacket(Ptr< const Packet > p, AnimPacketInfo &pktInfo)
Output CSMA packet function.
uint64_t GetAnimUidFromPacket(Ptr< const Packet >)
Get anim UID from packet function.
EnergyFractionMap m_nodeEnergyFraction
node energy fraction
void GenericWirelessTxTrace(std::string context, Ptr< const Packet > p, ProtocolType protocolType)
Generic wireless transmit trace function.
void LteRxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &m)
LTE receive trace function.
std::string ProtocolTypeToString(ProtocolType protocolType)
Protocol type to string function.
NodeCounterMap64 m_nodeLrWpanMacRx
node LR-WPAN MAC receive
std::string m_routingFileName
routing file name
NodeCounterMap64 m_nodeIpv4Tx
node IPv4 transmit
std::map< std::string, uint32_t > m_ipv6ToNodeIdMap
IPv6 to node ID map.
void MobilityAutoCheck()
Mobility auto check function.
void WriteXmlRouting(uint32_t id, std::string routingInfo)
Write XML routing function.
void WifiPhyRxDropTrace(std::string context, Ptr< const Packet > p, WifiPhyRxfailureReason reason)
wifi Phy receive drop trace function
void WifiMacRxDropTrace(std::string context, Ptr< const Packet > p)
wifi MAC receive drop trace function
NodeCounterMap64 m_nodeQueueDrop
node queue drop
void ConnectLteUe(Ptr< Node > n, Ptr< LteUeNetDevice > nd, uint32_t devIndex)
Connect LTE ue function.
void DequeueTrace(std::string context, Ptr< const Packet >)
Dequeue trace function.
void ConnectCallbacks()
Connect callbacks function.
void WriteRoutePath(uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
Write route path function.
AnimUidPacketInfoMap * ProtocolTypeToPendingPackets(ProtocolType protocolType)
Protocol type to pending packets function.
void RemainingEnergyTrace(std::string context, double previousEnergy, double currentEnergy)
Remaining energy trace function.
void Ipv4DropTrace(std::string context, const Ipv4Header &ipv4Header, Ptr< const Packet > p, Ipv4L3Protocol::DropReason dropReason, Ptr< Ipv4 > ipv4, uint32_t interfaceIndex)
IPv4 drop trace function.
NodeColorsMap m_nodeColors
node colors
void UpdateNodeCounter(uint32_t nodeCounterId, uint32_t nodeId, double counter)
Helper function to update a node's counter referenced by the nodeCounterId.
void WifiPhyRxBeginTrace(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
wifi Phy receive begin trace function
void LrWpanMacRxDropTrace(std::string context, Ptr< const Packet > p)
LR-WPAN MAC receive drop trace function.
void LteSpectrumPhyTxStart(std::string context, Ptr< const PacketBurst > pb)
LTE Spectrum Phy transmit start function.
NodeCounterMap64 m_nodeLrWpanMacTx
node LR-WPAN MAC transmit
void WriteXmlAddNodeCounter(uint32_t counterId, std::string counterName, CounterType counterType)
Write XML add node counter function.
void WriteXmlPRef(uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo="")
Write XMLP Ref function.
NodeCounterMap64 m_nodeWifiPhyTxDrop
node wifi Phy transmit drop
void WriteLinkProperties()
Write link properties function.
void WriteIpv4Addresses()
Write IPv4 Addresses function.
const std::vector< std::string > GetElementsFromContext(const std::string &context) const
Get elements from context.
void WriteXmlAddResource(uint32_t resourceId, std::string resourcePath)
Write XML add resource function.
void OutputWirelessPacketTxInfo(Ptr< const Packet > p, AnimPacketInfo &pktInfo, uint64_t animUid)
Output wireless packet transmit info.
void LteSpectrumPhyRxStart(std::string context, Ptr< const PacketBurst > pb)
LTE Spectrum Phy receive start function.
void SetOutputFile(const std::string &fn, bool routing=false)
Set output file function.
NodeCounterMap64 m_nodeWifiMacTx
node wifi MAC transmit
AnimUidPacketInfoMap m_pendingWimaxPackets
pending wimax packets
void LteTxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &m)
LTE transmit trace function.
void EnableIpv4L3ProtocolCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Ipv4 L3 Protocol Counters such as Tx, Rx, Drop.
int WriteN(const char *data, uint32_t count, FILE *f)
WriteN function.
std::map< std::string, uint32_t > m_macToNodeIdMap
MAC to node ID map.
Ptr< Node > GetNodeFromContext(const std::string &context) const
Get node from context.
std::map< uint32_t, Vector > m_nodeLocation
node location
Ptr< NetDevice > GetNetDeviceFromContext(std::string context)
Get net device from context.
FILE * m_routingF
File handle for routing table output (0 if None);.
void UpdateNodeImage(uint32_t nodeId, uint32_t resourceId)
Helper function to update the image of a node.
void TrackWifiPhyCounters()
Track wifi phy counters function.
AnimUidPacketInfoMap m_pendingUanPackets
pending UAN packets
void TrackIpv4RoutePaths()
Track IPv4 route paths function.
double GetNodeEnergyFraction(Ptr< const Node > node) const
Get node's energy fraction (This used only for testing)
bool IsInTimeWindow()
Is in time window function.
void CsmaPhyTxBeginTrace(std::string context, Ptr< const Packet > p)
CSMA Phy transmit begin trace function.
bool m_enablePacketMetadata
enable packet metadata
void PurgePendingPackets(ProtocolType protocolType)
Purge pending packets function.
void SetMaxPktsPerTraceFile(uint64_t maxPktsPerFile)
Set Max packets per trace file.
uint64_t m_maxPktsPerFile
maximum packets per file
uint32_t m_ipv4L3ProtocolRxCounterId
IPv4 L3 protocol receive counter ID.
NodeCounterMap64 m_nodeIpv4Rx
node IPv4 receive
~AnimationInterface()
Destructor for the animator interface.
void AddToIpv4AddressNodeIdTable(std::string ipv4Address, uint32_t nodeId)
Add to IPv4 address node ID table function.
NodeIdIpv4Map m_nodeIdIpv4Map
node ID to IPv4 map
Time m_queueCountersPollInterval
queue counters poll interval
std::vector< std::string > GetIpv6Addresses(Ptr< NetDevice > nd)
Get IPv6 addresses.
void UpdateLinkDescription(uint32_t fromNode, uint32_t toNode, std::string linkDescription)
Helper function to update the description for a link.
void Ipv4RxTrace(std::string context, Ptr< const Packet > p, Ptr< Ipv4 > ipv4, uint32_t interfaceIndex)
IPv4 receive trace function.
NodeCounterMap64 m_nodeQueueEnqueue
node queue enqueue
void WriteXmlUpdateNodeCounter(uint32_t counterId, uint32_t nodeId, double value)
Write XML update node counter function.
std::vector< std::string > GetIpv4Addresses(Ptr< NetDevice > nd)
Get IPv4 addresses.
Time m_wifiPhyCountersPollInterval
wifi Phy counters poll interval
uint32_t m_queueDequeueCounterId
queue dequeue counter ID
NodeCounterMap64 m_nodeWifiMacRx
node wifi MAC receive
void AddToIpv6AddressNodeIdTable(std::string ipv6Address, uint32_t nodeId)
Add to IPv6 address node ID table function.
AnimationInterface & AddSourceDestination(uint32_t fromNodeId, std::string destinationIpv4Address)
Helper function to print the routing path from a source node to destination IP.
NodeCounterMap64 m_nodeIpv4Drop
node IPv4 drop
Time m_ipv4L3ProtocolCountersStopTime
IPv4 L3 protocol counters stop time.
uint32_t m_queueEnqueueCounterId
queue enqueue counter ID
void AddByteTag(uint64_t animUid, Ptr< const Packet > p)
Add byte tag function.
Time m_ipv4L3ProtocolCountersPollInterval
IPv4 L3 protocol counters poll interval.
void WriteNonP2pLinkProperties(uint32_t id, std::string ipv4Address, std::string channelType)
Write non P2P link properties function.
void StopAnimation(bool onlyAnimation=false)
Stop animation function.
std::vector< Ipv4RoutePathElement > Ipv4RoutePathElements
Ipv4RoutePathElements typedef.
void UanPhyGenTxTrace(std::string context, Ptr< const Packet >)
UAN Phy gen transmit trace function.
void WifiMacTxDropTrace(std::string context, Ptr< const Packet > p)
wifi MAC transmit drop trace function
uint32_t m_ipv4L3ProtocolTxCounterId
IPv4 L3 protocol transmit counter ID.
Time m_queueCountersStopTime
queue counters stop time
std::string CounterTypeToString(CounterType counterType)
Counter type to string function.
ProtocolType
ProtocolType enumeration.
std::string GetMacAddress(Ptr< NetDevice > nd)
Get MAC address function.
std::vector< Ptr< Node > > GetMovedNodes()
Get moved nodes function.
uint32_t m_wifiMacTxCounterId
wifi MAC transmit counter ID
void SkipPacketTracing()
Do not trace packets.
NodeCounterMap64 m_nodeWifiMacRxDrop
node wifi MAC receive drop
NodeDescriptionsMap m_nodeDescriptions
node description
void WriteXmlAnim(bool routing=false)
Write XML anim function.
void SetStartTime(Time t)
Specify the time at which capture should start.
uint32_t AddResource(std::string resourcePath)
Add a resource such as the path to an image file.
AnimationInterface(const std::string filename)
Constructor.
std::string GetIpv6Address(Ptr< NetDevice > nd)
Get IPv6 address.
void WriteNodeEnergies()
Write node energies function.
void CsmaMacRxTrace(std::string context, Ptr< const Packet > p)
CSMA MAC receive trace function.
void WifiPhyTxBeginTrace(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
wifi Phy transmit PSDU begin trace function
void UanPhyGenRxTrace(std::string context, Ptr< const Packet >)
UAN Phy gen receive trace function.
LinkPropertiesMap m_linkProperties
link properties
void WriteXmlUpdateNodeDescription(uint32_t nodeId)
Write XML update node description function.
void UpdateNodeSize(Ptr< Node > n, double width, double height)
Helper function to update the size of a node.
std::map< uint32_t, NodeSize > m_nodeSizes
node sizes
std::pair< uint32_t, std::string > NodeIdIpv6Pair
NodeIdIpv6Pair typedef.
void ConnectLte()
Connect LTE function.
bool m_trackPackets
track packets
std::string GetNetAnimVersion()
Get netanim version function.
void WriteXmlNonP2pLinkProperties(uint32_t id, std::string ipAddress, std::string channelType)
Write XML non P2P link properties function.
AnimationInterface & EnableIpv4RouteTracking(std::string fileName, Time startTime, Time stopTime, Time pollInterval=Seconds(5))
Enable tracking of the Ipv4 routing table for all Nodes.
void WriteXmlClose(std::string name, bool routing=false)
Write XML close function.
uint64_t gAnimUid
Packet unique identifier used by AnimationInterface.
void CheckMaxPktsPerTraceFile()
Check maximum packets per trace file function.
NodeCounterMap64 m_nodeLrWpanMacTxDrop
node LR-WPAN MAC transmit drop
NodeIdIpv6Map m_nodeIdIpv6Map
node ID to IPv6 map
void TrackIpv4Route()
Track IPv4 router function.
void EnableWifiPhyCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Wifi Phy Counters such as TxDrop, RxDrop.
AnimUidPacketInfoMap m_pendingWifiPackets
pending wifi packets
void EnablePacketMetadata(bool enable=true)
Enable Packet metadata.
Time m_routingStopTime
routing stop time
void SetStopTime(Time t)
Specify the time at which capture should stop.
void MobilityCourseChangeTrace(Ptr< const MobilityModel > mob)
Mobility course change trace function.
void EnableWifiMacCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Wifi Mac Counters such as Tx, TxDrop, Rx, RxDrop.
void WriteXmlP(std::string pktType, uint32_t fId, double fbTx, double lbTx, uint32_t tId, double fbRx, double lbRx, std::string metaInfo="")
Write XMLP function.
uint32_t m_wifiMacTxDropCounterId
wifi MAC transmit drop counter ID
void WriteXmlRp(uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
Write XMLRP function.
AnimUidPacketInfoMap m_pendingLrWpanPackets
pending LR-WPAN packets
void WifiMacTxTrace(std::string context, Ptr< const Packet > p)
wifi MAC transmit trace function
void ResetAnimWriteCallback()
Reset the write callback function.
void WimaxRxTrace(std::string context, Ptr< const Packet > p, const Mac48Address &m)
WIMax receive trace function.
void LrWpanMacTxDropTrace(std::string context, Ptr< const Packet > p)
LR-WPAN MAC transmit drop trace function.
void LrWpanMacRxTrace(std::string context, Ptr< const Packet > p)
LR-WPAN MAC receive trace function.
std::vector< std::string > m_nodeCounters
node counters
void WriteXmlNode(uint32_t id, uint32_t sysId, double locX, double locY)
Write XML node function.
AnimWriteCallback m_writeCallback
write callback
NodeCounterMap64 m_nodeWifiMacTxDrop
node wifi MAC transmit drop
uint64_t m_currentPktCount
current packet count
std::string GetIpv4RoutingTable(Ptr< Node > n)
Get IPv4 routing table function.
void Ipv4TxTrace(std::string context, Ptr< const Packet > p, Ptr< Ipv4 > ipv4, uint32_t interfaceIndex)
IPv4 transmit trace function.
std::pair< uint32_t, std::string > NodeIdIpv4Pair
NodeIdIpv4Pair typedef.
void EnqueueTrace(std::string context, Ptr< const Packet >)
Enqueue trace function.
uint64_t GetTracePktCount() const
Get trace file packet count (This used only for testing)
void WriteXmlUpdateNodeColor(uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
Write XML update node color function.
Vector UpdatePosition(Ptr< Node > n)
Update position function.
std::string m_outputFileName
output file name
void WriteIpv6Addresses()
Write IPv6 Addresses function.
void AddPendingPacket(ProtocolType protocolType, uint64_t animUid, AnimPacketInfo pktInfo)
Add pending packet function.
NodeCounterMap64 m_nodeWifiPhyRxDrop
node wifi Phy receive drop
void WriteXmlIpv4Addresses(uint32_t nodeId, std::vector< std::string > ipv4Addresses)
Write XML Ipv4 addresses function.
Vector GetPosition(Ptr< Node > n)
Get position function.
AnimUidPacketInfoMap m_pendingLtePackets
pending LTE packets
void SetBackgroundImage(std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
Helper function to set the background image.
void WriteNodes()
Write nodes function.
NodeCounterMap64 m_nodeLrWpanMacRxDrop
node LR-WPAN MAC receive drop
Time m_wifiMacCountersStopTime
wifi MAC counters stop time
void WriteNodeColors()
Write node colors function.
void RecursiveIpv4RoutePathSearch(std::string from, std::string to, Ipv4RoutePathElements &rpElements)
Recursive IPv4 route path search function.
static bool IsInitialized()
Check if AnimationInterface is initialized.
void LrWpanMacTxTrace(std::string context, Ptr< const Packet > p)
LR-WPAN MAC transmit trace function.
void WriteXmlUpdateBackground(std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
Write XML update background function.
void CsmaPhyTxEndTrace(std::string context, Ptr< const Packet > p)
CSMA Phy transmit end trace function.
void WriteXmlUpdateNodeSize(uint32_t nodeId, double width, double height)
Write XML update node size function.
uint32_t m_remainingEnergyCounterId
remaining energy counter ID
void WriteXmlUpdateNodeImage(uint32_t nodeId, uint32_t resourceId)
Write XML update node image function.
uint32_t m_wifiMacRxDropCounterId
wifi MAC receive drop counter ID
void TrackWifiMacCounters()
Track wifi MAC counters function.
void UpdateNodeDescription(Ptr< Node > n, std::string descr)
Helper function to update the description for a given node.
void UpdateNodeColor(Ptr< Node > n, uint8_t r, uint8_t g, uint8_t b)
Helper function to update the node color.
static void SetConstantPosition(Ptr< Node > n, double x, double y, double z=0)
Helper function to set Constant Position for a given node.
NodeCounterMap64 m_nodeQueueDequeue
node queue dequeue
void WifiPhyTxDropTrace(std::string context, Ptr< const Packet > p)
wifi Phy transmit drop trace function
uint32_t m_wifiPhyRxDropCounterId
wifi Phy receive drop counter ID
void WriteXmlUpdateLink(uint32_t fromId, uint32_t toId, std::string linkDescription)
Write XML update link counter function.
void ConnectLteEnb(Ptr< Node > n, Ptr< LteEnbNetDevice > nd, uint32_t devIndex)
Connect LTE ENB function.
void GenericWirelessRxTrace(std::string context, Ptr< const Packet > p, ProtocolType protocolType)
Generic wireless receive trace function.
std::string GetPacketMetadata(Ptr< const Packet > p)
Get packet metadata function.
uint32_t m_wifiPhyTxDropCounterId
wifi Phy transmit drop counter ID
std::vector< Ipv4RouteTrackElement > m_ipv4RouteTrackElements
IPv route track elements.
void EnableQueueCounters(Time startTime, Time stopTime, Time pollInterval=Seconds(1))
Enable tracking of Queue Counters such as Enqueue, Dequeue, Queue Drops.
uint32_t m_ipv4L3ProtocolDropCounterId
IPv4 protocol drop counter ID.
Time m_wifiPhyCountersStopTime
wifi Phy counters stop time
Time m_mobilityPollInterval
mobility poll interval
void OutputWirelessPacketRxInfo(Ptr< const Packet > p, AnimPacketInfo &pktInfo, uint64_t animUid)
Output wireless packet receive info.
std::map< std::string, uint32_t > m_ipv4ToNodeIdMap
IPv4 to node ID map.
AnimUidPacketInfoMap m_pendingCsmaPackets
pending CSMA packets
std::vector< std::string > m_resources
resources
void TrackIpv4L3ProtocolCounters()
Track IPv4 L3 protocol counters function.
void WriteXmlUpdateNodePosition(uint32_t nodeId, double x, double y)
Write XML update node position function.
void StartAnimation(bool restart=false)
Start animation function.
void DevTxTrace(std::string context, Ptr< const Packet > p, Ptr< NetDevice > tx, Ptr< NetDevice > rx, Time txTime, Time rxTime)
Device transmit trace function.
std::string GetIpv4Address(Ptr< NetDevice > nd)
Get IPv4 address.
void WifiMacRxTrace(std::string context, Ptr< const Packet > p)
wifi MAC receive trace function
bool IsStarted() const
Is AnimationInterface started.
void WriteXmlIpv6Addresses(uint32_t nodeId, std::vector< std::string > ipv6Addresses)
Write XML Ipv6 addresses function.
NodeContainer m_routingNc
routing node container
void SetAnimWriteCallback(AnimWriteCallback cb)
Set a callback function to listen to AnimationInterface write events.
void QueueDropTrace(std::string context, Ptr< const Packet >)
Queue trace function.
void WriteXmlLink(uint32_t fromId, uint32_t toLp, uint32_t toId)
Write XML link counter function.
std::map< uint64_t, AnimPacketInfo > AnimUidPacketInfoMap
AnimUidPacketInfoMap typedef.
BaseStation NetDevice.
Definition: bs-net-device.h:54
Identifies a byte tag and a set of bytes within a packet to which the tag applies.
Definition: packet.h:63
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition: packet.cc:54
TypeId GetTypeId() const
Definition: packet.cc:36
Iterator over the set of byte tags in a packet.
Definition: packet.h:56
bool HasNext() const
Definition: packet.cc:72
Mobility model for which the current position does not change once it has been set and until it is se...
A Device for a Csma Network Link.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Introspection did not find any typical Config paths.
Definition: energy-source.h:87
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:309
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
a class to store IPv4 address information on an interface
Ipv4Address GetLocal() const
Get the local address.
DropReason
Reason why a packet has been dropped.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
an EUI-48 address
Definition: mac48-address.h:46
an EUI-64 address
Definition: mac64-address.h:46
Keep track of the current position and velocity of an object.
virtual Ptr< Node > GetNode() const =0
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
A network Node.
Definition: node.h:57
uint32_t GetId() const
Definition: node.cc:117
static Iterator Begin()
Definition: node-list.cc:237
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:251
static Iterator End()
Definition: node-list.cc:244
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
static void EnablePrinting()
Enable printing packets metadata.
Definition: packet.cc:596
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static bool IsFinished()
Check if the simulation should finish.
Definition: simulator.cc:171
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
read and write tag data
Definition: tag-buffer.h:52
void WriteU64(uint64_t v)
Definition: tag-buffer.cc:104
uint64_t ReadU64()
Definition: tag-buffer.cc:139
tag a set of bytes in a packet
Definition: tag.h:39
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Net device for UAN models.
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
Hold together all Wifi-related objects.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Represent the Mac Header with the Frame Control and Sequence Number fields.
uint8_t GetSrcAddrMode() const
Get the Source Addressing Mode of Frame control field.
Time stopTime
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:988
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:964
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:454
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:706
static bool initialized
Initialization flag.
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
uint8_t data[writeSize]
Ipv4RoutePathElement structure IPv4 route path element.
Ipv4RouteTrackElement structure IPv4 route track element.
NodeSize structure node size.
RGB structure RGB structure.