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() && !hdr.IsFromDs())
605 {
606 destinationAddress = hdr.GetAddr3();
607 }
608 else if (!hdr.IsToDs() && hdr.IsFromDs())
609 {
610 destinationAddress = hdr.GetAddr1();
611 }
612 else if (!hdr.IsToDs() && !hdr.IsFromDs())
613 {
614 destinationAddress = hdr.GetAddr1();
615 }
616 else
617 {
618 destinationAddress = hdr.GetAddr3();
619 }
620 TraceNetDevTxCommon(context, packet, destinationAddress);
621}
622
623void
624PyViz::TraceNetDevTxCsma(std::string context, Ptr<const Packet> packet)
625{
626 EthernetHeader ethernetHeader;
627 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
628 TraceNetDevTxCommon(context, packet, ethernetHeader.GetDestination());
629}
630
631void
633{
634 TraceNetDevTxCommon(context, packet, Mac48Address());
635}
636
637// --------- RX device tracing -------------------
638
639void
640PyViz::TraceNetDevRxCommon(const std::string& context,
641 Ptr<const Packet> packet,
642 const Mac48Address& from)
643{
644 uint32_t uid;
645 PyVizPacketTag tag;
646 if (packet->FindFirstMatchingByteTag(tag))
647 {
648 uid = tag.m_packetId;
649 }
650 else
651 {
652 // NS_ASSERT (0);
653 NS_LOG_WARN("Packet has no byte tag; wimax link?");
654 uid = packet->GetUid();
655 }
656
657 NS_LOG_FUNCTION(context << uid);
658 std::vector<std::string> splitPath = PathSplit(context);
659 int nodeIndex = std::stoi(splitPath[1]);
660 int devIndex = std::stoi(splitPath[3]);
661
662 // ---- statistics
663 NetDeviceStatistics& stats = FindNetDeviceStatistics(nodeIndex, devIndex);
664 ++stats.receivedPackets;
665 stats.receivedBytes += packet->GetSize();
666
667 Ptr<Node> node = NodeList::GetNode(nodeIndex);
668 Ptr<NetDevice> device = node->GetDevice(devIndex);
669
670 // ---- "last packets"
671 const PacketCaptureOptions* captureOptions;
672 if (GetPacketCaptureOptions(nodeIndex, &captureOptions) &&
673 FilterPacket(packet, *captureOptions))
674 {
675 LastPacketsSample& last = m_lastPackets[nodeIndex];
676 RxPacketSample lastPacket;
677 lastPacket.time = Simulator::Now();
678 lastPacket.packet = packet->Copy();
679 lastPacket.device = device;
680 lastPacket.from = from;
681 last.lastReceivedPackets.push_back(lastPacket);
682 while (last.lastReceivedPackets.size() > captureOptions->numLastPackets)
683 {
684 last.lastReceivedPackets.erase(last.lastReceivedPackets.begin());
685 }
686 }
687
688 // ---- transmissions
689 if (m_packetsOfInterest.find(uid) == m_packetsOfInterest.end())
690 {
691 NS_LOG_DEBUG("RX Packet " << uid << " is not of interest");
692 return;
693 }
694
695 Ptr<Channel> channel = device->GetChannel();
696
697 auto recordIter = m_txRecords.find(TxRecordKey(channel, uid));
698
699 if (recordIter == m_txRecords.end())
700 {
701 NS_LOG_DEBUG("RX Packet " << uid << " was not transmitted?!");
702 return;
703 }
704
705 TxRecordValue& record = recordIter->second;
706
707 if (record.srcNode == node)
708 {
709 NS_LOG_WARN("Node " << node->GetId() << " receiving back the same packet (UID=" << uid
710 << ") it had previously transmitted, on the same channel!");
711 return;
712 }
713
714 TransmissionSampleKey key = {record.srcNode, node, channel};
715
716#ifdef NS3_LOG_ENABLE
717 NS_LOG_DEBUG("m_transmissionSamples begin:");
718 if (g_log.IsEnabled(ns3::LOG_DEBUG))
719 {
720 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
721 {
722 NS_LOG_DEBUG(iter->first.transmitter
723 << "/" << iter->first.transmitter->GetId() << ", " << iter->first.receiver
724 << "/" << iter->first.receiver->GetId() << ", " << iter->first.channel
725 << " => " << iter->second.bytes << " (@ " << &iter->second << ")");
726 }
727 }
728 NS_LOG_DEBUG("m_transmissionSamples end.");
729#endif
730
731 auto iter = m_transmissionSamples.find(key);
732
733 if (iter == m_transmissionSamples.end())
734 {
735 TransmissionSampleValue sample = {packet->GetSize()};
736 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
737 << key.receiver << "/" << key.receiver->GetId() << " channel "
738 << channel << ": " << packet->GetSize()
739 << " bytes more. => new sample with " << packet->GetSize()
740 << " bytes.");
741 m_transmissionSamples[key] = sample;
742 }
743 else
744 {
745 TransmissionSampleValue& sample = iter->second;
746 NS_LOG_DEBUG("RX: from " << key.transmitter << "/" << key.transmitter->GetId() << " to "
747 << key.receiver << "/" << key.receiver->GetId() << " channel "
748 << channel << ": " << packet->GetSize()
749 << " bytes more. => sample " << &sample << " with bytes "
750 << sample.bytes);
751
752 sample.bytes += packet->GetSize();
753 }
754}
755
756void
757PyViz::TraceNetDevRxWifi(std::string context, Ptr<const Packet> packet)
758{
759 NS_LOG_FUNCTION(context << packet->GetUid());
760
761 /*
762 * To DS From DS Address 1 Address 2 Address 3 Address 4
763 *----------------------------------------------------------------------
764 * 0 0 Destination Source BSSID N/A
765 * 0 1 Destination BSSID Source N/A
766 * 1 0 BSSID Source Destination N/A
767 * 1 1 Receiver Transmitter Destination Source
768 */
769 WifiMacHeader hdr;
770 NS_ABORT_IF(packet->PeekHeader(hdr) == 0);
771 Mac48Address sourceAddress;
772 if (hdr.IsToDs() && !hdr.IsFromDs())
773 {
774 sourceAddress = hdr.GetAddr2();
775 }
776 else if (!hdr.IsToDs() && hdr.IsFromDs())
777 {
778 sourceAddress = hdr.GetAddr3();
779 }
780 else if (!hdr.IsToDs() && !hdr.IsFromDs())
781 {
782 sourceAddress = hdr.GetAddr2();
783 }
784 else
785 {
786 sourceAddress = hdr.GetAddr4();
787 }
788
789 TraceNetDevRxCommon(context, packet, sourceAddress);
790}
791
792void
793PyViz::TraceNetDevRxCsma(std::string context, Ptr<const Packet> packet)
794{
795 EthernetHeader ethernetHeader;
796 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
797 TraceNetDevRxCommon(context, packet, ethernetHeader.GetSource());
798}
799
800void
802{
803 TraceNetDevRxCommon(context, packet, Mac48Address());
804}
805
806void
808{
809 EthernetHeader ethernetHeader;
810 NS_ABORT_IF(packet->PeekHeader(ethernetHeader) == 0);
811
813
814 // Other packet types are already being received by
815 // TraceNetDevRxCsma; we don't want to receive them twice.
816 if (packetType == NetDevice::PACKET_OTHERHOST)
817 {
818 TraceNetDevRxCommon(context, packet, ethernetHeader.GetDestination());
819 }
820}
821
822void
823PyViz::TraceNetDevTxWimax(std::string context,
824 Ptr<const Packet> packet,
825 const Mac48Address& destination)
826{
827 NS_LOG_FUNCTION(context);
828 TraceNetDevTxCommon(context, packet, destination);
829}
830
831void
832PyViz::TraceNetDevRxWimax(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
833{
834 NS_LOG_FUNCTION(context);
835 TraceNetDevRxCommon(context, packet, source);
836}
837
838void
839PyViz::TraceNetDevTxLte(std::string context,
840 Ptr<const Packet> packet,
841 const Mac48Address& destination)
842{
843 NS_LOG_FUNCTION(context);
844 TraceNetDevTxCommon(context, packet, destination);
845}
846
847void
848PyViz::TraceNetDevRxLte(std::string context, Ptr<const Packet> packet, const Mac48Address& source)
849{
850 NS_LOG_FUNCTION(context);
851 TraceNetDevRxCommon(context, packet, source);
852}
853
854// ---------------------
855
858{
859 NS_LOG_DEBUG("GetTransmissionSamples BEGIN");
861 for (auto iter = m_transmissionSamples.begin(); iter != m_transmissionSamples.end(); iter++)
862 {
863 TransmissionSample sample;
864 sample.transmitter = iter->first.transmitter;
865 sample.receiver = iter->first.receiver;
866 sample.channel = iter->first.channel;
867 sample.bytes = iter->second.bytes;
868 NS_LOG_DEBUG("from " << sample.transmitter->GetId() << " to " << sample.receiver->GetId()
869 << ": " << sample.bytes << " bytes.");
870 list.push_back(sample);
871 }
872 NS_LOG_DEBUG("GetTransmissionSamples END");
873 return list;
874}
875
878{
879 NS_LOG_DEBUG("GetPacketDropSamples BEGIN");
881 for (auto iter = m_packetDrops.begin(); iter != m_packetDrops.end(); iter++)
882 {
883 PacketDropSample sample;
884 sample.transmitter = iter->first;
885 sample.bytes = iter->second;
886 NS_LOG_DEBUG("in " << sample.transmitter->GetId() << ": " << sample.bytes
887 << " bytes dropped.");
888 list.push_back(sample);
889 }
890 NS_LOG_DEBUG("GetPacketDropSamples END");
891 return list;
892}
893
894void
896{
898}
899
900std::vector<PyViz::NodeStatistics>
902{
903 std::vector<PyViz::NodeStatistics> retval;
904 for (auto iter = m_nodesStatistics.begin(); iter != m_nodesStatistics.end(); iter++)
905 {
906 NodeStatistics stats = {iter->first, iter->second};
907 retval.push_back(stats);
908 }
909 return retval;
910}
911
914{
915 NS_LOG_DEBUG("GetLastPackets: " << nodeId);
916
917 auto iter = m_lastPackets.find(nodeId);
918 if (iter != m_lastPackets.end())
919 {
920 return iter->second;
921 }
922 else
923 {
924 return LastPacketsSample();
925 }
926}
927
928namespace
929{
930/// Adapted from http://en.wikipedia.org/w/index.php?title=Line_clipping&oldid=248609574
932{
933 public:
934 /// Vector2 structure
935 struct Vector2
936 {
937 double x; ///< X
938 double y; ///< Y
939 };
940
941 Vector2 m_clipMin; ///< clip minimum
942 Vector2 m_clipMax; ///< clip maximum
943
944 /// Line structure
945 struct Line
946 {
947 Vector2 start; ///< start
948 Vector2 end; ///< end
949 double dx; ///< dX
950 double dy; ///< dY
951 };
952
953 private:
954 /**
955 * Clip start top function
956 * \param line the clip line
957 */
958 void ClipStartTop(Line& line) const
959 {
960 line.start.x += line.dx * (m_clipMin.y - line.start.y) / line.dy;
961 line.start.y = m_clipMin.y;
962 }
963
964 /**
965 * Clip start bottom function
966 * \param line the clip line
967 */
968 void ClipStartBottom(Line& line) const
969 {
970 line.start.x += line.dx * (m_clipMax.y - line.start.y) / line.dy;
971 line.start.y = m_clipMax.y;
972 }
973
974 /**
975 * Clip start right function
976 * \param line the clip line
977 */
978 void ClipStartRight(Line& line) const
979 {
980 line.start.y += line.dy * (m_clipMax.x - line.start.x) / line.dx;
981 line.start.x = m_clipMax.x;
982 }
983
984 /**
985 * Clip start left function
986 * \param line the clip line
987 */
988 void ClipStartLeft(Line& line) const
989 {
990 line.start.y += line.dy * (m_clipMin.x - line.start.x) / line.dx;
991 line.start.x = m_clipMin.x;
992 }
993
994 /**
995 * Clip end top function
996 * \param line the clip line
997 */
998 void ClipEndTop(Line& line) const
999 {
1000 line.end.x += line.dx * (m_clipMin.y - line.end.y) / line.dy;
1001 line.end.y = m_clipMin.y;
1002 }
1003
1004 /**
1005 * Clip end bottom function
1006 * \param line the clip line
1007 */
1008 void ClipEndBottom(Line& line) const
1009 {
1010 line.end.x += line.dx * (m_clipMax.y - line.end.y) / line.dy;
1011 line.end.y = m_clipMax.y;
1012 }
1013
1014 /**
1015 * Clip end right function
1016 * \param line the clip line
1017 */
1018 void ClipEndRight(Line& line) const
1019 {
1020 line.end.y += line.dy * (m_clipMax.x - line.end.x) / line.dx;
1021 line.end.x = m_clipMax.x;
1022 }
1023
1024 /**
1025 * Clip end left function
1026 * \param line the clip line
1027 */
1028 void ClipEndLeft(Line& line) const
1029 {
1030 line.end.y += line.dy * (m_clipMin.x - line.end.x) / line.dx;
1031 line.end.x = m_clipMin.x;
1032 }
1033
1034 public:
1035 /**
1036 * Constructor
1037 *
1038 * \param clipMin minimum clipping vector
1039 * \param clipMax maximum clipping vector
1040 */
1041 FastClipping(Vector2 clipMin, Vector2 clipMax)
1042 : m_clipMin(clipMin),
1043 m_clipMax(clipMax)
1044 {
1045 }
1046
1047 /**
1048 * Clip line function
1049 * \param line the clip line
1050 * \returns true if clipped
1051 */
1052 bool ClipLine(Line& line)
1053 {
1054 uint8_t lineCode = 0;
1055
1056 if (line.end.y < m_clipMin.y)
1057 {
1058 lineCode |= 8;
1059 }
1060 else if (line.end.y > m_clipMax.y)
1061 {
1062 lineCode |= 4;
1063 }
1064
1065 if (line.end.x > m_clipMax.x)
1066 {
1067 lineCode |= 2;
1068 }
1069 else if (line.end.x < m_clipMin.x)
1070 {
1071 lineCode |= 1;
1072 }
1073
1074 if (line.start.y < m_clipMin.y)
1075 {
1076 lineCode |= 128;
1077 }
1078 else if (line.start.y > m_clipMax.y)
1079 {
1080 lineCode |= 64;
1081 }
1082
1083 if (line.start.x > m_clipMax.x)
1084 {
1085 lineCode |= 32;
1086 }
1087 else if (line.start.x < m_clipMin.x)
1088 {
1089 lineCode |= 16;
1090 }
1091
1092 // 9 - 8 - A
1093 // | | |
1094 // 1 - 0 - 2
1095 // | | |
1096 // 5 - 4 - 6
1097 switch (lineCode)
1098 {
1099 // center
1100 case 0x00:
1101 return true;
1102
1103 case 0x01:
1104 ClipEndLeft(line);
1105 return true;
1106
1107 case 0x02:
1108 ClipEndRight(line);
1109 return true;
1110
1111 case 0x04:
1112 ClipEndBottom(line);
1113 return true;
1114
1115 case 0x05:
1116 ClipEndLeft(line);
1117 if (line.end.y > m_clipMax.y)
1118 {
1119 ClipEndBottom(line);
1120 }
1121 return true;
1122
1123 case 0x06:
1124 ClipEndRight(line);
1125 if (line.end.y > m_clipMax.y)
1126 {
1127 ClipEndBottom(line);
1128 }
1129 return true;
1130
1131 case 0x08:
1132 ClipEndTop(line);
1133 return true;
1134
1135 case 0x09:
1136 ClipEndLeft(line);
1137 if (line.end.y < m_clipMin.y)
1138 {
1139 ClipEndTop(line);
1140 }
1141 return true;
1142
1143 case 0x0A:
1144 ClipEndRight(line);
1145 if (line.end.y < m_clipMin.y)
1146 {
1147 ClipEndTop(line);
1148 }
1149 return true;
1150
1151 // left
1152 case 0x10:
1153 ClipStartLeft(line);
1154 return true;
1155
1156 case 0x12:
1157 ClipStartLeft(line);
1158 ClipEndRight(line);
1159 return true;
1160
1161 case 0x14:
1162 ClipStartLeft(line);
1163 if (line.start.y > m_clipMax.y)
1164 {
1165 return false;
1166 }
1167 ClipEndBottom(line);
1168 return true;
1169
1170 case 0x16:
1171 ClipStartLeft(line);
1172 if (line.start.y > m_clipMax.y)
1173 {
1174 return false;
1175 }
1176 ClipEndBottom(line);
1177 if (line.end.x > m_clipMax.x)
1178 {
1179 ClipEndRight(line);
1180 }
1181 return true;
1182
1183 case 0x18:
1184 ClipStartLeft(line);
1185 if (line.start.y < m_clipMin.y)
1186 {
1187 return false;
1188 }
1189 ClipEndTop(line);
1190 return true;
1191
1192 case 0x1A:
1193 ClipStartLeft(line);
1194 if (line.start.y < m_clipMin.y)
1195 {
1196 return false;
1197 }
1198 ClipEndTop(line);
1199 if (line.end.x > m_clipMax.x)
1200 {
1201 ClipEndRight(line);
1202 }
1203 return true;
1204
1205 // right
1206 case 0x20:
1207 ClipStartRight(line);
1208 return true;
1209
1210 case 0x21:
1211 ClipStartRight(line);
1212 ClipEndLeft(line);
1213 return true;
1214
1215 case 0x24:
1216 ClipStartRight(line);
1217 if (line.start.y > m_clipMax.y)
1218 {
1219 return false;
1220 }
1221 ClipEndBottom(line);
1222 return true;
1223
1224 case 0x25:
1225 ClipStartRight(line);
1226 if (line.start.y > m_clipMax.y)
1227 {
1228 return false;
1229 }
1230 ClipEndBottom(line);
1231 if (line.end.x < m_clipMin.x)
1232 {
1233 ClipEndLeft(line);
1234 }
1235 return true;
1236
1237 case 0x28:
1238 ClipStartRight(line);
1239 if (line.start.y < m_clipMin.y)
1240 {
1241 return false;
1242 }
1243 ClipEndTop(line);
1244 return true;
1245
1246 case 0x29:
1247 ClipStartRight(line);
1248 if (line.start.y < m_clipMin.y)
1249 {
1250 return false;
1251 }
1252 ClipEndTop(line);
1253 if (line.end.x < m_clipMin.x)
1254 {
1255 ClipEndLeft(line);
1256 }
1257 return true;
1258
1259 // bottom
1260 case 0x40:
1261 ClipStartBottom(line);
1262 return true;
1263
1264 case 0x41:
1265 ClipStartBottom(line);
1266 if (line.start.x < m_clipMin.x)
1267 {
1268 return false;
1269 }
1270 ClipEndLeft(line);
1271 if (line.end.y > m_clipMax.y)
1272 {
1273 ClipEndBottom(line);
1274 }
1275 return true;
1276
1277 case 0x42:
1278 ClipStartBottom(line);
1279 if (line.start.x > m_clipMax.x)
1280 {
1281 return false;
1282 }
1283 ClipEndRight(line);
1284 return true;
1285
1286 case 0x48:
1287 ClipStartBottom(line);
1288 ClipEndTop(line);
1289 return true;
1290
1291 case 0x49:
1292 ClipStartBottom(line);
1293 if (line.start.x < m_clipMin.x)
1294 {
1295 return false;
1296 }
1297 ClipEndLeft(line);
1298 if (line.end.y < m_clipMin.y)
1299 {
1300 ClipEndTop(line);
1301 }
1302 return true;
1303
1304 case 0x4A:
1305 ClipStartBottom(line);
1306 if (line.start.x > m_clipMax.x)
1307 {
1308 return false;
1309 }
1310 ClipEndRight(line);
1311 if (line.end.y < m_clipMin.y)
1312 {
1313 ClipEndTop(line);
1314 }
1315 return true;
1316
1317 // bottom-left
1318 case 0x50:
1319 ClipStartLeft(line);
1320 if (line.start.y > m_clipMax.y)
1321 {
1322 ClipStartBottom(line);
1323 }
1324 return true;
1325
1326 case 0x52:
1327 ClipEndRight(line);
1328 if (line.end.y > m_clipMax.y)
1329 {
1330 return false;
1331 }
1332 ClipStartBottom(line);
1333 if (line.start.x < m_clipMin.x)
1334 {
1335 ClipStartLeft(line);
1336 }
1337 return true;
1338
1339 case 0x58:
1340 ClipEndTop(line);
1341 if (line.end.x < m_clipMin.x)
1342 {
1343 return false;
1344 }
1345 ClipStartBottom(line);
1346 if (line.start.x < m_clipMin.x)
1347 {
1348 ClipStartLeft(line);
1349 }
1350 return true;
1351
1352 case 0x5A:
1353 ClipStartLeft(line);
1354 if (line.start.y < m_clipMin.y)
1355 {
1356 return false;
1357 }
1358 ClipEndRight(line);
1359 if (line.end.y > m_clipMax.y)
1360 {
1361 return false;
1362 }
1363 if (line.start.y > m_clipMax.y)
1364 {
1365 ClipStartBottom(line);
1366 }
1367 if (line.end.y < m_clipMin.y)
1368 {
1369 ClipEndTop(line);
1370 }
1371 return true;
1372
1373 // bottom-right
1374 case 0x60:
1375 ClipStartRight(line);
1376 if (line.start.y > m_clipMax.y)
1377 {
1378 ClipStartBottom(line);
1379 }
1380 return true;
1381
1382 case 0x61:
1383 ClipEndLeft(line);
1384 if (line.end.y > m_clipMax.y)
1385 {
1386 return false;
1387 }
1388 ClipStartBottom(line);
1389 if (line.start.x > m_clipMax.x)
1390 {
1391 ClipStartRight(line);
1392 }
1393 return true;
1394
1395 case 0x68:
1396 ClipEndTop(line);
1397 if (line.end.x > m_clipMax.x)
1398 {
1399 return false;
1400 }
1401 ClipStartRight(line);
1402 if (line.start.y > m_clipMax.y)
1403 {
1404 ClipStartBottom(line);
1405 }
1406 return true;
1407
1408 case 0x69:
1409 ClipEndLeft(line);
1410 if (line.end.y > m_clipMax.y)
1411 {
1412 return false;
1413 }
1414 ClipStartRight(line);
1415 if (line.start.y < m_clipMin.y)
1416 {
1417 return false;
1418 }
1419 if (line.end.y < m_clipMin.y)
1420 {
1421 ClipEndTop(line);
1422 }
1423 if (line.start.y > m_clipMax.y)
1424 {
1425 ClipStartBottom(line);
1426 }
1427 return true;
1428
1429 // top
1430 case 0x80:
1431 ClipStartTop(line);
1432 return true;
1433
1434 case 0x81:
1435 ClipStartTop(line);
1436 if (line.start.x < m_clipMin.x)
1437 {
1438 return false;
1439 }
1440 ClipEndLeft(line);
1441 return true;
1442
1443 case 0x82:
1444 ClipStartTop(line);
1445 if (line.start.x > m_clipMax.x)
1446 {
1447 return false;
1448 }
1449 ClipEndRight(line);
1450 return true;
1451
1452 case 0x84:
1453 ClipStartTop(line);
1454 ClipEndBottom(line);
1455 return true;
1456
1457 case 0x85:
1458 ClipStartTop(line);
1459 if (line.start.x < m_clipMin.x)
1460 {
1461 return false;
1462 }
1463 ClipEndLeft(line);
1464 if (line.end.y > m_clipMax.y)
1465 {
1466 ClipEndBottom(line);
1467 }
1468 return true;
1469
1470 case 0x86:
1471 ClipStartTop(line);
1472 if (line.start.x > m_clipMax.x)
1473 {
1474 return false;
1475 }
1476 ClipEndRight(line);
1477 if (line.end.y > m_clipMax.y)
1478 {
1479 ClipEndBottom(line);
1480 }
1481 return true;
1482
1483 // top-left
1484 case 0x90:
1485 ClipStartLeft(line);
1486 if (line.start.y < m_clipMin.y)
1487 {
1488 ClipStartTop(line);
1489 }
1490 return true;
1491
1492 case 0x92:
1493 ClipEndRight(line);
1494 if (line.end.y < m_clipMin.y)
1495 {
1496 return false;
1497 }
1498 ClipStartTop(line);
1499 if (line.start.x < m_clipMin.x)
1500 {
1501 ClipStartLeft(line);
1502 }
1503 return true;
1504
1505 case 0x94:
1506 ClipEndBottom(line);
1507 if (line.end.x < m_clipMin.x)
1508 {
1509 return false;
1510 }
1511 ClipStartLeft(line);
1512 if (line.start.y < m_clipMin.y)
1513 {
1514 ClipStartTop(line);
1515 }
1516 return true;
1517
1518 case 0x96:
1519 ClipStartLeft(line);
1520 if (line.start.y > m_clipMax.y)
1521 {
1522 return false;
1523 }
1524 ClipEndRight(line);
1525 if (line.end.y < m_clipMin.y)
1526 {
1527 return false;
1528 }
1529 if (line.start.y < m_clipMin.y)
1530 {
1531 ClipStartTop(line);
1532 }
1533 if (line.end.y > m_clipMax.y)
1534 {
1535 ClipEndBottom(line);
1536 }
1537 return true;
1538
1539 // top-right
1540 case 0xA0:
1541 ClipStartRight(line);
1542 if (line.start.y < m_clipMin.y)
1543 {
1544 ClipStartTop(line);
1545 }
1546 return true;
1547
1548 case 0xA1:
1549 ClipEndLeft(line);
1550 if (line.end.y < m_clipMin.y)
1551 {
1552 return false;
1553 }
1554 ClipStartTop(line);
1555 if (line.start.x > m_clipMax.x)
1556 {
1557 ClipStartRight(line);
1558 }
1559 return true;
1560
1561 case 0xA4:
1562 ClipEndBottom(line);
1563 if (line.end.x > m_clipMax.x)
1564 {
1565 return false;
1566 }
1567 ClipStartRight(line);
1568 if (line.start.y < m_clipMin.y)
1569 {
1570 ClipStartTop(line);
1571 }
1572 return true;
1573
1574 case 0xA5:
1575 ClipEndLeft(line);
1576 if (line.end.y < m_clipMin.y)
1577 {
1578 return false;
1579 }
1580 ClipStartRight(line);
1581 if (line.start.y > m_clipMax.y)
1582 {
1583 return false;
1584 }
1585 if (line.end.y > m_clipMax.y)
1586 {
1587 ClipEndBottom(line);
1588 }
1589 if (line.start.y < m_clipMin.y)
1590 {
1591 ClipStartTop(line);
1592 }
1593 return true;
1594 }
1595
1596 return false;
1597 }
1598};
1599} // namespace
1600
1601void
1602PyViz::LineClipping(double boundsX1,
1603 double boundsY1,
1604 double boundsX2,
1605 double boundsY2,
1606 double& lineX1,
1607 double& lineY1,
1608 double& lineX2,
1609 double& lineY2)
1610{
1611 FastClipping::Vector2 clipMin = {boundsX1, boundsY1};
1612 FastClipping::Vector2 clipMax = {boundsX2, boundsY2};
1613 FastClipping::Line line = {{lineX1, lineY1},
1614 {lineX2, lineY2},
1615 (lineX2 - lineX1),
1616 (lineY2 - lineY1)};
1617
1618 FastClipping clipper(clipMin, clipMax);
1619 clipper.ClipLine(line);
1620 lineX1 = line.start.x;
1621 lineX2 = line.end.x;
1622 lineY1 = line.start.y;
1623 lineY2 = line.end.y;
1624}
1625
1626} // 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:793
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:801
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:839
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:877
void SetNodesOfInterest(std::set< uint32_t > nodes)
Set nodes of interest function.
Definition: pyviz.cc:895
~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:624
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:901
void TraceNetDevRxWimax(std::string context, Ptr< const Packet > packet, const Mac48Address &source)
WiMax transmit trace callback function.
Definition: pyviz.cc:832
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:807
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:848
void TraceNetDevTxWimax(std::string context, Ptr< const Packet > packet, const Mac48Address &destination)
WiMax transmit trace callback function.
Definition: pyviz.cc:823
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:640
TransmissionSampleList GetTransmissionSamples() const
Get transmission samples.
Definition: pyviz.cc:857
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:1602
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:632
void TraceNetDevRxWifi(std::string context, Ptr< const Packet > packet)
Wi-Fi receive trace callback function.
Definition: pyviz.cc:757
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:913
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:932
bool ClipLine(Line &line)
Clip line function.
Definition: pyviz.cc:1052
void ClipEndRight(Line &line) const
Clip end right function.
Definition: pyviz.cc:1018
void ClipEndBottom(Line &line) const
Clip end bottom function.
Definition: pyviz.cc:1008
void ClipStartLeft(Line &line) const
Clip start left function.
Definition: pyviz.cc:988
void ClipStartTop(Line &line) const
Clip start top function.
Definition: pyviz.cc:958
void ClipStartBottom(Line &line) const
Clip start bottom function.
Definition: pyviz.cc:968
void ClipStartRight(Line &line) const
Clip start right function.
Definition: pyviz.cc:978
FastClipping(Vector2 clipMin, Vector2 clipMax)
Constructor.
Definition: pyviz.cc:1041
void ClipEndLeft(Line &line) const
Clip end left function.
Definition: pyviz.cc:1028
void ClipEndTop(Line &line) const
Clip end top function.
Definition: pyviz.cc:998
#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:706
@ 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