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