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