satellite-stats-link-rx-power-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("SatStatsLinkRxPowerHelper");
57 
58 namespace ns3
59 {
60 
61 NS_OBJECT_ENSURE_REGISTERED(SatStatsLinkRxPowerHelper);
62 
64  : SatStatsHelper(satHelper),
65  m_traceSinkCallback(MakeCallback(&SatStatsLinkRxPowerHelper::RxPowerCallback, 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::SatStatsLinkRxPowerHelper").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("rx_power_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("rx_power_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("rx_power_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("rx_power_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("RX Power (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("RX Power (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("RX Power (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 SatStatsLinkRxPowerHelper::RxPowerCallback(double rxPowerDb, const Address& from)
403 {
404  // NS_LOG_FUNCTION (this << rxPowerDb << from);
405 
406  if (from.IsInvalid())
407  {
408  NS_LOG_WARN(this << " discarding a packet RX power of " << rxPowerDb << "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(rxPowerDb, 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(rxPowerDb, it->second);
427  }
428  else
429  {
430  NS_LOG_WARN(this << " discarding a packet RX power of " << rxPowerDb << "dB"
431  << " from statistics collection because of"
432  << " unknown sender address " << from);
433  }
434  }
435 }
436 
437 bool
438 SatStatsLinkRxPowerHelper::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 SatStatsLinkRxPowerHelper::PassSampleToCollector(double rxPowerDb, uint32_t identifier)
505 {
506  // NS_LOG_FUNCTION (this << rxPowerDb << 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, rxPowerDb);
518  break;
519  }
520 
523  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
524  NS_ASSERT(c != nullptr);
525  c->TraceSinkDouble(0.0, rxPowerDb);
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, rxPowerDb);
540  }
541  else
542  {
543  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
544  NS_ASSERT(c != nullptr);
545  c->TraceSinkDouble(0.0, rxPowerDb);
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(SatStatsFwdFeederLinkRxPowerHelper);
568 
570  Ptr<const SatHelper> satHelper)
571  : SatStatsLinkRxPowerHelper(satHelper)
572 {
573  NS_LOG_FUNCTION(this << satHelper);
574 }
575 
577 {
578  NS_LOG_FUNCTION(this);
579 }
580 
581 TypeId // static
583 {
584  static TypeId tid =
585  TypeId("ns3::SatStatsFwdFeederLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
586  return tid;
587 }
588 
589 void
591 {
592  NS_LOG_FUNCTION(this);
593 
594  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
595 
596  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
597  {
598  // Create a map of UT addresses and identifiers.
600  }
601 
602  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
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  ObjectMapValue phy;
611  satOrbiterDev->GetAttribute("FeederPhy", phy);
612  NS_LOG_DEBUG(this << " OrbiterSat Node ID " << (*it)->GetId() << " device #"
613  << dev->GetIfIndex() << " has " << phy.GetN() << " PHY instance(s)");
614 
615  for (ObjectMapValue::Iterator itPhy = phy.Begin(); itPhy != phy.End(); ++itPhy)
616  {
617  Ptr<SatPhy> satPhy = itPhy->second->GetObject<SatPhy>();
618  NS_ASSERT(satPhy != nullptr);
619  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
620  NS_ASSERT(satPhyRx != nullptr);
621  ObjectVectorValue carriers;
622  satPhyRx->GetAttribute("RxCarrierList", carriers);
623  NS_LOG_DEBUG(this << " PHY #" << itPhy->first << " has " << carriers.GetN()
624  << " RX carrier(s)");
625 
626  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
627  itCarrier != carriers.End();
628  ++itCarrier)
629  {
630  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_FEEDER_CH)
631  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
633  {
634  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
635  << " of SatPhyRxCarrier"
636  << " at OrbiterSat node ID " << (*it)->GetId() << " device #"
637  << dev->GetIfIndex() << " PHY #" << itPhy->first
638  << " RX carrier #" << itCarrier->first);
639  }
640 
641  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
642 
643  } // end of `for (ObjectMapValue::Iterator itPhy = phys)`
644  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
645 
646 } // end of `void DoInstallProbes ();`
647 
648 // FORWARD USER LINK ////////////////////////////////////////////////////////
649 
650 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserLinkRxPowerHelper);
651 
653  : SatStatsLinkRxPowerHelper(satHelper)
654 {
655  NS_LOG_FUNCTION(this << satHelper);
656 }
657 
659 {
660  NS_LOG_FUNCTION(this);
661 }
662 
663 TypeId // static
665 {
666  static TypeId tid =
667  TypeId("ns3::SatStatsFwdUserLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
668  return tid;
669 }
670 
671 void
673 {
674  NS_LOG_FUNCTION(this);
675 
676  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
677  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
678  {
679  // Create a map of UT addresses and identifiers.
681 
682  // const int32_t utId = GetUtId (*it);
683  // NS_ASSERT_MSG (utId > 0,
684  // "Node " << (*it)->GetId () << " is not a valid UT");
685  // const uint32_t identifier = GetIdentifierForUt (*it);
686  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
687  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
688  NS_ASSERT(satDev != nullptr);
689  Ptr<SatPhy> satPhy = satDev->GetPhy();
690  NS_ASSERT(satPhy != nullptr);
691  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
692  NS_ASSERT(satPhyRx != nullptr);
693  ObjectVectorValue carriers;
694  satPhyRx->GetAttribute("RxCarrierList", carriers);
695  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #" << dev->GetIfIndex()
696  << " has " << carriers.GetN() << " RX carriers");
697 
698  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
699  ++itCarrier)
700  {
701  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_USER_CH)
702  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
704  {
705  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
706  << " of SatPhyRxCarrier"
707  << " at node ID " << (*it)->GetId() << " device #"
708  << dev->GetIfIndex() << " RX carrier #" << itCarrier->first);
709  }
710 
711  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
712 
713  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
714 
715 } // end of `void DoInstallProbes ();`
716 
717 // RETURN FEEDER LINK ////////////////////////////////////////////////////////
718 
719 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederLinkRxPowerHelper);
720 
722  Ptr<const SatHelper> satHelper)
723  : SatStatsLinkRxPowerHelper(satHelper)
724 {
725  NS_LOG_FUNCTION(this << satHelper);
726 }
727 
729 {
730  NS_LOG_FUNCTION(this);
731 }
732 
733 TypeId // static
735 {
736  static TypeId tid =
737  TypeId("ns3::SatStatsRtnFeederLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
738  return tid;
739 }
740 
741 void
743 {
744  NS_LOG_FUNCTION(this);
745 
746  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
747  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
748  {
749  // Create a map of UT addresses and identifiers.
751  }
752 
753  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
754  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
755  {
756  NetDeviceContainer devs = GetGwSatNetDevice(*it);
757 
758  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
759  {
760  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
761  NS_ASSERT(satDev != nullptr);
762  Ptr<SatPhy> satPhy = satDev->GetPhy();
763  NS_ASSERT(satPhy != nullptr);
764  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
765  NS_ASSERT(satPhyRx != nullptr);
766  ObjectVectorValue carriers;
767  satPhyRx->GetAttribute("RxCarrierList", carriers);
768  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
769  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
770  << " RX carriers");
771 
772  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
773  itCarrier != carriers.End();
774  ++itCarrier)
775  {
776  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
777  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
779  {
780  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
781  << " of SatPhyRxCarrier"
782  << " at node ID " << (*it)->GetId() << " device #"
783  << (*itDev)->GetIfIndex() << " RX carrier #"
784  << itCarrier->first);
785  }
786 
787  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
788 
789  } // end of `for (it = gws.Begin(); it != gws.End (); ++it)`
790 
791  } // end of `for (itDev = devs.Begin (); itDev != devs.End (); ++itDev)`
792 
793 } // end of `void DoInstallProbes ();`
794 
795 // RETURN USER LINK ////////////////////////////////////////////////////////
796 
797 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserLinkRxPowerHelper);
798 
800  : SatStatsLinkRxPowerHelper(satHelper)
801 {
802  NS_LOG_FUNCTION(this << satHelper);
803 }
804 
806 {
807  NS_LOG_FUNCTION(this);
808 }
809 
810 TypeId // static
812 {
813  static TypeId tid =
814  TypeId("ns3::SatStatsRtnUserLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
815  return tid;
816 }
817 
818 void
820 {
821  NS_LOG_FUNCTION(this);
822 
823  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
824  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
825  {
826  // Create a map of UT addresses and identifiers.
828  }
829 
830  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
831 
832  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
833  {
834  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(*it);
835  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
836  NS_ASSERT(satOrbiterDev != nullptr);
837  Ptr<SatPhy> satPhy;
838  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
839  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satOrbiterUserPhys.begin();
840  it2 != satOrbiterUserPhys.end();
841  ++it2)
842  {
843  satPhy = it2->second;
844  NS_ASSERT(satPhy != nullptr);
845  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
846  NS_ASSERT(satPhyRx != nullptr);
847  ObjectVectorValue carriers;
848  satPhyRx->GetAttribute("RxCarrierList", carriers);
849  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
850  << satOrbiterDev->GetIfIndex() << " has " << carriers.GetN()
851  << " RX carriers");
852 
853  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
854  itCarrier != carriers.End();
855  ++itCarrier)
856  {
857  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
858  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
860  {
861  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
862  << " of SatPhyRxCarrier"
863  << " at node ID " << (*it)->GetId() << " device #"
864  << satOrbiterDev->GetIfIndex() << " RX carrier #"
865  << itCarrier->first);
866  }
867 
868  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
869  }
870  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
871 
872 } // end of `void DoInstallProbes ();`
873 
874 } // 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.