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