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