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