satellite-stats-throughput-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 Magister Solutions
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: Budiarto Herman <budiarto.herman@magister.fi>
19  *
20  */
21 
23 
24 #include <ns3/application-packet-probe.h>
25 #include <ns3/application.h>
26 #include <ns3/boolean.h>
27 #include <ns3/callback.h>
28 #include <ns3/data-collection-object.h>
29 #include <ns3/distribution-collector.h>
30 #include <ns3/enum.h>
31 #include <ns3/inet-socket-address.h>
32 #include <ns3/interval-rate-collector.h>
33 #include <ns3/ipv4.h>
34 #include <ns3/log.h>
35 #include <ns3/mac48-address.h>
36 #include <ns3/magister-gnuplot-aggregator.h>
37 #include <ns3/multi-file-aggregator.h>
38 #include <ns3/net-device.h>
39 #include <ns3/node-container.h>
40 #include <ns3/packet.h>
41 #include <ns3/probe.h>
42 #include <ns3/satellite-helper.h>
43 #include <ns3/satellite-id-mapper.h>
44 #include <ns3/satellite-mac.h>
45 #include <ns3/satellite-net-device.h>
46 #include <ns3/satellite-orbiter-net-device.h>
47 #include <ns3/satellite-phy.h>
48 #include <ns3/satellite-topology.h>
49 #include <ns3/scalar-collector.h>
50 #include <ns3/singleton.h>
51 #include <ns3/string.h>
52 #include <ns3/unit-conversion-collector.h>
53 
54 #include <map>
55 #include <sstream>
56 #include <string>
57 #include <utility>
58 
59 NS_LOG_COMPONENT_DEFINE("SatStatsThroughputHelper");
60 
61 namespace ns3
62 {
63 
64 NS_OBJECT_ENSURE_REGISTERED(SatStatsThroughputHelper);
65 
67  : SatStatsHelper(satHelper),
68  m_averagingMode(false)
69 {
70  NS_LOG_FUNCTION(this << satHelper);
71 }
72 
74 {
75  NS_LOG_FUNCTION(this);
76 }
77 
78 TypeId // static
80 {
81  static TypeId tid =
82  TypeId("ns3::SatStatsThroughputHelper")
83  .SetParent<SatStatsHelper>()
84  .AddAttribute("AveragingMode",
85  "If true, all samples will be averaged before passed to aggregator. "
86  "Only affects histogram, PDF, and CDF output types.",
87  BooleanValue(false),
88  MakeBooleanAccessor(&SatStatsThroughputHelper::SetAveragingMode,
90  MakeBooleanChecker());
91  return tid;
92 }
93 
94 void
96 {
97  NS_LOG_FUNCTION(this << averagingMode);
98  m_averagingMode = averagingMode;
99 }
100 
101 bool
103 {
104  return m_averagingMode;
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION(this);
111 
112  switch (GetOutputType())
113  {
115  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
116  << " is not a valid output type for this statistics.");
117  break;
118 
120  // Setup aggregator.
121  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
122  "OutputFileName",
123  StringValue(GetOutputFileName()),
124  "MultiFileMode",
125  BooleanValue(false),
126  "EnableContextPrinting",
127  BooleanValue(true),
128  "GeneralHeading",
129  StringValue(GetIdentifierHeading("throughput_kbps")));
130 
131  // Setup second-level collectors.
132  m_terminalCollectors.SetType("ns3::ScalarCollector");
133  m_terminalCollectors.SetAttribute("InputDataType",
134  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
135  m_terminalCollectors.SetAttribute(
136  "OutputType",
137  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SECOND));
139  m_terminalCollectors.ConnectToAggregator("Output",
140  m_aggregator,
141  &MultiFileAggregator::Write1d);
142 
143  // Setup first-level collectors.
144  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
145  m_conversionCollectors.SetAttribute("ConversionType",
146  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
148  m_conversionCollectors.ConnectToCollector("Output",
150  &ScalarCollector::TraceSinkDouble);
151  break;
152  }
153 
155  // Setup aggregator.
156  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
157  "OutputFileName",
158  StringValue(GetOutputFileName()),
159  "GeneralHeading",
160  StringValue(GetTimeHeading("throughput_kbps")));
161 
162  // Setup second-level collectors.
163  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
164  m_terminalCollectors.SetAttribute("InputDataType",
165  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
167  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
168  m_aggregator,
169  &MultiFileAggregator::Write2d);
170  m_terminalCollectors.ConnectToAggregator("OutputString",
171  m_aggregator,
172  &MultiFileAggregator::AddContextHeading);
173 
174  // Setup first-level collectors.
175  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
176  m_conversionCollectors.SetAttribute("ConversionType",
177  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
179  m_conversionCollectors.ConnectToCollector("Output",
181  &IntervalRateCollector::TraceSinkDouble);
182  break;
183  }
184 
188  if (!m_averagingMode)
189  {
190  NS_FATAL_ERROR("This statistics require AveragingMode to be enabled");
191  }
192 
193  // Setup aggregator.
194  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
195  "OutputFileName",
196  StringValue(GetOutputFileName()),
197  "MultiFileMode",
198  BooleanValue(false),
199  "EnableContextPrinting",
200  BooleanValue(false),
201  "GeneralHeading",
202  StringValue(GetDistributionHeading("throughput_kbps")));
203  Ptr<MultiFileAggregator> fileAggregator = m_aggregator->GetObject<MultiFileAggregator>();
204  NS_ASSERT(fileAggregator != nullptr);
205 
206  // Setup the final-level collector.
207  m_averagingCollector = CreateObject<DistributionCollector>();
208  DistributionCollector::OutputType_t outputType =
209  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
211  {
212  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
213  }
215  {
216  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
217  }
218  m_averagingCollector->SetOutputType(outputType);
219  m_averagingCollector->SetName("0");
220  m_averagingCollector->TraceConnect(
221  "Output",
222  "0",
223  MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
224  m_averagingCollector->TraceConnect(
225  "OutputString",
226  "0",
227  MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
228  m_averagingCollector->TraceConnect(
229  "Warning",
230  "0",
231  MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
232 
233  // Setup second-level collectors.
234  m_terminalCollectors.SetType("ns3::ScalarCollector");
235  m_terminalCollectors.SetAttribute("InputDataType",
236  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
237  m_terminalCollectors.SetAttribute(
238  "OutputType",
239  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SECOND));
241  Callback<void, double> callback =
242  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
243  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
244  it != m_terminalCollectors.End();
245  ++it)
246  {
247  it->second->TraceConnectWithoutContext("Output", callback);
248  }
249 
250  // Setup first-level collectors.
251  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
252  m_conversionCollectors.SetAttribute("ConversionType",
253  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
255  m_conversionCollectors.ConnectToCollector("Output",
257  &ScalarCollector::TraceSinkDouble);
258  break;
259  }
260 
263  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
264  << " is not a valid output type for this statistics.");
265  break;
266 
268  // Setup aggregator.
269  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
270  "OutputPath",
271  StringValue(GetOutputPath()),
272  "OutputFileName",
273  StringValue(GetName()));
274  Ptr<MagisterGnuplotAggregator> plotAggregator =
275  m_aggregator->GetObject<MagisterGnuplotAggregator>();
276  NS_ASSERT(plotAggregator != nullptr);
277  // plot->SetTitle ("");
278  plotAggregator->SetLegend("Time (in seconds)",
279  "Received throughput (in kilobits per second)");
280  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
281 
282  // Setup second-level collectors.
283  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
284  m_terminalCollectors.SetAttribute("InputDataType",
285  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
287  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
288  it != m_terminalCollectors.End();
289  ++it)
290  {
291  const std::string context = it->second->GetName();
292  plotAggregator->Add2dDataset(context, context);
293  }
294  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
295  m_aggregator,
296  &MagisterGnuplotAggregator::Write2d);
297 
298  // Setup first-level collectors.
299  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
300  m_conversionCollectors.SetAttribute("ConversionType",
301  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
303  m_conversionCollectors.ConnectToCollector("Output",
305  &IntervalRateCollector::TraceSinkDouble);
306  break;
307  }
308 
312  if (!m_averagingMode)
313  {
314  NS_FATAL_ERROR("This statistics require AveragingMode to be enabled");
315  }
316 
317  // Setup aggregator.
318  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
319  "OutputPath",
320  StringValue(GetOutputPath()),
321  "OutputFileName",
322  StringValue(GetName()));
323  Ptr<MagisterGnuplotAggregator> plotAggregator =
324  m_aggregator->GetObject<MagisterGnuplotAggregator>();
325  NS_ASSERT(plotAggregator != nullptr);
326  // plot->SetTitle ("");
327  plotAggregator->SetLegend("Received throughput (in kilobits per second)", "Frequency");
328  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
329  plotAggregator->Add2dDataset(GetName(), GetName());
331 
332  // Setup the final-level collector.
333  m_averagingCollector = CreateObject<DistributionCollector>();
334  DistributionCollector::OutputType_t outputType =
335  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
337  {
338  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
339  }
341  {
342  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
343  }
344  m_averagingCollector->SetOutputType(outputType);
345  m_averagingCollector->SetName("0");
346  m_averagingCollector->TraceConnect(
347  "Output",
348  GetName(),
349  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
351 
352  // Setup second-level collectors.
353  m_terminalCollectors.SetType("ns3::ScalarCollector");
354  m_terminalCollectors.SetAttribute("InputDataType",
355  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
356  m_terminalCollectors.SetAttribute(
357  "OutputType",
358  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SECOND));
360  Callback<void, double> callback =
361  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
362  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
363  it != m_terminalCollectors.End();
364  ++it)
365  {
366  it->second->TraceConnectWithoutContext("Output", callback);
367  }
368 
369  // Setup first-level collectors.
370  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
371  m_conversionCollectors.SetAttribute("ConversionType",
372  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
374  m_conversionCollectors.ConnectToCollector("Output",
376  &ScalarCollector::TraceSinkDouble);
377  break;
378  }
379 
380  default:
381  NS_FATAL_ERROR("SatStatsThroughputHelper - Invalid output type");
382  break;
383  }
384 
385  // Setup probes and connect them to conversion collectors.
386  InstallProbes();
387 
388 } // end of `void DoInstall ();`
389 
390 void
392 {
393  NS_LOG_FUNCTION(this);
394 
395  // The method below is supposed to be implemented by the child class.
396  DoInstallProbes();
397 }
398 
399 void
400 SatStatsThroughputHelper::RxCallback(Ptr<const Packet> packet, const Address& from)
401 {
402  NS_LOG_FUNCTION(this << packet->GetSize() << from);
403 
404  if (from.IsInvalid())
405  {
406  NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
407  << " bytes)"
408  << " from statistics collection because of"
409  << " invalid sender address");
410  }
411  else
412  {
413  // Determine the identifier associated with the sender address.
414  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
415 
416  if (it == m_identifierMap.end())
417  {
418  NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
419  << " bytes)"
420  << " from statistics collection because of"
421  << " unknown sender address " << from);
422  }
423  else
424  {
425  // Find the first-level collector with the right identifier.
426  Ptr<DataCollectionObject> collector = m_conversionCollectors.Get(it->second);
427  NS_ASSERT_MSG(collector != nullptr,
428  "Unable to find collector with identifier " << it->second);
429  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
430  NS_ASSERT(c != nullptr);
431 
432  // Pass the sample to the collector.
433  c->TraceSinkUinteger32(0, packet->GetSize());
434  }
435  }
436 
437 } // end of `void RxCallback (Ptr<const Packet>, const Address);`
438 
439 // FORWARD LINK APPLICATION-LEVEL /////////////////////////////////////////////
440 
441 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdAppThroughputHelper);
442 
444  : SatStatsThroughputHelper(satHelper)
445 {
446  NS_LOG_FUNCTION(this << satHelper);
447 }
448 
450 {
451  NS_LOG_FUNCTION(this);
452 }
453 
454 TypeId // static
456 {
457  static TypeId tid =
458  TypeId("ns3::SatStatsFwdAppThroughputHelper").SetParent<SatStatsThroughputHelper>();
459  return tid;
460 }
461 
462 void
464 {
465  NS_LOG_FUNCTION(this);
466  NodeContainer utUsers = Singleton<SatTopology>::Get()->GetUtUserNodes();
467 
468  for (NodeContainer::Iterator it = utUsers.Begin(); it != utUsers.End(); ++it)
469  {
470  const int32_t utUserId = GetUtUserId(*it);
471  NS_ASSERT_MSG(utUserId > 0, "Node " << (*it)->GetId() << " is not a valid UT user");
472  const uint32_t identifier = GetIdentifierForUtUser(*it);
473 
474  for (uint32_t i = 0; i < (*it)->GetNApplications(); i++)
475  {
476  // Create the probe.
477  std::ostringstream probeName;
478  probeName << utUserId << "-" << i;
479  Ptr<ApplicationPacketProbe> probe = CreateObject<ApplicationPacketProbe>();
480  probe->SetName(probeName.str());
481 
482  // Connect the object to the probe.
483  if (probe->ConnectByObject("Rx", (*it)->GetApplication(i)))
484  {
485  // Connect the probe to the right collector.
486  if (m_conversionCollectors.ConnectWithProbe(
487  probe->GetObject<Probe>(),
488  "OutputBytes",
489  identifier,
490  &UnitConversionCollector::TraceSinkUinteger32))
491  {
492  NS_LOG_INFO(this << " created probe " << probeName.str()
493  << ", connected to collector " << identifier);
494  m_probes.insert(
495  std::make_pair(probe->GetObject<Probe>(), std::make_pair(*it, identifier)));
496  }
497  else
498  {
499  NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
500  << " to collector " << identifier);
501  }
502  }
503  else
504  {
505  /*
506  * We're being tolerant here by only logging a warning, because
507  * not every kind of Application is equipped with the expected
508  * Rx trace source.
509  */
510  NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
511  << " with node ID " << (*it)->GetId() << " application #" << i);
512  }
513 
514  } // end of `for (i = 0; i < (*it)->GetNApplications (); i++)`
515 
516  } // end of `for (it = utUsers.Begin(); it != utUsers.End (); ++it)`
517 
518 } // end of `void DoInstallProbes ();`
519 
520 void
522 {
523  NS_LOG_FUNCTION(this);
524 
525  std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
526 
527  for (it = m_probes.begin(); it != m_probes.end(); it++)
528  {
529  Ptr<Probe> probe = it->first;
530  Ptr<Node> node = it->second.first;
531  uint32_t identifier = it->second.second;
532  m_conversionCollectors.DisconnectWithProbe(probe->GetObject<Probe>(),
533  "OutputBytes",
534  identifier,
535  &UnitConversionCollector::TraceSinkUinteger32);
536 
537  identifier = GetIdentifierForUtUser(node);
538 
539  m_conversionCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
540  "OutputBytes",
541  identifier,
542  &UnitConversionCollector::TraceSinkUinteger32);
543 
544  it->second.second = identifier;
545  }
546 } // end of `void UpdateIdentifierOnProbes ();`
547 
548 // FORWARD FEEDER LINK DEVICE-LEVEL //////////////////////////////////////////////////
549 
550 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederDevThroughputHelper);
551 
553  Ptr<const SatHelper> satHelper)
554  : SatStatsThroughputHelper(satHelper)
555 {
556  NS_LOG_FUNCTION(this << satHelper);
557 }
558 
560 {
561  NS_LOG_FUNCTION(this);
562 }
563 
564 TypeId // static
566 {
567  static TypeId tid =
568  TypeId("ns3::SatStatsFwdFeederDevThroughputHelper").SetParent<SatStatsThroughputHelper>();
569  return tid;
570 }
571 
572 void
574 {
575  NS_LOG_FUNCTION(this);
576 
577  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
578  Callback<void, Ptr<const Packet>, const Address&> callback =
580 
581  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
582  {
583  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
584  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
585  NS_ASSERT(satOrbiterDev != nullptr);
586  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
587 
588  if (satOrbiterDev->TraceConnectWithoutContext("RxFeeder", callback))
589  {
590  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
591  << " device #" << satOrbiterDev->GetIfIndex());
592 
593  // Enable statistics-related tags and trace sources on the device.
594  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
595  }
596  else
597  {
598  NS_FATAL_ERROR("Error connecting to Rx trace source of SatNetDevice"
599  << " at node ID " << (*it)->GetId() << " device #"
600  << satOrbiterDev->GetIfIndex());
601  }
602  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
603 
604  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
605 
606  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
607  {
608  // Create a map of UT addresses and identifiers.
610 
611  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
612  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
613  NS_ASSERT(satDev != nullptr);
614 
615  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
616 
617  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
618 
619  // Enable statistics-related tags on the transmitting device.
620  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
621  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
622  {
623  NetDeviceContainer devs = GetGwSatNetDevice(*it);
624 
625  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
626  {
627  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
628  NS_ASSERT(satDev != nullptr);
629 
630  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
631  }
632  }
633 } // end of `void DoInstallProbes ();`
634 
635 // FORWARD USER LINK DEVICE-LEVEL //////////////////////////////////////////////////
636 
637 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserDevThroughputHelper);
638 
640  Ptr<const SatHelper> satHelper)
641  : SatStatsThroughputHelper(satHelper)
642 {
643  NS_LOG_FUNCTION(this << satHelper);
644 }
645 
647 {
648  NS_LOG_FUNCTION(this);
649 }
650 
651 TypeId // static
653 {
654  static TypeId tid =
655  TypeId("ns3::SatStatsFwdUserDevThroughputHelper").SetParent<SatStatsThroughputHelper>();
656  return tid;
657 }
658 
659 void
661 {
662  NS_LOG_FUNCTION(this);
663  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
664 
665  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
666  {
667  const int32_t utId = GetUtId(*it);
668  NS_ASSERT_MSG(utId > 0, "Node " << (*it)->GetId() << " is not a valid UT");
669  const uint32_t identifier = GetIdentifierForUt(*it);
670 
671  // Create the probe.
672  std::ostringstream probeName;
673  probeName << utId;
674  Ptr<ApplicationPacketProbe> probe = CreateObject<ApplicationPacketProbe>();
675  probe->SetName(probeName.str());
676 
677  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
678 
679  // Connect the object to the probe.
680  if (probe->ConnectByObject("Rx", dev))
681  {
682  // Connect the probe to the right collector.
683  if (m_conversionCollectors.ConnectWithProbe(
684  probe->GetObject<Probe>(),
685  "OutputBytes",
686  identifier,
687  &UnitConversionCollector::TraceSinkUinteger32))
688  {
689  NS_LOG_INFO(this << " created probe " << probeName.str()
690  << ", connected to collector " << identifier);
691  m_probes.insert(
692  std::make_pair(probe->GetObject<Probe>(), std::make_pair(*it, identifier)));
693 
694  // Enable statistics-related tags and trace sources on the device.
695  dev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
696  }
697  else
698  {
699  NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
700  << " to collector " << identifier);
701  }
702 
703  } // end of `if (probe->ConnectByObject ("Rx", dev))`
704  else
705  {
706  NS_FATAL_ERROR("Error connecting to Rx trace source of SatNetDevice"
707  << " at node ID " << (*it)->GetId() << " device #2");
708  }
709 
710  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
711 
712  // Enable statistics-related tags on the transmitting device.
713  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
714  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
715  {
716  NetDeviceContainer devs = GetGwSatNetDevice(*it);
717 
718  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
719  {
720  NS_ASSERT((*itDev)->GetObject<SatNetDevice>() != nullptr);
721  (*itDev)->SetAttribute("EnableStatisticsTags", BooleanValue(true));
722  }
723  }
724 
725 } // end of `void DoInstallProbes ();`
726 
727 void
729 {
730  NS_LOG_FUNCTION(this);
731 
732  std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
733 
734  for (it = m_probes.begin(); it != m_probes.end(); it++)
735  {
736  Ptr<Probe> probe = it->first;
737  Ptr<Node> node = it->second.first;
738  uint32_t identifier = it->second.second;
739  m_conversionCollectors.DisconnectWithProbe(probe->GetObject<Probe>(),
740  "OutputBytes",
741  identifier,
742  &UnitConversionCollector::TraceSinkUinteger32);
743 
744  identifier = GetIdentifierForUt(node);
745 
746  m_conversionCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
747  "OutputBytes",
748  identifier,
749  &UnitConversionCollector::TraceSinkUinteger32);
750 
751  it->second.second = identifier;
752  }
753 } // end of `void UpdateIdentifierOnProbes ();`
754 
755 // FORWARD FEEDER LINK MAC-LEVEL /////////////////////////////////////////////////////
756 
757 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederMacThroughputHelper);
758 
760  Ptr<const SatHelper> satHelper)
761  : SatStatsThroughputHelper(satHelper)
762 {
763  NS_LOG_FUNCTION(this << satHelper);
764 }
765 
767 {
768  NS_LOG_FUNCTION(this);
769 }
770 
771 TypeId // static
773 {
774  static TypeId tid =
775  TypeId("ns3::SatStatsFwdFeederMacThroughputHelper").SetParent<SatStatsThroughputHelper>();
776  return tid;
777 }
778 
779 void
781 {
782  NS_LOG_FUNCTION(this);
783 
784  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
785  Callback<void, Ptr<const Packet>, const Address&> callback =
787 
788  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
789  {
790  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
791  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
792  NS_ASSERT(satOrbiterDev != nullptr);
793  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
794  std::map<uint32_t, Ptr<SatMac>> satOrbiterFeederMacs = satOrbiterDev->GetAllFeederMac();
795  Ptr<SatMac> satMac;
796  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterFeederMacs.begin();
797  it2 != satOrbiterFeederMacs.end();
798  ++it2)
799  {
800  satMac = it2->second;
801  NS_ASSERT(satMac != nullptr);
802  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
803 
804  // Connect the object to the probe.
805  if (satMac->TraceConnectWithoutContext("Rx", callback))
806  {
807  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
808  << " device #" << satOrbiterDev->GetIfIndex());
809  }
810  else
811  {
812  NS_FATAL_ERROR("Error connecting to Rx trace source of SatMac"
813  << " at node ID " << (*it)->GetId() << " device #"
814  << satOrbiterDev->GetIfIndex());
815  }
816  }
817  std::map<uint32_t, Ptr<SatMac>> satOrbiterUserMacs = satOrbiterDev->GetUserMac();
818  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterUserMacs.begin();
819  it2 != satOrbiterUserMacs.end();
820  ++it2)
821  {
822  satMac = it2->second;
823  NS_ASSERT(satMac != nullptr);
824  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
825  }
826  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
827 
828  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
829 
830  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
831  {
832  // Create a map of UT addresses and identifiers.
834 
835  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
836  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
837  NS_ASSERT(satDev != nullptr);
838  Ptr<SatMac> satMac = satDev->GetMac();
839  NS_ASSERT(satMac != nullptr);
840 
841  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
842  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
843 
844  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
845 
846  // Enable statistics-related tags on the transmitting device.
847  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
848  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
849  {
850  NetDeviceContainer devs = GetGwSatNetDevice(*it);
851 
852  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
853  {
854  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
855  NS_ASSERT(satDev != nullptr);
856  Ptr<SatMac> satMac = satDev->GetMac();
857  NS_ASSERT(satMac != nullptr);
858 
859  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
860  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
861  }
862  }
863 
864 } // end of `void DoInstallProbes ();`
865 
866 // FORWARD USER LINK MAC-LEVEL /////////////////////////////////////////////////////
867 
868 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserMacThroughputHelper);
869 
871  Ptr<const SatHelper> satHelper)
872  : SatStatsThroughputHelper(satHelper)
873 {
874  NS_LOG_FUNCTION(this << satHelper);
875 }
876 
878 {
879  NS_LOG_FUNCTION(this);
880 }
881 
882 TypeId // static
884 {
885  static TypeId tid =
886  TypeId("ns3::SatStatsFwdUserMacThroughputHelper").SetParent<SatStatsThroughputHelper>();
887  return tid;
888 }
889 
890 void
892 {
893  NS_LOG_FUNCTION(this);
894 
895  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
896 
897  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
898  {
899  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
900  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
901  NS_ASSERT(satOrbiterDev != nullptr);
902  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
903  std::map<uint32_t, Ptr<SatMac>> satOrbiterFeederMacs = satOrbiterDev->GetAllFeederMac();
904  Ptr<SatMac> satMac;
905  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterFeederMacs.begin();
906  it2 != satOrbiterFeederMacs.end();
907  ++it2)
908  {
909  satMac = it2->second;
910  NS_ASSERT(satMac != nullptr);
911  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
912  }
913  std::map<uint32_t, Ptr<SatMac>> satOrbiterUserMacs = satOrbiterDev->GetUserMac();
914  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterUserMacs.begin();
915  it2 != satOrbiterUserMacs.end();
916  ++it2)
917  {
918  satMac = it2->second;
919  NS_ASSERT(satMac != nullptr);
920  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
921  }
922  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
923 
924  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
925 
926  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
927  {
928  const int32_t utId = GetUtId(*it);
929  NS_ASSERT_MSG(utId > 0, "Node " << (*it)->GetId() << " is not a valid UT");
930  const uint32_t identifier = GetIdentifierForUt(*it);
931 
932  // Create the probe.
933  std::ostringstream probeName;
934  probeName << utId;
935  Ptr<ApplicationPacketProbe> probe = CreateObject<ApplicationPacketProbe>();
936  probe->SetName(probeName.str());
937 
938  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
939  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
940  NS_ASSERT(satDev != nullptr);
941  Ptr<SatMac> satMac = satDev->GetMac();
942  NS_ASSERT(satMac != nullptr);
943 
944  // Connect the object to the probe.
945  if (probe->ConnectByObject("Rx", satMac))
946  {
947  // Connect the probe to the right collector.
948  if (m_conversionCollectors.ConnectWithProbe(
949  probe->GetObject<Probe>(),
950  "OutputBytes",
951  identifier,
952  &UnitConversionCollector::TraceSinkUinteger32))
953  {
954  m_probes.insert(
955  std::make_pair(probe->GetObject<Probe>(), std::make_pair(*it, identifier)));
956 
957  // Enable statistics-related tags and trace sources on the device.
958  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
959  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
960  }
961  else
962  {
963  NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
964  << " to collector " << identifier);
965  }
966  }
967  else
968  {
969  NS_FATAL_ERROR("Error connecting to Rx trace source of SatMac"
970  << " at node ID " << (*it)->GetId() << " device #2");
971  }
972  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
973 
974  // Enable statistics-related tags on the transmitting device.
975  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
976  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
977  {
978  NetDeviceContainer devs = GetGwSatNetDevice(*it);
979 
980  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
981  {
982  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
983  NS_ASSERT(satDev != nullptr);
984  Ptr<SatMac> satMac = satDev->GetMac();
985  NS_ASSERT(satMac != nullptr);
986 
987  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
988  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
989  }
990  }
991 
992 } // end of `void DoInstallProbes ();`
993 
994 void
996 {
997  NS_LOG_FUNCTION(this);
998 
999  std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
1000 
1001  for (it = m_probes.begin(); it != m_probes.end(); it++)
1002  {
1003  Ptr<Probe> probe = it->first;
1004  Ptr<Node> node = it->second.first;
1005  uint32_t identifier = it->second.second;
1006  m_conversionCollectors.DisconnectWithProbe(probe->GetObject<Probe>(),
1007  "OutputBytes",
1008  identifier,
1009  &UnitConversionCollector::TraceSinkUinteger32);
1010 
1011  identifier = GetIdentifierForUt(node);
1012 
1013  m_conversionCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
1014  "OutputBytes",
1015  identifier,
1016  &UnitConversionCollector::TraceSinkUinteger32);
1017 
1018  it->second.second = identifier;
1019  }
1020 } // end of `void UpdateIdentifierOnProbes ();`
1021 
1022 // FORWARD FEEDER LINK PHY-LEVEL /////////////////////////////////////////////////////
1023 
1024 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederPhyThroughputHelper);
1025 
1027  Ptr<const SatHelper> satHelper)
1028  : SatStatsThroughputHelper(satHelper)
1029 {
1030  NS_LOG_FUNCTION(this << satHelper);
1031 }
1032 
1034 {
1035  NS_LOG_FUNCTION(this);
1036 }
1037 
1038 TypeId // static
1040 {
1041  static TypeId tid =
1042  TypeId("ns3::SatStatsFwdFeederPhyThroughputHelper").SetParent<SatStatsThroughputHelper>();
1043  return tid;
1044 }
1045 
1046 void
1048 {
1049  NS_LOG_FUNCTION(this);
1050 
1051  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1052  Callback<void, Ptr<const Packet>, const Address&> callback =
1054 
1055  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1056  {
1057  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1058  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1059  NS_ASSERT(satOrbiterDev != nullptr);
1060  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1061  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
1062  Ptr<SatPhy> satPhy;
1063  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
1064  it2 != satOrbiterFeederPhys.end();
1065  ++it2)
1066  {
1067  satPhy = it2->second;
1068  NS_ASSERT(satPhy != nullptr);
1069  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1070 
1071  // Connect the object to the probe.
1072  if (satPhy->TraceConnectWithoutContext("Rx", callback))
1073  {
1074  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1075  << " device #" << satOrbiterDev->GetIfIndex());
1076 
1077  // Enable statistics-related tags and trace sources on the device.
1078  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1079  }
1080  else
1081  {
1082  NS_FATAL_ERROR("Error connecting to Rx trace source of SatPhy"
1083  << " at node ID " << (*it)->GetId() << " device #"
1084  << satOrbiterDev->GetIfIndex());
1085  }
1086  }
1087  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
1088  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
1089  it2 != satOrbiterUserPhys.end();
1090  ++it2)
1091  {
1092  satPhy = it2->second;
1093  NS_ASSERT(satPhy != nullptr);
1094  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1095  }
1096  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
1097 
1098  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1099 
1100  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1101  {
1102  // Create a map of UT addresses and identifiers.
1104 
1105  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1106  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
1107  NS_ASSERT(satDev != nullptr);
1108  Ptr<SatPhy> satPhy = satDev->GetPhy();
1109  NS_ASSERT(satPhy != nullptr);
1110 
1111  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1112  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1113 
1114  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
1115 
1116  // Enable statistics-related tags on the transmitting device.
1117  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1118  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1119  {
1120  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1121 
1122  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1123  {
1124  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
1125  NS_ASSERT(satDev != nullptr);
1126  Ptr<SatPhy> satPhy = satDev->GetPhy();
1127  NS_ASSERT(satPhy != nullptr);
1128 
1129  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1130  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1131  }
1132  }
1133 
1134 } // end of `void DoInstallProbes ();`
1135 
1136 // FORWARD USER LINK PHY-LEVEL /////////////////////////////////////////////////////
1137 
1138 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserPhyThroughputHelper);
1139 
1141  Ptr<const SatHelper> satHelper)
1142  : SatStatsThroughputHelper(satHelper)
1143 {
1144  NS_LOG_FUNCTION(this << satHelper);
1145 }
1146 
1148 {
1149  NS_LOG_FUNCTION(this);
1150 }
1151 
1152 TypeId // static
1154 {
1155  static TypeId tid =
1156  TypeId("ns3::SatStatsFwdUserPhyThroughputHelper").SetParent<SatStatsThroughputHelper>();
1157  return tid;
1158 }
1159 
1160 void
1162 {
1163  NS_LOG_FUNCTION(this);
1164 
1165  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1166 
1167  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1168  {
1169  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1170  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1171  NS_ASSERT(satOrbiterDev != nullptr);
1172  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1173  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
1174  Ptr<SatPhy> satPhy;
1175  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
1176  it2 != satOrbiterFeederPhys.end();
1177  ++it2)
1178  {
1179  satPhy = it2->second;
1180  NS_ASSERT(satPhy != nullptr);
1181  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1182  }
1183  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
1184  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
1185  it2 != satOrbiterUserPhys.end();
1186  ++it2)
1187  {
1188  satPhy = it2->second;
1189  NS_ASSERT(satPhy != nullptr);
1190  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1191  }
1192  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
1193 
1194  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1195 
1196  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1197  {
1198  const int32_t utId = GetUtId(*it);
1199  NS_ASSERT_MSG(utId > 0, "Node " << (*it)->GetId() << " is not a valid UT");
1200  const uint32_t identifier = GetIdentifierForUt(*it);
1201 
1202  // Create the probe.
1203  std::ostringstream probeName;
1204  probeName << utId;
1205  Ptr<ApplicationPacketProbe> probe = CreateObject<ApplicationPacketProbe>();
1206  probe->SetName(probeName.str());
1207 
1208  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1209  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
1210  NS_ASSERT(satDev != nullptr);
1211  Ptr<SatPhy> satPhy = satDev->GetPhy();
1212  NS_ASSERT(satPhy != nullptr);
1213 
1214  // Connect the object to the probe.
1215  if (probe->ConnectByObject("Rx", satPhy))
1216  { // Connect the probe to the right collector.
1217  if (m_conversionCollectors.ConnectWithProbe(
1218  probe->GetObject<Probe>(),
1219  "OutputBytes",
1220  identifier,
1221  &UnitConversionCollector::TraceSinkUinteger32))
1222  {
1223  m_probes.insert(
1224  std::make_pair(probe->GetObject<Probe>(), std::make_pair(*it, identifier)));
1225 
1226  // Enable statistics-related tags and trace sources on the device.
1227  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1228  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1229  }
1230  else
1231  {
1232  NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
1233  << " to collector " << identifier);
1234  }
1235  }
1236  else
1237  {
1238  NS_FATAL_ERROR("Error connecting to Rx trace source of SatPhy"
1239  << " at node ID " << (*it)->GetId() << " device #2");
1240  }
1241  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
1242 
1243  // Enable statistics-related tags on the transmitting device.
1244  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1245  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1246  {
1247  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1248 
1249  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1250  {
1251  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
1252  NS_ASSERT(satDev != nullptr);
1253  Ptr<SatPhy> satPhy = satDev->GetPhy();
1254  NS_ASSERT(satPhy != nullptr);
1255 
1256  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1257  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1258  }
1259  }
1260 
1261 } // end of `void DoInstallProbes ();`
1262 
1263 void
1265 {
1266  NS_LOG_FUNCTION(this);
1267 
1268  std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
1269 
1270  for (it = m_probes.begin(); it != m_probes.end(); it++)
1271  {
1272  Ptr<Probe> probe = it->first;
1273  Ptr<Node> node = it->second.first;
1274  uint32_t identifier = it->second.second;
1275  m_conversionCollectors.DisconnectWithProbe(probe->GetObject<Probe>(),
1276  "OutputBytes",
1277  identifier,
1278  &UnitConversionCollector::TraceSinkUinteger32);
1279 
1280  identifier = GetIdentifierForUt(node);
1281 
1282  m_conversionCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
1283  "OutputBytes",
1284  identifier,
1285  &UnitConversionCollector::TraceSinkUinteger32);
1286 
1287  it->second.second = identifier;
1288  }
1289 } // end of `void UpdateIdentifierOnProbes ();`
1290 
1291 // RETURN LINK APPLICATION-LEVEL //////////////////////////////////////////////
1292 
1293 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnAppThroughputHelper);
1294 
1296  : SatStatsThroughputHelper(satHelper)
1297 {
1298  NS_LOG_FUNCTION(this << satHelper);
1299 }
1300 
1302 {
1303  NS_LOG_FUNCTION(this);
1304 }
1305 
1306 TypeId // static
1308 {
1309  static TypeId tid =
1310  TypeId("ns3::SatStatsRtnAppThroughputHelper").SetParent<SatStatsThroughputHelper>();
1311  return tid;
1312 }
1313 
1314 void
1316 {
1317  NS_LOG_FUNCTION(this);
1318 
1319  // Create a map of UT user addresses and identifiers.
1320  NodeContainer utUsers = Singleton<SatTopology>::Get()->GetUtUserNodes();
1321  for (NodeContainer::Iterator it = utUsers.Begin(); it != utUsers.End(); ++it)
1322  {
1324  }
1325 
1326  // Connect to trace sources at GW user node's applications.
1327 
1328  NodeContainer gwUsers = Singleton<SatTopology>::Get()->GetGwUserNodes();
1329  Callback<void, Ptr<const Packet>, const Address&> callback =
1330  MakeCallback(&SatStatsRtnAppThroughputHelper::Ipv4Callback, this);
1331 
1332  for (NodeContainer::Iterator it = gwUsers.Begin(); it != gwUsers.End(); ++it)
1333  {
1334  for (uint32_t i = 0; i < (*it)->GetNApplications(); i++)
1335  {
1336  Ptr<Application> app = (*it)->GetApplication(i);
1337 
1338  if (app->TraceConnectWithoutContext("Rx", callback))
1339  {
1340  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1341  << " application #" << i);
1342  }
1343  else
1344  {
1345  /*
1346  * We're being tolerant here by only logging a warning, because
1347  * not every kind of Application is equipped with the expected
1348  * Rx trace source.
1349  */
1350  NS_LOG_WARN(this << " unable to connect with node ID " << (*it)->GetId()
1351  << " application #" << i);
1352  }
1353  }
1354  }
1355 
1356 } // end of `void DoInstallProbes ();`
1357 
1358 void
1359 SatStatsRtnAppThroughputHelper::Ipv4Callback(Ptr<const Packet> packet, const Address& from)
1360 {
1361  // NS_LOG_FUNCTION (this << packet->GetSize () << from);
1362 
1363  if (InetSocketAddress::IsMatchingType(from))
1364  {
1365  // Determine the identifier associated with the sender address.
1366  const Address ipv4Addr = InetSocketAddress::ConvertFrom(from).GetIpv4();
1367  std::map<const Address, uint32_t>::const_iterator it1 = m_identifierMap.find(ipv4Addr);
1368 
1369  if (it1 == m_identifierMap.end())
1370  {
1371  NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
1372  << " bytes)"
1373  << " from statistics collection because of"
1374  << " unknown sender IPv4 address " << ipv4Addr);
1375  }
1376  else
1377  {
1378  // Find the collector with the right identifier.
1379  Ptr<DataCollectionObject> collector = m_conversionCollectors.Get(it1->second);
1380  NS_ASSERT_MSG(collector != nullptr,
1381  "Unable to find collector with identifier " << it1->second);
1382  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
1383  NS_ASSERT(c != nullptr);
1384 
1385  // Pass the sample to the collector.
1386  c->TraceSinkUinteger32(0, packet->GetSize());
1387  }
1388  }
1389  else
1390  {
1391  NS_LOG_WARN(
1392  this << " discarding packet " << packet << " (" << packet->GetSize() << " bytes)"
1393  << " from statistics collection"
1394  << " because it comes from sender " << from << " without valid InetSocketAddress");
1395  }
1396 
1397 } // end of `void Ipv4Callback (Ptr<const Packet>, const Address);`
1398 
1399 void
1401 {
1402  NS_LOG_FUNCTION(this << utUserNode->GetId());
1403 
1404  Ptr<Ipv4> ipv4 = utUserNode->GetObject<Ipv4>();
1405 
1406  if (ipv4 == nullptr)
1407  {
1408  NS_LOG_INFO(this << " Node " << utUserNode->GetId() << " does not support IPv4 protocol");
1409  }
1410  else if (ipv4->GetNInterfaces() >= 2)
1411  {
1412  const uint32_t identifier = GetIdentifierForUtUser(utUserNode);
1413 
1414  /*
1415  * Assuming that #0 is for loopback interface and #1 is for subscriber
1416  * network interface.
1417  */
1418  for (uint32_t i = 0; i < ipv4->GetNAddresses(1); i++)
1419  {
1420  const Address addr = ipv4->GetAddress(1, i).GetLocal();
1421  m_identifierMap[addr] = identifier;
1422  NS_LOG_INFO(this << " associated address " << addr << " with identifier "
1423  << identifier);
1424  }
1425  }
1426  else
1427  {
1428  NS_LOG_WARN(this << " Node " << utUserNode->GetId() << " is not a valid UT user");
1429  }
1430 }
1431 
1432 // RETURN FEEDER LINK DEVICE-LEVEL ///////////////////////////////////////////////////
1433 
1434 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederDevThroughputHelper);
1435 
1437  Ptr<const SatHelper> satHelper)
1438  : SatStatsThroughputHelper(satHelper)
1439 {
1440  NS_LOG_FUNCTION(this << satHelper);
1441 }
1442 
1444 {
1445  NS_LOG_FUNCTION(this);
1446 }
1447 
1448 TypeId // static
1450 {
1451  static TypeId tid =
1452  TypeId("ns3::SatStatsRtnFeederDevThroughputHelper").SetParent<SatStatsThroughputHelper>();
1453  return tid;
1454 }
1455 
1456 void
1458 {
1459  NS_LOG_FUNCTION(this);
1460 
1461  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1462  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1463  {
1464  // Create a map of UT addresses and identifiers.
1466 
1467  // Enable statistics-related tags and trace sources on the device.
1468  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1469  dev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1470  }
1471 
1472  // Connect to trace sources at GW nodes.
1473 
1474  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1475  Callback<void, Ptr<const Packet>, const Address&> callback =
1477 
1478  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1479  {
1480  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1481 
1482  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1483  {
1484  NS_ASSERT((*itDev)->GetObject<SatNetDevice>() != nullptr);
1485 
1486  if ((*itDev)->TraceConnectWithoutContext("Rx", callback))
1487  {
1488  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1489  << " device #" << (*itDev)->GetIfIndex());
1490 
1491  // Enable statistics-related tags and trace sources on the device.
1492  (*itDev)->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1493  }
1494  else
1495  {
1496  NS_FATAL_ERROR("Error connecting to Rx trace source of SatNetDevice"
1497  << " at node ID " << (*it)->GetId() << " device #"
1498  << (*itDev)->GetIfIndex());
1499  }
1500 
1501  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
1502 
1503  } // end of `for (NodeContainer::Iterator it = gws)`
1504 
1505 } // end of `void DoInstallProbes ();`
1506 
1507 // RETURN USER LINK DEVICE-LEVEL ///////////////////////////////////////////////////
1508 
1509 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserDevThroughputHelper);
1510 
1512  Ptr<const SatHelper> satHelper)
1513  : SatStatsThroughputHelper(satHelper)
1514 {
1515  NS_LOG_FUNCTION(this << satHelper);
1516 }
1517 
1519 {
1520  NS_LOG_FUNCTION(this);
1521 }
1522 
1523 TypeId // static
1525 {
1526  static TypeId tid =
1527  TypeId("ns3::SatStatsRtnUserDevThroughputHelper").SetParent<SatStatsThroughputHelper>();
1528  return tid;
1529 }
1530 
1531 void
1533 {
1534  NS_LOG_FUNCTION(this);
1535 
1536  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1537  Callback<void, Ptr<const Packet>, const Address&> callback =
1539 
1540  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1541  {
1542  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1543  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1544  NS_ASSERT(satOrbiterDev != nullptr);
1545  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1546 
1547  // Connect the object to the probe.
1548  if (satOrbiterDev->TraceConnectWithoutContext("RxUser", callback))
1549  {
1550  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1551  << " device #" << satOrbiterDev->GetIfIndex());
1552  }
1553  else
1554  {
1555  NS_FATAL_ERROR("Error connecting to Rx trace source of SatMac"
1556  << " at node ID " << (*it)->GetId() << " device #"
1557  << satOrbiterDev->GetIfIndex());
1558  }
1559  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
1560 
1561  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1562  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1563  {
1564  // Create a map of UT addresses and identifiers.
1566 
1567  // Enable statistics-related tags and trace sources on the device.
1568  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1569  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
1570  NS_ASSERT(satDev != nullptr);
1571  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1572  }
1573 
1574  // Connect to trace sources at GW nodes.
1575 
1576  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1577 
1578  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1579  {
1580  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1581 
1582  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1583  {
1584  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
1585  NS_ASSERT(satDev != nullptr);
1586 
1587  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1588  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
1589 
1590  } // end of `for (NodeContainer::Iterator it = gws)`
1591 
1592 } // end of `void DoInstallProbes ();`
1593 
1594 // RETURN FEEDER LINK MAC-LEVEL //////////////////////////////////////////////////////
1595 
1596 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederMacThroughputHelper);
1597 
1599  Ptr<const SatHelper> satHelper)
1600  : SatStatsThroughputHelper(satHelper)
1601 {
1602  NS_LOG_FUNCTION(this << satHelper);
1603 }
1604 
1606 {
1607  NS_LOG_FUNCTION(this);
1608 }
1609 
1610 TypeId // static
1612 {
1613  static TypeId tid =
1614  TypeId("ns3::SatStatsRtnFeederMacThroughputHelper").SetParent<SatStatsThroughputHelper>();
1615  return tid;
1616 }
1617 
1618 void
1620 {
1621  NS_LOG_FUNCTION(this);
1622 
1623  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1624 
1625  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1626  {
1627  Ptr<SatMac> satMac;
1628  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1629  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1630  NS_ASSERT(satOrbiterDev != nullptr);
1631  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1632  std::map<uint32_t, Ptr<SatMac>> satOrbiterFeederMacs = satOrbiterDev->GetAllFeederMac();
1633  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterFeederMacs.begin();
1634  it2 != satOrbiterFeederMacs.end();
1635  ++it2)
1636  {
1637  satMac = it2->second;
1638  NS_ASSERT(satMac != nullptr);
1639  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1640  }
1641  std::map<uint32_t, Ptr<SatMac>> satOrbiterUserMacs = satOrbiterDev->GetUserMac();
1642  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterUserMacs.begin();
1643  it2 != satOrbiterUserMacs.end();
1644  ++it2)
1645  {
1646  satMac = it2->second;
1647  NS_ASSERT(satMac != nullptr);
1648  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1649  }
1650  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
1651 
1652  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1653  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1654  {
1655  // Create a map of UT addresses and identifiers.
1657 
1658  // Enable statistics-related tags and trace sources on the device.
1659  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1660  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
1661  NS_ASSERT(satDev != nullptr);
1662  Ptr<SatMac> satMac = satDev->GetMac();
1663  NS_ASSERT(satMac != nullptr);
1664  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1665  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1666  }
1667 
1668  // Connect to trace sources at GW nodes.
1669 
1670  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1671  Callback<void, Ptr<const Packet>, const Address&> callback =
1673 
1674  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1675  {
1676  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1677 
1678  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1679  {
1680  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
1681  NS_ASSERT(satDev != nullptr);
1682  Ptr<SatMac> satMac = satDev->GetMac();
1683  NS_ASSERT(satMac != nullptr);
1684 
1685  // Connect the object to the probe.
1686  if (satMac->TraceConnectWithoutContext("Rx", callback))
1687  {
1688  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1689  << " device #" << satDev->GetIfIndex());
1690 
1691  // Enable statistics-related tags and trace sources on the device.
1692  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1693  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1694  }
1695  else
1696  {
1697  NS_FATAL_ERROR("Error connecting to Rx trace source of SatMac"
1698  << " at node ID " << (*it)->GetId() << " device #"
1699  << satDev->GetIfIndex());
1700  }
1701 
1702  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
1703 
1704  } // end of `for (NodeContainer::Iterator it = gws)`
1705 
1706 } // end of `void DoInstallProbes ();`
1707 
1708 // RETURN USER LINK MAC-LEVEL //////////////////////////////////////////////////////
1709 
1710 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserMacThroughputHelper);
1711 
1713  Ptr<const SatHelper> satHelper)
1714  : SatStatsThroughputHelper(satHelper)
1715 {
1716  NS_LOG_FUNCTION(this << satHelper);
1717 }
1718 
1720 {
1721  NS_LOG_FUNCTION(this);
1722 }
1723 
1724 TypeId // static
1726 {
1727  static TypeId tid =
1728  TypeId("ns3::SatStatsRtnUserMacThroughputHelper").SetParent<SatStatsThroughputHelper>();
1729  return tid;
1730 }
1731 
1732 void
1734 {
1735  NS_LOG_FUNCTION(this);
1736 
1737  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1738  Callback<void, Ptr<const Packet>, const Address&> callback =
1740 
1741  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1742  {
1743  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1744  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1745  NS_ASSERT(satOrbiterDev != nullptr);
1746  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1747  std::map<uint32_t, Ptr<SatMac>> satOrbiterFeederMacs = satOrbiterDev->GetAllFeederMac();
1748  Ptr<SatMac> satMac;
1749  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterFeederMacs.begin();
1750  it2 != satOrbiterFeederMacs.end();
1751  ++it2)
1752  {
1753  satMac = it2->second;
1754  NS_ASSERT(satMac != nullptr);
1755  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1756  }
1757  std::map<uint32_t, Ptr<SatMac>> satOrbiterUserMacs = satOrbiterDev->GetUserMac();
1758  for (std::map<uint32_t, Ptr<SatMac>>::iterator it2 = satOrbiterUserMacs.begin();
1759  it2 != satOrbiterUserMacs.end();
1760  ++it2)
1761  {
1762  satMac = it2->second;
1763  NS_ASSERT(satMac != nullptr);
1764  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1765 
1766  // Connect the object to the probe.
1767  if (satMac->TraceConnectWithoutContext("Rx", callback))
1768  {
1769  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1770  << " device #" << satOrbiterDev->GetIfIndex());
1771  }
1772  else
1773  {
1774  NS_FATAL_ERROR("Error connecting to Rx trace source of SatMac"
1775  << " at node ID " << (*it)->GetId() << " device #"
1776  << satOrbiterDev->GetIfIndex());
1777  }
1778  }
1779  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
1780 
1781  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1782  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1783  {
1784  // Create a map of UT addresses and identifiers.
1786 
1787  // Enable statistics-related tags and trace sources on the device.
1788  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1789  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
1790  NS_ASSERT(satDev != nullptr);
1791  Ptr<SatMac> satMac = satDev->GetMac();
1792  NS_ASSERT(satMac != nullptr);
1793  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1794  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1795  }
1796 
1797  // Connect to trace sources at GW nodes.
1798 
1799  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1800 
1801  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1802  {
1803  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1804 
1805  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1806  {
1807  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
1808  NS_ASSERT(satDev != nullptr);
1809  Ptr<SatMac> satMac = satDev->GetMac();
1810  NS_ASSERT(satMac != nullptr);
1811 
1812  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1813  satMac->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1814  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
1815 
1816  } // end of `for (NodeContainer::Iterator it = gws)`
1817 
1818 } // end of `void DoInstallProbes ();`
1819 
1820 // RETURN FEEDER LINK PHY-LEVEL //////////////////////////////////////////////////////
1821 
1822 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederPhyThroughputHelper);
1823 
1825  Ptr<const SatHelper> satHelper)
1826  : SatStatsThroughputHelper(satHelper)
1827 {
1828  NS_LOG_FUNCTION(this << satHelper);
1829 }
1830 
1832 {
1833  NS_LOG_FUNCTION(this);
1834 }
1835 
1836 TypeId // static
1838 {
1839  static TypeId tid =
1840  TypeId("ns3::SatStatsRtnFeederPhyThroughputHelper").SetParent<SatStatsThroughputHelper>();
1841  return tid;
1842 }
1843 
1844 void
1846 {
1847  NS_LOG_FUNCTION(this);
1848 
1849  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1850 
1851  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1852  {
1853  Ptr<SatPhy> satPhy;
1854  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1855  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1856  NS_ASSERT(satOrbiterDev != nullptr);
1857  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1858  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
1859  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
1860  it2 != satOrbiterFeederPhys.end();
1861  ++it2)
1862  {
1863  satPhy = it2->second;
1864  NS_ASSERT(satPhy != nullptr);
1865  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1866  }
1867  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
1868  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
1869  it2 != satOrbiterUserPhys.end();
1870  ++it2)
1871  {
1872  satPhy = it2->second;
1873  NS_ASSERT(satPhy != nullptr);
1874  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1875  }
1876  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
1877 
1878  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
1879  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
1880  {
1881  // Create a map of UT addresses and identifiers.
1883 
1884  // Enable statistics-related tags and trace sources on the device.
1885  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
1886  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
1887  NS_ASSERT(satDev != nullptr);
1888  Ptr<SatPhy> satPhy = satDev->GetPhy();
1889  NS_ASSERT(satPhy != nullptr);
1890  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1891  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1892  }
1893 
1894  // Connect to trace sources at GW nodes.
1895 
1896  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
1897  Callback<void, Ptr<const Packet>, const Address&> callback =
1899 
1900  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
1901  {
1902  NetDeviceContainer devs = GetGwSatNetDevice(*it);
1903 
1904  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
1905  {
1906  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
1907  NS_ASSERT(satDev != nullptr);
1908  Ptr<SatPhy> satPhy = satDev->GetPhy();
1909  NS_ASSERT(satPhy != nullptr);
1910 
1911  // Connect the object to the probe.
1912  if (satPhy->TraceConnectWithoutContext("Rx", callback))
1913  {
1914  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1915  << " device #" << satDev->GetIfIndex());
1916 
1917  // Enable statistics-related tags and trace sources on the device.
1918  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1919  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1920  }
1921  else
1922  {
1923  NS_FATAL_ERROR("Error connecting to Rx trace source of SatPhy"
1924  << " at node ID " << (*it)->GetId() << " device #"
1925  << satDev->GetIfIndex());
1926  }
1927 
1928  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
1929 
1930  } // end of `for (NodeContainer::Iterator it = gws)`
1931 
1932 } // end of `void DoInstallProbes ();`
1933 
1934 // RETURN USER LINK PHY-LEVEL //////////////////////////////////////////////////////
1935 
1936 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserPhyThroughputHelper);
1937 
1939  Ptr<const SatHelper> satHelper)
1940  : SatStatsThroughputHelper(satHelper)
1941 {
1942  NS_LOG_FUNCTION(this << satHelper);
1943 }
1944 
1946 {
1947  NS_LOG_FUNCTION(this);
1948 }
1949 
1950 TypeId // static
1952 {
1953  static TypeId tid =
1954  TypeId("ns3::SatStatsRtnUserPhyThroughputHelper").SetParent<SatStatsThroughputHelper>();
1955  return tid;
1956 }
1957 
1958 void
1960 {
1961  NS_LOG_FUNCTION(this);
1962 
1963  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
1964  Callback<void, Ptr<const Packet>, const Address&> callback =
1966 
1967  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
1968  {
1969  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
1970  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
1971  NS_ASSERT(satOrbiterDev != nullptr);
1972  satOrbiterDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1973  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
1974  Ptr<SatPhy> satPhy;
1975  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
1976  it2 != satOrbiterFeederPhys.end();
1977  ++it2)
1978  {
1979  satPhy = it2->second;
1980  NS_ASSERT(satPhy != nullptr);
1981  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1982  }
1983  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
1984  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
1985  it2 != satOrbiterUserPhys.end();
1986  ++it2)
1987  {
1988  satPhy = it2->second;
1989  NS_ASSERT(satPhy != nullptr);
1990  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1991 
1992  // Connect the object to the probe.
1993  if (satPhy->TraceConnectWithoutContext("Rx", callback))
1994  {
1995  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
1996  << " device #" << satOrbiterDev->GetIfIndex());
1997  }
1998  else
1999  {
2000  NS_FATAL_ERROR("Error connecting to Rx trace source of SatPhy"
2001  << " at node ID " << (*it)->GetId() << " device #"
2002  << satOrbiterDev->GetIfIndex());
2003  }
2004  }
2005  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
2006 
2007  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
2008  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
2009  {
2010  // Create a map of UT addresses and identifiers.
2012 
2013  // Enable statistics-related tags and trace sources on the device.
2014  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
2015  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
2016  NS_ASSERT(satDev != nullptr);
2017  Ptr<SatPhy> satPhy = satDev->GetPhy();
2018  NS_ASSERT(satPhy != nullptr);
2019  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
2020  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
2021  }
2022 
2023  // Connect to trace sources at GW nodes.
2024 
2025  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
2026 
2027  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
2028  {
2029  NetDeviceContainer devs = GetGwSatNetDevice(*it);
2030 
2031  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
2032  {
2033  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
2034  NS_ASSERT(satDev != nullptr);
2035  Ptr<SatPhy> satPhy = satDev->GetPhy();
2036  NS_ASSERT(satPhy != nullptr);
2037 
2038  satDev->SetAttribute("EnableStatisticsTags", BooleanValue(true));
2039  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
2040  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
2041 
2042  } // end of `for (NodeContainer::Iterator it = gws)`
2043 
2044 } // end of `void DoInstallProbes ();`
2045 
2046 } // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
SatOrbiterNetDevice to be utilized in geostationary satellite.
Produce forward link application-level throughput statistics from a satellite module simulation.
std::map< Ptr< Probe >, std::pair< Ptr< Node >, uint32_t > > m_probes
Maintains a list of probes created by this helper.
SatStatsFwdAppThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
Produce forward feeder link device-level throughput statistics from a satellite module simulation.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsFwdFeederDevThroughputHelper(Ptr< const SatHelper > satHelper)
Produce forward feeder link MAC-level throughput statistics from a satellite module simulation.
SatStatsFwdFeederMacThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce forward feeder link PHY-level throughput statistics from a satellite module simulation.
SatStatsFwdFeederPhyThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce forward user link device-level throughput statistics from a satellite module simulation.
SatStatsFwdUserDevThroughputHelper(Ptr< const SatHelper > satHelper)
std::map< Ptr< Probe >, std::pair< Ptr< Node >, uint32_t > > m_probes
Maintains a list of probes created by this helper.
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce forward user link MAC-level throughput statistics from a satellite module simulation.
std::map< Ptr< Probe >, std::pair< Ptr< Node >, uint32_t > > m_probes
Maintains a list of probes created by this helper.
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
SatStatsFwdUserMacThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce forward user link PHY-level throughput statistics from a satellite module simulation.
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
SatStatsFwdUserPhyThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
std::map< Ptr< Probe >, std::pair< Ptr< Node >, uint32_t > > m_probes
Maintains a list of probes created by this helper.
Parent abstract class of all satellite statistics helpers.
static Ptr< NetDevice > GetSatSatOrbiterNetDevice(Ptr< Node > satNode)
uint32_t GetIdentifierForUtUser(Ptr< Node > utUserNode) const
static NetDeviceContainer GetGwSatNetDevice(Ptr< Node > gwNode)
virtual void SaveAddressAndIdentifier(Ptr< Node > utNode)
Save the address and the proper identifier from the given UT node.
static std::string GetOutputTypeName(OutputType_t outputType)
virtual std::string GetIdentifierHeading(std::string dataLabel) const
virtual std::string GetOutputPath() const
Ptr< DataCollectionObject > CreateAggregator(std::string aggregatorTypeId, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue())
Create the aggregator according to the output type.
virtual std::string GetOutputFileName() const
Compute the path and file name where statistics output should be written to.
uint32_t GetUtId(Ptr< Node > utNode) const
uint32_t CreateCollectorPerIdentifier(CollectorMap &collectorMap) const
Create one collector instance for each identifier in the simulation.
static Ptr< NetDevice > GetUtSatNetDevice(Ptr< Node > utNode)
OutputType_t GetOutputType() const
uint32_t GetIdentifierForUt(Ptr< Node > utNode) const
std::map< const Address, uint32_t > m_identifierMap
Map of address and the identifier associated with it.
uint32_t GetUtUserId(Ptr< Node > utUserNode) const
std::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
virtual std::string GetDistributionHeading(std::string dataLabel) const
Produce return link application-level throughput statistics from a satellite module simulation.
void Ipv4Callback(Ptr< const Packet > packet, const Address &from)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
SatStatsRtnAppThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
void SaveIpv4AddressAndIdentifier(Ptr< Node > utUserNode)
Save the IPv4 address and the proper identifier from the given UT user node.
Produce return feeder link device-level throughput statistics from a satellite module simulation.
SatStatsRtnFeederDevThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce return feeder link MAC-level throughput statistics from a satellite module simulation.
SatStatsRtnFeederMacThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce return feeder link PHY-level throughput statistics from a satellite module simulation.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsRtnFeederPhyThroughputHelper(Ptr< const SatHelper > satHelper)
Produce return user link device-level throughput statistics from a satellite module simulation.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsRtnUserDevThroughputHelper(Ptr< const SatHelper > satHelper)
Produce return user link MAC-level throughput statistics from a satellite module simulation.
SatStatsRtnUserMacThroughputHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce return user link PHY-level throughput statistics from a satellite module simulation.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsRtnUserPhyThroughputHelper(Ptr< const SatHelper > satHelper)
CollectorMap m_conversionCollectors
Maintains a list of first-level collectors created by this helper.
void InstallProbes()
Set up several probes or other means of listeners and connect them to the first-level collectors.
Ptr< DistributionCollector > m_averagingCollector
The final collector utilized in averaged output (histogram, PDF, and CDF).
void RxCallback(Ptr< const Packet > packet, const Address &from)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
static TypeId GetTypeId()
inherited from ObjectBase base class
virtual void DoInstallProbes()=0
CollectorMap m_terminalCollectors
Maintains a list of second-level collectors created by this helper.
SatStatsThroughputHelper(Ptr< const SatHelper > satHelper)
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.