A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
pyviz.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INESC Porto
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Gustavo Carneiro <gjc@inescporto.pt>
7 */
8
9#include "pyviz.h"
10
12
13#include "ns3/abort.h"
14#include "ns3/config.h"
15#include "ns3/ethernet-header.h"
16#include "ns3/log.h"
17#include "ns3/node-list.h"
18#include "ns3/ppp-header.h"
19#include "ns3/simulator.h"
20#include "ns3/wifi-mac-header.h"
21#include "ns3/wifi-net-device.h"
22
23#include <cstdlib>
24#include <sstream>
25
27
28#define NUM_LAST_PACKETS 10
29
30static std::vector<std::string>
31PathSplit(std::string str)
32{
33 std::vector<std::string> results;
34 size_t cutAt;
35 while ((cutAt = str.find_first_of('/')) != std::string::npos)
36 {
37 if (cutAt > 0)
38 {
39 results.push_back(str.substr(0, cutAt));
40 }
41 str = str.substr(cutAt + 1);
42 }
43 if (!str.empty())
44 {
45 results.push_back(str);
46 }
47 return results;
48}
49
50namespace ns3
51{
52
53static PyViz* g_visualizer = nullptr; ///< the visualizer
54
55/**
56 * PyVizPacketTag structure
57 */
58struct PyVizPacketTag : public Tag
59{
60 static TypeId GetTypeId();
61 TypeId GetInstanceTypeId() const override;
62 uint32_t GetSerializedSize() const override;
63 void Serialize(TagBuffer buf) const override;
64 void Deserialize(TagBuffer buf) override;
65 void Print(std::ostream& os) const override;
67
68 uint32_t m_packetId; ///< packet id
69};
70
71/**
72 * \brief Get the type ID.
73 * \return the object TypeId
74 */
77{
78 static TypeId tid = TypeId("ns3::PyVizPacketTag")
79 .SetParent<Tag>()
80 .SetGroupName("Visualizer")
81 .AddConstructor<PyVizPacketTag>();
82 return tid;
83}
84
87{
88 return GetTypeId();
89}
90
93{
94 return 4;
95}
96
97void
102
103void
108
109void
110PyVizPacketTag::Print(std::ostream& os) const
111{
112 os << "PacketId=" << m_packetId;
113}
114
119
121{
123 NS_ASSERT(g_visualizer == nullptr);
124 g_visualizer = this;
125
126 // WiFi
127 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
129
130 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
132
133 // CSMA
134 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacTx",
136
137 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
139
140 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacPromiscRx",
142
143 // Generic queue drop
144 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/TxQueue/Drop",
146 // IPv4 drop
147 Config::ConnectFailSafe("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
149
150 // Point-to-Point
151 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacTx",
153
154 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacRx",
156
157 // WiMax
158 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
160
161 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
163
164 // LTE
165 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
167
168 Config::ConnectFailSafe("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
170}
171
172void
173PyViz::RegisterCsmaLikeDevice(const std::string& deviceTypeName)
174{
175 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
176
177 std::ostringstream sstream;
178 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/MacTx";
180
181 sstream.str("");
182 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
184
185 sstream.str("");
186 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/PromiscRx";
188}
189
190void
191PyViz::RegisterWifiLikeDevice(const std::string& deviceTypeName)
192{
193 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
194
195 std::ostringstream sstream;
196 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Tx";
198
199 sstream.str("");
200 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
202}
203
204void
205PyViz::RegisterPointToPointLikeDevice(const std::string& deviceTypeName)
206{
207 TypeId::LookupByName(deviceTypeName); // this will assert if the type name is invalid
208
209 std::ostringstream sstream;
210 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/TxQueue/Dequeue";
212
213 sstream.str("");
214 sstream << "/NodeList/*/DeviceList/*/$" << deviceTypeName << "/Rx";
216}
217
218void
220{
221 NS_LOG_DEBUG(" SetPacketCaptureOptions "
222 << nodeId << " PacketCaptureOptions (headers size = " << options.headers.size()
223 << " mode = " << options.mode << " numLastPackets = " << options.numLastPackets
224 << ")");
225 m_packetCaptureOptions[nodeId] = options;
226}
227
228void
229PyViz::RegisterDropTracePath(const std::string& tracePath)
230{
232}
233
235{
237
238 NS_ASSERT(g_visualizer == this);
239 g_visualizer = nullptr;
240}
241
242void
243PyViz::DoPause(const std::string& message)
244{
245 m_pauseMessages.push_back(message);
246 m_stop = true;
248 << ": Have " << g_visualizer->m_pauseMessages.size() << " pause messages");
249}
250
251void
252PyViz::Pause(const std::string& message)
253{
255 g_visualizer->DoPause(message);
256}
257
258std::vector<std::string>
260{
262 << ": GetPauseMessages: have " << g_visualizer->m_pauseMessages.size()
263 << " pause messages");
264 return m_pauseMessages;
265}
266
267void
269{
271 if (m_runUntil <= Simulator::Now())
272 {
273 Simulator::Stop(Seconds(0)); // Stop right now
274 m_stop = true;
275 }
276}
277
278void
280{
281 NS_LOG_LOGIC("SimulatorRunUntil " << time << " (now is " << Simulator::Now() << ")");
282
283 m_pauseMessages.clear();
284 m_transmissionSamples.clear();
285 m_packetDrops.clear();
286
287 Time expirationTime = Simulator::Now() - Seconds(10);
288
289 // Clear very old transmission records
290 for (auto iter = m_txRecords.begin(); iter != m_txRecords.end();)
291 {
292 if (iter->second.time < expirationTime)
293 {
294 m_txRecords.erase(iter++);
295 }
296 else
297 {
298 iter++;
299 }
300 }
301
302 // Clear very old packets of interest
303 for (auto iter = m_packetsOfInterest.begin(); iter != m_packetsOfInterest.end();)
304 {
305 if (iter->second < expirationTime)
306 {
307 m_packetsOfInterest.erase(iter++);
308 }
309 else
310 {
311 iter++;
312 }
313 }
314
315 if (Simulator::Now() >= time)
316 {
317 return;
318 }
319 // Schedule a dummy callback function for the target time, to make
320 // sure we stop at the right time. Otherwise, simulations with few
321 // events just appear to "jump" big chunks of time.
322 NS_LOG_LOGIC("Schedule dummy callback to be called in " << (time - Simulator::Now()));
323 m_runUntil = time;
324 m_stop = false;
326 time - Simulator::Now(),
328 this);
329
332 if (visualImpl)
333 {
334 visualImpl->RunRealSimulator();
335 }
336 else
337 {
338 impl->Run();
339 }
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; wimax link?");
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::TraceNetDevTxWimax(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::TraceNetDevRxWimax(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
810{
811 NS_LOG_FUNCTION(context);
812 TraceNetDevRxCommon(context, packet, source);
813}
814
815void
816PyViz::TraceNetDevTxLte(std::string context,
817 Ptr<const Packet> packet,
818 const Mac48Address& destination)
819{
820 NS_LOG_FUNCTION(context);
821 TraceNetDevTxCommon(context, packet, destination);
822}
823
824void
825PyViz::TraceNetDevRxLte(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
826{
827 NS_LOG_FUNCTION(context);
828 TraceNetDevRxCommon(context, packet, source);
829}
830
831// ---------------------
832
835{
836 NS_LOG_DEBUG("GetTransmissionSamples BEGIN");
838 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
839 {
840 TransmissionSample sample;
841 sample.transmitter = iter->first.transmitter;
842 sample.receiver = iter->first.receiver;
843 sample.channel = iter->first.channel;
844 sample.bytes = iter->second.bytes;
845 NS_LOG_DEBUG("from " << sample.transmitter->GetId() << " to " << sample.receiver->GetId()
846 << ": " << sample.bytes << " bytes.");
847 list.push_back(sample);
848 }
849 NS_LOG_DEBUG("GetTransmissionSamples END");
850 return list;
851}
852
855{
856 NS_LOG_DEBUG("GetPacketDropSamples BEGIN");
858 for (auto iter = m_packetDrops.begin(); iter != m_packetDrops.end(); iter++)
859 {
860 PacketDropSample sample;
861 sample.transmitter = iter->first;
862 sample.bytes = iter->second;
863 NS_LOG_DEBUG("in " << sample.transmitter->GetId() << ": " << sample.bytes
864 << " bytes dropped.");
865 list.push_back(sample);
866 }
867 NS_LOG_DEBUG("GetPacketDropSamples END");
868 return list;
869}
870
871void
873{
875}
876
877std::vector<PyViz::NodeStatistics>
879{
880 std::vector<PyViz::NodeStatistics> retval;
881 for (auto iter = m_nodesStatistics.begin(); iter != m_nodesStatistics.end(); iter++)
882 {
883 NodeStatistics stats = {iter->first, iter->second};
884 retval.push_back(stats);
885 }
886 return retval;
887}
888
891{
892 NS_LOG_DEBUG("GetLastPackets: " << nodeId);
893
894 auto iter = m_lastPackets.find(nodeId);
895 if (iter != m_lastPackets.end())
896 {
897 return iter->second;
898 }
899 else
900 {
901 return LastPacketsSample();
902 }
903}
904
905namespace
906{
907/// Adapted from http://en.wikipedia.org/w/index.php?title=Line_clipping&oldid=248609574
909{
910 public:
911 /// Vector2 structure
912 struct Vector2
913 {
914 double x; ///< X
915 double y; ///< Y
916 };
917
918 Vector2 m_clipMin; ///< clip minimum
919 Vector2 m_clipMax; ///< clip maximum
920
921 /// Line structure
922 struct Line
923 {
924 Vector2 start; ///< start
925 Vector2 end; ///< end
926 double dx; ///< dX
927 double dy; ///< dY
928 };
929
930 private:
931 /**
932 * Clip start top function
933 * \param line the clip line
934 */
935 void ClipStartTop(Line& line) const
936 {
937 line.start.x += line.dx * (m_clipMin.y - line.start.y) / line.dy;
938 line.start.y = m_clipMin.y;
939 }
940
941 /**
942 * Clip start bottom function
943 * \param line the clip line
944 */
945 void ClipStartBottom(Line& line) const
946 {
947 line.start.x += line.dx * (m_clipMax.y - line.start.y) / line.dy;
948 line.start.y = m_clipMax.y;
949 }
950
951 /**
952 * Clip start right function
953 * \param line the clip line
954 */
955 void ClipStartRight(Line& line) const
956 {
957 line.start.y += line.dy * (m_clipMax.x - line.start.x) / line.dx;
958 line.start.x = m_clipMax.x;
959 }
960
961 /**
962 * Clip start left function
963 * \param line the clip line
964 */
965 void ClipStartLeft(Line& line) const
966 {
967 line.start.y += line.dy * (m_clipMin.x - line.start.x) / line.dx;
968 line.start.x = m_clipMin.x;
969 }
970
971 /**
972 * Clip end top function
973 * \param line the clip line
974 */
975 void ClipEndTop(Line& line) const
976 {
977 line.end.x += line.dx * (m_clipMin.y - line.end.y) / line.dy;
978 line.end.y = m_clipMin.y;
979 }
980
981 /**
982 * Clip end bottom function
983 * \param line the clip line
984 */
985 void ClipEndBottom(Line& line) const
986 {
987 line.end.x += line.dx * (m_clipMax.y - line.end.y) / line.dy;
988 line.end.y = m_clipMax.y;
989 }
990
991 /**
992 * Clip end right function
993 * \param line the clip line
994 */
995 void ClipEndRight(Line& line) const
996 {
997 line.end.y += line.dy * (m_clipMax.x - line.end.x) / line.dx;
998 line.end.x = m_clipMax.x;
999 }
1000
1001 /**
1002 * Clip end left function
1003 * \param line the clip line
1004 */
1005 void ClipEndLeft(Line& line) const
1006 {
1007 line.end.y += line.dy * (m_clipMin.x - line.end.x) / line.dx;
1008 line.end.x = m_clipMin.x;
1009 }
1010
1011 public:
1012 /**
1013 * Constructor
1014 *
1015 * \param clipMin minimum clipping vector
1016 * \param clipMax maximum clipping vector
1017 */
1018 FastClipping(Vector2 clipMin, Vector2 clipMax)
1019 : m_clipMin(clipMin),
1020 m_clipMax(clipMax)
1021 {
1022 }
1023
1024 /**
1025 * Clip line function
1026 * \param line the clip line
1027 * \returns true if clipped
1028 */
1029 bool ClipLine(Line& line)
1030 {
1031 uint8_t lineCode = 0;
1032
1033 if (line.end.y < m_clipMin.y)
1034 {
1035 lineCode |= 8;
1036 }
1037 else if (line.end.y > m_clipMax.y)
1038 {
1039 lineCode |= 4;
1040 }
1041
1042 if (line.end.x > m_clipMax.x)
1043 {
1044 lineCode |= 2;
1045 }
1046 else if (line.end.x < m_clipMin.x)
1047 {
1048 lineCode |= 1;
1049 }
1050
1051 if (line.start.y < m_clipMin.y)
1052 {
1053 lineCode |= 128;
1054 }
1055 else if (line.start.y > m_clipMax.y)
1056 {
1057 lineCode |= 64;
1058 }
1059
1060 if (line.start.x > m_clipMax.x)
1061 {
1062 lineCode |= 32;
1063 }
1064 else if (line.start.x < m_clipMin.x)
1065 {
1066 lineCode |= 16;
1067 }
1068
1069 // 9 - 8 - A
1070 // | | |
1071 // 1 - 0 - 2
1072 // | | |
1073 // 5 - 4 - 6
1074 switch (lineCode)
1075 {
1076 // center
1077 case 0x00:
1078 return true;
1079
1080 case 0x01:
1081 ClipEndLeft(line);
1082 return true;
1083
1084 case 0x02:
1085 ClipEndRight(line);
1086 return true;
1087
1088 case 0x04:
1089 ClipEndBottom(line);
1090 return true;
1091
1092 case 0x05:
1093 ClipEndLeft(line);
1094 if (line.end.y > m_clipMax.y)
1095 {
1096 ClipEndBottom(line);
1097 }
1098 return true;
1099
1100 case 0x06:
1101 ClipEndRight(line);
1102 if (line.end.y > m_clipMax.y)
1103 {
1104 ClipEndBottom(line);
1105 }
1106 return true;
1107
1108 case 0x08:
1109 ClipEndTop(line);
1110 return true;
1111
1112 case 0x09:
1113 ClipEndLeft(line);
1114 if (line.end.y < m_clipMin.y)
1115 {
1116 ClipEndTop(line);
1117 }
1118 return true;
1119
1120 case 0x0A:
1121 ClipEndRight(line);
1122 if (line.end.y < m_clipMin.y)
1123 {
1124 ClipEndTop(line);
1125 }
1126 return true;
1127
1128 // left
1129 case 0x10:
1130 ClipStartLeft(line);
1131 return true;
1132
1133 case 0x12:
1134 ClipStartLeft(line);
1135 ClipEndRight(line);
1136 return true;
1137
1138 case 0x14:
1139 ClipStartLeft(line);
1140 if (line.start.y > m_clipMax.y)
1141 {
1142 return false;
1143 }
1144 ClipEndBottom(line);
1145 return true;
1146
1147 case 0x16:
1148 ClipStartLeft(line);
1149 if (line.start.y > m_clipMax.y)
1150 {
1151 return false;
1152 }
1153 ClipEndBottom(line);
1154 if (line.end.x > m_clipMax.x)
1155 {
1156 ClipEndRight(line);
1157 }
1158 return true;
1159
1160 case 0x18:
1161 ClipStartLeft(line);
1162 if (line.start.y < m_clipMin.y)
1163 {
1164 return false;
1165 }
1166 ClipEndTop(line);
1167 return true;
1168
1169 case 0x1A:
1170 ClipStartLeft(line);
1171 if (line.start.y < m_clipMin.y)
1172 {
1173 return false;
1174 }
1175 ClipEndTop(line);
1176 if (line.end.x > m_clipMax.x)
1177 {
1178 ClipEndRight(line);
1179 }
1180 return true;
1181
1182 // right
1183 case 0x20:
1184 ClipStartRight(line);
1185 return true;
1186
1187 case 0x21:
1188 ClipStartRight(line);
1189 ClipEndLeft(line);
1190 return true;
1191
1192 case 0x24:
1193 ClipStartRight(line);
1194 if (line.start.y > m_clipMax.y)
1195 {
1196 return false;
1197 }
1198 ClipEndBottom(line);
1199 return true;
1200
1201 case 0x25:
1202 ClipStartRight(line);
1203 if (line.start.y > m_clipMax.y)
1204 {
1205 return false;
1206 }
1207 ClipEndBottom(line);
1208 if (line.end.x < m_clipMin.x)
1209 {
1210 ClipEndLeft(line);
1211 }
1212 return true;
1213
1214 case 0x28:
1215 ClipStartRight(line);
1216 if (line.start.y < m_clipMin.y)
1217 {
1218 return false;
1219 }
1220 ClipEndTop(line);
1221 return true;
1222
1223 case 0x29:
1224 ClipStartRight(line);
1225 if (line.start.y < m_clipMin.y)
1226 {
1227 return false;
1228 }
1229 ClipEndTop(line);
1230 if (line.end.x < m_clipMin.x)
1231 {
1232 ClipEndLeft(line);
1233 }
1234 return true;
1235
1236 // bottom
1237 case 0x40:
1238 ClipStartBottom(line);
1239 return true;
1240
1241 case 0x41:
1242 ClipStartBottom(line);
1243 if (line.start.x < m_clipMin.x)
1244 {
1245 return false;
1246 }
1247 ClipEndLeft(line);
1248 if (line.end.y > m_clipMax.y)
1249 {
1250 ClipEndBottom(line);
1251 }
1252 return true;
1253
1254 case 0x42:
1255 ClipStartBottom(line);
1256 if (line.start.x > m_clipMax.x)
1257 {
1258 return false;
1259 }
1260 ClipEndRight(line);
1261 return true;
1262
1263 case 0x48:
1264 ClipStartBottom(line);
1265 ClipEndTop(line);
1266 return true;
1267
1268 case 0x49:
1269 ClipStartBottom(line);
1270 if (line.start.x < m_clipMin.x)
1271 {
1272 return false;
1273 }
1274 ClipEndLeft(line);
1275 if (line.end.y < m_clipMin.y)
1276 {
1277 ClipEndTop(line);
1278 }
1279 return true;
1280
1281 case 0x4A:
1282 ClipStartBottom(line);
1283 if (line.start.x > m_clipMax.x)
1284 {
1285 return false;
1286 }
1287 ClipEndRight(line);
1288 if (line.end.y < m_clipMin.y)
1289 {
1290 ClipEndTop(line);
1291 }
1292 return true;
1293
1294 // bottom-left
1295 case 0x50:
1296 ClipStartLeft(line);
1297 if (line.start.y > m_clipMax.y)
1298 {
1299 ClipStartBottom(line);
1300 }
1301 return true;
1302
1303 case 0x52:
1304 ClipEndRight(line);
1305 if (line.end.y > m_clipMax.y)
1306 {
1307 return false;
1308 }
1309 ClipStartBottom(line);
1310 if (line.start.x < m_clipMin.x)
1311 {
1312 ClipStartLeft(line);
1313 }
1314 return true;
1315
1316 case 0x58:
1317 ClipEndTop(line);
1318 if (line.end.x < m_clipMin.x)
1319 {
1320 return false;
1321 }
1322 ClipStartBottom(line);
1323 if (line.start.x < m_clipMin.x)
1324 {
1325 ClipStartLeft(line);
1326 }
1327 return true;
1328
1329 case 0x5A:
1330 ClipStartLeft(line);
1331 if (line.start.y < m_clipMin.y)
1332 {
1333 return false;
1334 }
1335 ClipEndRight(line);
1336 if (line.end.y > m_clipMax.y)
1337 {
1338 return false;
1339 }
1340 if (line.start.y > m_clipMax.y)
1341 {
1342 ClipStartBottom(line);
1343 }
1344 if (line.end.y < m_clipMin.y)
1345 {
1346 ClipEndTop(line);
1347 }
1348 return true;
1349
1350 // bottom-right
1351 case 0x60:
1352 ClipStartRight(line);
1353 if (line.start.y > m_clipMax.y)
1354 {
1355 ClipStartBottom(line);
1356 }
1357 return true;
1358
1359 case 0x61:
1360 ClipEndLeft(line);
1361 if (line.end.y > m_clipMax.y)
1362 {
1363 return false;
1364 }
1365 ClipStartBottom(line);
1366 if (line.start.x > m_clipMax.x)
1367 {
1368 ClipStartRight(line);
1369 }
1370 return true;
1371
1372 case 0x68:
1373 ClipEndTop(line);
1374 if (line.end.x > m_clipMax.x)
1375 {
1376 return false;
1377 }
1378 ClipStartRight(line);
1379 if (line.start.y > m_clipMax.y)
1380 {
1381 ClipStartBottom(line);
1382 }
1383 return true;
1384
1385 case 0x69:
1386 ClipEndLeft(line);
1387 if (line.end.y > m_clipMax.y)
1388 {
1389 return false;
1390 }
1391 ClipStartRight(line);
1392 if (line.start.y < m_clipMin.y)
1393 {
1394 return false;
1395 }
1396 if (line.end.y < m_clipMin.y)
1397 {
1398 ClipEndTop(line);
1399 }
1400 if (line.start.y > m_clipMax.y)
1401 {
1402 ClipStartBottom(line);
1403 }
1404 return true;
1405
1406 // top
1407 case 0x80:
1408 ClipStartTop(line);
1409 return true;
1410
1411 case 0x81:
1412 ClipStartTop(line);
1413 if (line.start.x < m_clipMin.x)
1414 {
1415 return false;
1416 }
1417 ClipEndLeft(line);
1418 return true;
1419
1420 case 0x82:
1421 ClipStartTop(line);
1422 if (line.start.x > m_clipMax.x)
1423 {
1424 return false;
1425 }
1426 ClipEndRight(line);
1427 return true;
1428
1429 case 0x84:
1430 ClipStartTop(line);
1431 ClipEndBottom(line);
1432 return true;
1433
1434 case 0x85:
1435 ClipStartTop(line);
1436 if (line.start.x < m_clipMin.x)
1437 {
1438 return false;
1439 }
1440 ClipEndLeft(line);
1441 if (line.end.y > m_clipMax.y)
1442 {
1443 ClipEndBottom(line);
1444 }
1445 return true;
1446
1447 case 0x86:
1448 ClipStartTop(line);
1449 if (line.start.x > m_clipMax.x)
1450 {
1451 return false;
1452 }
1453 ClipEndRight(line);
1454 if (line.end.y > m_clipMax.y)
1455 {
1456 ClipEndBottom(line);
1457 }
1458 return true;
1459
1460 // top-left
1461 case 0x90:
1462 ClipStartLeft(line);
1463 if (line.start.y < m_clipMin.y)
1464 {
1465 ClipStartTop(line);
1466 }
1467 return true;
1468
1469 case 0x92:
1470 ClipEndRight(line);
1471 if (line.end.y < m_clipMin.y)
1472 {
1473 return false;
1474 }
1475 ClipStartTop(line);
1476 if (line.start.x < m_clipMin.x)
1477 {
1478 ClipStartLeft(line);
1479 }
1480 return true;
1481
1482 case 0x94:
1483 ClipEndBottom(line);
1484 if (line.end.x < m_clipMin.x)
1485 {
1486 return false;
1487 }
1488 ClipStartLeft(line);
1489 if (line.start.y < m_clipMin.y)
1490 {
1491 ClipStartTop(line);
1492 }
1493 return true;
1494
1495 case 0x96:
1496 ClipStartLeft(line);
1497 if (line.start.y > m_clipMax.y)
1498 {
1499 return false;
1500 }
1501 ClipEndRight(line);
1502 if (line.end.y < m_clipMin.y)
1503 {
1504 return false;
1505 }
1506 if (line.start.y < m_clipMin.y)
1507 {
1508 ClipStartTop(line);
1509 }
1510 if (line.end.y > m_clipMax.y)
1511 {
1512 ClipEndBottom(line);
1513 }
1514 return true;
1515
1516 // top-right
1517 case 0xA0:
1518 ClipStartRight(line);
1519 if (line.start.y < m_clipMin.y)
1520 {
1521 ClipStartTop(line);
1522 }
1523 return true;
1524
1525 case 0xA1:
1526 ClipEndLeft(line);
1527 if (line.end.y < m_clipMin.y)
1528 {
1529 return false;
1530 }
1531 ClipStartTop(line);
1532 if (line.start.x > m_clipMax.x)
1533 {
1534 ClipStartRight(line);
1535 }
1536 return true;
1537
1538 case 0xA4:
1539 ClipEndBottom(line);
1540 if (line.end.x > m_clipMax.x)
1541 {
1542 return false;
1543 }
1544 ClipStartRight(line);
1545 if (line.start.y < m_clipMin.y)
1546 {
1547 ClipStartTop(line);
1548 }
1549 return true;
1550
1551 case 0xA5:
1552 ClipEndLeft(line);
1553 if (line.end.y < m_clipMin.y)
1554 {
1555 return false;
1556 }
1557 ClipStartRight(line);
1558 if (line.start.y > m_clipMax.y)
1559 {
1560 return false;
1561 }
1562 if (line.end.y > m_clipMax.y)
1563 {
1564 ClipEndBottom(line);
1565 }
1566 if (line.start.y < m_clipMin.y)
1567 {
1568 ClipStartTop(line);
1569 }
1570 return true;
1571 }
1572
1573 return false;
1574 }
1575};
1576} // namespace
1577
1578void
1579PyViz::LineClipping(double boundsX1,
1580 double boundsY1,
1581 double boundsX2,
1582 double boundsY2,
1583 double& lineX1,
1584 double& lineY1,
1585 double& lineX2,
1586 double& lineY2)
1587{
1588 FastClipping::Vector2 clipMin = {boundsX1, boundsY1};
1589 FastClipping::Vector2 clipMax = {boundsX2, boundsY2};
1590 FastClipping::Line line = {{lineX1, lineY1},
1591 {lineX2, lineY2},
1592 (lineX2 - lineX1),
1593 (lineY2 - lineY1)};
1594
1595 FastClipping clipper(clipMin, clipMax);
1596 clipper.ClipLine(line);
1597 lineX1 = line.start.x;
1598 lineX2 = line.end.x;
1599 lineY1 = line.start.y;
1600 lineY2 = line.end.y;
1601}
1602
1603} // 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.
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:173
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:219
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:229
void RegisterWifiLikeDevice(const std::string &deviceTypeName)
Register WIFI like device function.
Definition pyviz.cc:191
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:816
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:279
bool m_stop
stop?
Definition pyviz.h:447
PacketDropSampleList GetPacketDropSamples() const
Get packet drop samples.
Definition pyviz.cc:854
void SetNodesOfInterest(std::set< uint32_t > nodes)
Set nodes of interest function.
Definition pyviz.cc:872
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:605
void TraceNetDevTxCommon(const std::string &context, Ptr< const Packet > packet, const Mac48Address &destination)
Network transmit common trace callback function.
Definition pyviz.cc:510
void DoPause(const std::string &message)
Do pause function.
Definition pyviz.cc:243
std::vector< NodeStatistics > GetNodesStatistics() const
Get node statistics.
Definition pyviz.cc:878
void TraceNetDevRxWimax(std::string context, Ptr< const Packet > packet, const Mac48Address &source)
WiMax transmit trace callback function.
Definition pyviz.cc:809
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:784
static void Pause(const std::string &message)
Pause function.
Definition pyviz.cc:252
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:825
void TraceNetDevTxWimax(std::string context, Ptr< const Packet > packet, const Mac48Address &destination)
WiMax transmit 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: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:834
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:1579
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: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:298
std::vector< std::string > GetPauseMessages() const
Get pause message function.
Definition pyviz.cc:259
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:406
void CallbackStopSimulation()
Stop simulation callback function.
Definition pyviz.cc:268
void RegisterPointToPointLikeDevice(const std::string &deviceTypeName)
Register point to point like device function.
Definition pyviz.cc:205
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:890
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:448
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:577
@ NO_CONTEXT
Flag for events not associated with any particular context.
Definition simulator.h:199
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
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:94
@ S
second
Definition nstime.h:105
a unique identifier for an interface.
Definition type-id.h:48
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.
Adapted from http://en.wikipedia.org/w/index.php?title=Line_clipping&oldid=248609574.
Definition pyviz.cc:909
bool ClipLine(Line &line)
Clip line function.
Definition pyviz.cc:1029
void ClipEndRight(Line &line) const
Clip end right function.
Definition pyviz.cc:995
void ClipEndBottom(Line &line) const
Clip end bottom function.
Definition pyviz.cc:985
void ClipStartLeft(Line &line) const
Clip start left function.
Definition pyviz.cc:965
void ClipStartTop(Line &line) const
Clip start top function.
Definition pyviz.cc:935
void ClipStartBottom(Line &line) const
Clip start bottom function.
Definition pyviz.cc:945
void ClipStartRight(Line &line) const
Clip start right function.
Definition pyviz.cc:955
FastClipping(Vector2 clipMin, Vector2 clipMax)
Constructor.
Definition pyviz.cc:1018
void ClipEndLeft(Line &line) const
Clip end left function.
Definition pyviz.cc:1005
void ClipEndTop(Line &line) const
Clip end top function.
Definition pyviz.cc:975
#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:967
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:977
#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:1308
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:580
@ LOG_DEBUG
Full voluminous logging to support debugging.
Definition log.h:101
static PyViz * g_visualizer
the visualizer
Definition pyviz.cc:53
#define list
static std::vector< std::string > PathSplit(std::string str)
Definition pyviz.cc:31
structure describing a packet metadata item
TypeId tid
TypeId of Header or Trailer.
LastPacketsSample structure.
Definition pyviz.h:138
std::vector< PacketSample > lastDroppedPackets
last dropped packets
Definition pyviz.h:141
std::vector< TxPacketSample > lastTransmittedPackets
last transmitted packets
Definition pyviz.h:140
std::vector< RxPacketSample > lastReceivedPackets
last received packets
Definition pyviz.h:139
NetDeviceStatistics structure.
Definition pyviz.h:159
uint64_t receivedBytes
received bytes
Definition pyviz.h:170
uint64_t transmittedBytes
transmitted bytes
Definition pyviz.h:169
uint32_t receivedPackets
received packets
Definition pyviz.h:172
uint32_t transmittedPackets
transmitted packets
Definition pyviz.h:171
NodeStatistics structure.
Definition pyviz.h:177
PacketCaptureOptions structure.
Definition pyviz.h:200
PacketCaptureMode mode
mode
Definition pyviz.h:203
uint32_t numLastPackets
num last packets
Definition pyviz.h:202
std::set< TypeId > headers
headers
Definition pyviz.h:201
PacketDropSample structure.
Definition pyviz.h:104
Ptr< Node > transmitter
transmitter
Definition pyviz.h:105
PacketSample structure.
Definition pyviz.h:118
Ptr< Packet > packet
packet
Definition pyviz.h:120
Ptr< NetDevice > device
device
Definition pyviz.h:121
RxPacketSample structure.
Definition pyviz.h:132
Mac48Address from
from
Definition pyviz.h:133
TransmissionSample structure.
Definition pyviz.h:87
Ptr< Node > transmitter
transmitter
Definition pyviz.h:88
Ptr< Channel > channel
channel
Definition pyviz.h:90
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:89
TransmissionSampleKey structure.
Definition pyviz.h:269
Ptr< Channel > channel
channel
Definition pyviz.h:286
bool operator==(const TransmissionSampleKey &other) const
Equality operator.
Definition pyviz.cc:365
bool operator<(const TransmissionSampleKey &other) const
Less than operator.
Definition pyviz.cc:343
Ptr< Node > transmitter
transmitter
Definition pyviz.h:284
Ptr< Node > receiver
NULL if broadcast.
Definition pyviz.h:285
TransmissionSampleValue structure.
Definition pyviz.h:291
TxPacketSample structure.
Definition pyviz.h:126
Mac48Address to
to
Definition pyviz.h:127
TxRecordValue structure.
Definition pyviz.h:261
Ptr< Node > srcNode
source node
Definition pyviz.h:263
bool isBroadcast
is broadcast?
Definition pyviz.h:264
PyVizPacketTag structure.
Definition pyviz.cc:59
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition pyviz.cc:86
void Deserialize(TagBuffer buf) override
Definition pyviz.cc:104
void Serialize(TagBuffer buf) const override
Definition pyviz.cc:98
static TypeId GetTypeId()
Get the type ID.
Definition pyviz.cc:76
uint32_t m_packetId
packet id
Definition pyviz.cc:68
void Print(std::ostream &os) const override
Definition pyviz.cc:110
uint32_t GetSerializedSize() const override
Definition pyviz.cc:92