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 "fast-clipping.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
56namespace visualizer
57{
58
59static PyViz* g_visualizer = nullptr; ///< the visualizer
60
61/**
62 * PyVizPacketTag structure
63 */
64struct PyVizPacketTag : public Tag
65{
66 static TypeId GetTypeId();
67 TypeId GetInstanceTypeId() const override;
68 uint32_t GetSerializedSize() const override;
69 void Serialize(TagBuffer buf) const override;
70 void Deserialize(TagBuffer buf) override;
71 void Print(std::ostream& os) const override;
73
74 uint32_t m_packetId; ///< packet id
75};
76
77/**
78 * @brief Get the type ID.
79 * @return the object TypeId
80 */
83{
84 static TypeId tid = TypeId("ns3::visualizer::PyVizPacketTag")
85 .AddDeprecatedName("ns3::PyVizPacketTag")
86 .SetParent<Tag>()
87 .SetGroupName("Visualizer")
88 .AddConstructor<PyVizPacketTag>();
89 return tid;
90}
91
94{
95 return GetTypeId();
96}
97
100{
101 return 4;
102}
103
104void
109
110void
115
116void
117PyVizPacketTag::Print(std::ostream& os) const
118{
119 os << "PacketId=" << m_packetId;
120}
121
126
128{
130 NS_ASSERT(g_visualizer == nullptr);
131 g_visualizer = this;
132
133 // WiFi
134 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
136
137 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
139 // Lr-Wpan
140 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::lrwpan::LrWpanNetDevice/Mac/MacTx",
142
143 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::lrwpan::LrWpanNetDevice/Mac/MacRx",
145
146 // CSMA
147 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacTx",
149
150 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
152
153 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacPromiscRx",
155
156 // Generic queue drop
157 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/TxQueue/Drop",
159 // IPv4 drop
160 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
162
163 // Point-to-Point
164 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacTx",
166
167 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacRx",
169
170 // LTE
171 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
173
174 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
176}
177
178void
179PyViz::RegisterCsmaLikeDevice(const std::string& deviceTypeName)
180{
181 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
182
183 std::ostringstream sstream;
184 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/MacTx";
186
187 sstream.str("");
188 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
190
191 sstream.str("");
192 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/PromiscRx";
194}
195
196void
197PyViz::RegisterWifiLikeDevice(const std::string& deviceTypeName)
198{
199 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
200
201 std::ostringstream sstream;
202 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Tx";
204
205 sstream.str("");
206 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
208}
209
210void
211PyViz::RegisterPointToPointLikeDevice(const std::string& deviceTypeName)
212{
213 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
214
215 std::ostringstream sstream;
216 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/TxQueue/Dequeue";
218
219 sstream.str("");
220 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
222}
223
224void
226{
227 NS_LOG_DEBUG(" SetPacketCaptureOptions "
228 << nodeId << " PacketCaptureOptions (headers size = " << options.headers.size()
229 << " mode = " << options.mode << " numLastPackets = " << options.numLastPackets
230 << ")");
231 m_packetCaptureOptions[nodeId] = options;
232}
233
234void
235PyViz::RegisterDropTracePath(const std::string& tracePath)
236{
238}
239
241{
243
244 NS_ASSERT(g_visualizer == this);
245 g_visualizer = nullptr;
246}
247
248void
249PyViz::DoPause(const std::string& message)
250{
251 m_pauseMessages.push_back(message);
252 m_stop = true;
254 << ": Have " << g_visualizer->m_pauseMessages.size() << " pause messages");
255}
256
257void
258PyViz::Pause(const std::string& message)
259{
261 g_visualizer->DoPause(message);
262}
263
264std::vector<std::string>
266{
268 << ": GetPauseMessages: have " << g_visualizer->m_pauseMessages.size()
269 << " pause messages");
270 return m_pauseMessages;
271}
272
273void
275{
277 if (m_runUntil <= Simulator::Now())
278 {
279 Simulator::Stop(); // Stop right now
280 m_stop = true;
281 }
282}
283
284void
286{
287 NS_LOG_LOGIC("SimulatorRunUntil " << time << " (now is " << Simulator::Now() << ")");
288
289 m_pauseMessages.clear();
290 m_transmissionSamples.clear();
291 m_packetDrops.clear();
292
293 Time expirationTime = Simulator::Now() - Seconds(10);
294
295 // Clear very old transmission records
296 for (auto iter = m_txRecords.begin(); iter != m_txRecords.end();)
297 {
298 if (iter->second.time < expirationTime)
299 {
300 m_txRecords.erase(iter++);
301 }
302 else
303 {
304 iter++;
305 }
306 }
307
308 // Clear very old packets of interest
309 for (auto iter = m_packetsOfInterest.begin(); iter != m_packetsOfInterest.end();)
310 {
311 if (iter->second < expirationTime)
312 {
313 m_packetsOfInterest.erase(iter++);
314 }
315 else
316 {
317 iter++;
318 }
319 }
320
321 if (Simulator::Now() >= time)
322 {
323 return;
324 }
325
326 // Schedule a dummy callback function for the target time, to make
327 // sure we stop at the right time. Otherwise, simulations with few
328 // events just appear to "jump" big chunks of time.
329 NS_LOG_LOGIC("Schedule dummy callback to be called in " << (time - Simulator::Now()));
330 m_runUntil = time;
331 m_stop = false;
333 time - Simulator::Now(),
335 this);
336
339 if (visualImpl)
340 {
341 visualImpl->RunRealSimulator();
342 }
343 else
344 {
345 impl->Run();
346 }
347}
348
349Time
351{
354 return visualImpl->GetStopTime();
355}
356
357bool
359{
360 if (this->transmitter < other.transmitter)
361 {
362 return true;
363 }
364 if (this->transmitter != other.transmitter)
365 {
366 return false;
367 }
368 if (this->receiver < other.receiver)
369 {
370 return true;
371 }
372 if (this->receiver != other.receiver)
373 {
374 return false;
375 }
376 return this->channel < other.channel;
377}
378
379bool
381{
382 bool retval = (transmitter == other.transmitter) && (receiver == other.receiver) &&
383 (channel == other.channel);
384 return retval;
385}
386
388PyViz::FindNetDeviceStatistics(int node, int interface)
389{
390 auto nodeStatsIter = m_nodesStatistics.find(node);
391 std::vector<NetDeviceStatistics>* stats;
392 if (nodeStatsIter == m_nodesStatistics.end())
393 {
394 stats = &m_nodesStatistics[node];
395 stats->resize(NodeList::GetNode(node)->GetNDevices());
396 }
397 else
398 {
399 stats = &(nodeStatsIter->second);
400 }
401 NetDeviceStatistics& devStats = (*stats)[interface];
402 return devStats;
403}
404
405bool
407{
408 auto iter = m_packetCaptureOptions.find(nodeId);
409 if (iter == m_packetCaptureOptions.end())
410 {
411 return false;
412 }
413 else
414 {
415 *outOptions = &iter->second;
416 return true;
417 }
418}
419
420bool
422{
423 switch (options.mode)
424 {
426 return false;
427
429 PacketMetadata::ItemIterator metadataIterator = packet->BeginItem();
430 while (metadataIterator.HasNext())
431 {
432 PacketMetadata::Item item = metadataIterator.Next();
433 if (options.headers.find(item.tid) != options.headers.end())
434 {
435 return true;
436 }
437 }
438 return false;
439 }
440
442 std::set<TypeId> missingHeaders(options.headers);
443 PacketMetadata::ItemIterator metadataIterator = packet->BeginItem();
444 while (metadataIterator.HasNext())
445 {
446 PacketMetadata::Item item = metadataIterator.Next();
447 auto missingIter = missingHeaders.find(item.tid);
448 if (missingIter != missingHeaders.end())
449 {
450 missingHeaders.erase(missingIter);
451 }
452 }
453 return missingHeaders.empty();
454 }
455
456 default:
457 NS_FATAL_ERROR("should not be reached");
458 return false;
459 }
460}
461
462void
463PyViz::TraceDevQueueDrop(std::string context, Ptr<const Packet> packet)
464{
465 NS_LOG_FUNCTION(context << packet->GetUid());
466 std::vector<std::string> splitPath = PathSplit(context);
467 int nodeIndex = std::stoi(splitPath[1]);
468 Ptr<Node> node = NodeList::GetNode(nodeIndex);
469
470 if (m_nodesOfInterest.find(nodeIndex) == m_nodesOfInterest.end())
471 {
472 // if the transmitting node is not "of interest", we still
473 // record the transmission if it is a packet of interest.
474 if (m_packetsOfInterest.find(packet->GetUid()) == m_packetsOfInterest.end())
475 {
476 NS_LOG_DEBUG("Packet " << packet->GetUid() << " is not of interest");
477 return;
478 }
479 }
480
481 // ---- "last packets"
482 const PacketCaptureOptions* captureOptions;
483 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
484 FilterPacket(packet, *captureOptions))
485 {
486 LastPacketsSample& last = m_lastPackets[nodeIndex];
487 PacketSample lastPacket;
488 lastPacket.time = Simulator::Now();
489 lastPacket.packet = packet->Copy();
490 lastPacket.device = nullptr;
491 last.lastDroppedPackets.push_back(lastPacket);
492 while (last.lastDroppedPackets.size() > captureOptions->numLastPackets)
493 {
494 last.lastDroppedPackets.erase(last.lastDroppedPackets.begin());
495 }
496 }
497
498 auto iter = m_packetDrops.find(node);
499 if (iter == m_packetDrops.end())
500 {
501 m_packetDrops[node] = packet->GetSize();
502 }
503 else
504 {
505 iter->second += packet->GetSize();
506 }
507}
508
509void
510PyViz::TraceIpv4Drop(std::string context,
511 const ns3::Ipv4Header& hdr,
512 Ptr<const Packet> packet,
514 Ptr<Ipv4> dummy_ipv4,
515 uint32_t interface)
516{
517 Ptr<Packet> packetCopy = packet->Copy();
518 packetCopy->AddHeader(hdr);
519 TraceDevQueueDrop(context, packetCopy);
520}
521
522// --------- TX device tracing -------------------
523
524void
526 const std::string& context,
527 Ptr<const Packet> packet,
528 const std::variant<Mac16Address, Mac48Address, Mac64Address>& destination)
529{
530 NS_LOG_FUNCTION(context << packet->GetUid() << *packet);
531
532 std::vector<std::string> splitPath = PathSplit(context);
533 int nodeIndex = std::stoi(splitPath[1]);
534 int devIndex = std::stoi(splitPath[3]);
535 Ptr<Node> node = NodeList::GetNode(nodeIndex);
536 Ptr<NetDevice> device = node->GetDevice(devIndex);
537
538 // ---- statistics
539 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
540 ++stats.transmittedPackets;
541 stats.transmittedBytes += packet->GetSize();
542
543 // ---- "last packets"
544 const PacketCaptureOptions* captureOptions;
545 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
546 FilterPacket(packet, *captureOptions))
547 {
548 LastPacketsSample& last = m_lastPackets[nodeIndex];
549 TxPacketSample lastPacket;
550 lastPacket.time = Simulator::Now();
551 lastPacket.packet = packet->Copy();
552 lastPacket.device = device;
553 lastPacket.to = destination;
554
555 last.lastTransmittedPackets.push_back(lastPacket);
556 while (last.lastTransmittedPackets.size() > captureOptions->numLastPackets)
557 {
558 last.lastTransmittedPackets.erase(last.lastTransmittedPackets.begin());
559 }
560 }
561
562 // ---- transmissions records
563
564 if (m_nodesOfInterest.find(nodeIndex) == m_nodesOfInterest.end())
565 {
566 // if the transmitting node is not "of interest", we still
567 // record the transmission if it is a packet of interest.
568 if (m_packetsOfInterest.find(packet->GetUid()) == m_packetsOfInterest.end())
569 {
570 NS_LOG_DEBUG("Packet " << packet->GetUid() << " is not of interest");
571 return;
572 }
573 }
574 else
575 {
576 // We will follow this packet throughout the network.
577 m_packetsOfInterest[packet->GetUid()] = Simulator::Now();
578 }
579
580 TxRecordValue record = {Simulator::Now(), node, false};
581
582 if (std::holds_alternative<Mac16Address>(destination))
583 {
584 if (std::get<Mac16Address>(destination) == Mac16Address("FF:FF"))
585 {
586 record.isBroadcast = true;
587 }
588 }
589 else if (std::holds_alternative<Mac48Address>(destination))
590 {
591 if (std::get<Mac48Address>(destination) == device->GetBroadcast())
592 {
593 record.isBroadcast = true;
594 }
595 }
596 else if (std::holds_alternative<Mac64Address>(destination))
597 {
598 if (std::get<Mac64Address>(destination) == Mac64Address("FF:FF:FF:FF:FF:FF:FF:FF"))
599 {
600 // Note: A broadcast using th the MAC 64 bit address is not really used in practice.
601 // instead the 16 bit MAC address is used.
602 record.isBroadcast = true;
603 }
604 }
605
606 m_txRecords[TxRecordKey(device->GetChannel(), packet->GetUid())] = record;
607
608 PyVizPacketTag tag;
609 // packet->RemovePacketTag (tag);
610 tag.m_packetId = packet->GetUid();
611 packet->AddByteTag(tag);
612}
613
614void
615PyViz::TraceNetDevTxWifi(std::string context, Ptr<const Packet> packet)
616{
617 NS_LOG_FUNCTION(context << packet->GetUid() << *packet);
618
619 /*
620 * To DS From DS Address 1 Address 2 Address 3 Address 4
621 *----------------------------------------------------------------------
622 * 0 0 Destination Source BSSID N/A
623 * 0 1 Destination BSSID Source N/A
624 * 1 0 BSSID Source Destination N/A
625 * 1 1 Receiver Transmitter Destination Source
626 */
627 WifiMacHeader hdr;
628 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
629
630 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
631 if (hdr.IsToDs())
632 {
633 destinationAddress = hdr.GetAddr3();
634 }
635 else
636 {
637 destinationAddress = hdr.GetAddr1();
638 }
639 TraceNetDevTxCommon(context, packet, destinationAddress);
640}
641
642void
644{
645 LrWpanMacHeader hdr;
646 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
647 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
648
649 switch (hdr.GetDstAddrMode())
650 {
652 destinationAddress = hdr.GetExtDstAddr();
653 break;
654 default:
655 destinationAddress = hdr.GetShortDstAddr();
656 break;
657 }
658
659 TraceNetDevTxCommon(context, packet, destinationAddress);
660}
661
662void
663PyViz::TraceNetDevTxCsma(std::string context, Ptr<const Packet> packet)
664{
665 EthernetHeader ethernetHeader;
666 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
667 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
668 destinationAddress = ethernetHeader.GetDestination();
669 TraceNetDevTxCommon(context, packet, destinationAddress);
670}
671
672void
674{
675 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
676 destinationAddress = Mac48Address();
677 TraceNetDevTxCommon(context, packet, destinationAddress);
678}
679
680// --------- RX device tracing -------------------
681
682void
683PyViz::TraceNetDevRxCommon(const std::string& context,
684 Ptr<const Packet> packet,
685 const std::variant<Mac16Address, Mac48Address, Mac64Address>& source)
686{
687 uint32_t uid;
688 PyVizPacketTag tag;
689 if (packet->FindFirstMatchingByteTag(tag))
690 {
691 uid = tag.m_packetId;
692 }
693 else
694 {
695 // NS_ASSERT (0);
696 NS_LOG_WARN("Packet has no byte tag");
697 uid = packet->GetUid();
698 }
699
700 NS_LOG_FUNCTION(context << uid);
701 std::vector<std::string> splitPath = PathSplit(context);
702 int nodeIndex = std::stoi(splitPath[1]);
703 int devIndex = std::stoi(splitPath[3]);
704
705 // ---- statistics
706 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
707 ++stats.receivedPackets;
708 stats.receivedBytes += packet->GetSize();
709
710 Ptr<Node> node = NodeList::GetNode(nodeIndex);
711 Ptr<NetDevice> device = node->GetDevice(devIndex);
712
713 // ---- "last packets"
714 const PacketCaptureOptions* captureOptions;
715 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
716 FilterPacket(packet, *captureOptions))
717 {
718 LastPacketsSample& last = m_lastPackets[nodeIndex];
719 RxPacketSample lastPacket;
720 lastPacket.time = Simulator::Now();
721 lastPacket.packet = packet->Copy();
722 lastPacket.device = device;
723 lastPacket.from = source;
724
725 last.lastReceivedPackets.push_back(lastPacket);
726 while (last.lastReceivedPackets.size() > captureOptions->numLastPackets)
727 {
728 last.lastReceivedPackets.erase(last.lastReceivedPackets.begin());
729 }
730 }
731
732 // ---- transmissions
733 if (m_packetsOfInterest.find(uid) == m_packetsOfInterest.end())
734 {
735 NS_LOG_DEBUG("RX Packet " << uid << " is not of interest");
736 return;
737 }
738
739 Ptr<Channel> channel = device->GetChannel();
740
741 auto recordIter = m_txRecords.find(TxRecordKey(channel, uid));
742
743 if (recordIter == m_txRecords.end())
744 {
745 NS_LOG_DEBUG("RX Packet " << uid << " was not transmitted?!");
746 return;
747 }
748
749 TxRecordValue& record = recordIter->second;
750
751 if (record.srcNode == node)
752 {
753 NS_LOG_WARN("Node " << node->GetId() << " receiving back the same packet (UID=" << uid
754 << ") it had previously transmitted, on the same channel!");
755 return;
756 }
757
758 TransmissionSampleKey key = {record.srcNode, node, channel};
759
760#ifdef NS3_LOG_ENABLE
761 NS_LOG_DEBUG("m_transmissionSamples begin:");
762 if (g_log.IsEnabled(ns3::LOG_DEBUG))
763 {
764 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
765 {
766 NS_LOG_DEBUG(iter->first.transmitter
767 << "/" << iter->first.transmitter->GetId() << ", " << iter->first.receiver
768 << "/" << iter->first.receiver->GetId() << ", " << iter->first.channel
769 << " => " << iter->second.bytes << " (@ " << &iter->second << ")");
770 }
771 }
772 NS_LOG_DEBUG("m_transmissionSamples end.");
773#endif
774
775 auto iter = m_transmissionSamples.find(key);
776
777 if (iter == m_transmissionSamples.end())
778 {
779 TransmissionSampleValue sample = {packet->GetSize()};
780 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
781 << key.receiver << "/" << key.receiver->GetId() << " channel "
782 << channel << ": " << packet->GetSize()
783 << " bytes more. => new sample with " << packet->GetSize()
784 << " bytes.");
785 m_transmissionSamples[key] = sample;
786 }
787 else
788 {
789 TransmissionSampleValue& sample = iter->second;
790 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
791 << key.receiver << "/" << key.receiver->GetId() << " channel "
792 << channel << ": " << packet->GetSize()
793 << " bytes more. => sample " << &sample << " with bytes "
794 << sample.bytes);
795
796 sample.bytes += packet->GetSize();
797 }
798}
799
800void
801PyViz::TraceNetDevRxWifi(std::string context, Ptr<const Packet> packet)
802{
803 NS_LOG_FUNCTION(context << packet->GetUid());
804
805 /*
806 * To DS From DS Address 1 Address 2 Address 3 Address 4
807 *----------------------------------------------------------------------
808 * 0 0 Destination Source BSSID N/A
809 * 0 1 Destination BSSID Source N/A
810 * 1 0 BSSID Source Destination N/A
811 * 1 1 Receiver Transmitter Destination Source
812 */
813 WifiMacHeader hdr;
814 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
815 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
816 if (!hdr.IsFromDs())
817 {
818 sourceAddress = hdr.GetAddr2();
819 }
820 else if (!hdr.IsToDs())
821 {
822 sourceAddress = hdr.GetAddr3();
823 }
824 else // if (hdr.IsToDs())
825 {
826 sourceAddress = hdr.GetAddr4();
827 }
828
829 TraceNetDevRxCommon(context, packet, sourceAddress);
830}
831
832void
834{
835 LrWpanMacHeader hdr;
836 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
837 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
838 switch (hdr.GetSrcAddrMode())
839 {
841 sourceAddress = hdr.GetExtSrcAddr();
842 break;
843 default:
844 sourceAddress = hdr.GetShortSrcAddr();
845 break;
846 }
847
848 TraceNetDevRxCommon(context, packet, sourceAddress);
849}
850
851void
852PyViz::TraceNetDevRxCsma(std::string context, Ptr<const Packet> packet)
853{
854 EthernetHeader ethernetHeader;
855 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
856 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
857 sourceAddress = ethernetHeader.GetSource();
858 TraceNetDevRxCommon(context, packet, sourceAddress);
859}
860
861void
863{
864 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
865 sourceAddress = Mac48Address();
866 TraceNetDevRxCommon(context, packet, sourceAddress);
867}
868
869void
871{
872 EthernetHeader ethernetHeader;
873 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
874
876
877 // Other packet types are already being received by
878 // TraceNetDevRxCsma; we don't want to receive them twice.
879 if (packetType == NetDevice::PACKET_OTHERHOST)
880 {
881 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
882 destinationAddress = ethernetHeader.GetDestination();
883 TraceNetDevRxCommon(context, packet, destinationAddress);
884 }
885}
886
887void
888PyViz::TraceNetDevTxLte(std::string context,
889 Ptr<const Packet> packet,
890 const Mac48Address& destination)
891{
892 NS_LOG_FUNCTION(context);
893 std::variant<Mac16Address, Mac48Address, Mac64Address> destinationAddress;
894 destinationAddress = destination;
895 TraceNetDevTxCommon(context, packet, destinationAddress);
896}
897
898void
899PyViz::TraceNetDevRxLte(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
900{
901 NS_LOG_FUNCTION(context);
902 std::variant<Mac16Address, Mac48Address, Mac64Address> sourceAddress;
903 sourceAddress = source;
904 TraceNetDevRxCommon(context, packet, sourceAddress);
905}
906
907// ---------------------
908
911{
912 NS_LOG_DEBUG("GetTransmissionSamples BEGIN");
914 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
915 {
916 TransmissionSample sample;
917 sample.transmitter = iter->first.transmitter;
918 sample.receiver = iter->first.receiver;
919 sample.channel = iter->first.channel;
920 sample.bytes = iter->second.bytes;
921 NS_LOG_DEBUG("from " << sample.transmitter->GetId() << " to " << sample.receiver->GetId()
922 << ": " << sample.bytes << " bytes.");
923 list.push_back(sample);
924 }
925 NS_LOG_DEBUG("GetTransmissionSamples END");
926 return list;
927}
928
931{
932 NS_LOG_DEBUG("GetPacketDropSamples BEGIN");
934 for (auto iter = m_packetDrops.begin(); iter != m_packetDrops.end(); iter++)
935 {
936 PacketDropSample sample;
937 sample.transmitter = iter->first;
938 sample.bytes = iter->second;
939 NS_LOG_DEBUG("in " << sample.transmitter->GetId() << ": " << sample.bytes
940 << " bytes dropped.");
941 list.push_back(sample);
942 }
943 NS_LOG_DEBUG("GetPacketDropSamples END");
944 return list;
945}
946
947void
949{
951}
952
953std::vector<NodeStatistics>
955{
956 std::vector<NodeStatistics> retval;
957 for (auto iter = m_nodesStatistics.begin(); iter != m_nodesStatistics.end(); iter++)
958 {
959 NodeStatistics stats = {iter->first, iter->second};
960 retval.push_back(stats);
961 }
962 return retval;
963}
964
967{
968 NS_LOG_DEBUG("GetLastPackets: " << nodeId);
969
970 auto iter = m_lastPackets.find(nodeId);
971 if (iter != m_lastPackets.end())
972 {
973 return iter->second;
974 }
975 else
976 {
977 return LastPacketsSample();
978 }
979}
980
981void
982PyViz::LineClipping(double boundsX1,
983 double boundsY1,
984 double boundsX2,
985 double boundsY2,
986 double& lineX1,
987 double& lineY1,
988 double& lineX2,
989 double& lineY2)
990{
991 FastClipping::Vector2 clipMin = {boundsX1, boundsY1};
992 FastClipping::Vector2 clipMax = {boundsX2, boundsY2};
993 FastClipping::Line line = {{lineX1, lineY1},
994 {lineX2, lineY2},
995 (lineX2 - lineX1),
996 (lineY2 - lineY1)};
997
998 FastClipping clipper(clipMin, clipMax);
999 clipper.ClipLine(line);
1000 lineX1 = line.start.x;
1001 lineX2 = line.end.x;
1002 lineY1 = line.start.y;
1003 lineY2 = line.end.y;
1004}
1005
1006} // namespace visualizer
1007} // namespace ns3
Packet header for Ethernet.
Mac48Address GetDestination() const
Mac48Address GetSource() const
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
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 AddDeprecatedName(const std::string &name)
Add an deprecated name for a TypeId.
Definition type-id.cc:860
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.
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.
helper class to be used by the visualizer
Definition pyviz.h:156
std::pair< Ptr< Channel >, uint32_t > TxRecordKey
TxRecordKey type definition.
Definition pyviz.h:515
void TraceNetDevTxLte(std::string context, Ptr< const Packet > packet, const Mac48Address &destination)
LTE transmit trace callback function.
Definition pyviz.cc:888
void SetNodesOfInterest(std::set< uint32_t > nodes)
Set nodes of interest function.
Definition pyviz.cc:948
void TraceNetDevRxCsma(std::string context, Ptr< const Packet > packet)
CSMA receive trace callback function.
Definition pyviz.cc:852
void SetPacketCaptureOptions(uint32_t nodeId, PacketCaptureOptions options)
Set packet capture options function.
Definition pyviz.cc:225
void TraceNetDevRxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi receive trace callback function.
Definition pyviz.cc:801
void TraceNetDevRxPointToPoint(std::string context, Ptr< const Packet > packet)
Point to point receive trace callback function.
Definition pyviz.cc:862
NetDeviceStatistics & FindNetDeviceStatistics(int node, int interface)
Find net device statistics function.
Definition pyviz.cc:388
void TraceDevQueueDrop(std::string context, Ptr< const Packet > packet)
Queue drop trace callback function.
Definition pyviz.cc:463
std::vector< NodeStatistics > GetNodesStatistics() const
Get node statistics.
Definition pyviz.cc:954
static bool FilterPacket(Ptr< const Packet > packet, const PacketCaptureOptions &options)
Filter packet function.
Definition pyviz.cc:421
std::map< TransmissionSampleKey, TransmissionSampleValue > m_transmissionSamples
Transmission samples.
Definition pyviz.h:522
void TraceNetDevPromiscRxCsma(std::string context, Ptr< const Packet > packet)
CSMA promiscuous receive function.
Definition pyviz.cc:870
Time GetSimulatorStopTime()
Get the stop time of the underlying visual simulator implementation.
Definition pyviz.cc:350
std::map< uint32_t, PacketCaptureOptions > m_packetCaptureOptions
Packet capture options.
Definition pyviz.h:517
std::vector< std::string > GetPauseMessages() const
Get pause message function.
Definition pyviz.cc:265
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:525
void TraceNetDevTxPointToPoint(std::string context, Ptr< const Packet > packet)
Point to point transmit trace callback function.
Definition pyviz.cc:673
std::map< uint32_t, Time > m_packetsOfInterest
List of packet UIDs that will be monitored.
Definition pyviz.h:526
void RegisterCsmaLikeDevice(const std::string &deviceTypeName)
Register CSMA like device function.
Definition pyviz.cc:179
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:683
std::set< uint32_t > m_nodesOfInterest
List of node IDs whose transmissions will be monitored.
Definition pyviz.h:524
void TraceNetDevTxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi transmit trace callback function.
Definition pyviz.cc:615
std::map< Ptr< Node >, uint32_t > m_packetDrops
Packet drops.
Definition pyviz.h:523
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:510
TransmissionSampleList GetTransmissionSamples() const
Get transmission samples.
Definition pyviz.cc:910
LastPacketsSample GetLastPackets(uint32_t nodeId) const
Get last packets function.
Definition pyviz.cc:966
std::map< uint32_t, LastPacketsSample > m_lastPackets
Last packets.
Definition pyviz.h:527
static void Pause(const std::string &message)
Pause function.
Definition pyviz.cc:258
bool m_stop
Stop simulation flag.
Definition pyviz.h:529
void RegisterPointToPointLikeDevice(const std::string &deviceTypeName)
Register point to point like device function.
Definition pyviz.cc:211
void TraceNetDevTxLrWpan(std::string context, Ptr< const Packet > packet)
Lr-Wpan transmit trace callback function.
Definition pyviz.cc:643
void RegisterWifiLikeDevice(const std::string &deviceTypeName)
Register WIFI like device function.
Definition pyviz.cc:197
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:982
std::map< TxRecordKey, TxRecordValue > m_txRecords
Transmit records.
Definition pyviz.h:519
void DoPause(const std::string &message)
Do pause function.
Definition pyviz.cc:249
void TraceNetDevRxLrWpan(std::string context, Ptr< const Packet > packet)
Lr-Wpan receive trace callback function.
Definition pyviz.cc:833
void SimulatorRunUntil(Time time)
Run simulation until a given (simulated, absolute) time is reached.
Definition pyviz.cc:285
void TraceNetDevRxLte(std::string context, Ptr< const Packet > packet, const Mac48Address &source)
LTE receive trace callback function.
Definition pyviz.cc:899
PacketDropSampleList GetPacketDropSamples() const
Get packet drop samples.
Definition pyviz.cc:930
std::map< uint32_t, std::vector< NetDeviceStatistics > > m_nodesStatistics
Node statistics.
Definition pyviz.h:528
Time m_runUntil
Indicates until when the simulation should run for its next step.
Definition pyviz.h:530
void RegisterDropTracePath(const std::string &tracePath)
Register drop trace path function.
Definition pyviz.cc:235
void TraceNetDevTxCsma(std::string context, Ptr< const Packet > packet)
CSMA transmit trace callback function.
Definition pyviz.cc:663
void CallbackStopSimulation()
Stop simulation callback function.
Definition pyviz.cc:274
std::vector< std::string > m_pauseMessages
Pause message.
Definition pyviz.h:518
bool GetPacketCaptureOptions(uint32_t nodeId, const PacketCaptureOptions **outOptions) const
Get packet capture options function.
Definition pyviz.cc:406
#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
@ PACKET_CAPTURE_DISABLED
Packet capture is disabled.
Definition pyviz.h:124
@ PACKET_CAPTURE_FILTER_HEADERS_AND
Packet capture if all of the indicated headers are present.
Definition pyviz.h:127
@ PACKET_CAPTURE_FILTER_HEADERS_OR
Packet capture if any of the indicated headers is present.
Definition pyviz.h:125
std::vector< TransmissionSample > TransmissionSampleList
The transmission sample list.
Definition pyviz.h:141
static PyViz * g_visualizer
the visualizer
Definition pyviz.cc:59
std::vector< PacketDropSample > PacketDropSampleList
The packet drop list.
Definition pyviz.h:142
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 std::vector< std::string > PathSplit(std::string str)
Definition pyviz.cc:34
structure describing a packet metadata item
TypeId tid
TypeId of Header or Trailer.
Vector2 start
The start point of the line.
Vector2 end
The end point of the line.
Structure to handle a sample of the last received, transmitted or drop packets in a node.
Definition pyviz.h:85
std::vector< PacketSample > lastDroppedPackets
Last dropped packets.
Definition pyviz.h:88
std::vector< TxPacketSample > lastTransmittedPackets
Last transmitted packets.
Definition pyviz.h:87
std::vector< RxPacketSample > lastReceivedPackets
Last received packets.
Definition pyviz.h:86
The NetDeviceStatistics structure.
Definition pyviz.h:95
uint32_t transmittedPackets
Transmitted packets.
Definition pyviz.h:106
uint64_t receivedBytes
Received bytes.
Definition pyviz.h:105
uint64_t transmittedBytes
Transmitted bytes.
Definition pyviz.h:104
uint32_t receivedPackets
Received packets.
Definition pyviz.h:107
The NodeStatistics structure.
Definition pyviz.h:114
The PacketCaptureOptions structure.
Definition pyviz.h:135
uint32_t numLastPackets
Number of last packets.
Definition pyviz.h:137
std::set< TypeId > headers
The headers.
Definition pyviz.h:136
PacketCaptureMode mode
The packet capture node.
Definition pyviz.h:138
PacketDropSample structure.
Definition pyviz.h:49
uint32_t bytes
The number of bytes dropped.
Definition pyviz.h:51
Ptr< Node > transmitter
The transmitter node where the drop was registered.
Definition pyviz.h:50
PacketSample structure.
Definition pyviz.h:58
Ptr< Packet > packet
The packet reference.
Definition pyviz.h:60
Ptr< NetDevice > device
The NetDevice reference.
Definition pyviz.h:61
Time time
The received or transmitted time of the sample.
Definition pyviz.h:59
The TransmissionSampleKey structure.
Definition pyviz.h:487
bool operator==(const TransmissionSampleKey &other) const
Equality operator.
Definition pyviz.cc:380
bool operator<(const TransmissionSampleKey &other) const
Less than operator.
Definition pyviz.cc:358
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:503
The TransmissionSampleValue structure.
Definition pyviz.h:511
uint32_t bytes
The nuumber of bytes of the transmission sample.
Definition pyviz.h:512
The TxRecordValue structure.
Definition pyviz.h:477
Ptr< Node > srcNode
The source node of the transmission.
Definition pyviz.h:479
bool isBroadcast
Broadcast flag.
Definition pyviz.h:480
PyVizPacketTag structure.
Definition pyviz.cc:65
void Deserialize(TagBuffer buf) override
Definition pyviz.cc:111
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition pyviz.cc:93
static TypeId GetTypeId()
Get the type ID.
Definition pyviz.cc:82
uint32_t m_packetId
packet id
Definition pyviz.cc:74
void Print(std::ostream &os) const override
Definition pyviz.cc:117
uint32_t GetSerializedSize() const override
Definition pyviz.cc:99
void Serialize(TagBuffer buf) const override
Definition pyviz.cc:105
RxPacketSample structure.
Definition pyviz.h:76
std::variant< Mac16Address, Mac48Address, Mac64Address > from
The source MAC address.
Definition pyviz.h:77
TransmissionSample structure.
Definition pyviz.h:38
Ptr< Channel > channel
The channel reference used for the transmission.
Definition pyviz.h:41
Ptr< Node > receiver
The destination node of the transmission (Null if broadcast).
Definition pyviz.h:40
Ptr< Node > transmitter
The source node of the transmission.
Definition pyviz.h:39
uint32_t bytes
The number of bytes transmitted.
Definition pyviz.h:42
TxPacketSample structure.
Definition pyviz.h:68
std::variant< Mac16Address, Mac48Address, Mac64Address > to
The destination MAC address.
Definition pyviz.h:69