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