satellite-stats-satellite-queue-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: Bastien Tauran <bastien.tauran@viveris.fr>
19  *
20  */
21 
23 
24 #include <ns3/boolean.h>
25 #include <ns3/callback.h>
26 #include <ns3/data-collection-object.h>
27 #include <ns3/distribution-collector.h>
28 #include <ns3/double-probe.h>
29 #include <ns3/enum.h>
30 #include <ns3/log.h>
31 #include <ns3/mac48-address.h>
32 #include <ns3/magister-gnuplot-aggregator.h>
33 #include <ns3/multi-file-aggregator.h>
34 #include <ns3/node.h>
35 #include <ns3/object-map.h>
36 #include <ns3/object-vector.h>
37 #include <ns3/probe.h>
38 #include <ns3/satellite-helper.h>
39 #include <ns3/satellite-id-mapper.h>
40 #include <ns3/satellite-orbiter-feeder-phy.h>
41 #include <ns3/satellite-orbiter-net-device.h>
42 #include <ns3/satellite-orbiter-user-phy.h>
43 #include <ns3/satellite-phy.h>
44 #include <ns3/satellite-topology.h>
45 #include <ns3/scalar-collector.h>
46 #include <ns3/singleton.h>
47 #include <ns3/string.h>
48 #include <ns3/unit-conversion-collector.h>
49 
50 #include <map>
51 #include <sstream>
52 #include <string>
53 #include <utility>
54 
55 NS_LOG_COMPONENT_DEFINE("SatStatsSatelliteQueueHelper");
56 
57 namespace ns3
58 {
59 
60 NS_OBJECT_ENSURE_REGISTERED(SatStatsSatelliteQueueHelper);
61 
62 std::string // static
64 {
65  switch (unitType)
66  {
68  return "UNIT_BYTES";
70  return "UNIT_NUMBER_OF_PACKETS";
71  default:
72  NS_FATAL_ERROR("SatStatsSatelliteQueueHelper - Invalid unit type");
73  break;
74  }
75 
76  NS_FATAL_ERROR("SatStatsSatelliteQueueHelper - Invalid unit type");
77  return "";
78 }
79 
81  : SatStatsHelper(satHelper)
82 {
83  NS_LOG_FUNCTION(this << satHelper);
84 }
85 
87 {
88  NS_LOG_FUNCTION(this);
89 }
90 
91 TypeId // static
93 {
94  static TypeId tid = TypeId("ns3::SatStatsSatelliteQueueHelper").SetParent<SatStatsHelper>();
95  return tid;
96 }
97 
98 void
100 {
101  NS_LOG_FUNCTION(this << GetUnitTypeName(unitType));
102  m_unitType = unitType;
103 
104  // Update presentation-based attributes.
106  {
107  m_shortLabel = "size_bytes";
108  m_longLabel = "Queue size (in bytes)";
109  }
111  {
112  m_shortLabel = "num_packets";
113  m_longLabel = "Queue size (in number of packets)";
114  }
115  else
116  {
117  NS_FATAL_ERROR("SatStatsSatelliteQueueHelper - Invalid unit type");
118  }
119 }
120 
121 void
123 {
124  NS_LOG_FUNCTION(this << averagingMode);
125  m_averagingMode = averagingMode;
126 }
127 
128 void
130 {
131  NS_LOG_FUNCTION(this);
132 
133  switch (GetOutputType())
134  {
136  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
137  << " is not a valid output type for this statistics.");
138  break;
139 
141  // Setup aggregator.
142  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
143  "OutputFileName",
144  StringValue(GetOutputFileName()),
145  "MultiFileMode",
146  BooleanValue(false),
147  "EnableContextPrinting",
148  BooleanValue(true),
149  "GeneralHeading",
150  StringValue(GetIdentifierHeading(m_shortLabel)));
151 
152  // Setup collectors.
153  m_terminalCollectors.SetType("ns3::ScalarCollector");
154  m_terminalCollectors.SetAttribute("InputDataType",
155  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
156  m_terminalCollectors.SetAttribute(
157  "OutputType",
158  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
160  m_terminalCollectors.ConnectToAggregator("Output",
161  m_aggregator,
162  &MultiFileAggregator::Write1d);
163  break;
164  }
165 
167  // Setup aggregator.
168  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
169  "OutputFileName",
170  StringValue(GetOutputFileName()),
171  "GeneralHeading",
172  StringValue(GetTimeHeading(m_shortLabel)));
173 
174  // Setup collectors.
175  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
176  m_terminalCollectors.SetAttribute("ConversionType",
177  EnumValue(UnitConversionCollector::TRANSPARENT));
179  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
180  m_aggregator,
181  &MultiFileAggregator::Write2d);
182  break;
183  }
184 
188  if (m_averagingMode)
189  {
190  // Setup aggregator.
191  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
192  "OutputFileName",
193  StringValue(GetOutputFileName()),
194  "MultiFileMode",
195  BooleanValue(false),
196  "EnableContextPrinting",
197  BooleanValue(false),
198  "GeneralHeading",
199  StringValue(GetDistributionHeading(m_shortLabel)));
200  Ptr<MultiFileAggregator> fileAggregator =
201  m_aggregator->GetObject<MultiFileAggregator>();
202  NS_ASSERT(fileAggregator != nullptr);
203 
204  // Setup the final-level collector.
205  m_averagingCollector = CreateObject<DistributionCollector>();
206  DistributionCollector::OutputType_t outputType =
207  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
209  {
210  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
211  }
213  {
214  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
215  }
216  m_averagingCollector->SetOutputType(outputType);
217  m_averagingCollector->SetName("0");
218  m_averagingCollector->TraceConnect(
219  "Output",
220  "0",
221  MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
222  m_averagingCollector->TraceConnect(
223  "OutputString",
224  "0",
225  MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
226  m_averagingCollector->TraceConnect(
227  "Warning",
228  "0",
229  MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
230 
231  // Setup collectors.
232  m_terminalCollectors.SetType("ns3::ScalarCollector");
233  m_terminalCollectors.SetAttribute("InputDataType",
234  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
235  m_terminalCollectors.SetAttribute(
236  "OutputType",
237  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
239  Callback<void, double> callback =
240  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
241  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
242  it != m_terminalCollectors.End();
243  ++it)
244  {
245  it->second->TraceConnectWithoutContext("Output", callback);
246  }
247  }
248  else
249  {
250  // Setup aggregator.
251  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
252  "OutputFileName",
253  StringValue(GetOutputFileName()),
254  "GeneralHeading",
255  StringValue(GetDistributionHeading(m_shortLabel)));
256 
257  // Setup collectors.
258  m_terminalCollectors.SetType("ns3::DistributionCollector");
259  DistributionCollector::OutputType_t outputType =
260  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
262  {
263  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
264  }
266  {
267  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
268  }
269  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
271  m_terminalCollectors.ConnectToAggregator("Output",
272  m_aggregator,
273  &MultiFileAggregator::Write2d);
274  m_terminalCollectors.ConnectToAggregator("OutputString",
275  m_aggregator,
276  &MultiFileAggregator::AddContextHeading);
277  m_terminalCollectors.ConnectToAggregator("Warning",
278  m_aggregator,
279  &MultiFileAggregator::EnableContextWarning);
280  }
281 
282  break;
283  }
284 
287  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
288  << " is not a valid output type for this statistics.");
289  break;
290 
292  // Setup aggregator.
293  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
294  "OutputPath",
295  StringValue(GetOutputPath()),
296  "OutputFileName",
297  StringValue(GetName()));
298  Ptr<MagisterGnuplotAggregator> plotAggregator =
299  m_aggregator->GetObject<MagisterGnuplotAggregator>();
300  NS_ASSERT(plotAggregator != nullptr);
301  // plot->SetTitle ("");
302  plotAggregator->SetLegend(m_longLabel, "Frequency");
303  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
304 
305  // Setup collectors.
306  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
307  m_terminalCollectors.SetAttribute("ConversionType",
308  EnumValue(UnitConversionCollector::TRANSPARENT));
310  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
311  it != m_terminalCollectors.End();
312  ++it)
313  {
314  const std::string context = it->second->GetName();
315  plotAggregator->Add2dDataset(context, context);
316  }
317  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
318  m_aggregator,
319  &MagisterGnuplotAggregator::Write2d);
320  break;
321  }
322 
326  if (m_averagingMode)
327  {
328  // Setup aggregator.
329  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
330  "OutputPath",
331  StringValue(GetOutputPath()),
332  "OutputFileName",
333  StringValue(GetName()));
334  Ptr<MagisterGnuplotAggregator> plotAggregator =
335  m_aggregator->GetObject<MagisterGnuplotAggregator>();
336  NS_ASSERT(plotAggregator != nullptr);
337  // plot->SetTitle ("");
338  plotAggregator->SetLegend(m_longLabel, "Frequency");
339  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
340  plotAggregator->Add2dDataset(GetName(), GetName());
342 
343  // Setup the final-level collector.
344  m_averagingCollector = CreateObject<DistributionCollector>();
345  DistributionCollector::OutputType_t outputType =
346  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
348  {
349  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
350  }
352  {
353  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
354  }
355  m_averagingCollector->SetOutputType(outputType);
356  m_averagingCollector->SetName("0");
357  m_averagingCollector->TraceConnect(
358  "Output",
359  GetName(),
360  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
362 
363  // Setup collectors.
364  m_terminalCollectors.SetType("ns3::ScalarCollector");
365  m_terminalCollectors.SetAttribute("InputDataType",
366  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
367  m_terminalCollectors.SetAttribute(
368  "OutputType",
369  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
371  Callback<void, double> callback =
372  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
373  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
374  it != m_terminalCollectors.End();
375  ++it)
376  {
377  it->second->TraceConnectWithoutContext("Output", callback);
378  }
379  }
380  else
381  {
382  // Setup aggregator.
383  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
384  "OutputPath",
385  StringValue(GetOutputPath()),
386  "OutputFileName",
387  StringValue(GetName()));
388  Ptr<MagisterGnuplotAggregator> plotAggregator =
389  m_aggregator->GetObject<MagisterGnuplotAggregator>();
390  NS_ASSERT(plotAggregator != nullptr);
391  // plot->SetTitle ("");
392  plotAggregator->SetLegend(m_longLabel, "Frequency");
393  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
394 
395  // Setup collectors.
396  m_terminalCollectors.SetType("ns3::DistributionCollector");
397  DistributionCollector::OutputType_t outputType =
398  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
400  {
401  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
402  }
404  {
405  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
406  }
407  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
409  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
410  it != m_terminalCollectors.End();
411  ++it)
412  {
413  const std::string context = it->second->GetName();
414  plotAggregator->Add2dDataset(context, context);
415  }
416  m_terminalCollectors.ConnectToAggregator("Output",
417  m_aggregator,
418  &MagisterGnuplotAggregator::Write2d);
419  }
420 
421  break;
422  }
423 
424  default:
425  NS_FATAL_ERROR("SatStatsLinkDelayHelper - Invalid output type");
426  break;
427  }
428 
429  // Setup probes and connect them to the collectors.
430  InstallProbes();
431 
432 } // end of `void DoInstall ();`
433 
434 void
435 SatStatsSatelliteQueueHelper::QueueSizeCallback(uint32_t size, const Address& from)
436 {
437  // NS_LOG_FUNCTION (this << size << from);
438 
439  if (from.IsInvalid())
440  {
441  NS_LOG_WARN(this << " discarding a packet"
442  << " from statistics collection because of"
443  << " invalid sender address");
444  }
445  else if (Mac48Address::ConvertFrom(from).IsBroadcast())
446  {
447  for (std::pair<const Address, uint32_t> item : m_identifierMap)
448  {
449  PassSampleToCollector(size, item.second);
450  }
451  }
452  else
453  {
454  // Determine the identifier associated with the sender address.
455  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
456 
457  if (it != m_identifierMap.end())
458  {
459  PassSampleToCollector(size, it->second);
460  }
461  else
462  {
463  NS_LOG_WARN(this << " discarding a packet"
464  << " from statistics collection because of"
465  << " unknown sender address " << from);
466  }
467  }
468 }
469 
470 bool
471 SatStatsSatelliteQueueHelper::ConnectProbeToCollector(Ptr<Probe> probe, uint32_t identifier)
472 {
473  NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
474 
475  bool ret = false;
476  switch (GetOutputType())
477  {
480  ret = m_terminalCollectors.ConnectWithProbe(probe,
481  "OutputSeconds",
482  identifier,
483  &ScalarCollector::TraceSinkDouble);
484  break;
485 
488  ret = m_terminalCollectors.ConnectWithProbe(probe,
489  "OutputSeconds",
490  identifier,
491  &UnitConversionCollector::TraceSinkDouble);
492  break;
493 
500  if (m_averagingMode)
501  {
502  ret = m_terminalCollectors.ConnectWithProbe(probe,
503  "OutputSeconds",
504  identifier,
505  &ScalarCollector::TraceSinkDouble);
506  }
507  else
508  {
509  ret = m_terminalCollectors.ConnectWithProbe(probe,
510  "OutputSeconds",
511  identifier,
512  &DistributionCollector::TraceSinkDouble);
513  }
514  break;
515 
516  default:
517  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
518  << " is not a valid output type for this statistics.");
519  break;
520  }
521 
522  if (ret)
523  {
524  NS_LOG_INFO(this << " created probe " << probe->GetName() << ", connected to collector "
525  << identifier);
526  }
527  else
528  {
529  NS_LOG_WARN(this << " unable to connect probe " << probe->GetName() << " to collector "
530  << identifier);
531  }
532 
533  return ret;
534 }
535 
536 void
537 SatStatsSatelliteQueueHelper::PassSampleToCollector(uint32_t size, uint32_t identifier)
538 {
539  // NS_LOG_FUNCTION (this << size << identifier);
540 
541  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifier);
542  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << identifier);
543 
544  switch (GetOutputType())
545  {
548  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
549  NS_ASSERT(c != nullptr);
550  c->TraceSinkDouble(0.0, size);
551  break;
552  }
553 
556  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
557  NS_ASSERT(c != nullptr);
558  c->TraceSinkDouble(0.0, size);
559  break;
560  }
561 
568  if (m_averagingMode)
569  {
570  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
571  NS_ASSERT(c != nullptr);
572  c->TraceSinkDouble(0.0, size);
573  }
574  else
575  {
576  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
577  NS_ASSERT(c != nullptr);
578  c->TraceSinkDouble(0.0, size);
579  }
580  break;
581 
582  default:
583  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
584  << " is not a valid output type for this statistics.");
585  break;
586 
587  } // end of `switch (GetOutputType ())`
588 
589 } // end of `void PassSampleToCollector (double, uint32_t)`
590 
591 void
593 {
594  // The method below is supposed to be implemented by the child class.
595  DoInstallProbes();
596 }
597 
598 // RTN FEEDER QUEUE IN BYTES ////////////////////////////////////////////////////////
599 
600 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederQueueBytesHelper);
601 
603  : SatStatsSatelliteQueueHelper(satHelper)
604 {
605  NS_LOG_FUNCTION(this << satHelper);
607 }
608 
610 {
611  NS_LOG_FUNCTION(this);
612 }
613 
614 TypeId // static
616 {
617  static TypeId tid =
618  TypeId("ns3::SatStatsRtnFeederQueueBytesHelper").SetParent<SatStatsSatelliteQueueHelper>();
619  return tid;
620 }
621 
622 void
624 {
625  NS_LOG_FUNCTION(this);
626 
627  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
628  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
629  {
630  // Create a map of UT addresses and identifiers.
632  }
633 
634  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
635  Callback<void, uint32_t, const Address&> callback =
637 
638  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
639  {
640  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
641  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
642  NS_ASSERT(satOrbiterDev != nullptr);
643  Ptr<SatPhy> satPhy;
644  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
645  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
646  it2 != satOrbiterFeederPhys.end();
647  ++it2)
648  {
649  satPhy = it2->second;
650  NS_ASSERT(satPhy != nullptr);
651  Ptr<SatOrbiterFeederPhy> satOrbiterFeederPhy = satPhy->GetObject<SatOrbiterFeederPhy>();
652  NS_ASSERT(satOrbiterFeederPhy != nullptr);
653 
654  if (satOrbiterFeederPhy->TraceConnectWithoutContext("QueueSizeBytes", callback))
655  {
656  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
657  << " device #" << satOrbiterDev->GetIfIndex());
658  }
659  else
660  {
661  NS_FATAL_ERROR("Error connecting to QueueSizeBytes trace source"
662  << " at node ID " << (*it)->GetId() << " device #"
663  << satOrbiterDev->GetIfIndex());
664  }
665  }
666  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
667 
668 } // end of `void DoInstallProbes ();`
669 
670 // RTN FEEDER QUEUE IN PACKETS ////////////////////////////////////////////////////////
671 
672 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederQueuePacketsHelper);
673 
675  Ptr<const SatHelper> satHelper)
676  : SatStatsSatelliteQueueHelper(satHelper)
677 {
678  NS_LOG_FUNCTION(this << satHelper);
680 }
681 
683 {
684  NS_LOG_FUNCTION(this);
685 }
686 
687 TypeId // static
689 {
690  static TypeId tid = TypeId("ns3::SatStatsRtnFeederQueuePacketsHelper")
691  .SetParent<SatStatsSatelliteQueueHelper>();
692  return tid;
693 }
694 
695 void
697 {
698  NS_LOG_FUNCTION(this);
699 
700  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
701  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
702  {
703  // Create a map of UT addresses and identifiers.
705  }
706 
707  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
708  Callback<void, uint32_t, const Address&> callback =
710 
711  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
712  {
713  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
714  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
715  NS_ASSERT(satOrbiterDev != nullptr);
716  Ptr<SatPhy> satPhy;
717  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
718  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
719  it2 != satOrbiterFeederPhys.end();
720  ++it2)
721  {
722  satPhy = it2->second;
723  NS_ASSERT(satPhy != nullptr);
724  Ptr<SatOrbiterFeederPhy> satOrbiterFeederPhy = satPhy->GetObject<SatOrbiterFeederPhy>();
725  NS_ASSERT(satOrbiterFeederPhy != nullptr);
726 
727  if (satOrbiterFeederPhy->TraceConnectWithoutContext("QueueSizePackets", callback))
728  {
729  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
730  << " device #" << satOrbiterDev->GetIfIndex());
731  }
732  else
733  {
734  NS_FATAL_ERROR("Error connecting to QueueSizePackets trace source"
735  << " at node ID " << (*it)->GetId() << " device #"
736  << satOrbiterDev->GetIfIndex());
737  }
738  }
739  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
740 
741 } // end of `void DoInstallProbes ();`
742 
743 // FWD USER QUEUE IN BYTES ////////////////////////////////////////////////////////
744 
745 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserQueueBytesHelper);
746 
748  : SatStatsSatelliteQueueHelper(satHelper)
749 {
750  NS_LOG_FUNCTION(this << satHelper);
752 }
753 
755 {
756  NS_LOG_FUNCTION(this);
757 }
758 
759 TypeId // static
761 {
762  static TypeId tid =
763  TypeId("ns3::SatStatsFwdUserQueueBytesHelper").SetParent<SatStatsSatelliteQueueHelper>();
764  return tid;
765 }
766 
767 void
769 {
770  NS_LOG_FUNCTION(this);
771 
772  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
773  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
774  {
775  // Create a map of UT addresses and identifiers.
777  }
778 
779  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
780  Callback<void, uint32_t, const Address&> callback =
782 
783  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
784  {
785  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
786  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
787  NS_ASSERT(satOrbiterDev != nullptr);
788  Ptr<SatPhy> satPhy;
789  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
790  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
791  it2 != satOrbiterUserPhys.end();
792  ++it2)
793  {
794  satPhy = it2->second;
795  NS_ASSERT(satPhy != nullptr);
796  Ptr<SatOrbiterUserPhy> satOrbiterUserPhy = satPhy->GetObject<SatOrbiterUserPhy>();
797  NS_ASSERT(satOrbiterUserPhy != nullptr);
798 
799  if (satOrbiterUserPhy->TraceConnectWithoutContext("QueueSizeBytes", callback))
800  {
801  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
802  << " device #" << satOrbiterDev->GetIfIndex());
803  }
804  else
805  {
806  NS_FATAL_ERROR("Error connecting to QueueSizeBytes trace source"
807  << " at node ID " << (*it)->GetId() << " device #"
808  << satOrbiterDev->GetIfIndex());
809  }
810  }
811  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
812 
813 } // end of `void DoInstallProbes ();`
814 
815 // FWD USER QUEUE IN PACKETS ////////////////////////////////////////////////////////
816 
817 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserQueuePacketsHelper);
818 
820  : SatStatsSatelliteQueueHelper(satHelper)
821 {
822  NS_LOG_FUNCTION(this << satHelper);
824 }
825 
827 {
828  NS_LOG_FUNCTION(this);
829 }
830 
831 TypeId // static
833 {
834  static TypeId tid =
835  TypeId("ns3::SatStatsFwdUserQueuePacketsHelper").SetParent<SatStatsSatelliteQueueHelper>();
836  return tid;
837 }
838 
839 void
841 {
842  NS_LOG_FUNCTION(this);
843 
844  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
845  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
846  {
847  // Create a map of UT addresses and identifiers.
849  }
850 
851  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
852  Callback<void, uint32_t, const Address&> callback =
854 
855  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
856  {
857  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
858  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
859  NS_ASSERT(satOrbiterDev != nullptr);
860  Ptr<SatPhy> satPhy;
861  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
862  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
863  it2 != satOrbiterUserPhys.end();
864  ++it2)
865  {
866  satPhy = it2->second;
867  NS_ASSERT(satPhy != nullptr);
868  Ptr<SatOrbiterUserPhy> satOrbiterUserPhy = satPhy->GetObject<SatOrbiterUserPhy>();
869  NS_ASSERT(satOrbiterUserPhy != nullptr);
870 
871  if (satOrbiterUserPhy->TraceConnectWithoutContext("QueueSizePackets", callback))
872  {
873  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
874  << " device #" << satOrbiterDev->GetIfIndex());
875  }
876  else
877  {
878  NS_FATAL_ERROR("Error connecting to QueueSizePackets trace source"
879  << " at node ID " << (*it)->GetId() << " device #"
880  << satOrbiterDev->GetIfIndex());
881  }
882  }
883  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
884 
885 } // end of `void DoInstallProbes ();`
886 
887 } // end of namespace ns3
The SatOrbiterFeederPhy models the feeder link physical layer of the satellite node.
SatOrbiterNetDevice to be utilized in geostationary satellite.
The SatOrbiterUserPhy models the user link physical layer of the satellite node.
Produce queue size statistics in packets for return feeder link.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsFwdUserQueueBytesHelper(Ptr< const SatHelper > satHelper)
Produce queue size statistics in packets for return feeder link.
SatStatsFwdUserQueuePacketsHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Parent abstract class of all satellite statistics helpers.
static Ptr< NetDevice > GetSatSatOrbiterNetDevice(Ptr< Node > satNode)
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 CreateCollectorPerIdentifier(CollectorMap &collectorMap) const
Create one collector instance for each identifier in the simulation.
OutputType_t GetOutputType() const
std::map< const Address, uint32_t > m_identifierMap
Map of address and the identifier associated with it.
std::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
virtual std::string GetDistributionHeading(std::string dataLabel) const
Produce queue size statistics in packets for return feeder link.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsRtnFeederQueueBytesHelper(Ptr< const SatHelper > satHelper)
Produce queue size statistics in packets for return feeder link.
static TypeId GetTypeId()
inherited from ObjectBase base class
Base class for sat queue statistics helpers.
SatStatsSatelliteQueueHelper(Ptr< const SatHelper > satHelper)
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
bool ConnectProbeToCollector(Ptr< Probe > probe, uint32_t identifier)
Connect the probe to the right collector.
Ptr< DistributionCollector > m_averagingCollector
The final collector utilized in averaged output (histogram, PDF, and CDF).
void InstallProbes()
Set up several probes or other means of listeners and connect them to the collectors.
static TypeId GetTypeId()
inherited from ObjectBase base class
void QueueSizeCallback(uint32_t size, const Address &addr)
Receive inputs from trace sources and forward them to the collector.
CollectorMap m_terminalCollectors
Maintains a list of collectors created by this helper.
static std::string GetUnitTypeName(UnitType_t unitType)
void PassSampleToCollector(uint32_t size, uint32_t identifier)
Find a collector with the right identifier and pass a sample data to it.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.