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