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