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
12
13#include "ns3/abort.h"
14#include "ns3/config.h"
15#include "ns3/ethernet-header.h"
16#include "ns3/log.h"
17#include "ns3/node-list.h"
18#include "ns3/ppp-header.h"
19#include "ns3/simulator.h"
20#include "ns3/wifi-mac-header.h"
21#include "ns3/wifi-net-device.h"
22
23#include <cstdlib>
24#include <sstream>
25
27
28#define NUM_LAST_PACKETS 10
29
30static std::vector<std::string>
31PathSplit(std::string str)
32{
33 std::vector<std::string> results;
34 size_t cutAt;
35 while ((cutAt = str.find_first_of('/')) != std::string::npos)
36 {
37 if (cutAt > 0)
38 {
39 results.push_back(str.substr(0, cutAt));
40 }
41 str = str.substr(cutAt + 1);
42 }
43 if (!str.empty())
44 {
45 results.push_back(str);
46 }
47 return results;
48}
49
50namespace ns3
51{
52
53static PyViz* g_visualizer = nullptr; ///< the visualizer
54
55/**
56 * PyVizPacketTag structure
57 */
58struct PyVizPacketTag : public Tag
59{
60 static TypeId GetTypeId();
61 TypeId GetInstanceTypeId() const override;
62 uint32_t GetSerializedSize() const override;
63 void Serialize(TagBuffer buf) const override;
64 void Deserialize(TagBuffer buf) override;
65 void Print(std::ostream& os) const override;
67
68 uint32_t m_packetId; ///< packet id
69};
70
71/**
72 * @brief Get the type ID.
73 * @return the object TypeId
74 */
77{
78 static TypeId tid = TypeId("ns3::PyVizPacketTag")
79 .SetParent<Tag>()
80 .SetGroupName("Visualizer")
81 .AddConstructor<PyVizPacketTag>();
82 return tid;
83}
84
87{
88 return GetTypeId();
89}
90
93{
94 return 4;
95}
96
97void
102
103void
108
109void
110PyVizPacketTag::Print(std::ostream& os) const
111{
112 os << "PacketId=" << m_packetId;
113}
114
119
121{
123 NS_ASSERT(g_visualizer == nullptr);
124 g_visualizer = this;
125
126 // WiFi
127 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
129
130 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
132
133 // CSMA
134 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacTx",
136
137 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
139
140 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacPromiscRx",
142
143 // Generic queue drop
144 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/TxQueue/Drop",
146 // IPv4 drop
147 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
149
150 // Point-to-Point
151 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacTx",
153
154 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacRx",
156
157 // LTE
158 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
160
161 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
163}
164
165void
166PyViz::RegisterCsmaLikeDevice(const std::string& deviceTypeName)
167{
168 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
169
170 std::ostringstream sstream;
171 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/MacTx";
173
174 sstream.str("");
175 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
177
178 sstream.str("");
179 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/PromiscRx";
181}
182
183void
184PyViz::RegisterWifiLikeDevice(const std::string& deviceTypeName)
185{
186 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
187
188 std::ostringstream sstream;
189 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Tx";
191
192 sstream.str("");
193 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
195}
196
197void
198PyViz::RegisterPointToPointLikeDevice(const std::string& deviceTypeName)
199{
200 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
201
202 std::ostringstream sstream;
203 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/TxQueue/Dequeue";
205
206 sstream.str("");
207 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
209}
210
211void
213{
214 NS_LOG_DEBUG(" SetPacketCaptureOptions "
215 << nodeId << " PacketCaptureOptions (headers size = " << options.headers.size()
216 << " mode = " << options.mode << " numLastPackets = " << options.numLastPackets
217 << ")");
218 m_packetCaptureOptions[nodeId] = options;
219}
220
221void
222PyViz::RegisterDropTracePath(const std::string& tracePath)
223{
225}
226
228{
230
231 NS_ASSERT(g_visualizer == this);
232 g_visualizer = nullptr;
233}
234
235void
236PyViz::DoPause(const std::string& message)
237{
238 m_pauseMessages.push_back(message);
239 m_stop = true;
241 << ": Have " << g_visualizer->m_pauseMessages.size() << " pause messages");
242}
243
244void
245PyViz::Pause(const std::string& message)
246{
248 g_visualizer->DoPause(message);
249}
250
251std::vector<std::string>
253{
255 << ": GetPauseMessages: have " << g_visualizer->m_pauseMessages.size()
256 << " pause messages");
257 return m_pauseMessages;
258}
259
260void
262{
264 if (m_runUntil <= Simulator::Now())
265 {
266 Simulator::Stop(Seconds(0)); // Stop right now
267 m_stop = true;
268 }
269}
270
271void
273{
274 NS_LOG_LOGIC("SimulatorRunUntil " << time << " (now is " << Simulator::Now() << ")");
275
276 m_pauseMessages.clear();
277 m_transmissionSamples.clear();
278 m_packetDrops.clear();
279
280 Time expirationTime = Simulator::Now() - Seconds(10);
281
282 // Clear very old transmission records
283 for (auto iter = m_txRecords.begin(); iter != m_txRecords.end();)
284 {
285 if (iter->second.time < expirationTime)
286 {
287 m_txRecords.erase(iter++);
288 }
289 else
290 {
291 iter++;
292 }
293 }
294
295 // Clear very old packets of interest
296 for (auto iter = m_packetsOfInterest.begin(); iter != m_packetsOfInterest.end();)
297 {
298 if (iter->second < expirationTime)
299 {
300 m_packetsOfInterest.erase(iter++);
301 }
302 else
303 {
304 iter++;
305 }
306 }
307
308 if (Simulator::Now() >= time)
309 {
310 return;
311 }
312 // Schedule a dummy callback function for the target time, to make
313 // sure we stop at the right time. Otherwise, simulations with few
314 // events just appear to "jump" big chunks of time.
315 NS_LOG_LOGIC("Schedule dummy callback to be called in " << (time - Simulator::Now()));
316 m_runUntil = time;
317 m_stop = false;
319 time - Simulator::Now(),
321 this);
322
325 if (visualImpl)
326 {
327 visualImpl->RunRealSimulator();
328 }
329 else
330 {
331 impl->Run();
332 }
333}
334
335bool
337{
338 if (this->transmitter < other.transmitter)
339 {
340 return true;
341 }
342 if (this->transmitter != other.transmitter)
343 {
344 return false;
345 }
346 if (this->receiver < other.receiver)
347 {
348 return true;
349 }
350 if (this->receiver != other.receiver)
351 {
352 return false;
353 }
354 return this->channel < other.channel;
355}
356
357bool
359{
360 bool retval = (transmitter == other.transmitter) && (receiver == other.receiver) &&
361 (channel == other.channel);
362 return retval;
363}
364
366PyViz::FindNetDeviceStatistics(int node, int interface)
367{
368 auto nodeStatsIter = m_nodesStatistics.find(node);
369 std::vector<NetDeviceStatistics>* stats;
370 if (nodeStatsIter == m_nodesStatistics.end())
371 {
372 stats = &m_nodesStatistics[node];
373 stats->resize(NodeList::GetNode(node)->GetNDevices());
374 }
375 else
376 {
377 stats = &(nodeStatsIter->second);
378 }
379 NetDeviceStatistics& devStats = (*stats)[interface];
380 return devStats;
381}
382
383bool
385{
386 auto iter = m_packetCaptureOptions.find(nodeId);
387 if (iter == m_packetCaptureOptions.end())
388 {
389 return false;
390 }
391 else
392 {
393 *outOptions = &iter->second;
394 return true;
395 }
396}
397
398bool
400{
401 switch (options.mode)
402 {
404 return false;
405
407 PacketMetadata::ItemIterator metadataIterator = packet->BeginItem();
408 while (metadataIterator.HasNext())
409 {
410 PacketMetadata::Item item = metadataIterator.Next();
411 if (options.headers.find(item.tid) != options.headers.end())
412 {
413 return true;
414 }
415 }
416 return false;
417 }
418
420 std::set<TypeId> missingHeaders(options.headers);
421 PacketMetadata::ItemIterator metadataIterator = packet->BeginItem();
422 while (metadataIterator.HasNext())
423 {
424 PacketMetadata::Item item = metadataIterator.Next();
425 auto missingIter = missingHeaders.find(item.tid);
426 if (missingIter != missingHeaders.end())
427 {
428 missingHeaders.erase(missingIter);
429 }
430 }
431 return missingHeaders.empty();
432 }
433
434 default:
435 NS_FATAL_ERROR("should not be reached");
436 return false;
437 }
438}
439
440void
441PyViz::TraceDevQueueDrop(std::string context, Ptr<const Packet> packet)
442{
443 NS_LOG_FUNCTION(context << packet->GetUid());
444 std::vector<std::string> splitPath = PathSplit(context);
445 int nodeIndex = std::stoi(splitPath[1]);
446 Ptr<Node> node = NodeList::GetNode(nodeIndex);
447
448 if (m_nodesOfInterest.find(nodeIndex) == m_nodesOfInterest.end())
449 {
450 // if the transmitting node is not "of interest", we still
451 // record the transmission if it is a packet of interest.
452 if (m_packetsOfInterest.find(packet->GetUid()) == m_packetsOfInterest.end())
453 {
454 NS_LOG_DEBUG("Packet " << packet->GetUid() << " is not of interest");
455 return;
456 }
457 }
458
459 // ---- "last packets"
460 const PacketCaptureOptions* captureOptions;
461 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
462 FilterPacket(packet, *captureOptions))
463 {
464 LastPacketsSample& last = m_lastPackets[nodeIndex];
465 PacketSample lastPacket;
466 lastPacket.time = Simulator::Now();
467 lastPacket.packet = packet->Copy();
468 lastPacket.device = nullptr;
469 last.lastDroppedPackets.push_back(lastPacket);
470 while (last.lastDroppedPackets.size() > captureOptions->numLastPackets)
471 {
472 last.lastDroppedPackets.erase(last.lastDroppedPackets.begin());
473 }
474 }
475
476 auto iter = m_packetDrops.find(node);
477 if (iter == m_packetDrops.end())
478 {
479 m_packetDrops[node] = packet->GetSize();
480 }
481 else
482 {
483 iter->second += packet->GetSize();
484 }
485}
486
487void
488PyViz::TraceIpv4Drop(std::string context,
489 const ns3::Ipv4Header& hdr,
490 Ptr<const Packet> packet,
492 Ptr<Ipv4> dummy_ipv4,
493 uint32_t interface)
494{
495 Ptr<Packet> packetCopy = packet->Copy();
496 packetCopy->AddHeader(hdr);
497 TraceDevQueueDrop(context, packetCopy);
498}
499
500// --------- TX device tracing -------------------
501
502void
503PyViz::TraceNetDevTxCommon(const std::string& context,
504 Ptr<const Packet> packet,
505 const Mac48Address& destinationAddress)
506{
507 NS_LOG_FUNCTION(context << packet->GetUid() << *packet);
508
509 std::vector<std::string> splitPath = PathSplit(context);
510 int nodeIndex = std::stoi(splitPath[1]);
511 int devIndex = std::stoi(splitPath[3]);
512 Ptr<Node> node = NodeList::GetNode(nodeIndex);
513 Ptr<NetDevice> device = node->GetDevice(devIndex);
514
515 // ---- statistics
516 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
517 ++stats.transmittedPackets;
518 stats.transmittedBytes += packet->GetSize();
519
520 // ---- "last packets"
521 const PacketCaptureOptions* captureOptions;
522 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
523 FilterPacket(packet, *captureOptions))
524 {
525 LastPacketsSample& last = m_lastPackets[nodeIndex];
526 TxPacketSample lastPacket;
527 lastPacket.time = Simulator::Now();
528 lastPacket.packet = packet->Copy();
529 lastPacket.device = device;
530 lastPacket.to = destinationAddress;
531 last.lastTransmittedPackets.push_back(lastPacket);
532 while (last.lastTransmittedPackets.size() > captureOptions->numLastPackets)
533 {
534 last.lastTransmittedPackets.erase(last.lastTransmittedPackets.begin());
535 }
536 }
537
538 // ---- transmissions records
539
540 if (m_nodesOfInterest.find(nodeIndex) == m_nodesOfInterest.end())
541 {
542 // if the transmitting node is not "of interest", we still
543 // record the transmission if it is a packet of interest.
544 if (m_packetsOfInterest.find(packet->GetUid()) == m_packetsOfInterest.end())
545 {
546 NS_LOG_DEBUG("Packet " << packet->GetUid() << " is not of interest");
547 return;
548 }
549 }
550 else
551 {
552 // We will follow this packet throughout the network.
553 m_packetsOfInterest[packet->GetUid()] = Simulator::Now();
554 }
555
556 TxRecordValue record = {Simulator::Now(), node, false};
557 if (destinationAddress == device->GetBroadcast())
558 {
559 record.isBroadcast = true;
560 }
561
562 m_txRecords[TxRecordKey(device->GetChannel(), packet->GetUid())] = record;
563
564 PyVizPacketTag tag;
565 // packet->RemovePacketTag (tag);
566 tag.m_packetId = packet->GetUid();
567 packet->AddByteTag(tag);
568}
569
570void
571PyViz::TraceNetDevTxWifi(std::string context, Ptr<const Packet> packet)
572{
573 NS_LOG_FUNCTION(context << packet->GetUid() << *packet);
574
575 /*
576 * To DS From DS Address 1 Address 2 Address 3 Address 4
577 *----------------------------------------------------------------------
578 * 0 0 Destination Source BSSID N/A
579 * 0 1 Destination BSSID Source N/A
580 * 1 0 BSSID Source Destination N/A
581 * 1 1 Receiver Transmitter Destination Source
582 */
583 WifiMacHeader hdr;
584 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
585 Mac48Address destinationAddress;
586 if (hdr.IsToDs())
587 {
588 destinationAddress = hdr.GetAddr3();
589 }
590 else
591 {
592 destinationAddress = hdr.GetAddr1();
593 }
594 TraceNetDevTxCommon(context, packet, destinationAddress);
595}
596
597void
598PyViz::TraceNetDevTxCsma(std::string context, Ptr<const Packet> packet)
599{
600 EthernetHeader ethernetHeader;
601 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
602 TraceNetDevTxCommon(context, packet, ethernetHeader.GetDestination());
603}
604
605void
607{
608 TraceNetDevTxCommon(context, packet, Mac48Address());
609}
610
611// --------- RX device tracing -------------------
612
613void
614PyViz::TraceNetDevRxCommon(const std::string& context,
615 Ptr<const Packet> packet,
616 const Mac48Address& from)
617{
618 uint32_t uid;
619 PyVizPacketTag tag;
620 if (packet->FindFirstMatchingByteTag(tag))
621 {
622 uid = tag.m_packetId;
623 }
624 else
625 {
626 // NS_ASSERT (0);
627 NS_LOG_WARN("Packet has no byte tag");
628 uid = packet->GetUid();
629 }
630
631 NS_LOG_FUNCTION(context << uid);
632 std::vector<std::string> splitPath = PathSplit(context);
633 int nodeIndex = std::stoi(splitPath[1]);
634 int devIndex = std::stoi(splitPath[3]);
635
636 // ---- statistics
637 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
638 ++stats.receivedPackets;
639 stats.receivedBytes += packet->GetSize();
640
641 Ptr<Node> node = NodeList::GetNode(nodeIndex);
642 Ptr<NetDevice> device = node->GetDevice(devIndex);
643
644 // ---- "last packets"
645 const PacketCaptureOptions* captureOptions;
646 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
647 FilterPacket(packet, *captureOptions))
648 {
649 LastPacketsSample& last = m_lastPackets[nodeIndex];
650 RxPacketSample lastPacket;
651 lastPacket.time = Simulator::Now();
652 lastPacket.packet = packet->Copy();
653 lastPacket.device = device;
654 lastPacket.from = from;
655 last.lastReceivedPackets.push_back(lastPacket);
656 while (last.lastReceivedPackets.size() > captureOptions->numLastPackets)
657 {
658 last.lastReceivedPackets.erase(last.lastReceivedPackets.begin());
659 }
660 }
661
662 // ---- transmissions
663 if (m_packetsOfInterest.find(uid) == m_packetsOfInterest.end())
664 {
665 NS_LOG_DEBUG("RX Packet " << uid << " is not of interest");
666 return;
667 }
668
669 Ptr<Channel> channel = device->GetChannel();
670
671 auto recordIter = m_txRecords.find(TxRecordKey(channel, uid));
672
673 if (recordIter == m_txRecords.end())
674 {
675 NS_LOG_DEBUG("RX Packet " << uid << " was not transmitted?!");
676 return;
677 }
678
679 TxRecordValue& record = recordIter->second;
680
681 if (record.srcNode == node)
682 {
683 NS_LOG_WARN("Node " << node->GetId() << " receiving back the same packet (UID=" << uid
684 << ") it had previously transmitted, on the same channel!");
685 return;
686 }
687
688 TransmissionSampleKey key = {record.srcNode, node, channel};
689
690#ifdef NS3_LOG_ENABLE
691 NS_LOG_DEBUG("m_transmissionSamples begin:");
692 if (g_log.IsEnabled(ns3::LOG_DEBUG))
693 {
694 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
695 {
696 NS_LOG_DEBUG(iter->first.transmitter
697 << "/" << iter->first.transmitter->GetId() << ", " << iter->first.receiver
698 << "/" << iter->first.receiver->GetId() << ", " << iter->first.channel
699 << " => " << iter->second.bytes << " (@ " << &iter->second << ")");
700 }
701 }
702 NS_LOG_DEBUG("m_transmissionSamples end.");
703#endif
704
705 auto iter = m_transmissionSamples.find(key);
706
707 if (iter == m_transmissionSamples.end())
708 {
709 TransmissionSampleValue sample = {packet->GetSize()};
710 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
711 << key.receiver << "/" << key.receiver->GetId() << " channel "
712 << channel << ": " << packet->GetSize()
713 << " bytes more. => new sample with " << packet->GetSize()
714 << " bytes.");
715 m_transmissionSamples[key] = sample;
716 }
717 else
718 {
719 TransmissionSampleValue& sample = iter->second;
720 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
721 << key.receiver << "/" << key.receiver->GetId() << " channel "
722 << channel << ": " << packet->GetSize()
723 << " bytes more. => sample " << &sample << " with bytes "
724 << sample.bytes);
725
726 sample.bytes += packet->GetSize();
727 }
728}
729
730void
731PyViz::TraceNetDevRxWifi(std::string context, Ptr<const Packet> packet)
732{
733 NS_LOG_FUNCTION(context << packet->GetUid());
734
735 /*
736 * To DS From DS Address 1 Address 2 Address 3 Address 4
737 *----------------------------------------------------------------------
738 * 0 0 Destination Source BSSID N/A
739 * 0 1 Destination BSSID Source N/A
740 * 1 0 BSSID Source Destination N/A
741 * 1 1 Receiver Transmitter Destination Source
742 */
743 WifiMacHeader hdr;
744 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
745 Mac48Address sourceAddress;
746 if (!hdr.IsFromDs())
747 {
748 sourceAddress = hdr.GetAddr2();
749 }
750 else if (!hdr.IsToDs())
751 {
752 sourceAddress = hdr.GetAddr3();
753 }
754 else // if (hdr.IsToDs())
755 {
756 sourceAddress = hdr.GetAddr4();
757 }
758
759 TraceNetDevRxCommon(context, packet, sourceAddress);
760}
761
762void
763PyViz::TraceNetDevRxCsma(std::string context, Ptr<const Packet> packet)
764{
765 EthernetHeader ethernetHeader;
766 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
767 TraceNetDevRxCommon(context, packet, ethernetHeader.GetSource());
768}
769
770void
772{
773 TraceNetDevRxCommon(context, packet, Mac48Address());
774}
775
776void
778{
779 EthernetHeader ethernetHeader;
780 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
781
783
784 // Other packet types are already being received by
785 // TraceNetDevRxCsma; we don't want to receive them twice.
786 if (packetType == NetDevice::PACKET_OTHERHOST)
787 {
788 TraceNetDevRxCommon(context, packet, ethernetHeader.GetDestination());
789 }
790}
791
792void
793PyViz::TraceNetDevTxLte(std::string context,
794 Ptr<const Packet> packet,
795 const Mac48Address& destination)
796{
797 NS_LOG_FUNCTION(context);
798 TraceNetDevTxCommon(context, packet, destination);
799}
800
801void
802PyViz::TraceNetDevRxLte(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
803{
804 NS_LOG_FUNCTION(context);
805 TraceNetDevRxCommon(context, packet, source);
806}
807
808// ---------------------
809
812{
813 NS_LOG_DEBUG("GetTransmissionSamples BEGIN");
815 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
816 {
817 TransmissionSample sample;
818 sample.transmitter = iter->first.transmitter;
819 sample.receiver = iter->first.receiver;
820 sample.channel = iter->first.channel;
821 sample.bytes = iter->second.bytes;
822 NS_LOG_DEBUG("from " << sample.transmitter->GetId() << " to " << sample.receiver->GetId()
823 << ": " << sample.bytes << " bytes.");
824 list.push_back(sample);
825 }
826 NS_LOG_DEBUG("GetTransmissionSamples END");
827 return list;
828}
829
832{
833 NS_LOG_DEBUG("GetPacketDropSamples BEGIN");
835 for (auto iter = m_packetDrops.begin(); iter != m_packetDrops.end(); iter++)
836 {
837 PacketDropSample sample;
838 sample.transmitter = iter->first;
839 sample.bytes = iter->second;
840 NS_LOG_DEBUG("in " << sample.transmitter->GetId() << ": " << sample.bytes
841 << " bytes dropped.");
842 list.push_back(sample);
843 }
844 NS_LOG_DEBUG("GetPacketDropSamples END");
845 return list;
846}
847
848void
850{
852}
853
854std::vector<PyViz::NodeStatistics>
856{
857 std::vector<PyViz::NodeStatistics> retval;
858 for (auto iter = m_nodesStatistics.begin(); iter != m_nodesStatistics.end(); iter++)
859 {
860 NodeStatistics stats = {iter->first, iter->second};
861 retval.push_back(stats);
862 }
863 return retval;
864}
865
868{
869 NS_LOG_DEBUG("GetLastPackets: " << nodeId);
870
871 auto iter = m_lastPackets.find(nodeId);
872 if (iter != m_lastPackets.end())
873 {
874 return iter->second;
875 }
876 else
877 {
878 return LastPacketsSample();
879 }
880}
881
882namespace
883{
884/// Adapted from http://en.wikipedia.org/w/index.php?title=Line_clipping&oldid=248609574
886{
887 public:
888 /// Vector2 structure
889 struct Vector2
890 {
891 double x; ///< X
892 double y; ///< Y
893 };
894
895 Vector2 m_clipMin; ///< clip minimum
896 Vector2 m_clipMax; ///< clip maximum
897
898 /// Line structure
899 struct Line
900 {
901 Vector2 start; ///< start
902 Vector2 end; ///< end
903 double dx; ///< dX
904 double dy; ///< dY
905 };
906
907 private:
908 /**
909 * Clip start top function
910 * @param line the clip line
911 */
912 void ClipStartTop(Line& line) const
913 {
914 line.start.x += line.dx * (m_clipMin.y - line.start.y) / line.dy;
915 line.start.y = m_clipMin.y;
916 }
917
918 /**
919 * Clip start bottom function
920 * @param line the clip line
921 */
922 void ClipStartBottom(Line& line) const
923 {
924 line.start.x += line.dx * (m_clipMax.y - line.start.y) / line.dy;
925 line.start.y = m_clipMax.y;
926 }
927
928 /**
929 * Clip start right function
930 * @param line the clip line
931 */
932 void ClipStartRight(Line& line) const
933 {
934 line.start.y += line.dy * (m_clipMax.x - line.start.x) / line.dx;
935 line.start.x = m_clipMax.x;
936 }
937
938 /**
939 * Clip start left function
940 * @param line the clip line
941 */
942 void ClipStartLeft(Line& line) const
943 {
944 line.start.y += line.dy * (m_clipMin.x - line.start.x) / line.dx;
945 line.start.x = m_clipMin.x;
946 }
947
948 /**
949 * Clip end top function
950 * @param line the clip line
951 */
952 void ClipEndTop(Line& line) const
953 {
954 line.end.x += line.dx * (m_clipMin.y - line.end.y) / line.dy;
955 line.end.y = m_clipMin.y;
956 }
957
958 /**
959 * Clip end bottom function
960 * @param line the clip line
961 */
962 void ClipEndBottom(Line& line) const
963 {
964 line.end.x += line.dx * (m_clipMax.y - line.end.y) / line.dy;
965 line.end.y = m_clipMax.y;
966 }
967
968 /**
969 * Clip end right function
970 * @param line the clip line
971 */
972 void ClipEndRight(Line& line) const
973 {
974 line.end.y += line.dy * (m_clipMax.x - line.end.x) / line.dx;
975 line.end.x = m_clipMax.x;
976 }
977
978 /**
979 * Clip end left function
980 * @param line the clip line
981 */
982 void ClipEndLeft(Line& line) const
983 {
984 line.end.y += line.dy * (m_clipMin.x - line.end.x) / line.dx;
985 line.end.x = m_clipMin.x;
986 }
987
988 public:
989 /**
990 * Constructor
991 *
992 * @param clipMin minimum clipping vector
993 * @param clipMax maximum clipping vector
994 */
995 FastClipping(Vector2 clipMin, Vector2 clipMax)
996 : m_clipMin(clipMin),
997 m_clipMax(clipMax)
998 {
999 }
1000
1001 /**
1002 * Clip line function
1003 * @param line the clip line
1004 * @returns true if clipped
1005 */
1006 bool ClipLine(Line& line)
1007 {
1008 uint8_t lineCode = 0;
1009
1010 if (line.end.y < m_clipMin.y)
1011 {
1012 lineCode |= 8;
1013 }
1014 else if (line.end.y > m_clipMax.y)
1015 {
1016 lineCode |= 4;
1017 }
1018
1019 if (line.end.x > m_clipMax.x)
1020 {
1021 lineCode |= 2;
1022 }
1023 else if (line.end.x < m_clipMin.x)
1024 {
1025 lineCode |= 1;
1026 }
1027
1028 if (line.start.y < m_clipMin.y)
1029 {
1030 lineCode |= 128;
1031 }
1032 else if (line.start.y > m_clipMax.y)
1033 {
1034 lineCode |= 64;
1035 }
1036
1037 if (line.start.x > m_clipMax.x)
1038 {
1039 lineCode |= 32;
1040 }
1041 else if (line.start.x < m_clipMin.x)
1042 {
1043 lineCode |= 16;
1044 }
1045
1046 // 9 - 8 - A
1047 // | | |
1048 // 1 - 0 - 2
1049 // | | |
1050 // 5 - 4 - 6
1051 switch (lineCode)
1052 {
1053 // center
1054 case 0x00:
1055 return true;
1056
1057 case 0x01:
1058 ClipEndLeft(line);
1059 return true;
1060
1061 case 0x02:
1062 ClipEndRight(line);
1063 return true;
1064
1065 case 0x04:
1066 ClipEndBottom(line);
1067 return true;
1068
1069 case 0x05:
1070 ClipEndLeft(line);
1071 if (line.end.y > m_clipMax.y)
1072 {
1073 ClipEndBottom(line);
1074 }
1075 return true;
1076
1077 case 0x06:
1078 ClipEndRight(line);
1079 if (line.end.y > m_clipMax.y)
1080 {
1081 ClipEndBottom(line);
1082 }
1083 return true;
1084
1085 case 0x08:
1086 ClipEndTop(line);
1087 return true;
1088
1089 case 0x09:
1090 ClipEndLeft(line);
1091 if (line.end.y < m_clipMin.y)
1092 {
1093 ClipEndTop(line);
1094 }
1095 return true;
1096
1097 case 0x0A:
1098 ClipEndRight(line);
1099 if (line.end.y < m_clipMin.y)
1100 {
1101 ClipEndTop(line);
1102 }
1103 return true;
1104
1105 // left
1106 case 0x10:
1107 ClipStartLeft(line);
1108 return true;
1109
1110 case 0x12:
1111 ClipStartLeft(line);
1112 ClipEndRight(line);
1113 return true;
1114
1115 case 0x14:
1116 ClipStartLeft(line);
1117 if (line.start.y > m_clipMax.y)
1118 {
1119 return false;
1120 }
1121 ClipEndBottom(line);
1122 return true;
1123
1124 case 0x16:
1125 ClipStartLeft(line);
1126 if (line.start.y > m_clipMax.y)
1127 {
1128 return false;
1129 }
1130 ClipEndBottom(line);
1131 if (line.end.x > m_clipMax.x)
1132 {
1133 ClipEndRight(line);
1134 }
1135 return true;
1136
1137 case 0x18:
1138 ClipStartLeft(line);
1139 if (line.start.y < m_clipMin.y)
1140 {
1141 return false;
1142 }
1143 ClipEndTop(line);
1144 return true;
1145
1146 case 0x1A:
1147 ClipStartLeft(line);
1148 if (line.start.y < m_clipMin.y)
1149 {
1150 return false;
1151 }
1152 ClipEndTop(line);
1153 if (line.end.x > m_clipMax.x)
1154 {
1155 ClipEndRight(line);
1156 }
1157 return true;
1158
1159 // right
1160 case 0x20:
1161 ClipStartRight(line);
1162 return true;
1163
1164 case 0x21:
1165 ClipStartRight(line);
1166 ClipEndLeft(line);
1167 return true;
1168
1169 case 0x24:
1170 ClipStartRight(line);
1171 if (line.start.y > m_clipMax.y)
1172 {
1173 return false;
1174 }
1175 ClipEndBottom(line);
1176 return true;
1177
1178 case 0x25:
1179 ClipStartRight(line);
1180 if (line.start.y > m_clipMax.y)
1181 {
1182 return false;
1183 }
1184 ClipEndBottom(line);
1185 if (line.end.x < m_clipMin.x)
1186 {
1187 ClipEndLeft(line);
1188 }
1189 return true;
1190
1191 case 0x28:
1192 ClipStartRight(line);
1193 if (line.start.y < m_clipMin.y)
1194 {
1195 return false;
1196 }
1197 ClipEndTop(line);
1198 return true;
1199
1200 case 0x29:
1201 ClipStartRight(line);
1202 if (line.start.y < m_clipMin.y)
1203 {
1204 return false;
1205 }
1206 ClipEndTop(line);
1207 if (line.end.x < m_clipMin.x)
1208 {
1209 ClipEndLeft(line);
1210 }
1211 return true;
1212
1213 // bottom
1214 case 0x40:
1215 ClipStartBottom(line);
1216 return true;
1217
1218 case 0x41:
1219 ClipStartBottom(line);
1220 if (line.start.x < m_clipMin.x)
1221 {
1222 return false;
1223 }
1224 ClipEndLeft(line);
1225 if (line.end.y > m_clipMax.y)
1226 {
1227 ClipEndBottom(line);
1228 }
1229 return true;
1230
1231 case 0x42:
1232 ClipStartBottom(line);
1233 if (line.start.x > m_clipMax.x)
1234 {
1235 return false;
1236 }
1237 ClipEndRight(line);
1238 return true;
1239
1240 case 0x48:
1241 ClipStartBottom(line);
1242 ClipEndTop(line);
1243 return true;
1244
1245 case 0x49:
1246 ClipStartBottom(line);
1247 if (line.start.x < m_clipMin.x)
1248 {
1249 return false;
1250 }
1251 ClipEndLeft(line);
1252 if (line.end.y < m_clipMin.y)
1253 {
1254 ClipEndTop(line);
1255 }
1256 return true;
1257
1258 case 0x4A:
1259 ClipStartBottom(line);
1260 if (line.start.x > m_clipMax.x)
1261 {
1262 return false;
1263 }
1264 ClipEndRight(line);
1265 if (line.end.y < m_clipMin.y)
1266 {
1267 ClipEndTop(line);
1268 }
1269 return true;
1270
1271 // bottom-left
1272 case 0x50:
1273 ClipStartLeft(line);
1274 if (line.start.y > m_clipMax.y)
1275 {
1276 ClipStartBottom(line);
1277 }
1278 return true;
1279
1280 case 0x52:
1281 ClipEndRight(line);
1282 if (line.end.y > m_clipMax.y)
1283 {
1284 return false;
1285 }
1286 ClipStartBottom(line);
1287 if (line.start.x < m_clipMin.x)
1288 {
1289 ClipStartLeft(line);
1290 }
1291 return true;
1292
1293 case 0x58:
1294 ClipEndTop(line);
1295 if (line.end.x < m_clipMin.x)
1296 {
1297 return false;
1298 }
1299 ClipStartBottom(line);
1300 if (line.start.x < m_clipMin.x)
1301 {
1302 ClipStartLeft(line);
1303 }
1304 return true;
1305
1306 case 0x5A:
1307 ClipStartLeft(line);
1308 if (line.start.y < m_clipMin.y)
1309 {
1310 return false;
1311 }
1312 ClipEndRight(line);
1313 if (line.end.y > m_clipMax.y)
1314 {
1315 return false;
1316 }
1317 if (line.start.y > m_clipMax.y)
1318 {
1319 ClipStartBottom(line);
1320 }
1321 if (line.end.y < m_clipMin.y)
1322 {
1323 ClipEndTop(line);
1324 }
1325 return true;
1326
1327 // bottom-right
1328 case 0x60:
1329 ClipStartRight(line);
1330 if (line.start.y > m_clipMax.y)
1331 {
1332 ClipStartBottom(line);
1333 }
1334 return true;
1335
1336 case 0x61:
1337 ClipEndLeft(line);
1338 if (line.end.y > m_clipMax.y)
1339 {
1340 return false;
1341 }
1342 ClipStartBottom(line);
1343 if (line.start.x > m_clipMax.x)
1344 {
1345 ClipStartRight(line);
1346 }
1347 return true;
1348
1349 case 0x68:
1350 ClipEndTop(line);
1351 if (line.end.x > m_clipMax.x)
1352 {
1353 return false;
1354 }
1355 ClipStartRight(line);
1356 if (line.start.y > m_clipMax.y)
1357 {
1358 ClipStartBottom(line);
1359 }
1360 return true;
1361
1362 case 0x69:
1363 ClipEndLeft(line);
1364 if (line.end.y > m_clipMax.y)
1365 {
1366 return false;
1367 }
1368 ClipStartRight(line);
1369 if (line.start.y < m_clipMin.y)
1370 {
1371 return false;
1372 }
1373 if (line.end.y < m_clipMin.y)
1374 {
1375 ClipEndTop(line);
1376 }
1377 if (line.start.y > m_clipMax.y)
1378 {
1379 ClipStartBottom(line);
1380 }
1381 return true;
1382
1383 // top
1384 case 0x80:
1385 ClipStartTop(line);
1386 return true;
1387
1388 case 0x81:
1389 ClipStartTop(line);
1390 if (line.start.x < m_clipMin.x)
1391 {
1392 return false;
1393 }
1394 ClipEndLeft(line);
1395 return true;
1396
1397 case 0x82:
1398 ClipStartTop(line);
1399 if (line.start.x > m_clipMax.x)
1400 {
1401 return false;
1402 }
1403 ClipEndRight(line);
1404 return true;
1405
1406 case 0x84:
1407 ClipStartTop(line);
1408 ClipEndBottom(line);
1409 return true;
1410
1411 case 0x85:
1412 ClipStartTop(line);
1413 if (line.start.x < m_clipMin.x)
1414 {
1415 return false;
1416 }
1417 ClipEndLeft(line);
1418 if (line.end.y > m_clipMax.y)
1419 {
1420 ClipEndBottom(line);
1421 }
1422 return true;
1423
1424 case 0x86:
1425 ClipStartTop(line);
1426 if (line.start.x > m_clipMax.x)
1427 {
1428 return false;
1429 }
1430 ClipEndRight(line);
1431 if (line.end.y > m_clipMax.y)
1432 {
1433 ClipEndBottom(line);
1434 }
1435 return true;
1436
1437 // top-left
1438 case 0x90:
1439 ClipStartLeft(line);
1440 if (line.start.y < m_clipMin.y)
1441 {
1442 ClipStartTop(line);
1443 }
1444 return true;
1445
1446 case 0x92:
1447 ClipEndRight(line);
1448 if (line.end.y < m_clipMin.y)
1449 {
1450 return false;
1451 }
1452 ClipStartTop(line);
1453 if (line.start.x < m_clipMin.x)
1454 {
1455 ClipStartLeft(line);
1456 }
1457 return true;
1458
1459 case 0x94:
1460 ClipEndBottom(line);
1461 if (line.end.x < m_clipMin.x)
1462 {
1463 return false;
1464 }
1465 ClipStartLeft(line);
1466 if (line.start.y < m_clipMin.y)
1467 {
1468 ClipStartTop(line);
1469 }
1470 return true;
1471
1472 case 0x96:
1473 ClipStartLeft(line);
1474 if (line.start.y > m_clipMax.y)
1475 {
1476 return false;
1477 }
1478 ClipEndRight(line);
1479 if (line.end.y < m_clipMin.y)
1480 {
1481 return false;
1482 }
1483 if (line.start.y < m_clipMin.y)
1484 {
1485 ClipStartTop(line);
1486 }
1487 if (line.end.y > m_clipMax.y)
1488 {
1489 ClipEndBottom(line);
1490 }
1491 return true;
1492
1493 // top-right
1494 case 0xA0:
1495 ClipStartRight(line);
1496 if (line.start.y < m_clipMin.y)
1497 {
1498 ClipStartTop(line);
1499 }
1500 return true;
1501
1502 case 0xA1:
1503 ClipEndLeft(line);
1504 if (line.end.y < m_clipMin.y)
1505 {
1506 return false;
1507 }
1508 ClipStartTop(line);
1509 if (line.start.x > m_clipMax.x)
1510 {
1511 ClipStartRight(line);
1512 }
1513 return true;
1514
1515 case 0xA4:
1516 ClipEndBottom(line);
1517 if (line.end.x > m_clipMax.x)
1518 {
1519 return false;
1520 }
1521 ClipStartRight(line);
1522 if (line.start.y < m_clipMin.y)
1523 {
1524 ClipStartTop(line);
1525 }
1526 return true;
1527
1528 case 0xA5:
1529 ClipEndLeft(line);
1530 if (line.end.y < m_clipMin.y)
1531 {
1532 return false;
1533 }
1534 ClipStartRight(line);
1535 if (line.start.y > m_clipMax.y)
1536 {
1537 return false;
1538 }
1539 if (line.end.y > m_clipMax.y)
1540 {
1541 ClipEndBottom(line);
1542 }
1543 if (line.start.y < m_clipMin.y)
1544 {
1545 ClipStartTop(line);
1546 }
1547 return true;
1548 }
1549
1550 return false;
1551 }
1552};
1553} // namespace
1554
1555void
1556PyViz::LineClipping(double boundsX1,
1557 double boundsY1,
1558 double boundsX2,
1559 double boundsY2,
1560 double& lineX1,
1561 double& lineY1,
1562 double& lineX2,
1563 double& lineY2)
1564{
1565 FastClipping::Vector2 clipMin = {boundsX1, boundsY1};
1566 FastClipping::Vector2 clipMax = {boundsX2, boundsY2};
1567 FastClipping::Line line = {{lineX1, lineY1},
1568 {lineX2, lineY2},
1569 (lineX2 - lineX1),
1570 (lineY2 - lineY1)};
1571
1572 FastClipping clipper(clipMin, clipMax);
1573 clipper.ClipLine(line);
1574 lineX1 = line.start.x;
1575 lineX2 = line.end.x;
1576 lineY1 = line.start.y;
1577 lineY2 = line.end.y;
1578}
1579
1580} // 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.
an EUI-48 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:67
helper class to be used by the visualizer
Definition pyviz.h:41
void RegisterCsmaLikeDevice(const std::string &deviceTypeName)
Register CSMA like device function.
Definition pyviz.cc:166
void TraceNetDevRxCsma(std::string context, Ptr< const Packet > packet)
CSMA receive trace callback function.
Definition pyviz.cc:763
void SetPacketCaptureOptions(uint32_t nodeId, PacketCaptureOptions options)
Set packet capture options function.
Definition pyviz.cc:212
void TraceNetDevRxPointToPoint(std::string context, Ptr< const Packet > packet)
Point to point receive trace callback function.
Definition pyviz.cc:771
void RegisterDropTracePath(const std::string &tracePath)
Register drop trace path function.
Definition pyviz.cc:222
void RegisterWifiLikeDevice(const std::string &deviceTypeName)
Register WIFI like device function.
Definition pyviz.cc:184
std::map< uint32_t, PacketCaptureOptions > m_packetCaptureOptions
packet capture options
Definition pyviz.h:296
void TraceNetDevTxLte(std::string context, Ptr< const Packet > packet, const Mac48Address &destination)
LTE transmit trace callback function.
Definition pyviz.cc:793
std::map< uint32_t, LastPacketsSample > m_lastPackets
last packets
Definition pyviz.h:305
void SimulatorRunUntil(Time time)
Run simulation until a given (simulated, absolute) time is reached.
Definition pyviz.cc:272
bool m_stop
stop?
Definition pyviz.h:428
PacketDropSampleList GetPacketDropSamples() const
Get packet drop samples.
Definition pyviz.cc:831
void SetNodesOfInterest(std::set< uint32_t > nodes)
Set nodes of interest function.
Definition pyviz.cc:849
std::map< uint32_t, std::vector< NetDeviceStatistics > > m_nodesStatistics
node statistics
Definition pyviz.h:306
void TraceNetDevTxCsma(std::string context, Ptr< const Packet > packet)
CSMA transmit trace callback function.
Definition pyviz.cc:598
void TraceNetDevTxCommon(const std::string &context, Ptr< const Packet > packet, const Mac48Address &destination)
Network transmit common trace callback function.
Definition pyviz.cc:503
void DoPause(const std::string &message)
Do pause function.
Definition pyviz.cc:236
std::vector< NodeStatistics > GetNodesStatistics() const
Get node statistics.
Definition pyviz.cc:855
std::set< uint32_t > m_nodesOfInterest
list of node IDs whose transmissions will be monitored
Definition pyviz.h:303
void TraceNetDevPromiscRxCsma(std::string context, Ptr< const Packet > packet)
CSMA promiscuous receive function.
Definition pyviz.cc:777
static void Pause(const std::string &message)
Pause function.
Definition pyviz.cc:245
std::vector< std::string > m_pauseMessages
pause message
Definition pyviz.h:297
void TraceNetDevRxLte(std::string context, Ptr< const Packet > packet, const Mac48Address &source)
LTE receive trace callback function.
Definition pyviz.cc:802
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:488
void TraceNetDevRxCommon(const std::string &context, Ptr< const Packet > packet, const Mac48Address &source)
Network receive common trace callback function.
Definition pyviz.cc:614
TransmissionSampleList GetTransmissionSamples() const
Get transmission samples.
Definition pyviz.cc:811
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:1556
std::map< TransmissionSampleKey, TransmissionSampleValue > m_transmissionSamples
transmission samples
Definition pyviz.h:300
void TraceNetDevTxPointToPoint(std::string context, Ptr< const Packet > packet)
Point to point transmit trace callback function.
Definition pyviz.cc:606
void TraceNetDevRxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi receive trace callback function.
Definition pyviz.cc:731
NetDeviceStatistics & FindNetDeviceStatistics(int node, int interface)
Find net device statistics function.
Definition pyviz.cc:366
void TraceDevQueueDrop(std::string context, Ptr< const Packet > packet)
Queue drop trace callback function.
Definition pyviz.cc:441
std::map< TxRecordKey, TxRecordValue > m_txRecords
transmit records
Definition pyviz.h:298
std::vector< std::string > GetPauseMessages() const
Get pause message function.
Definition pyviz.cc:252
std::vector< PacketDropSample > PacketDropSampleList
PacketDropSampleList typedef.
Definition pyviz.h:109
static bool FilterPacket(Ptr< const Packet > packet, const PacketCaptureOptions &options)
Filter packet function.
Definition pyviz.cc:399
void CallbackStopSimulation()
Stop simulation callback function.
Definition pyviz.cc:261
void RegisterPointToPointLikeDevice(const std::string &deviceTypeName)
Register point to point like device function.
Definition pyviz.cc:198
std::map< Ptr< Node >, uint32_t > m_packetDrops
packet drops
Definition pyviz.h:301
LastPacketsSample GetLastPackets(uint32_t nodeId) const
Get last packets function.
Definition pyviz.cc:867
void TraceNetDevTxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi transmit trace callback function.
Definition pyviz.cc:571
bool GetPacketCaptureOptions(uint32_t nodeId, const PacketCaptureOptions **outOptions) const
Get packet capture options function.
Definition pyviz.cc:384
Time m_runUntil
run until time
Definition pyviz.h:429
std::map< uint32_t, Time > m_packetsOfInterest
list of packet UIDs that will be monitored
Definition pyviz.h:304
std::pair< Ptr< Channel >, uint32_t > TxRecordKey
TxRecordKey typedef.
Definition pyviz.h:257
std::vector< TransmissionSample > TransmissionSampleList
TransmissionSampleList typedef.
Definition pyviz.h:95
@ PACKET_CAPTURE_FILTER_HEADERS_OR
Definition pyviz.h:192
@ PACKET_CAPTURE_DISABLED
Definition pyviz.h:191
@ PACKET_CAPTURE_FILTER_HEADERS_AND
Definition pyviz.h:194
static Ptr< SimulatorImpl > GetImplementation()
Get the SimulatorImpl singleton.
Definition simulator.cc:362
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:578
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
@ NO_CONTEXT
Flag for events not associated with any particular context.
Definition simulator.h:199
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
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:872
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
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.
bool ClipLine(Line &line)
Clip line function.
Definition pyviz.cc:1006
void ClipEndRight(Line &line) const
Clip end right function.
Definition pyviz.cc:972
void ClipEndBottom(Line &line) const
Clip end bottom function.
Definition pyviz.cc:962
void ClipStartLeft(Line &line) const
Clip start left function.
Definition pyviz.cc:942
void ClipStartTop(Line &line) const
Clip start top function.
Definition pyviz.cc:912
void ClipStartBottom(Line &line) const
Clip start bottom function.
Definition pyviz.cc:922
void ClipStartRight(Line &line) const
Clip start right function.
Definition pyviz.cc:932
FastClipping(Vector2 clipMin, Vector2 clipMax)
Constructor.
Definition pyviz.cc:995
void ClipEndLeft(Line &line) const
Clip end left function.
Definition pyviz.cc:982
void ClipEndTop(Line &line) const
Clip end top function.
Definition pyviz.cc:952
#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
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:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:250
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585
@ LOG_DEBUG
Full voluminous logging to support debugging.
Definition log.h:101
static PyViz * g_visualizer
the visualizer
Definition pyviz.cc:53
#define list
static std::vector< std::string > PathSplit(std::string str)
Definition pyviz.cc:31
structure describing a packet metadata item
TypeId tid
TypeId of Header or Trailer.
LastPacketsSample structure.
Definition pyviz.h:138
std::vector< PacketSample > lastDroppedPackets
last dropped packets
Definition pyviz.h:141
std::vector< TxPacketSample > lastTransmittedPackets
last transmitted packets
Definition pyviz.h:140
std::vector< RxPacketSample > lastReceivedPackets
last received packets
Definition pyviz.h:139
NetDeviceStatistics structure.
Definition pyviz.h:159
uint64_t receivedBytes
received bytes
Definition pyviz.h:170
uint64_t transmittedBytes
transmitted bytes
Definition pyviz.h:169
uint32_t receivedPackets
received packets
Definition pyviz.h:172
uint32_t transmittedPackets
transmitted packets
Definition pyviz.h:171
NodeStatistics structure.
Definition pyviz.h:177
PacketCaptureOptions structure.
Definition pyviz.h:200
PacketCaptureMode mode
mode
Definition pyviz.h:203
uint32_t numLastPackets
num last packets
Definition pyviz.h:202
std::set< TypeId > headers
headers
Definition pyviz.h:201
PacketDropSample structure.
Definition pyviz.h:104
Ptr< Node > transmitter
transmitter
Definition pyviz.h:105
PacketSample structure.
Definition pyviz.h:118
Ptr< Packet > packet
packet
Definition pyviz.h:120
Ptr< NetDevice > device
device
Definition pyviz.h:121
RxPacketSample structure.
Definition pyviz.h:132
Mac48Address from
from
Definition pyviz.h:133
TransmissionSample structure.
Definition pyviz.h:87
Ptr< Node > transmitter
transmitter
Definition pyviz.h:88
Ptr< Channel > channel
channel
Definition pyviz.h:90
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:89
TransmissionSampleKey structure.
Definition pyviz.h:269
Ptr< Channel > channel
channel
Definition pyviz.h:286
bool operator==(const TransmissionSampleKey &other) const
Equality operator.
Definition pyviz.cc:358
bool operator<(const TransmissionSampleKey &other) const
Less than operator.
Definition pyviz.cc:336
Ptr< Node > transmitter
transmitter
Definition pyviz.h:284
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:285
TransmissionSampleValue structure.
Definition pyviz.h:291
TxPacketSample structure.
Definition pyviz.h:126
Mac48Address to
to
Definition pyviz.h:127
TxRecordValue structure.
Definition pyviz.h:261
Ptr< Node > srcNode
source node
Definition pyviz.h:263
bool isBroadcast
is broadcast?
Definition pyviz.h:264
PyVizPacketTag structure.
Definition pyviz.cc:59
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition pyviz.cc:86
void Deserialize(TagBuffer buf) override
Definition pyviz.cc:104
void Serialize(TagBuffer buf) const override
Definition pyviz.cc:98
static TypeId GetTypeId()
Get the type ID.
Definition pyviz.cc:76
uint32_t m_packetId
packet id
Definition pyviz.cc:68
void Print(std::ostream &os) const override
Definition pyviz.cc:110
uint32_t GetSerializedSize() const override
Definition pyviz.cc:92