satellite-stats-link-sinr-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-net-device.h>
41 #include <ns3/satellite-orbiter-net-device.h>
42 #include <ns3/satellite-phy-rx-carrier.h>
43 #include <ns3/satellite-phy-rx.h>
44 #include <ns3/satellite-phy.h>
45 #include <ns3/satellite-topology.h>
46 #include <ns3/scalar-collector.h>
47 #include <ns3/singleton.h>
48 #include <ns3/string.h>
49 #include <ns3/unit-conversion-collector.h>
50 
51 #include <map>
52 #include <sstream>
53 #include <string>
54 #include <utility>
55 
56 NS_LOG_COMPONENT_DEFINE("SatStatsLinkSinrHelper");
57 
58 namespace ns3
59 {
60 
61 NS_OBJECT_ENSURE_REGISTERED(SatStatsLinkSinrHelper);
62 
63 SatStatsLinkSinrHelper::SatStatsLinkSinrHelper(Ptr<const SatHelper> satHelper)
64  : SatStatsHelper(satHelper),
65  m_traceSinkCallback(MakeCallback(&SatStatsLinkSinrHelper::SinrCallback, this))
66 {
67  NS_LOG_FUNCTION(this << satHelper);
68 }
69 
71 {
72  NS_LOG_FUNCTION(this);
73 }
74 
75 TypeId // static
77 {
78  static TypeId tid = TypeId("ns3::SatStatsLinkSinrHelper").SetParent<SatStatsHelper>();
79  return tid;
80 }
81 
82 void
84 {
85  NS_LOG_FUNCTION(this << averagingMode);
86  m_averagingMode = averagingMode;
87 }
88 
89 Callback<void, double, const Address&>
91 {
92  return m_traceSinkCallback;
93 }
94 
95 void
97 {
98  NS_LOG_FUNCTION(this);
99 
100  switch (GetOutputType())
101  {
103  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
104  << " is not a valid output type for this statistics.");
105  break;
106 
108  // Setup aggregator.
109  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
110  "OutputFileName",
111  StringValue(GetOutputFileName()),
112  "MultiFileMode",
113  BooleanValue(false),
114  "EnableContextPrinting",
115  BooleanValue(true),
116  "GeneralHeading",
117  StringValue(GetIdentifierHeading("sinr_db")));
118 
119  // Setup collectors.
120  m_terminalCollectors.SetType("ns3::ScalarCollector");
121  m_terminalCollectors.SetAttribute("InputDataType",
122  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
123  m_terminalCollectors.SetAttribute(
124  "OutputType",
125  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
127  m_terminalCollectors.ConnectToAggregator("Output",
128  m_aggregator,
129  &MultiFileAggregator::Write1d);
130  break;
131  }
132 
134  // Setup aggregator.
135  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
136  "OutputFileName",
137  StringValue(GetOutputFileName()),
138  "GeneralHeading",
139  StringValue(GetTimeHeading("sinr_db")));
140 
141  // Setup collectors.
142  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
143  m_terminalCollectors.SetAttribute("ConversionType",
144  EnumValue(UnitConversionCollector::TRANSPARENT));
146  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
147  m_aggregator,
148  &MultiFileAggregator::Write2d);
149  break;
150  }
151 
155  if (m_averagingMode)
156  {
157  // Setup aggregator.
158  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
159  "OutputFileName",
160  StringValue(GetOutputFileName()),
161  "MultiFileMode",
162  BooleanValue(false),
163  "EnableContextPrinting",
164  BooleanValue(false),
165  "GeneralHeading",
166  StringValue(GetDistributionHeading("sinr_db")));
167  Ptr<MultiFileAggregator> fileAggregator =
168  m_aggregator->GetObject<MultiFileAggregator>();
169  NS_ASSERT(fileAggregator != nullptr);
170 
171  // Setup the final-level collector.
172  m_averagingCollector = CreateObject<DistributionCollector>();
173  DistributionCollector::OutputType_t outputType =
174  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
176  {
177  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
178  }
180  {
181  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
182  }
183  m_averagingCollector->SetOutputType(outputType);
184  m_averagingCollector->SetName("0");
185  m_averagingCollector->TraceConnect(
186  "Output",
187  "0",
188  MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
189  m_averagingCollector->TraceConnect(
190  "OutputString",
191  "0",
192  MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
193  m_averagingCollector->TraceConnect(
194  "Warning",
195  "0",
196  MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
197 
198  // Setup collectors.
199  m_terminalCollectors.SetType("ns3::ScalarCollector");
200  m_terminalCollectors.SetAttribute("InputDataType",
201  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
202  m_terminalCollectors.SetAttribute(
203  "OutputType",
204  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
206  Callback<void, double> callback =
207  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
208  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
209  it != m_terminalCollectors.End();
210  ++it)
211  {
212  it->second->TraceConnectWithoutContext("Output", callback);
213  }
214  }
215  else
216  {
217  // Setup aggregator.
218  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
219  "OutputFileName",
220  StringValue(GetOutputFileName()),
221  "GeneralHeading",
222  StringValue(GetDistributionHeading("sinr_db")));
223 
224  // Setup collectors.
225  m_terminalCollectors.SetType("ns3::DistributionCollector");
226  DistributionCollector::OutputType_t outputType =
227  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
229  {
230  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
231  }
233  {
234  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
235  }
236  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
238  m_terminalCollectors.ConnectToAggregator("Output",
239  m_aggregator,
240  &MultiFileAggregator::Write2d);
241  m_terminalCollectors.ConnectToAggregator("OutputString",
242  m_aggregator,
243  &MultiFileAggregator::AddContextHeading);
244  m_terminalCollectors.ConnectToAggregator("Warning",
245  m_aggregator,
246  &MultiFileAggregator::EnableContextWarning);
247  }
248 
249  break;
250  }
251 
254  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
255  << " is not a valid output type for this statistics.");
256  break;
257 
259  // Setup aggregator.
260  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
261  "OutputPath",
262  StringValue(GetOutputPath()),
263  "OutputFileName",
264  StringValue(GetName()));
265  Ptr<MagisterGnuplotAggregator> plotAggregator =
266  m_aggregator->GetObject<MagisterGnuplotAggregator>();
267  NS_ASSERT(plotAggregator != nullptr);
268  // plot->SetTitle ("");
269  plotAggregator->SetLegend("SINR (in dB)", "Frequency");
270  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
271 
272  // Setup collectors.
273  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
274  m_terminalCollectors.SetAttribute("ConversionType",
275  EnumValue(UnitConversionCollector::TRANSPARENT));
277  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
278  it != m_terminalCollectors.End();
279  ++it)
280  {
281  const std::string context = it->second->GetName();
282  plotAggregator->Add2dDataset(context, context);
283  }
284  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
285  m_aggregator,
286  &MagisterGnuplotAggregator::Write2d);
287  break;
288  }
289 
293  if (m_averagingMode)
294  {
295  // Setup aggregator.
296  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
297  "OutputPath",
298  StringValue(GetOutputPath()),
299  "OutputFileName",
300  StringValue(GetName()));
301  Ptr<MagisterGnuplotAggregator> plotAggregator =
302  m_aggregator->GetObject<MagisterGnuplotAggregator>();
303  NS_ASSERT(plotAggregator != nullptr);
304  // plot->SetTitle ("");
305  plotAggregator->SetLegend("SINR (in dB)", "Frequency");
306  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
307  plotAggregator->Add2dDataset(GetName(), GetName());
309 
310  // Setup the final-level collector.
311  m_averagingCollector = CreateObject<DistributionCollector>();
312  DistributionCollector::OutputType_t outputType =
313  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
315  {
316  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
317  }
319  {
320  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
321  }
322  m_averagingCollector->SetOutputType(outputType);
323  m_averagingCollector->SetName("0");
324  m_averagingCollector->TraceConnect(
325  "Output",
326  GetName(),
327  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
329 
330  // Setup collectors.
331  m_terminalCollectors.SetType("ns3::ScalarCollector");
332  m_terminalCollectors.SetAttribute("InputDataType",
333  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
334  m_terminalCollectors.SetAttribute(
335  "OutputType",
336  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
338  Callback<void, double> callback =
339  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
340  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
341  it != m_terminalCollectors.End();
342  ++it)
343  {
344  it->second->TraceConnectWithoutContext("Output", callback);
345  }
346  }
347  else
348  {
349  // Setup aggregator.
350  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
351  "OutputPath",
352  StringValue(GetOutputPath()),
353  "OutputFileName",
354  StringValue(GetName()));
355  Ptr<MagisterGnuplotAggregator> plotAggregator =
356  m_aggregator->GetObject<MagisterGnuplotAggregator>();
357  NS_ASSERT(plotAggregator != nullptr);
358  // plot->SetTitle ("");
359  plotAggregator->SetLegend("SINR (in dB)", "Frequency");
360  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
361 
362  // Setup collectors.
363  m_terminalCollectors.SetType("ns3::DistributionCollector");
364  DistributionCollector::OutputType_t outputType =
365  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
367  {
368  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
369  }
371  {
372  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
373  }
374  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
376  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
377  it != m_terminalCollectors.End();
378  ++it)
379  {
380  const std::string context = it->second->GetName();
381  plotAggregator->Add2dDataset(context, context);
382  }
383  m_terminalCollectors.ConnectToAggregator("Output",
384  m_aggregator,
385  &MagisterGnuplotAggregator::Write2d);
386  }
387 
388  break;
389  }
390 
391  default:
392  NS_FATAL_ERROR("SatStatsLinkDelayHelper - Invalid output type");
393  break;
394  }
395 
396  // Setup probes and connect them to the collectors.
397  InstallProbes();
398 
399 } // end of `void DoInstall ();`
400 
401 void
402 SatStatsLinkSinrHelper::SinrCallback(double sinrDb, const Address& from)
403 {
404  // NS_LOG_FUNCTION (this << sinrDb << from);
405 
406  if (from.IsInvalid())
407  {
408  NS_LOG_WARN(this << " discarding a packet with a sinr of " << sinrDb << "dB"
409  << " from statistics collection because of"
410  << " invalid sender address");
411  }
412  else if (Mac48Address::ConvertFrom(from).IsBroadcast())
413  {
414  for (std::pair<const Address, uint32_t> item : m_identifierMap)
415  {
416  PassSampleToCollector(sinrDb, item.second);
417  }
418  }
419  else
420  {
421  // Determine the identifier associated with the sender address.
422  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
423 
424  if (it != m_identifierMap.end())
425  {
426  PassSampleToCollector(sinrDb, it->second);
427  }
428  else
429  {
430  NS_LOG_WARN(this << " discarding a packet with a sinr of " << sinrDb << "dB"
431  << " from statistics collection because of"
432  << " unknown sender address " << from);
433  }
434  }
435 }
436 
437 bool
438 SatStatsLinkSinrHelper::ConnectProbeToCollector(Ptr<Probe> probe, uint32_t identifier)
439 {
440  NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
441 
442  bool ret = false;
443  switch (GetOutputType())
444  {
447  ret = m_terminalCollectors.ConnectWithProbe(probe,
448  "OutputSeconds",
449  identifier,
450  &ScalarCollector::TraceSinkDouble);
451  break;
452 
455  ret = m_terminalCollectors.ConnectWithProbe(probe,
456  "OutputSeconds",
457  identifier,
458  &UnitConversionCollector::TraceSinkDouble);
459  break;
460 
467  if (m_averagingMode)
468  {
469  ret = m_terminalCollectors.ConnectWithProbe(probe,
470  "OutputSeconds",
471  identifier,
472  &ScalarCollector::TraceSinkDouble);
473  }
474  else
475  {
476  ret = m_terminalCollectors.ConnectWithProbe(probe,
477  "OutputSeconds",
478  identifier,
479  &DistributionCollector::TraceSinkDouble);
480  }
481  break;
482 
483  default:
484  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
485  << " is not a valid output type for this statistics.");
486  break;
487  }
488 
489  if (ret)
490  {
491  NS_LOG_INFO(this << " created probe " << probe->GetName() << ", connected to collector "
492  << identifier);
493  }
494  else
495  {
496  NS_LOG_WARN(this << " unable to connect probe " << probe->GetName() << " to collector "
497  << identifier);
498  }
499 
500  return ret;
501 }
502 
503 void
504 SatStatsLinkSinrHelper::PassSampleToCollector(double sinrDb, uint32_t identifier)
505 {
506  // NS_LOG_FUNCTION (this << sinrDb << identifier);
507 
508  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifier);
509  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << identifier);
510 
511  switch (GetOutputType())
512  {
515  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
516  NS_ASSERT(c != nullptr);
517  c->TraceSinkDouble(0.0, sinrDb);
518  break;
519  }
520 
523  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
524  NS_ASSERT(c != nullptr);
525  c->TraceSinkDouble(0.0, sinrDb);
526  break;
527  }
528 
535  if (m_averagingMode)
536  {
537  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
538  NS_ASSERT(c != nullptr);
539  c->TraceSinkDouble(0.0, sinrDb);
540  }
541  else
542  {
543  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
544  NS_ASSERT(c != nullptr);
545  c->TraceSinkDouble(0.0, sinrDb);
546  }
547  break;
548 
549  default:
550  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
551  << " is not a valid output type for this statistics.");
552  break;
553 
554  } // end of `switch (GetOutputType ())`
555 
556 } // end of `void PassSampleToCollector (double, uint32_t)`
557 
558 void
560 {
561  // The method below is supposed to be implemented by the child class.
562  DoInstallProbes();
563 }
564 
565 // FORWARD FEEDER LINK ////////////////////////////////////////////////////////
566 
567 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederLinkSinrHelper);
568 
570  : SatStatsLinkSinrHelper(satHelper)
571 {
572  NS_LOG_FUNCTION(this << satHelper);
573 }
574 
576 {
577  NS_LOG_FUNCTION(this);
578 }
579 
580 TypeId // static
582 {
583  static TypeId tid =
584  TypeId("ns3::SatStatsFwdFeederLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
585  return tid;
586 }
587 
588 void
590 {
591  NS_LOG_FUNCTION(this);
592 
593  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
594 
595  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
596  {
597  // Create a map of UT addresses and identifiers.
599  }
600 
601  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
602 
603  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
604  {
605  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
606  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
607  NS_ASSERT(satOrbiterDev != nullptr);
608  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
609  ObjectMapValue phy;
610  satOrbiterDev->GetAttribute("FeederPhy", phy);
611  NS_LOG_DEBUG(this << " OrbiterSat Node ID " << (*it)->GetId() << " device #"
612  << dev->GetIfIndex() << " has " << phy.GetN() << " PHY instance(s)");
613 
614  for (ObjectMapValue::Iterator itPhy = phy.Begin(); itPhy != phy.End(); ++itPhy)
615  {
616  Ptr<SatPhy> satPhy = itPhy->second->GetObject<SatPhy>();
617  NS_ASSERT(satPhy != nullptr);
618  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
619  NS_ASSERT(satPhyRx != nullptr);
620  ObjectVectorValue carriers;
621  satPhyRx->GetAttribute("RxCarrierList", carriers);
622  NS_LOG_DEBUG(this << " PHY #" << itPhy->first << " has " << carriers.GetN()
623  << " RX carrier(s)");
624 
625  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
626  itCarrier != carriers.End();
627  ++itCarrier)
628  {
629  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_FEEDER_CH)
630  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr",
632  {
633  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
634  << " of SatPhyRxCarrier"
635  << " at OrbiterSat node ID " << (*it)->GetId() << " device #"
636  << dev->GetIfIndex() << " PHY #" << itPhy->first
637  << " RX carrier #" << itCarrier->first);
638  }
639 
640  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
641 
642  } // end of `for (ObjectMapValue::Iterator itPhy = phys)`
643  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
644 
645 } // end of `void DoInstallProbes ();`
646 
647 // FORWARD USER LINK ////////////////////////////////////////////////////////
648 
649 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserLinkSinrHelper);
650 
652  : SatStatsLinkSinrHelper(satHelper)
653 {
654  NS_LOG_FUNCTION(this << satHelper);
655 }
656 
658 {
659  NS_LOG_FUNCTION(this);
660 }
661 
662 TypeId // static
664 {
665  static TypeId tid =
666  TypeId("ns3::SatStatsFwdUserLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
667  return tid;
668 }
669 
670 void
672 {
673  NS_LOG_FUNCTION(this);
674 
675  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
676  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
677  {
678  // Create a map of UT addresses and identifiers.
680 
681  // const int32_t utId = GetUtId (*it);
682  // NS_ASSERT_MSG (utId > 0,
683  // "Node " << (*it)->GetId () << " is not a valid UT");
684  // const uint32_t identifier = GetIdentifierForUt (*it);
685  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
686  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
687  NS_ASSERT(satDev != nullptr);
688  Ptr<SatPhy> satPhy = satDev->GetPhy();
689  NS_ASSERT(satPhy != nullptr);
690  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
691  NS_ASSERT(satPhyRx != nullptr);
692  ObjectVectorValue carriers;
693  satPhyRx->GetAttribute("RxCarrierList", carriers);
694  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #" << dev->GetIfIndex()
695  << " has " << carriers.GetN() << " RX carriers");
696 
697  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
698  ++itCarrier)
699  {
700  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_USER_CH)
701  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr", GetTraceSinkCallback()))
702  {
703  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
704  << " of SatPhyRxCarrier"
705  << " at node ID " << (*it)->GetId() << " device #"
706  << dev->GetIfIndex() << " RX carrier #" << itCarrier->first);
707  }
708 
709  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
710 
711  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
712 
713 } // end of `void DoInstallProbes ();`
714 
715 // RETURN FEEDER LINK ////////////////////////////////////////////////////////
716 
717 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederLinkSinrHelper);
718 
720  : SatStatsLinkSinrHelper(satHelper)
721 {
722  NS_LOG_FUNCTION(this << satHelper);
723 }
724 
726 {
727  NS_LOG_FUNCTION(this);
728 }
729 
730 TypeId // static
732 {
733  static TypeId tid =
734  TypeId("ns3::SatStatsRtnFeederLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
735  return tid;
736 }
737 
738 void
740 {
741  NS_LOG_FUNCTION(this);
742 
743  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
744  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
745  {
746  // Create a map of UT addresses and identifiers.
748  }
749 
750  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
751  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
752  {
753  NetDeviceContainer devs = GetGwSatNetDevice(*it);
754 
755  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
756  {
757  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
758  NS_ASSERT(satDev != nullptr);
759  Ptr<SatPhy> satPhy = satDev->GetPhy();
760  NS_ASSERT(satPhy != nullptr);
761  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
762  NS_ASSERT(satPhyRx != nullptr);
763  ObjectVectorValue carriers;
764  satPhyRx->GetAttribute("RxCarrierList", carriers);
765  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
766  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
767  << " RX carriers");
768 
769  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
770  itCarrier != carriers.End();
771  ++itCarrier)
772  {
773  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
774  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr",
776  {
777  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
778  << " of SatPhyRxCarrier"
779  << " at node ID " << (*it)->GetId() << " device #"
780  << (*itDev)->GetIfIndex() << " RX carrier #"
781  << itCarrier->first);
782  }
783 
784  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
785 
786  } // end of `for (it = gws.Begin(); it != gws.End (); ++it)`
787 
788  } // end of `for (itDev = devs.Begin (); itDev != devs.End (); ++itDev)`
789 
790 } // end of `void DoInstallProbes ();`
791 
792 // RETURN USER LINK ////////////////////////////////////////////////////////
793 
794 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserLinkSinrHelper);
795 
797  : SatStatsLinkSinrHelper(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::SatStatsRtnUserLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
812  return tid;
813 }
814 
815 void
817 {
818  NS_LOG_FUNCTION(this);
819 
820  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
821  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
822  {
823  // Create a map of UT addresses and identifiers.
825  }
826 
827  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
828 
829  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
830  {
831  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
832  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
833  NS_ASSERT(satOrbiterDev != nullptr);
834  Ptr<SatPhy> satPhy;
835  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
836  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
837  it2 != satOrbiterUserPhys.end();
838  ++it2)
839  {
840  satPhy = it2->second;
841  NS_ASSERT(satPhy != nullptr);
842  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
843  NS_ASSERT(satPhyRx != nullptr);
844  ObjectVectorValue carriers;
845  satPhyRx->GetAttribute("RxCarrierList", carriers);
846  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
847  << satOrbiterDev->GetIfIndex() << " has " << carriers.GetN()
848  << " RX carriers");
849 
850  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
851  itCarrier != carriers.End();
852  ++itCarrier)
853  {
854  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
855  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr",
857  {
858  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
859  << " of SatPhyRxCarrier"
860  << " at node ID " << (*it)->GetId() << " device #"
861  << satOrbiterDev->GetIfIndex() << " RX carrier #"
862  << itCarrier->first);
863  }
864 
865  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
866  }
867  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
868 
869 } // end of `void DoInstallProbes ();`
870 
871 } // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
SatOrbiterNetDevice to be utilized in geostationary satellite.
The SatPhy models the basic physical layer of the satellite system.
Definition: satellite-phy.h:62
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 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.