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