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