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-geo-net-device.h>
39 #include <ns3/satellite-helper.h>
40 #include <ns3/satellite-id-mapper.h>
41 #include <ns3/satellite-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/scalar-collector.h>
46 #include <ns3/singleton.h>
47 #include <ns3/string.h>
48 #include <ns3/unit-conversion-collector.h>
49 
50 #include <sstream>
51 
52 NS_LOG_COMPONENT_DEFINE("SatStatsLinkRxPowerHelper");
53 
54 namespace ns3
55 {
56 
57 NS_OBJECT_ENSURE_REGISTERED(SatStatsLinkRxPowerHelper);
58 
60  : SatStatsHelper(satHelper),
61  m_traceSinkCallback(MakeCallback(&SatStatsLinkRxPowerHelper::RxPowerCallback, this))
62 {
63  NS_LOG_FUNCTION(this << satHelper);
64 }
65 
67 {
68  NS_LOG_FUNCTION(this);
69 }
70 
71 TypeId // static
73 {
74  static TypeId tid = TypeId("ns3::SatStatsLinkRxPowerHelper").SetParent<SatStatsHelper>();
75  return tid;
76 }
77 
78 void
80 {
81  NS_LOG_FUNCTION(this << averagingMode);
82  m_averagingMode = averagingMode;
83 }
84 
85 Callback<void, double, const Address&>
87 {
88  return m_traceSinkCallback;
89 }
90 
91 void
93 {
94  NS_LOG_FUNCTION(this);
95 
96  switch (GetOutputType())
97  {
99  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
100  << " is not a valid output type for this statistics.");
101  break;
102 
104  // Setup aggregator.
105  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
106  "OutputFileName",
107  StringValue(GetOutputFileName()),
108  "MultiFileMode",
109  BooleanValue(false),
110  "EnableContextPrinting",
111  BooleanValue(true),
112  "GeneralHeading",
113  StringValue(GetIdentifierHeading("rx_power_db")));
114 
115  // Setup collectors.
116  m_terminalCollectors.SetType("ns3::ScalarCollector");
117  m_terminalCollectors.SetAttribute("InputDataType",
118  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
119  m_terminalCollectors.SetAttribute(
120  "OutputType",
121  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
123  m_terminalCollectors.ConnectToAggregator("Output",
124  m_aggregator,
125  &MultiFileAggregator::Write1d);
126  break;
127  }
128 
130  // Setup aggregator.
131  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
132  "OutputFileName",
133  StringValue(GetOutputFileName()),
134  "GeneralHeading",
135  StringValue(GetTimeHeading("rx_power_db")));
136 
137  // Setup collectors.
138  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
139  m_terminalCollectors.SetAttribute("ConversionType",
140  EnumValue(UnitConversionCollector::TRANSPARENT));
142  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
143  m_aggregator,
144  &MultiFileAggregator::Write2d);
145  break;
146  }
147 
151  if (m_averagingMode)
152  {
153  // Setup aggregator.
154  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
155  "OutputFileName",
156  StringValue(GetOutputFileName()),
157  "MultiFileMode",
158  BooleanValue(false),
159  "EnableContextPrinting",
160  BooleanValue(false),
161  "GeneralHeading",
162  StringValue(GetDistributionHeading("rx_power_db")));
163  Ptr<MultiFileAggregator> fileAggregator =
164  m_aggregator->GetObject<MultiFileAggregator>();
165  NS_ASSERT(fileAggregator != nullptr);
166 
167  // Setup the final-level collector.
168  m_averagingCollector = CreateObject<DistributionCollector>();
169  DistributionCollector::OutputType_t outputType =
170  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
172  {
173  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
174  }
176  {
177  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
178  }
179  m_averagingCollector->SetOutputType(outputType);
180  m_averagingCollector->SetName("0");
181  m_averagingCollector->TraceConnect(
182  "Output",
183  "0",
184  MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
185  m_averagingCollector->TraceConnect(
186  "OutputString",
187  "0",
188  MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
189  m_averagingCollector->TraceConnect(
190  "Warning",
191  "0",
192  MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
193 
194  // Setup collectors.
195  m_terminalCollectors.SetType("ns3::ScalarCollector");
196  m_terminalCollectors.SetAttribute("InputDataType",
197  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
198  m_terminalCollectors.SetAttribute(
199  "OutputType",
200  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
202  Callback<void, double> callback =
203  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
204  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
205  it != m_terminalCollectors.End();
206  ++it)
207  {
208  it->second->TraceConnectWithoutContext("Output", callback);
209  }
210  }
211  else
212  {
213  // Setup aggregator.
214  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
215  "OutputFileName",
216  StringValue(GetOutputFileName()),
217  "GeneralHeading",
218  StringValue(GetDistributionHeading("rx_power_db")));
219 
220  // Setup collectors.
221  m_terminalCollectors.SetType("ns3::DistributionCollector");
222  DistributionCollector::OutputType_t outputType =
223  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
225  {
226  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
227  }
229  {
230  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
231  }
232  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
234  m_terminalCollectors.ConnectToAggregator("Output",
235  m_aggregator,
236  &MultiFileAggregator::Write2d);
237  m_terminalCollectors.ConnectToAggregator("OutputString",
238  m_aggregator,
239  &MultiFileAggregator::AddContextHeading);
240  m_terminalCollectors.ConnectToAggregator("Warning",
241  m_aggregator,
242  &MultiFileAggregator::EnableContextWarning);
243  }
244 
245  break;
246  }
247 
250  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
251  << " is not a valid output type for this statistics.");
252  break;
253 
255  // Setup aggregator.
256  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
257  "OutputPath",
258  StringValue(GetOutputPath()),
259  "OutputFileName",
260  StringValue(GetName()));
261  Ptr<MagisterGnuplotAggregator> plotAggregator =
262  m_aggregator->GetObject<MagisterGnuplotAggregator>();
263  NS_ASSERT(plotAggregator != nullptr);
264  // plot->SetTitle ("");
265  plotAggregator->SetLegend("RX Power (in dB)", "Frequency");
266  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
267 
268  // Setup collectors.
269  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
270  m_terminalCollectors.SetAttribute("ConversionType",
271  EnumValue(UnitConversionCollector::TRANSPARENT));
273  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
274  it != m_terminalCollectors.End();
275  ++it)
276  {
277  const std::string context = it->second->GetName();
278  plotAggregator->Add2dDataset(context, context);
279  }
280  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
281  m_aggregator,
282  &MagisterGnuplotAggregator::Write2d);
283  break;
284  }
285 
289  if (m_averagingMode)
290  {
291  // Setup aggregator.
292  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
293  "OutputPath",
294  StringValue(GetOutputPath()),
295  "OutputFileName",
296  StringValue(GetName()));
297  Ptr<MagisterGnuplotAggregator> plotAggregator =
298  m_aggregator->GetObject<MagisterGnuplotAggregator>();
299  NS_ASSERT(plotAggregator != nullptr);
300  // plot->SetTitle ("");
301  plotAggregator->SetLegend("RX Power (in dB)", "Frequency");
302  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
303  plotAggregator->Add2dDataset(GetName(), GetName());
305 
306  // Setup the final-level collector.
307  m_averagingCollector = CreateObject<DistributionCollector>();
308  DistributionCollector::OutputType_t outputType =
309  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
311  {
312  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
313  }
315  {
316  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
317  }
318  m_averagingCollector->SetOutputType(outputType);
319  m_averagingCollector->SetName("0");
320  m_averagingCollector->TraceConnect(
321  "Output",
322  GetName(),
323  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
325 
326  // Setup collectors.
327  m_terminalCollectors.SetType("ns3::ScalarCollector");
328  m_terminalCollectors.SetAttribute("InputDataType",
329  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
330  m_terminalCollectors.SetAttribute(
331  "OutputType",
332  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
334  Callback<void, double> callback =
335  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
336  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
337  it != m_terminalCollectors.End();
338  ++it)
339  {
340  it->second->TraceConnectWithoutContext("Output", callback);
341  }
342  }
343  else
344  {
345  // Setup aggregator.
346  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
347  "OutputPath",
348  StringValue(GetOutputPath()),
349  "OutputFileName",
350  StringValue(GetName()));
351  Ptr<MagisterGnuplotAggregator> plotAggregator =
352  m_aggregator->GetObject<MagisterGnuplotAggregator>();
353  NS_ASSERT(plotAggregator != nullptr);
354  // plot->SetTitle ("");
355  plotAggregator->SetLegend("RX Power (in dB)", "Frequency");
356  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
357 
358  // Setup collectors.
359  m_terminalCollectors.SetType("ns3::DistributionCollector");
360  DistributionCollector::OutputType_t outputType =
361  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
363  {
364  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
365  }
367  {
368  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
369  }
370  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
372  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
373  it != m_terminalCollectors.End();
374  ++it)
375  {
376  const std::string context = it->second->GetName();
377  plotAggregator->Add2dDataset(context, context);
378  }
379  m_terminalCollectors.ConnectToAggregator("Output",
380  m_aggregator,
381  &MagisterGnuplotAggregator::Write2d);
382  }
383 
384  break;
385  }
386 
387  default:
388  NS_FATAL_ERROR("SatStatsLinkDelayHelper - Invalid output type");
389  break;
390  }
391 
392  // Setup probes and connect them to the collectors.
393  InstallProbes();
394 
395 } // end of `void DoInstall ();`
396 
397 void
398 SatStatsLinkRxPowerHelper::RxPowerCallback(double rxPowerDb, const Address& from)
399 {
400  // NS_LOG_FUNCTION (this << rxPowerDb << from);
401 
402  if (from.IsInvalid())
403  {
404  NS_LOG_WARN(this << " discarding a packet RX power of " << rxPowerDb << "dB"
405  << " from statistics collection because of"
406  << " invalid sender address");
407  }
408  else if (Mac48Address::ConvertFrom(from).IsBroadcast())
409  {
410  for (std::pair<const Address, uint32_t> item : m_identifierMap)
411  {
412  PassSampleToCollector(rxPowerDb, item.second);
413  }
414  }
415  else
416  {
417  // Determine the identifier associated with the sender address.
418  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
419 
420  if (it != m_identifierMap.end())
421  {
422  PassSampleToCollector(rxPowerDb, it->second);
423  }
424  else
425  {
426  NS_LOG_WARN(this << " discarding a packet RX power of " << rxPowerDb << "dB"
427  << " from statistics collection because of"
428  << " unknown sender address " << from);
429  }
430  }
431 }
432 
433 void
435 {
436  NS_LOG_FUNCTION(this << utNode->GetId());
437 
438  const SatIdMapper* satIdMapper = Singleton<SatIdMapper>::Get();
439  const Address addr = satIdMapper->GetUtMacWithNode(utNode);
440 
441  if (addr.IsInvalid())
442  {
443  NS_LOG_WARN(this << " Node " << utNode->GetId() << " is not a valid UT");
444  }
445  else
446  {
447  const uint32_t identifier = GetIdentifierForUt(utNode);
448  m_identifierMap[addr] = identifier;
449  NS_LOG_INFO(this << " associated address " << addr << " with identifier " << identifier);
450  }
451 }
452 
453 bool
454 SatStatsLinkRxPowerHelper::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 SatStatsLinkRxPowerHelper::PassSampleToCollector(double rxPowerDb, uint32_t identifier)
521 {
522  // NS_LOG_FUNCTION (this << rxPowerDb << identifier);
523 
524  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifier);
525  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << identifier);
526 
527  switch (GetOutputType())
528  {
531  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
532  NS_ASSERT(c != nullptr);
533  c->TraceSinkDouble(0.0, rxPowerDb);
534  break;
535  }
536 
539  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
540  NS_ASSERT(c != nullptr);
541  c->TraceSinkDouble(0.0, rxPowerDb);
542  break;
543  }
544 
551  if (m_averagingMode)
552  {
553  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
554  NS_ASSERT(c != nullptr);
555  c->TraceSinkDouble(0.0, rxPowerDb);
556  }
557  else
558  {
559  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
560  NS_ASSERT(c != nullptr);
561  c->TraceSinkDouble(0.0, rxPowerDb);
562  }
563  break;
564 
565  default:
566  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
567  << " is not a valid output type for this statistics.");
568  break;
569 
570  } // end of `switch (GetOutputType ())`
571 
572 } // end of `void PassSampleToCollector (double, uint32_t)`
573 
574 void
576 {
577  // The method below is supposed to be implemented by the child class.
578  DoInstallProbes();
579 }
580 
581 // FORWARD FEEDER LINK ////////////////////////////////////////////////////////
582 
583 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederLinkRxPowerHelper);
584 
586  Ptr<const SatHelper> satHelper)
587  : SatStatsLinkRxPowerHelper(satHelper)
588 {
589  NS_LOG_FUNCTION(this << satHelper);
590 }
591 
593 {
594  NS_LOG_FUNCTION(this);
595 }
596 
597 TypeId // static
599 {
600  static TypeId tid =
601  TypeId("ns3::SatStatsFwdFeederLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
602  return tid;
603 }
604 
605 void
607 {
608  NS_LOG_FUNCTION(this);
609 
610  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
611 
612  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
613  {
614  // Create a map of UT addresses and identifiers.
616  }
617 
618  NodeContainer sats = GetSatHelper()->GetBeamHelper()->GetGeoSatNodes();
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  ObjectMapValue phy;
627  satGeoDev->GetAttribute("FeederPhy", phy);
628  NS_LOG_DEBUG(this << " GeoSat Node ID " << (*it)->GetId() << " device #"
629  << dev->GetIfIndex() << " has " << phy.GetN() << " PHY instance(s)");
630 
631  for (ObjectMapValue::Iterator itPhy = phy.Begin(); itPhy != phy.End(); ++itPhy)
632  {
633  Ptr<SatPhy> satPhy = itPhy->second->GetObject<SatPhy>();
634  NS_ASSERT(satPhy != nullptr);
635  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
636  NS_ASSERT(satPhyRx != nullptr);
637  ObjectVectorValue carriers;
638  satPhyRx->GetAttribute("RxCarrierList", carriers);
639  NS_LOG_DEBUG(this << " PHY #" << itPhy->first << " has " << carriers.GetN()
640  << " RX carrier(s)");
641 
642  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
643  itCarrier != carriers.End();
644  ++itCarrier)
645  {
646  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_FEEDER_CH)
647  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
649  {
650  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
651  << " of SatPhyRxCarrier"
652  << " at GeoSat node ID " << (*it)->GetId() << " device #"
653  << dev->GetIfIndex() << " PHY #" << itPhy->first
654  << " RX carrier #" << itCarrier->first);
655  }
656 
657  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
658 
659  } // end of `for (ObjectMapValue::Iterator itPhy = phys)`
660  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
661 
662 } // end of `void DoInstallProbes ();`
663 
664 // FORWARD USER LINK ////////////////////////////////////////////////////////
665 
666 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserLinkRxPowerHelper);
667 
669  : SatStatsLinkRxPowerHelper(satHelper)
670 {
671  NS_LOG_FUNCTION(this << satHelper);
672 }
673 
675 {
676  NS_LOG_FUNCTION(this);
677 }
678 
679 TypeId // static
681 {
682  static TypeId tid =
683  TypeId("ns3::SatStatsFwdUserLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
684  return tid;
685 }
686 
687 void
689 {
690  NS_LOG_FUNCTION(this);
691 
692  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
693  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
694  {
695  // Create a map of UT addresses and identifiers.
697 
698  // const int32_t utId = GetUtId (*it);
699  // NS_ASSERT_MSG (utId > 0,
700  // "Node " << (*it)->GetId () << " is not a valid UT");
701  // const uint32_t identifier = GetIdentifierForUt (*it);
702  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
703  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
704  NS_ASSERT(satDev != nullptr);
705  Ptr<SatPhy> satPhy = satDev->GetPhy();
706  NS_ASSERT(satPhy != nullptr);
707  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
708  NS_ASSERT(satPhyRx != nullptr);
709  ObjectVectorValue carriers;
710  satPhyRx->GetAttribute("RxCarrierList", carriers);
711  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #" << dev->GetIfIndex()
712  << " has " << carriers.GetN() << " RX carriers");
713 
714  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
715  ++itCarrier)
716  {
717  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_USER_CH)
718  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
720  {
721  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
722  << " of SatPhyRxCarrier"
723  << " at node ID " << (*it)->GetId() << " device #"
724  << dev->GetIfIndex() << " RX carrier #" << itCarrier->first);
725  }
726 
727  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
728 
729  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
730 
731 } // end of `void DoInstallProbes ();`
732 
733 // RETURN FEEDER LINK ////////////////////////////////////////////////////////
734 
735 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederLinkRxPowerHelper);
736 
738  Ptr<const SatHelper> satHelper)
739  : SatStatsLinkRxPowerHelper(satHelper)
740 {
741  NS_LOG_FUNCTION(this << satHelper);
742 }
743 
745 {
746  NS_LOG_FUNCTION(this);
747 }
748 
749 TypeId // static
751 {
752  static TypeId tid =
753  TypeId("ns3::SatStatsRtnFeederLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
754  return tid;
755 }
756 
757 void
759 {
760  NS_LOG_FUNCTION(this);
761 
762  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
763  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
764  {
765  // Create a map of UT addresses and identifiers.
767  }
768 
769  NodeContainer gws = GetSatHelper()->GetBeamHelper()->GetGwNodes();
770  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
771  {
772  NetDeviceContainer devs = GetGwSatNetDevice(*it);
773 
774  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
775  {
776  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
777  NS_ASSERT(satDev != nullptr);
778  Ptr<SatPhy> satPhy = satDev->GetPhy();
779  NS_ASSERT(satPhy != nullptr);
780  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
781  NS_ASSERT(satPhyRx != nullptr);
782  ObjectVectorValue carriers;
783  satPhyRx->GetAttribute("RxCarrierList", carriers);
784  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
785  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
786  << " RX carriers");
787 
788  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
789  itCarrier != carriers.End();
790  ++itCarrier)
791  {
792  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
793  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
795  {
796  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
797  << " of SatPhyRxCarrier"
798  << " at node ID " << (*it)->GetId() << " device #"
799  << (*itDev)->GetIfIndex() << " RX carrier #"
800  << itCarrier->first);
801  }
802 
803  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
804 
805  } // end of `for (it = gws.Begin(); it != gws.End (); ++it)`
806 
807  } // end of `for (itDev = devs.Begin (); itDev != devs.End (); ++itDev)`
808 
809 } // end of `void DoInstallProbes ();`
810 
811 // RETURN USER LINK ////////////////////////////////////////////////////////
812 
813 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserLinkRxPowerHelper);
814 
816  : SatStatsLinkRxPowerHelper(satHelper)
817 {
818  NS_LOG_FUNCTION(this << satHelper);
819 }
820 
822 {
823  NS_LOG_FUNCTION(this);
824 }
825 
826 TypeId // static
828 {
829  static TypeId tid =
830  TypeId("ns3::SatStatsRtnUserLinkRxPowerHelper").SetParent<SatStatsLinkRxPowerHelper>();
831  return tid;
832 }
833 
834 void
836 {
837  NS_LOG_FUNCTION(this);
838 
839  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
840  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
841  {
842  // Create a map of UT addresses and identifiers.
844  }
845 
846  NodeContainer sats = GetSatHelper()->GetBeamHelper()->GetGeoSatNodes();
847 
848  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
849  {
850  Ptr<NetDevice> dev = GetSatSatGeoNetDevice(*it);
851  Ptr<SatGeoNetDevice> satGeoDev = dev->GetObject<SatGeoNetDevice>();
852  NS_ASSERT(satGeoDev != nullptr);
853  Ptr<SatPhy> satPhy;
854  std::map<uint32_t, Ptr<SatPhy>> satGeoUserPhys = satGeoDev->GetUserPhy();
855  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satGeoUserPhys.begin();
856  it2 != satGeoUserPhys.end();
857  ++it2)
858  {
859  satPhy = it2->second;
860  NS_ASSERT(satPhy != nullptr);
861  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
862  NS_ASSERT(satPhyRx != nullptr);
863  ObjectVectorValue carriers;
864  satPhyRx->GetAttribute("RxCarrierList", carriers);
865  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
866  << satGeoDev->GetIfIndex() << " has " << carriers.GetN()
867  << " RX carriers");
868 
869  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
870  itCarrier != carriers.End();
871  ++itCarrier)
872  {
873  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
874  if (!itCarrier->second->TraceConnectWithoutContext("RxPowerTrace",
876  {
877  NS_FATAL_ERROR("Error connecting to RxPowerTrace trace source"
878  << " of SatPhyRxCarrier"
879  << " at node ID " << (*it)->GetId() << " device #"
880  << satGeoDev->GetIfIndex() << " RX carrier #"
881  << itCarrier->first);
882  }
883 
884  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
885  }
886  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
887 
888 } // end of `void DoInstallProbes ();`
889 
890 } // 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.
The SatPhy models the basic physical layer of the satellite system.
Definition: satellite-phy.h:61
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 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.