satellite-stats-link-modcod-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/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/ipv4.h>
33 #include <ns3/log.h>
34 #include <ns3/mac48-address.h>
35 #include <ns3/magister-gnuplot-aggregator.h>
36 #include <ns3/multi-file-aggregator.h>
37 #include <ns3/net-device.h>
38 #include <ns3/node-container.h>
39 #include <ns3/nstime.h>
40 #include <ns3/probe.h>
41 #include <ns3/satellite-helper.h>
42 #include <ns3/satellite-id-mapper.h>
43 #include <ns3/satellite-net-device.h>
44 #include <ns3/satellite-orbiter-net-device.h>
45 #include <ns3/satellite-phy.h>
46 #include <ns3/satellite-topology.h>
47 #include <ns3/scalar-collector.h>
48 #include <ns3/singleton.h>
49 #include <ns3/string.h>
50 #include <ns3/traffic-time-tag.h>
51 #include <ns3/unit-conversion-collector.h>
52 
53 #include <map>
54 #include <sstream>
55 #include <string>
56 #include <utility>
57 
58 NS_LOG_COMPONENT_DEFINE("SatStatsLinkModcodHelper");
59 
60 namespace ns3
61 {
62 
63 NS_OBJECT_ENSURE_REGISTERED(SatStatsLinkModcodHelper);
64 
66  : SatStatsHelper(satHelper),
67  m_averagingMode(false)
68 {
69  NS_LOG_FUNCTION(this << satHelper);
70 }
71 
73 {
74  NS_LOG_FUNCTION(this);
75 }
76 
77 TypeId // static
79 {
80  static TypeId tid =
81  TypeId("ns3::SatStatsLinkModcodHelper")
82  .SetParent<SatStatsHelper>()
83  .AddAttribute("AveragingMode",
84  "If true, all samples will be averaged before passed to aggregator. "
85  "Only affects histogram, PDF, and CDF output types.",
86  BooleanValue(false),
87  MakeBooleanAccessor(&SatStatsLinkModcodHelper::SetAveragingMode,
89  MakeBooleanChecker());
90  return tid;
91 }
92 
93 void
95 {
96  NS_LOG_FUNCTION(this << averagingMode);
97  m_averagingMode = averagingMode;
98 }
99 
100 bool
102 {
103  return m_averagingMode;
104 }
105 
106 void
108 {
109  NS_LOG_FUNCTION(this);
110 
111  switch (GetOutputType())
112  {
114  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
115  << " is not a valid output type for this statistics.");
116  break;
117 
119  // Setup aggregator.
120  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
121  "OutputFileName",
122  StringValue(GetOutputFileName()),
123  "MultiFileMode",
124  BooleanValue(false),
125  "EnableContextPrinting",
126  BooleanValue(true),
127  "GeneralHeading",
128  StringValue(GetIdentifierHeading("modcod_id")));
129 
130  // Setup collectors.
131  m_terminalCollectors.SetType("ns3::ScalarCollector");
132  m_terminalCollectors.SetAttribute("InputDataType",
133  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
134  m_terminalCollectors.SetAttribute(
135  "OutputType",
136  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
138  m_terminalCollectors.ConnectToAggregator("Output",
139  m_aggregator,
140  &MultiFileAggregator::Write1d);
141  break;
142  }
143 
145  // Setup aggregator.
146  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
147  "OutputFileName",
148  StringValue(GetOutputFileName()),
149  "GeneralHeading",
150  StringValue(GetTimeHeading("modcod_id")));
151 
152  // Setup collectors.
153  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
154  m_terminalCollectors.SetAttribute("ConversionType",
155  EnumValue(UnitConversionCollector::TRANSPARENT));
157  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
158  m_aggregator,
159  &MultiFileAggregator::Write2d);
160  break;
161  }
162 
166  if (m_averagingMode)
167  {
168  // Setup aggregator.
169  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
170  "OutputFileName",
171  StringValue(GetOutputFileName()),
172  "MultiFileMode",
173  BooleanValue(false),
174  "EnableContextPrinting",
175  BooleanValue(false),
176  "GeneralHeading",
177  StringValue(GetDistributionHeading("modcod_id")));
178  Ptr<MultiFileAggregator> fileAggregator =
179  m_aggregator->GetObject<MultiFileAggregator>();
180  NS_ASSERT(fileAggregator != nullptr);
181 
182  // Setup the final-level collector.
183  m_averagingCollector = CreateObject<DistributionCollector>();
184  DistributionCollector::OutputType_t outputType =
185  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
187  {
188  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
189  }
191  {
192  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
193  }
194  m_averagingCollector->SetOutputType(outputType);
195  m_averagingCollector->SetName("0");
196  m_averagingCollector->TraceConnect(
197  "Output",
198  "0",
199  MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
200  m_averagingCollector->TraceConnect(
201  "OutputString",
202  "0",
203  MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
204  m_averagingCollector->TraceConnect(
205  "Warning",
206  "0",
207  MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
208 
209  // Setup collectors.
210  m_terminalCollectors.SetType("ns3::ScalarCollector");
211  m_terminalCollectors.SetAttribute("InputDataType",
212  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
213  m_terminalCollectors.SetAttribute(
214  "OutputType",
215  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
217  Callback<void, double> callback =
218  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
219  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
220  it != m_terminalCollectors.End();
221  ++it)
222  {
223  it->second->TraceConnectWithoutContext("Output", callback);
224  }
225  }
226  else
227  {
228  // Setup aggregator.
229  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
230  "OutputFileName",
231  StringValue(GetOutputFileName()),
232  "GeneralHeading",
233  StringValue(GetDistributionHeading("modcod_id")));
234 
235  // Setup collectors.
236  m_terminalCollectors.SetType("ns3::DistributionCollector");
237  DistributionCollector::OutputType_t outputType =
238  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
240  {
241  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
242  }
244  {
245  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
246  }
247  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
249  m_terminalCollectors.ConnectToAggregator("Output",
250  m_aggregator,
251  &MultiFileAggregator::Write2d);
252  m_terminalCollectors.ConnectToAggregator("OutputString",
253  m_aggregator,
254  &MultiFileAggregator::AddContextHeading);
255  m_terminalCollectors.ConnectToAggregator("Warning",
256  m_aggregator,
257  &MultiFileAggregator::EnableContextWarning);
258  }
259 
260  break;
261  }
262 
265  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
266  << " is not a valid output type for this statistics.");
267  break;
268 
270  // Setup aggregator.
271  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
272  "OutputPath",
273  StringValue(GetOutputPath()),
274  "OutputFileName",
275  StringValue(GetName()));
276  Ptr<MagisterGnuplotAggregator> plotAggregator =
277  m_aggregator->GetObject<MagisterGnuplotAggregator>();
278  NS_ASSERT(plotAggregator != nullptr);
279  // plot->SetTitle ("");
280  plotAggregator->SetLegend("Time (in seconds)", "MODCOD ID");
281  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
282 
283  // Setup collectors.
284  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
285  m_terminalCollectors.SetAttribute("ConversionType",
286  EnumValue(UnitConversionCollector::TRANSPARENT));
288  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
289  it != m_terminalCollectors.End();
290  ++it)
291  {
292  const std::string context = it->second->GetName();
293  plotAggregator->Add2dDataset(context, context);
294  }
295  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
296  m_aggregator,
297  &MagisterGnuplotAggregator::Write2d);
298  break;
299  }
300 
304  if (m_averagingMode)
305  {
306  // Setup aggregator.
307  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
308  "OutputPath",
309  StringValue(GetOutputPath()),
310  "OutputFileName",
311  StringValue(GetName()));
312  Ptr<MagisterGnuplotAggregator> plotAggregator =
313  m_aggregator->GetObject<MagisterGnuplotAggregator>();
314  NS_ASSERT(plotAggregator != nullptr);
315  // plot->SetTitle ("");
316  plotAggregator->SetLegend("MODCOD ID", "Frequency");
317  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
318  plotAggregator->Add2dDataset(GetName(), GetName());
320 
321  // Setup the final-level collector.
322  m_averagingCollector = CreateObject<DistributionCollector>();
323  DistributionCollector::OutputType_t outputType =
324  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
326  {
327  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
328  }
330  {
331  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
332  }
333  m_averagingCollector->SetOutputType(outputType);
334  m_averagingCollector->SetName("0");
335  m_averagingCollector->TraceConnect(
336  "Output",
337  GetName(),
338  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
340 
341  // Setup collectors.
342  m_terminalCollectors.SetType("ns3::ScalarCollector");
343  m_terminalCollectors.SetAttribute("InputDataType",
344  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
345  m_terminalCollectors.SetAttribute(
346  "OutputType",
347  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
349  Callback<void, double> callback =
350  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
351  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
352  it != m_terminalCollectors.End();
353  ++it)
354  {
355  it->second->TraceConnectWithoutContext("Output", callback);
356  }
357  }
358  else
359  {
360  // Setup aggregator.
361  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
362  "OutputPath",
363  StringValue(GetOutputPath()),
364  "OutputFileName",
365  StringValue(GetName()));
366  Ptr<MagisterGnuplotAggregator> plotAggregator =
367  m_aggregator->GetObject<MagisterGnuplotAggregator>();
368  NS_ASSERT(plotAggregator != nullptr);
369  // plot->SetTitle ("");
370  plotAggregator->SetLegend("MODCOD ID", "Frequency");
371  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
372 
373  // Setup collectors.
374  m_terminalCollectors.SetType("ns3::DistributionCollector");
375  DistributionCollector::OutputType_t outputType =
376  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
378  {
379  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
380  }
382  {
383  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
384  }
385  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
387  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
388  it != m_terminalCollectors.End();
389  ++it)
390  {
391  const std::string context = it->second->GetName();
392  plotAggregator->Add2dDataset(context, context);
393  }
394  m_terminalCollectors.ConnectToAggregator("Output",
395  m_aggregator,
396  &MagisterGnuplotAggregator::Write2d);
397  }
398 
399  break;
400  }
401 
402  default:
403  NS_FATAL_ERROR("SatStatsLinkModcodHelper - Invalid output type");
404  break;
405  }
406 
407  // Setup probes and connect them to the collectors.
408  InstallProbes();
409 
410 } // end of `void DoInstall ();`
411 
412 void
414 {
415  // The method below is supposed to be implemented by the child class.
416  DoInstallProbes();
417 }
418 
419 void
420 SatStatsLinkModcodHelper::RxLinkModcodCallback(uint32_t modcod, const Address& from)
421 {
422  if (from.IsInvalid())
423  {
424  NS_LOG_WARN(this << " discarding a packet MODCOD ID " << modcod
425  << " from statistics collection because of"
426  << " invalid sender address");
427  }
428  else if (Mac48Address::ConvertFrom(from).IsBroadcast())
429  {
430  for (std::pair<const Address, uint32_t> item : m_identifierMap)
431  {
432  PassSampleToCollector(modcod, item.second);
433  }
434  }
435  else
436  {
437  // Determine the identifier associated with the sender address.
438  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
439 
440  if (it != m_identifierMap.end())
441  {
442  PassSampleToCollector(modcod, it->second);
443  }
444  else
445  {
446  NS_LOG_WARN(this << " discarding a packet MODCOD ID " << modcod
447  << " from statistics collection because of"
448  << " unknown sender address " << from);
449  }
450  }
451 }
452 
453 bool
454 SatStatsLinkModcodHelper::ConnectProbeToCollector(Ptr<Probe> probe, uint32_t identifier)
455 {
456  NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
457 
458  bool ret = false;
459  switch (GetOutputType())
460  {
463  ret = m_terminalCollectors.ConnectWithProbe(probe,
464  "OutputSeconds",
465  identifier,
466  &ScalarCollector::TraceSinkDouble);
467  break;
468 
471  ret = m_terminalCollectors.ConnectWithProbe(probe,
472  "OutputSeconds",
473  identifier,
474  &UnitConversionCollector::TraceSinkDouble);
475  break;
476 
483  if (m_averagingMode)
484  {
485  ret = m_terminalCollectors.ConnectWithProbe(probe,
486  "OutputSeconds",
487  identifier,
488  &ScalarCollector::TraceSinkDouble);
489  }
490  else
491  {
492  ret = m_terminalCollectors.ConnectWithProbe(probe,
493  "OutputSeconds",
494  identifier,
495  &DistributionCollector::TraceSinkDouble);
496  }
497  break;
498 
499  default:
500  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
501  << " is not a valid output type for this statistics.");
502  break;
503  }
504 
505  if (ret)
506  {
507  NS_LOG_INFO(this << " created probe " << probe->GetName() << ", connected to collector "
508  << identifier);
509  }
510  else
511  {
512  NS_LOG_WARN(this << " unable to connect probe " << probe->GetName() << " to collector "
513  << identifier);
514  }
515 
516  return ret;
517 }
518 
519 void
520 SatStatsLinkModcodHelper::PassSampleToCollector(uint32_t modcod, uint32_t identifier)
521 {
522  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifier);
523  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << identifier);
524 
525  switch (GetOutputType())
526  {
529  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
530  NS_ASSERT(c != nullptr);
531  c->TraceSinkUinteger32(0.0, modcod);
532  break;
533  }
534 
537  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
538  NS_ASSERT(c != nullptr);
539  c->TraceSinkUinteger32(0.0, modcod);
540  break;
541  }
542 
549  if (m_averagingMode)
550  {
551  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
552  NS_ASSERT(c != nullptr);
553  c->TraceSinkUinteger32(0.0, modcod);
554  }
555  else
556  {
557  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
558  NS_ASSERT(c != nullptr);
559  c->TraceSinkUinteger32(0.0, modcod);
560  }
561  break;
562 
563  default:
564  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
565  << " is not a valid output type for this statistics.");
566  break;
567 
568  } // end of `switch (GetOutputType ())`
569 
570 } // end of `void PassSampleToCollector (Time, uint32_t)`
571 
572 // FORWARD FEEDER LINK /////////////////////////////////////////////////////
573 
574 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederLinkModcodHelper);
575 
577  : SatStatsLinkModcodHelper(satHelper)
578 {
579  NS_LOG_FUNCTION(this << satHelper);
580 }
581 
583 {
584  NS_LOG_FUNCTION(this);
585 }
586 
587 TypeId // static
589 {
590  static TypeId tid =
591  TypeId("ns3::SatStatsFwdFeederLinkModcodHelper").SetParent<SatStatsLinkModcodHelper>();
592  return tid;
593 }
594 
595 void
597 {
598  NS_LOG_FUNCTION(this);
599 
600  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
601  Callback<void, uint32_t, const Address&> callback =
603 
604  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
605  {
606  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
607  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
608  NS_ASSERT(satOrbiterDev != nullptr);
609  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
610  Ptr<SatPhy> satPhy;
611  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
612  it2 != satOrbiterFeederPhys.end();
613  ++it2)
614  {
615  satPhy = it2->second;
616  NS_ASSERT(satPhy != nullptr);
617  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
618 
619  // Connect the object to the probe.
620  if (satPhy->TraceConnectWithoutContext("RxLinkModcod", callback))
621  {
622  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
623  << " device #" << satOrbiterDev->GetIfIndex());
624 
625  // Enable statistics-related tags and trace sources on the device.
626  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
627  }
628  else
629  {
630  NS_FATAL_ERROR("Error connecting to RxLinkModcod trace source of SatNetDevice"
631  << " at node ID " << (*it)->GetId() << " device #"
632  << satOrbiterDev->GetIfIndex());
633  }
634  }
635  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
636  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
637  it2 != satOrbiterUserPhys.end();
638  ++it2)
639  {
640  satPhy = it2->second;
641  NS_ASSERT(satPhy != nullptr);
642  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
643  }
644  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
645 
646  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
647 
648  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
649  {
650  // Create a map of UT addresses and identifiers.
652 
653  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
654  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
655  NS_ASSERT(satDev != nullptr);
656  Ptr<SatPhy> satPhy = satDev->GetPhy();
657  NS_ASSERT(satPhy != nullptr);
658 
659  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
660 
661  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
662 
663  // Enable statistics-related tags on the transmitting device.
664  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
665  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
666  {
667  NetDeviceContainer devs = GetGwSatNetDevice(*it);
668 
669  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
670  {
671  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
672  NS_ASSERT(satDev != nullptr);
673  Ptr<SatPhy> satPhy = satDev->GetPhy();
674  NS_ASSERT(satPhy != nullptr);
675 
676  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
677  }
678  }
679 
680 } // end of `void DoInstallProbes ();`
681 
682 // FORWARD USER LINK /////////////////////////////////////////////////////
683 
684 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserLinkModcodHelper);
685 
687  : SatStatsLinkModcodHelper(satHelper)
688 {
689  NS_LOG_FUNCTION(this << satHelper);
690 }
691 
693 {
694  NS_LOG_FUNCTION(this);
695 }
696 
697 TypeId // static
699 {
700  static TypeId tid =
701  TypeId("ns3::SatStatsFwdUserLinkModcodHelper").SetParent<SatStatsLinkModcodHelper>();
702  return tid;
703 }
704 
705 void
707 {
708  NS_LOG_FUNCTION(this);
709 
710  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
711  Callback<void, uint32_t, const Address&> callback =
713 
714  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
715  {
716  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
717  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
718  NS_ASSERT(satOrbiterDev != nullptr);
719  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
720  Ptr<SatPhy> satPhy;
721  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
722  it2 != satOrbiterFeederPhys.end();
723  ++it2)
724  {
725  satPhy = it2->second;
726  NS_ASSERT(satPhy != nullptr);
727  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
728  }
729  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
730  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
731  it2 != satOrbiterUserPhys.end();
732  ++it2)
733  {
734  satPhy = it2->second;
735  NS_ASSERT(satPhy != nullptr);
736  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
737  }
738  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
739 
740  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
741 
742  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
743  {
744  // Create a map of UT addresses and identifiers.
746 
747  const int32_t utId = GetUtId(*it);
748  NS_ASSERT_MSG(utId > 0, "Node " << (*it)->GetId() << " is not a valid UT");
749 
750  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
751  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
752  NS_ASSERT(satDev != nullptr);
753  Ptr<SatPhy> satPhy = satDev->GetPhy();
754  NS_ASSERT(satPhy != nullptr);
755 
756  // Connect the object to the probe.
757  if (satPhy->TraceConnectWithoutContext("RxLinkModcod", callback))
758  {
759  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
760  << " device #2");
761 
762  // Enable statistics-related tags and trace sources on the device.
763  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
764  }
765  else
766  {
767  NS_FATAL_ERROR("Error connecting to RxLinkModcod trace source of SatPhy"
768  << " at node ID " << (*it)->GetId() << " device #2");
769  }
770 
771  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
772 
773  // Enable statistics-related tags on the transmitting device.
774  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
775  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
776  {
777  NetDeviceContainer devs = GetGwSatNetDevice(*it);
778 
779  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
780  {
781  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
782  NS_ASSERT(satDev != nullptr);
783  Ptr<SatPhy> satPhy = satDev->GetPhy();
784  NS_ASSERT(satPhy != nullptr);
785 
786  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
787  }
788  }
789 
790 } // end of `void DoInstallProbes ();`
791 
792 // RETURN FEEDER LINK //////////////////////////////////////////////////////
793 
794 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederLinkModcodHelper);
795 
797  : SatStatsLinkModcodHelper(satHelper)
798 {
799  NS_LOG_FUNCTION(this << satHelper);
800 }
801 
803 {
804  NS_LOG_FUNCTION(this);
805 }
806 
807 TypeId // static
809 {
810  static TypeId tid =
811  TypeId("ns3::SatStatsRtnFeederLinkModcodHelper").SetParent<SatStatsLinkModcodHelper>();
812  return tid;
813 }
814 
815 void
817 {
818  NS_LOG_FUNCTION(this);
819 
820  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
821 
822  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
823  {
824  Ptr<SatPhy> satPhy;
825  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
826  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
827  NS_ASSERT(satOrbiterDev != nullptr);
828  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
829  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
830  it2 != satOrbiterFeederPhys.end();
831  ++it2)
832  {
833  satPhy = it2->second;
834  NS_ASSERT(satPhy != nullptr);
835  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
836  }
837  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
838  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
839  it2 != satOrbiterUserPhys.end();
840  ++it2)
841  {
842  satPhy = it2->second;
843  NS_ASSERT(satPhy != nullptr);
844  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
845  }
846  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
847 
848  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
849  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
850  {
851  // Create a map of UT addresses and identifiers.
853 
854  // Enable statistics-related tags and trace sources on the device.
855  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
856  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
857  NS_ASSERT(satDev != nullptr);
858  Ptr<SatPhy> satPhy = satDev->GetPhy();
859  NS_ASSERT(satPhy != nullptr);
860  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
861  }
862 
863  // Connect to trace sources at GW nodes.
864 
865  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
866  Callback<void, uint32_t, const Address&> callback =
868 
869  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
870  {
871  NetDeviceContainer devs = GetGwSatNetDevice(*it);
872 
873  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
874  {
875  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
876  NS_ASSERT(satDev != nullptr);
877  Ptr<SatPhy> satPhy = satDev->GetPhy();
878  NS_ASSERT(satPhy != nullptr);
879 
880  // Connect the object to the probe.
881  if (satPhy->TraceConnectWithoutContext("RxLinkModcod", callback))
882  {
883  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
884  << " device #" << satDev->GetIfIndex());
885 
886  // Enable statistics-related tags and trace sources on the device.
887  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
888  }
889  else
890  {
891  NS_FATAL_ERROR("Error connecting to RxLinkModcod trace source of SatNetDevice"
892  << " at node ID " << (*it)->GetId() << " device #"
893  << satDev->GetIfIndex());
894  }
895 
896  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
897 
898  } // end of `for (NodeContainer::Iterator it = gws)`
899 
900 } // end of `void DoInstallProbes ();`
901 
902 // RETURN USER LINK //////////////////////////////////////////////////////
903 
904 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserLinkModcodHelper);
905 
907  : SatStatsLinkModcodHelper(satHelper)
908 {
909  NS_LOG_FUNCTION(this << satHelper);
910 }
911 
913 {
914  NS_LOG_FUNCTION(this);
915 }
916 
917 TypeId // static
919 {
920  static TypeId tid =
921  TypeId("ns3::SatStatsRtnUserLinkModcodHelper").SetParent<SatStatsLinkModcodHelper>();
922  return tid;
923 }
924 
925 void
927 {
928  NS_LOG_FUNCTION(this);
929 
930  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
931  Callback<void, uint32_t, const Address&> callback =
933 
934  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
935  {
936  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
937  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
938  NS_ASSERT(satOrbiterDev != nullptr);
939  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
940  Ptr<SatPhy> satPhy;
941  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterFeederPhys.begin();
942  it2 != satOrbiterFeederPhys.end();
943  ++it2)
944  {
945  satPhy = it2->second;
946  NS_ASSERT(satPhy != nullptr);
947  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
948  }
949  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
950  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
951  it2 != satOrbiterUserPhys.end();
952  ++it2)
953  {
954  satPhy = it2->second;
955  NS_ASSERT(satPhy != nullptr);
956  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
957 
958  // Connect the object to the probe.
959  if (satPhy->TraceConnectWithoutContext("RxLinkModcod", callback))
960  {
961  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
962  << " device #" << satOrbiterDev->GetIfIndex());
963  }
964  else
965  {
966  NS_FATAL_ERROR("Error connecting to RxLinkModcod trace source of SatNetDevice"
967  << " at node ID " << (*it)->GetId() << " device #"
968  << satOrbiterDev->GetIfIndex());
969  }
970  }
971  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
972 
973  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
974  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
975  {
976  // Create a map of UT addresses and identifiers.
978 
979  // Enable statistics-related tags and trace sources on the device.
980  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
981  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
982  NS_ASSERT(satDev != nullptr);
983  Ptr<SatPhy> satPhy = satDev->GetPhy();
984  NS_ASSERT(satPhy != nullptr);
985  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
986  }
987 
988  // Connect to trace sources at GW nodes.
989 
990  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
991 
992  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
993  {
994  NetDeviceContainer devs = GetGwSatNetDevice(*it);
995 
996  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
997  {
998  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
999  NS_ASSERT(satDev != nullptr);
1000  Ptr<SatPhy> satPhy = satDev->GetPhy();
1001  NS_ASSERT(satPhy != nullptr);
1002 
1003  satPhy->SetAttribute("EnableStatisticsTags", BooleanValue(true));
1004  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
1005 
1006  } // end of `for (NodeContainer::Iterator it = gws)`
1007 
1008 } // end of `void DoInstallProbes ();`
1009 
1010 } // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
SatOrbiterNetDevice to be utilized in geostationary satellite.
Parent abstract class of all satellite statistics helpers.
static Ptr< NetDevice > GetSatSatOrbiterNetDevice(Ptr< Node > satNode)
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
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
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.