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<energy::EnergySource> energySource = node->GetObject<energy::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;
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
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...
Energy source base class.
Definition: energy-source.h:88
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.
int nDevices
Number of end device nodes to create.
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:700
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.