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-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("SatStatsLinkSinrHelper");
53 
54 namespace ns3
55 {
56 
57 NS_OBJECT_ENSURE_REGISTERED(SatStatsLinkSinrHelper);
58 
59 SatStatsLinkSinrHelper::SatStatsLinkSinrHelper(Ptr<const SatHelper> satHelper)
60  : SatStatsHelper(satHelper),
61  m_traceSinkCallback(MakeCallback(&SatStatsLinkSinrHelper::SinrCallback, 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::SatStatsLinkSinrHelper").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("sinr_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("sinr_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("sinr_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("sinr_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("SINR (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("SINR (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("SINR (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 SatStatsLinkSinrHelper::SinrCallback(double sinrDb, const Address& from)
399 {
400  // NS_LOG_FUNCTION (this << sinrDb << from);
401 
402  if (from.IsInvalid())
403  {
404  NS_LOG_WARN(this << " discarding a packet with a sinr of " << sinrDb << "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(sinrDb, 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(sinrDb, it->second);
423  }
424  else
425  {
426  NS_LOG_WARN(this << " discarding a packet with a sinr of " << sinrDb << "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 SatStatsLinkSinrHelper::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 SatStatsLinkSinrHelper::PassSampleToCollector(double sinrDb, uint32_t identifier)
521 {
522  // NS_LOG_FUNCTION (this << sinrDb << 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, sinrDb);
534  break;
535  }
536 
539  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
540  NS_ASSERT(c != nullptr);
541  c->TraceSinkDouble(0.0, sinrDb);
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, sinrDb);
556  }
557  else
558  {
559  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
560  NS_ASSERT(c != nullptr);
561  c->TraceSinkDouble(0.0, sinrDb);
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(SatStatsFwdFeederLinkSinrHelper);
584 
586  : SatStatsLinkSinrHelper(satHelper)
587 {
588  NS_LOG_FUNCTION(this << satHelper);
589 }
590 
592 {
593  NS_LOG_FUNCTION(this);
594 }
595 
596 TypeId // static
598 {
599  static TypeId tid =
600  TypeId("ns3::SatStatsFwdFeederLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
601  return tid;
602 }
603 
604 void
606 {
607  NS_LOG_FUNCTION(this);
608 
609  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
610 
611  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
612  {
613  // Create a map of UT addresses and identifiers.
615  }
616 
617  NodeContainer sats = GetSatHelper()->GetBeamHelper()->GetGeoSatNodes();
618 
619  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
620  {
621  Ptr<NetDevice> dev = GetSatSatGeoNetDevice(*it);
622  Ptr<SatGeoNetDevice> satGeoDev = dev->GetObject<SatGeoNetDevice>();
623  NS_ASSERT(satGeoDev != nullptr);
624  std::map<uint32_t, Ptr<SatPhy>> satGeoFeederPhys = satGeoDev->GetFeederPhy();
625  ObjectMapValue phy;
626  satGeoDev->GetAttribute("FeederPhy", phy);
627  NS_LOG_DEBUG(this << " GeoSat Node ID " << (*it)->GetId() << " device #"
628  << dev->GetIfIndex() << " has " << phy.GetN() << " PHY instance(s)");
629 
630  for (ObjectMapValue::Iterator itPhy = phy.Begin(); itPhy != phy.End(); ++itPhy)
631  {
632  Ptr<SatPhy> satPhy = itPhy->second->GetObject<SatPhy>();
633  NS_ASSERT(satPhy != nullptr);
634  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
635  NS_ASSERT(satPhyRx != nullptr);
636  ObjectVectorValue carriers;
637  satPhyRx->GetAttribute("RxCarrierList", carriers);
638  NS_LOG_DEBUG(this << " PHY #" << itPhy->first << " has " << carriers.GetN()
639  << " RX carrier(s)");
640 
641  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
642  itCarrier != carriers.End();
643  ++itCarrier)
644  {
645  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_FEEDER_CH)
646  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr",
648  {
649  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
650  << " of SatPhyRxCarrier"
651  << " at GeoSat node ID " << (*it)->GetId() << " device #"
652  << dev->GetIfIndex() << " PHY #" << itPhy->first
653  << " RX carrier #" << itCarrier->first);
654  }
655 
656  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
657 
658  } // end of `for (ObjectMapValue::Iterator itPhy = phys)`
659  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
660 
661 } // end of `void DoInstallProbes ();`
662 
663 // FORWARD USER LINK ////////////////////////////////////////////////////////
664 
665 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserLinkSinrHelper);
666 
668  : SatStatsLinkSinrHelper(satHelper)
669 {
670  NS_LOG_FUNCTION(this << satHelper);
671 }
672 
674 {
675  NS_LOG_FUNCTION(this);
676 }
677 
678 TypeId // static
680 {
681  static TypeId tid =
682  TypeId("ns3::SatStatsFwdUserLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
683  return tid;
684 }
685 
686 void
688 {
689  NS_LOG_FUNCTION(this);
690 
691  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
692  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
693  {
694  // Create a map of UT addresses and identifiers.
696 
697  // const int32_t utId = GetUtId (*it);
698  // NS_ASSERT_MSG (utId > 0,
699  // "Node " << (*it)->GetId () << " is not a valid UT");
700  // const uint32_t identifier = GetIdentifierForUt (*it);
701  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
702  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
703  NS_ASSERT(satDev != nullptr);
704  Ptr<SatPhy> satPhy = satDev->GetPhy();
705  NS_ASSERT(satPhy != nullptr);
706  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
707  NS_ASSERT(satPhyRx != nullptr);
708  ObjectVectorValue carriers;
709  satPhyRx->GetAttribute("RxCarrierList", carriers);
710  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #" << dev->GetIfIndex()
711  << " has " << carriers.GetN() << " RX carriers");
712 
713  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
714  ++itCarrier)
715  {
716  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::FORWARD_USER_CH)
717  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr", GetTraceSinkCallback()))
718  {
719  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
720  << " of SatPhyRxCarrier"
721  << " at node ID " << (*it)->GetId() << " device #"
722  << dev->GetIfIndex() << " RX carrier #" << itCarrier->first);
723  }
724 
725  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
726 
727  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
728 
729 } // end of `void DoInstallProbes ();`
730 
731 // RETURN FEEDER LINK ////////////////////////////////////////////////////////
732 
733 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederLinkSinrHelper);
734 
736  : SatStatsLinkSinrHelper(satHelper)
737 {
738  NS_LOG_FUNCTION(this << satHelper);
739 }
740 
742 {
743  NS_LOG_FUNCTION(this);
744 }
745 
746 TypeId // static
748 {
749  static TypeId tid =
750  TypeId("ns3::SatStatsRtnFeederLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
751  return tid;
752 }
753 
754 void
756 {
757  NS_LOG_FUNCTION(this);
758 
759  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
760  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
761  {
762  // Create a map of UT addresses and identifiers.
764  }
765 
766  NodeContainer gws = GetSatHelper()->GetBeamHelper()->GetGwNodes();
767  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
768  {
769  NetDeviceContainer devs = GetGwSatNetDevice(*it);
770 
771  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
772  {
773  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
774  NS_ASSERT(satDev != nullptr);
775  Ptr<SatPhy> satPhy = satDev->GetPhy();
776  NS_ASSERT(satPhy != nullptr);
777  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
778  NS_ASSERT(satPhyRx != nullptr);
779  ObjectVectorValue carriers;
780  satPhyRx->GetAttribute("RxCarrierList", carriers);
781  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
782  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
783  << " RX carriers");
784 
785  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
786  itCarrier != carriers.End();
787  ++itCarrier)
788  {
789  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
790  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr",
792  {
793  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
794  << " of SatPhyRxCarrier"
795  << " at node ID " << (*it)->GetId() << " device #"
796  << (*itDev)->GetIfIndex() << " RX carrier #"
797  << itCarrier->first);
798  }
799 
800  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
801 
802  } // end of `for (it = gws.Begin(); it != gws.End (); ++it)`
803 
804  } // end of `for (itDev = devs.Begin (); itDev != devs.End (); ++itDev)`
805 
806 } // end of `void DoInstallProbes ();`
807 
808 // RETURN USER LINK ////////////////////////////////////////////////////////
809 
810 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserLinkSinrHelper);
811 
813  : SatStatsLinkSinrHelper(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::SatStatsRtnUserLinkSinrHelper").SetParent<SatStatsLinkSinrHelper>();
828  return tid;
829 }
830 
831 void
833 {
834  NS_LOG_FUNCTION(this);
835 
836  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
837  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
838  {
839  // Create a map of UT addresses and identifiers.
841  }
842 
843  NodeContainer sats = GetSatHelper()->GetBeamHelper()->GetGeoSatNodes();
844 
845  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
846  {
847  Ptr<NetDevice> dev = GetSatSatGeoNetDevice(*it);
848  Ptr<SatGeoNetDevice> satGeoDev = dev->GetObject<SatGeoNetDevice>();
849  NS_ASSERT(satGeoDev != nullptr);
850  Ptr<SatPhy> satPhy;
851  std::map<uint32_t, Ptr<SatPhy>> satGeoUserPhys = satGeoDev->GetUserPhy();
852  for (std::map<uint32_t, Ptr<SatPhy>>::iterator it2 = satGeoUserPhys.begin();
853  it2 != satGeoUserPhys.end();
854  ++it2)
855  {
856  satPhy = it2->second;
857  NS_ASSERT(satPhy != nullptr);
858  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
859  NS_ASSERT(satPhyRx != nullptr);
860  ObjectVectorValue carriers;
861  satPhyRx->GetAttribute("RxCarrierList", carriers);
862  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
863  << satGeoDev->GetIfIndex() << " has " << carriers.GetN()
864  << " RX carriers");
865 
866  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
867  itCarrier != carriers.End();
868  ++itCarrier)
869  {
870  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
871  if (!itCarrier->second->TraceConnectWithoutContext("LinkSinr",
873  {
874  NS_FATAL_ERROR("Error connecting to LinkSinr trace source"
875  << " of SatPhyRxCarrier"
876  << " at node ID " << (*it)->GetId() << " device #"
877  << satGeoDev->GetIfIndex() << " RX carrier #"
878  << itCarrier->first);
879  }
880 
881  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
882  }
883  } // end of `for (it = sats.Begin(); it != sats.End (); ++it)`
884 
885 } // end of `void DoInstallProbes ();`
886 
887 } // 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.