A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
pyviz.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INESC Porto
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Gustavo Carneiro <gjc@inescporto.pt>
7 */
8
9#include "pyviz.h"
10
11#include "fastClipping.h"
13
14#include "ns3/abort.h"
15#include "ns3/config.h"
16#include "ns3/ethernet-header.h"
17#include "ns3/log.h"
18#include "ns3/lr-wpan-mac-header.h"
19#include "ns3/lr-wpan-net-device.h"
20#include "ns3/node-list.h"
21#include "ns3/ppp-header.h"
22#include "ns3/simulator.h"
23#include "ns3/wifi-mac-header.h"
24#include "ns3/wifi-net-device.h"
25
26#include <cstdlib>
27#include <sstream>
28
29using namespace ns3::lrwpan;
30
32
33static std::vector<std::string>
34PathSplit(std::string str)
35{
36 std::vector<std::string> results;
37 size_t cutAt;
38 while ((cutAt = str.find_first_of('/')) != std::string::npos)
39 {
40 if (cutAt > 0)
41 {
42 results.push_back(str.substr(0, cutAt));
43 }
44 str = str.substr(cutAt + 1);
45 }
46 if (!str.empty())
47 {
48 results.push_back(str);
49 }
50 return results;
51}
52
53namespace ns3
54{
55
56static PyViz* g_visualizer = nullptr; ///< the visualizer
57
58/**
59 * PyVizPacketTag structure
60 */
61struct PyVizPacketTag : public Tag
62{
63 static TypeId GetTypeId();
64 TypeId GetInstanceTypeId() const override;
65 uint32_t GetSerializedSize() const override;
66 void Serialize(TagBuffer buf) const override;
67 void Deserialize(TagBuffer buf) override;
68 void Print(std::ostream& os) const override;
70
71 uint32_t m_packetId; ///< packet id
72};
73
74/**
75 * @brief Get the type ID.
76 * @return the object TypeId
77 */
80{
81 static TypeId tid = TypeId("ns3::PyVizPacketTag")
82 .SetParent<Tag>()
83 .SetGroupName("Visualizer")
84 .AddConstructor<PyVizPacketTag>();
85 return tid;
86}
87
90{
91 return GetTypeId();
92}
93
96{
97 return 4;
98}
99
100void
105
106void
111
112void
113PyVizPacketTag::Print(std::ostream& os) const
114{
115 os << "PacketId=" << m_packetId;
116}
117
122
124{
126 NS_ASSERT(g_visualizer == nullptr);
127 g_visualizer = this;
128
129 // WiFi
130 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
132
133 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
135 // Lr-Wpan
136 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::lrwpan::LrWpanNetDevice/Mac/MacTx",
138
139 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::lrwpan::LrWpanNetDevice/Mac/MacRx",
141
142 // CSMA
143 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacTx",
145
146 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
148
149 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacPromiscRx",
151
152 // Generic queue drop
153 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/TxQueue/Drop",
155 // IPv4 drop
156 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
158
159 // Point-to-Point
160 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacTx",
162
163 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacRx",
165
166 // LTE
167 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
169
170 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
172}
173
174void
175PyViz::RegisterCsmaLikeDevice(const std::string& deviceTypeName)
176{
177 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
178
179 std::ostringstream sstream;
180 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/MacTx";
182
183 sstream.str("");
184 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
186
187 sstream.str("");
188 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/PromiscRx";
190}
191
192void
193PyViz::RegisterWifiLikeDevice(const std::string& deviceTypeName)
194{
195 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
196
197 std::ostringstream sstream;
198 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Tx";
200
201 sstream.str("");
202 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
204}
205
206void
207PyViz::RegisterPointToPointLikeDevice(const std::string& deviceTypeName)
208{
209 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
210
211 std::ostringstream sstream;
212 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/TxQueue/Dequeue";
214
215 sstream.str("");
216 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
218}
219
220void
222{
223 NS_LOG_DEBUG(" SetPacketCaptureOptions "
224 << nodeId << " PacketCaptureOptions (headers size = " << options.headers.size()
225 << " mode = " << options.mode << " numLastPackets = " << options.numLastPackets
226 << ")");
227 m_packetCaptureOptions[nodeId] = options;
228}
229
230void
231PyViz::RegisterDropTracePath(const std::string& tracePath)
232{
234}
235
237{
239
240 NS_ASSERT(g_visualizer == this);
241 g_visualizer = nullptr;
242}
243
244void
245PyViz::DoPause(const std::string& message)
246{
247 m_pauseMessages.push_back(message);
248 m_stop = true;
250 << ": Have " << g_visualizer->m_pauseMessages.size() << " pause messages");
251}
252
253void
254PyViz::Pause(const std::string& message)
255{
257 g_visualizer->DoPause(message);
258}
259
260std::vector<std::string>
262{
264 << ": GetPauseMessages: have " << g_visualizer->m_pauseMessages.size()
265 << " pause messages");
266 return m_pauseMessages;
267}
268
269void
271{
273 if (m_runUntil <= Simulator::Now())
274 {
275 Simulator::Stop(); // Stop right now
276 m_stop = true;
277 }
278}
279
280void
282{
283 NS_LOG_LOGIC("SimulatorRunUntil " << time << " (now is " << Simulator::Now() << ")");
284
285 m_pauseMessages.clear();
286 m_transmissionSamples.clear();
287 m_packetDrops.clear();
288
289 Time expirationTime = Simulator::Now() - Seconds(10);
290
291 // Clear very old transmission records
292 for (auto iter = m_txRecords.begin(); iter != m_txRecords.end();)
293 {
294 if (iter->second.time < expirationTime)
295 {
296 m_txRecords.erase(iter++);
297 }
298 else
299 {
300 iter++;
301 }
302 }
303
304 // Clear very old packets of interest
305 for (auto iter = m_packetsOfInterest.begin(); iter != m_packetsOfInterest.end();)
306 {
307 if (iter->second < expirationTime)
308 {
309 m_packetsOfInterest.erase(iter++);
310 }
311 else
312 {
313 iter++;
314 }
315 }
316
317 if (Simulator::Now() >= time)
318 {
319 return;
320 }
321
322 // Schedule a dummy callback function for the target time, to make
323 // sure we stop at the right time. Otherwise, simulations with few
324 // events just appear to "jump" big chunks of time.
325 NS_LOG_LOGIC("Schedule dummy callback to be called in " << (time - Simulator::Now()));
326 m_runUntil = time;
327 m_stop = false;
329 time - Simulator::Now(),
331 this);
332
335 if (visualImpl)
336 {
337 visualImpl->RunRealSimulator();
338 }
339 else
340 {
341 impl->Run();
342 }
343}
344
345Time
347{
350 return visualImpl->GetStopTime();
351}
352
353bool
355{
356 if (this->transmitter < other.transmitter)
357 {
358 return true;
359 }
360 if (this->transmitter != other.transmitter)
361 {
362 return false;
363 }
364 if (this->receiver < other.receiver)
365 {
366 return true;
367 }
368 if (this->receiver != other.receiver)
369 {
370 return false;
371 }
372 return this->channel < other.channel;
373}
374
375bool
377{
378 bool retval = (transmitter == other.transmitter) && (receiver == other.receiver) &&
379 (channel == other.channel);
380 return retval;
381}
382
384PyViz::FindNetDeviceStatistics(int node, int interface)
385{
386 auto nodeStatsIter = m_nodesStatistics.find(node);
387 std::vector<NetDeviceStatistics>* stats;
388 if (nodeStatsIter == m_nodesStatistics.end())
389 {
390 stats = &m_nodesStatistics[node];
391 stats->resize(NodeList::GetNode(node)->GetNDevices());
392 }
393 else
394 {
395 stats = &(nodeStatsIter->second);
396 }
397 NetDeviceStatistics& devStats = (*stats)[interface];
398 return devStats;
399}
400
401bool
403{
404 auto iter = m_packetCaptureOptions.find(nodeId);
405 if (iter == m_packetCaptureOptions.end())
406 {
407 return false;
408 }
409 else
410 {
411 *outOptions = &iter->second;
412 return true;
413 }
414}
415
416bool
418{
419 switch (options.mode)
420 {
422 return false;
423
425 PacketMetadata::ItemIterator metadataIterator = packet->BeginItem();
426 while (metadataIterator.HasNext())
427 {
428 PacketMetadata::Item item = metadataIterator.Next();
429 if (options.headers.find(item.tid) != options.headers.end())
430 {
431 return true;
432 }
433 }
434 return false;
435 }
436
438 std::set<TypeId> missingHeaders(options.headers);
439 PacketMetadata::ItemIterator metadataIterator = packet->BeginItem();
440 while (metadataIterator.HasNext())
441 {
442 PacketMetadata::Item item = metadataIterator.Next();
443 auto missingIter = missingHeaders.find(item.tid);
444 if (missingIter != missingHeaders.end())
445 {
446 missingHeaders.erase(missingIter);
447 }
448 }
449 return missingHeaders.empty();
450 }
451
452 default:
453 NS_FATAL_ERROR("should not be reached");
454 return false;
455 }
456}
457
458void
459PyViz::TraceDevQueueDrop(std::string context, Ptr<const Packet> packet)
460{
461 NS_LOG_FUNCTION(context << packet->GetUid());
462 std::vector<std::string> splitPath = PathSplit(context);
463 int nodeIndex = std::stoi(splitPath[1]);
464 Ptr<Node> node = NodeList::GetNode(nodeIndex);
465
466 if (m_nodesOfInterest.find(nodeIndex) == m_nodesOfInterest.end())
467 {
468 // if the transmitting node is not "of interest", we still
469 // record the transmission if it is a packet of interest.
470 if (m_packetsOfInterest.find(packet->GetUid()) == m_packetsOfInterest.end())
471 {
472 NS_LOG_DEBUG("Packet " << packet->GetUid() << " is not of interest");
473 return;
474 }
475 }
476
477 // ---- "last packets"
478 const PacketCaptureOptions* captureOptions;
479 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
480 FilterPacket(packet, *captureOptions))
481 {
482 LastPacketsSample& last = m_lastPackets[nodeIndex];
483 PacketSample lastPacket;
484 lastPacket.time = Simulator::Now();
485 lastPacket.packet = packet->Copy();
486 lastPacket.device = nullptr;
487 last.lastDroppedPackets.push_back(lastPacket);
488 while (last.lastDroppedPackets.size() > captureOptions->numLastPackets)
489 {
490 last.lastDroppedPackets.erase(last.lastDroppedPackets.begin());
491 }
492 }
493
494 auto iter = m_packetDrops.find(node);
495 if (iter == m_packetDrops.end())
496 {
497 m_packetDrops[node] = packet->GetSize();
498 }
499 else
500 {
501 iter->second += packet->GetSize();
502 }
503}
504
505void
506PyViz::TraceIpv4Drop(std::string context,
507 const ns3::Ipv4Header& hdr,
508 Ptr<const Packet> packet,
510 Ptr<Ipv4> dummy_ipv4,
511 uint32_t interface)
512{
513 Ptr<Packet> packetCopy = packet->Copy();
514 packetCopy->AddHeader(hdr);
515 TraceDevQueueDrop(context, packetCopy);
516}
517
518// --------- TX device tracing -------------------
519
520void
522 const std::string& context,
523 Ptr<const Packet> packet,
524 const std::variant<Mac16Address, Mac48Address, Mac64Address>& destination)
525{
526 NS_LOG_FUNCTION(context << packet->GetUid() << *packet);
527
528 std::vector<std::string> splitPath = PathSplit(context);
529 int nodeIndex = std::stoi(splitPath[1]);
530 int devIndex = std::stoi(splitPath[3]);
531 Ptr<Node> node = NodeList::GetNode(nodeIndex);
532 Ptr<NetDevice> device = node->GetDevice(devIndex);
533
534 // ---- statistics
535 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
536 ++stats.transmittedPackets;
537 stats.transmittedBytes += packet->GetSize();
538
539 // ---- "last packets"
540 const PacketCaptureOptions* captureOptions;
541 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
542 FilterPacket(packet, *captureOptions))
543 {
544 LastPacketsSample& last = m_lastPackets[nodeIndex];
545 TxPacketSample lastPacket;
546 lastPacket.time = Simulator::Now();
547 lastPacket.packet = packet->Copy();
548 lastPacket.device = device;
549 lastPacket.to = destination;
550
551 last.lastTransmittedPackets.push_back(lastPacket);
552 while (last.lastTransmittedPackets.size() > captureOptions->numLastPackets)
553 {
554 last.lastTransmittedPackets.erase(last.lastTransmittedPackets.begin());
555 }
556 }
557
558 // ---- transmissions records
559
560 if (m_nodesOfInterest.find(nodeIndex) == m_nodesOfInterest.end())
561 {
562 // if the transmitting node is not "of interest", we still
563 // record the transmission if it is a packet of interest.
564 if (m_packetsOfInterest.find(packet->GetUid()) == m_packetsOfInterest.end())
565 {
566 NS_LOG_DEBUG("Packet " << packet->GetUid() << " is not of interest");
567 return;
568 }
569 }
570 else
571 {
572 // We will follow this packet throughout the network.
573 m_packetsOfInterest[packet->GetUid()] = Simulator::Now();
574 }
575
576 TxRecordValue record = {Simulator::Now(), node, false};
577
578 if (std::holds_alternative<Mac16Address>(destination))
579 {
580 if (std::get<Mac16Address>(destination) == Mac16Address("FF:FF"))
581 {
582 record.isBroadcast = true;
583 }
584 }
585 else if (std::holds_alternative<Mac48Address>(destination))
586 {
587 if (std::get<Mac48Address>(destination) == device->GetBroadcast())
588 {
589 record.isBroadcast = true;
590 }
591 }
592 else if (std::holds_alternative<Mac64Address>(destination))
593 {
594 if (std::get<Mac64Address>(destination) == Mac64Address("FF:FF:FF:FF:FF:FF:FF:FF"))
595 {
596 // Note: A broadcast using th the MAC 64 bit address is not really used in practice.
597 // instead the 16 bit MAC address is used.
598 record.isBroadcast = true;
599 }
600 }
601
602 m_txRecords[TxRecordKey(device->GetChannel(), packet->GetUid())] = record;
603
604 PyVizPacketTag tag;
605 // packet->RemovePacketTag (tag);
606 tag.m_packetId = packet->GetUid();
607 packet->AddByteTag(tag);
608}
609
610void
611PyViz::TraceNetDevTxWifi(std::string context, Ptr<const Packet> packet)
612{
613 NS_LOG_FUNCTION(context << packet->GetUid() << *packet);
614
615 /*
616 * To DS From DS Address 1 Address 2 Address 3 Address 4
617 *----------------------------------------------------------------------
618 * 0 0 Destination Source BSSID N/A
619 * 0 1 Destination BSSID Source N/A
620 * 1 0 BSSID Source Destination N/A
621 * 1 1 Receiver Transmitter Destination Source
622 */
623 WifiMacHeader hdr;
624 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
625
626 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
627 if (hdr.IsToDs())
628 {
629 destinationAddress = hdr.GetAddr3();
630 }
631 else
632 {
633 destinationAddress = hdr.GetAddr1();
634 }
635 TraceNetDevTxCommon(context, packet, destinationAddress);
636}
637
638void
640{
641 LrWpanMacHeader hdr;
642 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
643 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
644
645 switch (hdr.GetDstAddrMode())
646 {
648 destinationAddress = hdr.GetExtDstAddr();
649 break;
650 default:
651 destinationAddress = hdr.GetShortDstAddr();
652 break;
653 }
654
655 TraceNetDevTxCommon(context, packet, destinationAddress);
656}
657
658void
659PyViz::TraceNetDevTxCsma(std::string context, Ptr<const Packet> packet)
660{
661 EthernetHeader ethernetHeader;
662 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
663 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
664 destinationAddress = ethernetHeader.GetDestination();
665 TraceNetDevTxCommon(context, packet, destinationAddress);
666}
667
668void
670{
671 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
672 destinationAddress = Mac48Address();
673 TraceNetDevTxCommon(context, packet, destinationAddress);
674}
675
676// --------- RX device tracing -------------------
677
678void
679PyViz::TraceNetDevRxCommon(const std::string& context,
680 Ptr<const Packet> packet,
681 const std::variant<Mac16Address, Mac48Address, Mac64Address>& source)
682{
683 uint32_t uid;
684 PyVizPacketTag tag;
685 if (packet->FindFirstMatchingByteTag(tag))
686 {
687 uid = tag.m_packetId;
688 }
689 else
690 {
691 // NS_ASSERT (0);
692 NS_LOG_WARN("Packet has no byte tag");
693 uid = packet->GetUid();
694 }
695
696 NS_LOG_FUNCTION(context << uid);
697 std::vector<std::string> splitPath = PathSplit(context);
698 int nodeIndex = std::stoi(splitPath[1]);
699 int devIndex = std::stoi(splitPath[3]);
700
701 // ---- statistics
702 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
703 ++stats.receivedPackets;
704 stats.receivedBytes += packet->GetSize();
705
706 Ptr<Node> node = NodeList::GetNode(nodeIndex);
707 Ptr<NetDevice> device = node->GetDevice(devIndex);
708
709 // ---- "last packets"
710 const PacketCaptureOptions* captureOptions;
711 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
712 FilterPacket(packet, *captureOptions))
713 {
714 LastPacketsSample& last = m_lastPackets[nodeIndex];
715 RxPacketSample lastPacket;
716 lastPacket.time = Simulator::Now();
717 lastPacket.packet = packet->Copy();
718 lastPacket.device = device;
719 lastPacket.from = source;
720
721 last.lastReceivedPackets.push_back(lastPacket);
722 while (last.lastReceivedPackets.size() > captureOptions->numLastPackets)
723 {
724 last.lastReceivedPackets.erase(last.lastReceivedPackets.begin());
725 }
726 }
727
728 // ---- transmissions
729 if (m_packetsOfInterest.find(uid) == m_packetsOfInterest.end())
730 {
731 NS_LOG_DEBUG("RX Packet " << uid << " is not of interest");
732 return;
733 }
734
735 Ptr<Channel> channel = device->GetChannel();
736
737 auto recordIter = m_txRecords.find(TxRecordKey(channel, uid));
738
739 if (recordIter == m_txRecords.end())
740 {
741 NS_LOG_DEBUG("RX Packet " << uid << " was not transmitted?!");
742 return;
743 }
744
745 TxRecordValue& record = recordIter->second;
746
747 if (record.srcNode == node)
748 {
749 NS_LOG_WARN("Node " << node->GetId() << " receiving back the same packet (UID=" << uid
750 << ") it had previously transmitted, on the same channel!");
751 return;
752 }
753
754 TransmissionSampleKey key = {record.srcNode, node, channel};
755
756#ifdef NS3_LOG_ENABLE
757 NS_LOG_DEBUG("m_transmissionSamples begin:");
758 if (g_log.IsEnabled(ns3::LOG_DEBUG))
759 {
760 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
761 {
762 NS_LOG_DEBUG(iter->first.transmitter
763 << "/" << iter->first.transmitter->GetId() << ", " << iter->first.receiver
764 << "/" << iter->first.receiver->GetId() << ", " << iter->first.channel
765 << " => " << iter->second.bytes << " (@ " << &iter->second << ")");
766 }
767 }
768 NS_LOG_DEBUG("m_transmissionSamples end.");
769#endif
770
771 auto iter = m_transmissionSamples.find(key);
772
773 if (iter == m_transmissionSamples.end())
774 {
775 TransmissionSampleValue sample = {packet->GetSize()};
776 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
777 << key.receiver << "/" << key.receiver->GetId() << " channel "
778 << channel << ": " << packet->GetSize()
779 << " bytes more. => new sample with " << packet->GetSize()
780 << " bytes.");
781 m_transmissionSamples[key] = sample;
782 }
783 else
784 {
785 TransmissionSampleValue& sample = iter->second;
786 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
787 << key.receiver << "/" << key.receiver->GetId() << " channel "
788 << channel << ": " << packet->GetSize()
789 << " bytes more. => sample " << &sample << " with bytes "
790 << sample.bytes);
791
792 sample.bytes += packet->GetSize();
793 }
794}
795
796void
797PyViz::TraceNetDevRxWifi(std::string context, Ptr<const Packet> packet)
798{
799 NS_LOG_FUNCTION(context << packet->GetUid());
800
801 /*
802 * To DS From DS Address 1 Address 2 Address 3 Address 4
803 *----------------------------------------------------------------------
804 * 0 0 Destination Source BSSID N/A
805 * 0 1 Destination BSSID Source N/A
806 * 1 0 BSSID Source Destination N/A
807 * 1 1 Receiver Transmitter Destination Source
808 */
809 WifiMacHeader hdr;
810 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
811 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
812 if (!hdr.IsFromDs())
813 {
814 sourceAddress = hdr.GetAddr2();
815 }
816 else if (!hdr.IsToDs())
817 {
818 sourceAddress = hdr.GetAddr3();
819 }
820 else // if (hdr.IsToDs())
821 {
822 sourceAddress = hdr.GetAddr4();
823 }
824
825 TraceNetDevRxCommon(context, packet, sourceAddress);
826}
827
828void
830{
831 LrWpanMacHeader hdr;
832 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
833 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
834 switch (hdr.GetSrcAddrMode())
835 {
837 sourceAddress = hdr.GetExtSrcAddr();
838 break;
839 default:
840 sourceAddress = hdr.GetShortSrcAddr();
841 break;
842 }
843
844 TraceNetDevRxCommon(context, packet, sourceAddress);
845}
846
847void
848PyViz::TraceNetDevRxCsma(std::string context, Ptr<const Packet> packet)
849{
850 EthernetHeader ethernetHeader;
851 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
852 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
853 sourceAddress = ethernetHeader.GetSource();
854 TraceNetDevRxCommon(context, packet, sourceAddress);
855}
856
857void
859{
860 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
861 sourceAddress = Mac48Address();
862 TraceNetDevRxCommon(context, packet, sourceAddress);
863}
864
865void
867{
868 EthernetHeader ethernetHeader;
869 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
870
872
873 // Other packet types are already being received by
874 // TraceNetDevRxCsma; we don't want to receive them twice.
875 if (packetType == NetDevice::PACKET_OTHERHOST)
876 {
877 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
878 destinationAddress = ethernetHeader.GetDestination();
879 TraceNetDevRxCommon(context, packet, destinationAddress);
880 }
881}
882
883void
884PyViz::TraceNetDevTxLte(std::string context,
885 Ptr<const Packet> packet,
886 const Mac48Address& destination)
887{
888 NS_LOG_FUNCTION(context);
889 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
890 destinationAddress = destination;
891 TraceNetDevTxCommon(context, packet, destinationAddress);
892}
893
894void
895PyViz::TraceNetDevRxLte(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
896{
897 NS_LOG_FUNCTION(context);
898 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
899 sourceAddress = source;
900 TraceNetDevRxCommon(context, packet, sourceAddress);
901}
902
903// ---------------------
904
907{
908 NS_LOG_DEBUG("GetTransmissionSamples BEGIN");
910 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
911 {
912 TransmissionSample sample;
913 sample.transmitter = iter->first.transmitter;
914 sample.receiver = iter->first.receiver;
915 sample.channel = iter->first.channel;
916 sample.bytes = iter->second.bytes;
917 NS_LOG_DEBUG("from " << sample.transmitter->GetId() << " to " << sample.receiver->GetId()
918 << ": " << sample.bytes << " bytes.");
919 list.push_back(sample);
920 }
921 NS_LOG_DEBUG("GetTransmissionSamples END");
922 return list;
923}
924
927{
928 NS_LOG_DEBUG("GetPacketDropSamples BEGIN");
930 for (auto iter = m_packetDrops.begin(); iter != m_packetDrops.end(); iter++)
931 {
932 PacketDropSample sample;
933 sample.transmitter = iter->first;
934 sample.bytes = iter->second;
935 NS_LOG_DEBUG("in " << sample.transmitter->GetId() << ": " << sample.bytes
936 << " bytes dropped.");
937 list.push_back(sample);
938 }
939 NS_LOG_DEBUG("GetPacketDropSamples END");
940 return list;
941}
942
943void
945{
947}
948
949std::vector<PyViz::NodeStatistics>
951{
952 std::vector<PyViz::NodeStatistics> retval;
953 for (auto iter = m_nodesStatistics.begin(); iter != m_nodesStatistics.end(); iter++)
954 {
955 NodeStatistics stats = {iter->first, iter->second};
956 retval.push_back(stats);
957 }
958 return retval;
959}
960
963{
964 NS_LOG_DEBUG("GetLastPackets: " << nodeId);
965
966 auto iter = m_lastPackets.find(nodeId);
967 if (iter != m_lastPackets.end())
968 {
969 return iter->second;
970 }
971 else
972 {
973 return LastPacketsSample();
974 }
975}
976
977void
978PyViz::LineClipping(double boundsX1,
979 double boundsY1,
980 double boundsX2,
981 double boundsY2,
982 double& lineX1,
983 double& lineY1,
984 double& lineX2,
985 double& lineY2)
986{
987 FastClipping::Vector2 clipMin = {boundsX1, boundsY1};
988 FastClipping::Vector2 clipMax = {boundsX2, boundsY2};
989 FastClipping::Line line = {{lineX1, lineY1},
990 {lineX2, lineY2},
991 (lineX2 - lineX1),
992 (lineY2 - lineY1)};
993
994 FastClipping clipper(clipMin, clipMax);
995 clipper.ClipLine(line);
996 lineX1 = line.start.x;
997 lineX2 = line.end.x;
998 lineY1 = line.start.y;
999 lineY2 = line.end.y;
1000}
1001
1002} // namespace ns3
Packet header for Ethernet.
Mac48Address GetDestination() const
Mac48Address GetSource() const
This class is used by the visualizer for the process of removing lines or portions of lines outside o...
bool ClipLine(Line &line)
Clip line function.
Packet header for IPv4.
Definition ipv4-header.h:23
DropReason
Reason why a packet has been dropped.
This class can contain 16 bit addresses.
an EUI-48 address
an EUI-64 address
PacketType
Packet types are used as they are in Linux.
Definition net-device.h:289
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition net-device.h:296
uint32_t GetId() const
Definition node.cc:106
static Ptr< Node > GetNode(uint32_t n)
Definition node-list.cc:240
Iterator class for metadata items.
bool HasNext() const
Checks if there is another metadata item.
Item Next()
Retrieve the next metadata item.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
helper class to be used by the visualizer
Definition pyviz.h:44
void RegisterCsmaLikeDevice(const std::string &deviceTypeName)
Register CSMA like device function.
Definition pyviz.cc:175
void TraceNetDevRxCsma(std::string context, Ptr< const Packet > packet)
CSMA receive trace callback function.
Definition pyviz.cc:848
void SetPacketCaptureOptions(uint32_t nodeId, PacketCaptureOptions options)
Set packet capture options function.
Definition pyviz.cc:221
void TraceNetDevRxPointToPoint(std::string context, Ptr< const Packet > packet)
Point to point receive trace callback function.
Definition pyviz.cc:858
void RegisterDropTracePath(const std::string &tracePath)
Register drop trace path function.
Definition pyviz.cc:231
void RegisterWifiLikeDevice(const std::string &deviceTypeName)
Register WIFI like device function.
Definition pyviz.cc:193
std::map< uint32_t, PacketCaptureOptions > m_packetCaptureOptions
packet capture options
Definition pyviz.h:324
void TraceNetDevTxLte(std::string context, Ptr< const Packet > packet, const Mac48Address &destination)
LTE transmit trace callback function.
Definition pyviz.cc:884
std::map< uint32_t, LastPacketsSample > m_lastPackets
last packets
Definition pyviz.h:333
void SimulatorRunUntil(Time time)
Run simulation until a given (simulated, absolute) time is reached.
Definition pyviz.cc:281
bool m_stop
stop?
Definition pyviz.h:477
PacketDropSampleList GetPacketDropSamples() const
Get packet drop samples.
Definition pyviz.cc:926
void SetNodesOfInterest(std::set< uint32_t > nodes)
Set nodes of interest function.
Definition pyviz.cc:944
std::map< uint32_t, std::vector< NetDeviceStatistics > > m_nodesStatistics
node statistics
Definition pyviz.h:334
void TraceNetDevTxCsma(std::string context, Ptr< const Packet > packet)
CSMA transmit trace callback function.
Definition pyviz.cc:659
void TraceNetDevTxLrWpan(std::string context, Ptr< const Packet > packet)
Lr-Wpan transmit trace callback function.
Definition pyviz.cc:639
Time GetSimulatorStopTime()
Get the stop time of the underlying visual simulator implementation.
Definition pyviz.cc:346
void DoPause(const std::string &message)
Do pause function.
Definition pyviz.cc:245
std::vector< NodeStatistics > GetNodesStatistics() const
Get node statistics.
Definition pyviz.cc:950
std::set< uint32_t > m_nodesOfInterest
list of node IDs whose transmissions will be monitored
Definition pyviz.h:331
void TraceNetDevPromiscRxCsma(std::string context, Ptr< const Packet > packet)
CSMA promiscuous receive function.
Definition pyviz.cc:866
static void Pause(const std::string &message)
Pause function.
Definition pyviz.cc:254
void TraceNetDevRxCommon(const std::string &context, Ptr< const Packet > packet, const std::variant< Mac16Address, Mac48Address, Mac64Address > &source)
Network receive common trace callback function.
Definition pyviz.cc:679
std::vector< std::string > m_pauseMessages
pause message
Definition pyviz.h:325
void TraceNetDevRxLte(std::string context, Ptr< const Packet > packet, const Mac48Address &source)
LTE receive trace callback function.
Definition pyviz.cc:895
void TraceNetDevRxLrWpan(std::string context, Ptr< const Packet > packet)
Lr-Wpan receive trace callback function.
Definition pyviz.cc:829
void TraceIpv4Drop(std::string context, const ns3::Ipv4Header &hdr, Ptr< const Packet > packet, ns3::Ipv4L3Protocol::DropReason reason, Ptr< Ipv4 > dummy_ipv4, uint32_t interface)
Ipv4 drop trace callback function.
Definition pyviz.cc:506
TransmissionSampleList GetTransmissionSamples() const
Get transmission samples.
Definition pyviz.cc:906
static void LineClipping(double boundsX1, double boundsY1, double boundsX2, double boundsY2, double &lineX1, double &lineY1, double &lineX2, double &lineY2)
Utility function - clips a line to a bounding box.
Definition pyviz.cc:978
std::map< TransmissionSampleKey, TransmissionSampleValue > m_transmissionSamples
transmission samples
Definition pyviz.h:328
void TraceNetDevTxPointToPoint(std::string context, Ptr< const Packet > packet)
Point to point transmit trace callback function.
Definition pyviz.cc:669
void TraceNetDevRxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi receive trace callback function.
Definition pyviz.cc:797
NetDeviceStatistics & FindNetDeviceStatistics(int node, int interface)
Find net device statistics function.
Definition pyviz.cc:384
void TraceDevQueueDrop(std::string context, Ptr< const Packet > packet)
Queue drop trace callback function.
Definition pyviz.cc:459
std::map< TxRecordKey, TxRecordValue > m_txRecords
transmit records
Definition pyviz.h:326
std::vector< std::string > GetPauseMessages() const
Get pause message function.
Definition pyviz.cc:261
void TraceNetDevTxCommon(const std::string &context, Ptr< const Packet > packet, const std::variant< Mac16Address, Mac48Address, Mac64Address > &destination)
Network transmit common trace callback function.
Definition pyviz.cc:521
std::vector< PacketDropSample > PacketDropSampleList
PacketDropSampleList typedef.
Definition pyviz.h:118
static bool FilterPacket(Ptr< const Packet > packet, const PacketCaptureOptions &options)
Filter packet function.
Definition pyviz.cc:417
void CallbackStopSimulation()
Stop simulation callback function.
Definition pyviz.cc:270
void RegisterPointToPointLikeDevice(const std::string &deviceTypeName)
Register point to point like device function.
Definition pyviz.cc:207
std::map< Ptr< Node >, uint32_t > m_packetDrops
packet drops
Definition pyviz.h:329
LastPacketsSample GetLastPackets(uint32_t nodeId) const
Get last packets function.
Definition pyviz.cc:962
void TraceNetDevTxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi transmit trace callback function.
Definition pyviz.cc:611
bool GetPacketCaptureOptions(uint32_t nodeId, const PacketCaptureOptions **outOptions) const
Get packet capture options function.
Definition pyviz.cc:402
Time m_runUntil
run until time
Definition pyviz.h:478
std::map< uint32_t, Time > m_packetsOfInterest
list of packet UIDs that will be monitored
Definition pyviz.h:332
std::pair< Ptr< Channel >, uint32_t > TxRecordKey
TxRecordKey typedef.
Definition pyviz.h:285
std::vector< TransmissionSample > TransmissionSampleList
TransmissionSampleList typedef.
Definition pyviz.h:104
@ PACKET_CAPTURE_FILTER_HEADERS_OR
Definition pyviz.h:220
@ PACKET_CAPTURE_DISABLED
Definition pyviz.h:219
@ PACKET_CAPTURE_FILTER_HEADERS_AND
Definition pyviz.h:222
static Ptr< SimulatorImpl > GetImplementation()
Get the SimulatorImpl singleton.
Definition simulator.cc:356
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:597
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
@ NO_CONTEXT
Flag for events not associated with any particular context.
Definition simulator.h:207
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
read and write tag data
Definition tag-buffer.h:41
TAG_BUFFER_INLINE uint32_t ReadU32()
Definition tag-buffer.h:206
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition tag-buffer.h:176
tag a set of bytes in a packet
Definition tag.h:28
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
@ S
second
Definition nstime.h:107
a unique identifier for an interface.
Definition type-id.h:49
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:870
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr3() const
Return the address in the Address 3 field.
Mac48Address GetAddr4() const
Return the address in the Address 4 field.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
Represent the Mac Header with the Frame Control and Sequence Number fields.
Mac16Address GetShortSrcAddr() const
Get the Source Short address.
Mac64Address GetExtSrcAddr() const
Get the Source Extended address.
Mac16Address GetShortDstAddr() const
Get the Destination Short address.
uint8_t GetDstAddrMode() const
Get the Dest.
Mac64Address GetExtDstAddr() const
Get the Destination Extended address.
uint8_t GetSrcAddrMode() const
Get the Source Addressing Mode of Frame control field.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
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:690
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:980
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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:253
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
@ LOG_DEBUG
Full voluminous logging to support debugging.
Definition log.h:104
static PyViz * g_visualizer
the visualizer
Definition pyviz.cc:56
static std::vector< std::string > PathSplit(std::string str)
Definition pyviz.cc:34
The line struct.
Vector2 start
The start point of the line.
Vector2 end
The end point of the line.
The Vector 2 struct.
double x
X coordinate.
double y
Y coordinate.
structure describing a packet metadata item
TypeId tid
TypeId of Header or Trailer.
Structure to handle a sample of the last received, transmitted or drop packets in a node.
Definition pyviz.h:166
std::vector< PacketSample > lastDroppedPackets
Last dropped packets.
Definition pyviz.h:169
std::vector< TxPacketSample > lastTransmittedPackets
Last transmitted packets.
Definition pyviz.h:168
std::vector< RxPacketSample > lastReceivedPackets
Last received packets.
Definition pyviz.h:167
NetDeviceStatistics structure.
Definition pyviz.h:187
uint64_t receivedBytes
received bytes
Definition pyviz.h:198
uint64_t transmittedBytes
transmitted bytes
Definition pyviz.h:197
uint32_t receivedPackets
received packets
Definition pyviz.h:200
uint32_t transmittedPackets
transmitted packets
Definition pyviz.h:199
NodeStatistics structure.
Definition pyviz.h:205
PacketCaptureOptions structure.
Definition pyviz.h:228
PacketCaptureMode mode
mode
Definition pyviz.h:231
uint32_t numLastPackets
num last packets
Definition pyviz.h:230
std::set< TypeId > headers
headers
Definition pyviz.h:229
PacketDropSample structure.
Definition pyviz.h:113
Ptr< Node > transmitter
transmitter
Definition pyviz.h:114
PacketSample structure.
Definition pyviz.h:139
Ptr< Packet > packet
packet
Definition pyviz.h:141
Ptr< NetDevice > device
device
Definition pyviz.h:142
RxPacketSample structure.
Definition pyviz.h:157
std::variant< Mac16Address, Mac48Address, Mac64Address > from
The source MAC address.
Definition pyviz.h:158
TransmissionSample structure.
Definition pyviz.h:96
Ptr< Node > transmitter
transmitter
Definition pyviz.h:97
Ptr< Channel > channel
channel
Definition pyviz.h:99
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:98
TransmissionSampleKey structure.
Definition pyviz.h:297
Ptr< Channel > channel
channel
Definition pyviz.h:314
bool operator==(const TransmissionSampleKey &other) const
Equality operator.
Definition pyviz.cc:376
bool operator<(const TransmissionSampleKey &other) const
Less than operator.
Definition pyviz.cc:354
Ptr< Node > transmitter
transmitter
Definition pyviz.h:312
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:313
TransmissionSampleValue structure.
Definition pyviz.h:319
TxPacketSample structure.
Definition pyviz.h:149
std::variant< Mac16Address, Mac48Address, Mac64Address > to
The destination MAC address.
Definition pyviz.h:150
TxRecordValue structure.
Definition pyviz.h:289
Ptr< Node > srcNode
source node
Definition pyviz.h:291
bool isBroadcast
is broadcast?
Definition pyviz.h:292
PyVizPacketTag structure.
Definition pyviz.cc:62
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition pyviz.cc:89
void Deserialize(TagBuffer buf) override
Definition pyviz.cc:107
void Serialize(TagBuffer buf) const override
Definition pyviz.cc:101
static TypeId GetTypeId()
Get the type ID.
Definition pyviz.cc:79
uint32_t m_packetId
packet id
Definition pyviz.cc:71
void Print(std::ostream &os) const override
Definition pyviz.cc:113
uint32_t GetSerializedSize() const override
Definition pyviz.cc:95