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