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