satellite-stats-packet-error-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: Budiarto Herman <budiarto.herman@magister.fi>
19  *
20  */
21 
23 
25 
26 #include <ns3/boolean.h>
27 #include <ns3/callback.h>
28 #include <ns3/data-collection-object.h>
29 #include <ns3/enum.h>
30 #include <ns3/interval-rate-collector.h>
31 #include <ns3/log.h>
32 #include <ns3/mac48-address.h>
33 #include <ns3/magister-gnuplot-aggregator.h>
34 #include <ns3/multi-file-aggregator.h>
35 #include <ns3/node-container.h>
36 #include <ns3/object-vector.h>
37 #include <ns3/satellite-helper.h>
38 #include <ns3/satellite-id-mapper.h>
39 #include <ns3/satellite-net-device.h>
40 #include <ns3/satellite-orbiter-net-device.h>
41 #include <ns3/satellite-phy-rx-carrier.h>
42 #include <ns3/satellite-phy-rx.h>
43 #include <ns3/satellite-phy.h>
44 #include <ns3/satellite-topology.h>
45 #include <ns3/scalar-collector.h>
46 #include <ns3/singleton.h>
47 #include <ns3/string.h>
48 
49 #include <map>
50 #include <sstream>
51 #include <string>
52 #include <utility>
53 
54 NS_LOG_COMPONENT_DEFINE("SatStatsPacketErrorHelper");
55 
56 namespace ns3
57 {
58 
59 // BASE CLASS /////////////////////////////////////////////////////////////////
60 
61 NS_OBJECT_ENSURE_REGISTERED(SatStatsPacketErrorHelper);
62 
64  : SatStatsHelper(satHelper),
65  m_traceSourceName(""),
66  m_channelType(SatEnums::UNKNOWN_CH)
67 {
68  NS_LOG_FUNCTION(this << satHelper);
69 }
70 
72 {
73  NS_LOG_FUNCTION(this);
74 }
75 
76 TypeId // static
78 {
79  static TypeId tid = TypeId("ns3::SatStatsPacketErrorHelper").SetParent<SatStatsHelper>();
80  return tid;
81 }
82 
83 void
85 {
86  NS_LOG_FUNCTION(this << traceSourceName);
87  m_traceSourceName = traceSourceName;
88 }
89 
90 std::string
92 {
93  return m_traceSourceName;
94 }
95 
96 void
98 {
99  NS_LOG_FUNCTION(this << SatEnums::GetChannelTypeName(channelType));
100  m_channelType = channelType;
101 }
102 
105 {
106  return m_channelType;
107 }
108 
109 void
111 {
112  NS_LOG_FUNCTION(this);
113 
114  switch (GetOutputType())
115  {
117  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
118  << " is not a valid output type for this statistics.");
119  break;
120 
122  // Setup aggregator.
123  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
124  "OutputFileName",
125  StringValue(GetOutputFileName()),
126  "MultiFileMode",
127  BooleanValue(false),
128  "EnableContextPrinting",
129  BooleanValue(true),
130  "GeneralHeading",
131  StringValue(GetIdentifierHeading("error_rate")));
132 
133  // Setup collectors.
134  m_terminalCollectors.SetType("ns3::ScalarCollector");
135  m_terminalCollectors.SetAttribute("InputDataType",
136  EnumValue(ScalarCollector::INPUT_DATA_TYPE_BOOLEAN));
137  m_terminalCollectors.SetAttribute(
138  "OutputType",
139  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
141  m_terminalCollectors.ConnectToAggregator("Output",
142  m_aggregator,
143  &MultiFileAggregator::Write1d);
144  break;
145  }
146 
148  // Setup aggregator.
149  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
150  "OutputFileName",
151  StringValue(GetOutputFileName()),
152  "GeneralHeading",
153  StringValue(GetTimeHeading("error_rate")));
154 
155  // Setup collectors.
156  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
157  m_terminalCollectors.SetAttribute(
158  "InputDataType",
159  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_BOOLEAN));
160  m_terminalCollectors.SetAttribute(
161  "OutputType",
162  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
164  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
165  m_aggregator,
166  &MultiFileAggregator::Write2d);
167  m_terminalCollectors.ConnectToAggregator("OutputString",
168  m_aggregator,
169  &MultiFileAggregator::AddContextHeading);
170  break;
171  }
172 
176  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
177  << " is not a valid output type for this statistics.");
178  break;
179 
182  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
183  << " is not a valid output type for this statistics.");
184  break;
185 
187  // Setup aggregator.
188  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
189  "OutputPath",
190  StringValue(GetOutputPath()),
191  "OutputFileName",
192  StringValue(GetName()));
193  Ptr<MagisterGnuplotAggregator> plotAggregator =
194  m_aggregator->GetObject<MagisterGnuplotAggregator>();
195  NS_ASSERT(plotAggregator != nullptr);
196  // plot->SetTitle ("");
197  plotAggregator->SetLegend("Time (in seconds)", "Packet error rate");
198  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
199 
200  // Setup collectors.
201  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
202  m_terminalCollectors.SetAttribute(
203  "InputDataType",
204  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_BOOLEAN));
205  m_terminalCollectors.SetAttribute(
206  "OutputType",
207  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
209  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
210  it != m_terminalCollectors.End();
211  ++it)
212  {
213  const std::string context = it->second->GetName();
214  plotAggregator->Add2dDataset(context, context);
215  }
216  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
217  m_aggregator,
218  &MagisterGnuplotAggregator::Write2d);
219  break;
220  }
221 
225  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
226  << " is not a valid output type for this statistics.");
227  break;
228 
229  default:
230  NS_FATAL_ERROR("SatStatsPacketErrorHelper - Invalid output type");
231  break;
232  }
233 
234  switch (m_channelType)
235  {
237  // Connect to trace sources at UT nodes.
238  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
239  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
240  {
241  InstallProbeOnUt(*it);
242  }
243 
244  break;
245  }
246 
248  // Create a map of UT addresses and identifiers.
249  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
250  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
251  {
253  }
254 
255  // Connect to trace sources at SAT nodes.
256  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
257  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
258  {
260  }
261 
262  break;
263  }
264 
266  // Create a map of UT addresses and identifiers.
267  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
268  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
269  {
271  }
272 
273  // Connect to trace sources at GW nodes.
274  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
275  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
276  {
277  InstallProbeOnGw(*it);
278  }
279 
280  break;
281  }
282 
284  // Create a map of UT addresses and identifiers.
285  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
286  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
287  {
289  }
290 
291  // Connect to trace sources at SAT nodes.
292  NodeContainer sats = Singleton<SatTopology>::Get()->GetOrbiterNodes();
293  for (NodeContainer::Iterator it = sats.Begin(); it != sats.End(); ++it)
294  {
296  }
297 
298  break;
299  }
300 
301  default:
302  NS_FATAL_ERROR("SatStatsPacketErrorHelper - Invalid link");
303  break;
304  }
305 
306 } // end of `void DoInstall ();`
307 
308 void
309 SatStatsPacketErrorHelper::ErrorRxCallback(uint32_t nPackets, const Address& fromOrTo, bool isError)
310 {
311  NS_LOG_FUNCTION(this << nPackets << fromOrTo << isError);
312 
313  if (fromOrTo.IsInvalid())
314  {
315  NS_LOG_WARN(this << " discarding " << nPackets << " packets"
316  << " from statistics collection because of"
317  << " invalid sender/destination address");
318  }
319  else if (Mac48Address::ConvertFrom(fromOrTo).IsBroadcast())
320  {
321  for (std::pair<const Address, uint32_t> item : m_identifierMap)
322  {
323  // Find the first-level collector with the right identifier.
324  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(item.second);
325  NS_ASSERT_MSG(collector != nullptr,
326  "Unable to find collector with identifier " << item.second);
327 
328  switch (GetOutputType())
329  {
332  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
333  NS_ASSERT(c != nullptr);
334  c->TraceSinkBoolean(false, isError);
335  break;
336  }
337 
340  Ptr<IntervalRateCollector> c = collector->GetObject<IntervalRateCollector>();
341  NS_ASSERT(c != nullptr);
342  c->TraceSinkBoolean(false, isError);
343  break;
344  }
345 
346  default:
347  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
348  << " is not a valid output type for this statistics.");
349  break;
350 
351  } // end of `switch (GetOutputType ())`
352  } // end of for (it == m_identifierMap.begin ())
353  }
354  else
355  {
356  // Determine the identifier associated with the sender address.
357  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(fromOrTo);
358 
359  if (it == m_identifierMap.end())
360  {
361  NS_LOG_WARN(this << " discarding " << nPackets << " packets"
362  << " from statistics collection because of"
363  << " unknown sender/destination address " << fromOrTo);
364  }
365  else
366  {
367  // Find the first-level collector with the right identifier.
368  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(it->second);
369  NS_ASSERT_MSG(collector != nullptr,
370  "Unable to find collector with identifier " << it->second);
371 
372  switch (GetOutputType())
373  {
376  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
377  NS_ASSERT(c != nullptr);
378  c->TraceSinkBoolean(false, isError);
379  break;
380  }
381 
384  Ptr<IntervalRateCollector> c = collector->GetObject<IntervalRateCollector>();
385  NS_ASSERT(c != nullptr);
386  c->TraceSinkBoolean(false, isError);
387  break;
388  }
389 
390  default:
391  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
392  << " is not a valid output type for this statistics.");
393  break;
394 
395  } // end of `switch (GetOutputType ())`
396 
397  } // end of else of `if (it == m_identifierMap.end ())`
398 
399  } // end of else of `if (from.IsInvalid ())`
400 
401 } // end of `void ErrorRxCallback (uint32_t, const Address &, bool);`
402 
403 bool
404 SatStatsPacketErrorHelper::ConnectProbeToCollector(Ptr<Probe> probe, uint32_t identifier)
405 {
406  NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
407 
408  // Connect the probe to the right collector.
409  bool ret = false;
410  switch (GetOutputType())
411  {
414  ret = m_terminalCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
415  "OutputBool",
416  identifier,
417  &ScalarCollector::TraceSinkBoolean);
418  break;
419 
422  ret = m_terminalCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
423  "OutputBool",
424  identifier,
425  &IntervalRateCollector::TraceSinkBoolean);
426  break;
427 
428  default:
429  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
430  << " is not a valid output type for this statistics.");
431  break;
432 
433  } // end of `switch (GetOutputType ())`
434 
435  if (ret)
436  {
437  NS_LOG_INFO(this << " created probe " << probe->GetName() << ", connected to collector "
438  << identifier);
439  }
440  else
441  {
442  NS_LOG_WARN(this << " unable to connect probe " << probe->GetName() << " to collector "
443  << identifier);
444  }
445 
446  return ret;
447 }
448 
449 bool
450 SatStatsPacketErrorHelper::DisconnectProbeFromCollector(Ptr<Probe> probe, uint32_t identifier)
451 {
452  NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
453 
454  // Connect the probe to the right collector.
455  bool ret = false;
456  switch (GetOutputType())
457  {
460  ret = m_terminalCollectors.DisconnectWithProbe(probe->GetObject<Probe>(),
461  "OutputBool",
462  identifier,
463  &ScalarCollector::TraceSinkBoolean);
464  break;
465 
468  ret = m_terminalCollectors.DisconnectWithProbe(probe->GetObject<Probe>(),
469  "OutputBool",
470  identifier,
471  &IntervalRateCollector::TraceSinkBoolean);
472  break;
473 
474  default:
475  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
476  << " is not a valid output type for this statistics.");
477  break;
478 
479  } // end of `switch (GetOutputType ())`
480 
481  if (ret)
482  {
483  NS_LOG_INFO(this << " probe " << probe->GetName() << ", disconnected from collector "
484  << identifier);
485  }
486  else
487  {
488  NS_LOG_WARN(this << " unable to disconnect probe " << probe->GetName() << " from collector "
489  << identifier);
490  }
491 
492  return ret;
493 }
494 
495 void
497 {
498  NS_LOG_FUNCTION(this);
499 
500  std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
501 
502  for (it = m_probes.begin(); it != m_probes.end(); it++)
503  {
504  Ptr<Probe> probe = it->first;
505  Ptr<Node> node = it->second.first;
506  uint32_t identifier = it->second.second;
507 
508  if (!DisconnectProbeFromCollector(probe, identifier))
509  {
510  NS_FATAL_ERROR("Error disconnecting trace file on handover");
511  }
512 
513  identifier = GetIdentifierForUtUser(node);
514 
515  if (!ConnectProbeToCollector(probe, identifier))
516  {
517  NS_FATAL_ERROR("Error connecting trace file on handover");
518  }
519 
520  it->second.second = identifier;
521  }
522 } // end of `void UpdateIdentifierOnProbes ();`
523 
524 void
526 {
527  NS_LOG_FUNCTION(this << gwNode->GetId());
528 
529  NetDeviceContainer devs = GetGwSatNetDevice(gwNode);
530  Callback<void, uint32_t, const Address&, bool> callback =
531  MakeCallback(&SatStatsPacketErrorHelper::ErrorRxCallback, this);
532 
533  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
534  {
535  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
536  NS_ASSERT(satDev != nullptr);
537  Ptr<SatPhy> satPhy = satDev->GetPhy();
538  NS_ASSERT(satPhy != nullptr);
539  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
540  NS_ASSERT(satPhyRx != nullptr);
541  ObjectVectorValue carriers;
542  satPhyRx->GetAttribute("RxCarrierList", carriers);
543  NS_LOG_DEBUG(this << " Node ID " << gwNode->GetId() << " device #" << (*itDev)->GetIfIndex()
544  << " has " << carriers.GetN() << " RX carriers");
545 
546  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
547  ++itCarrier)
548  {
549  if (DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType() !=
551  {
552  continue;
553  }
554  const bool ret =
555  itCarrier->second->TraceConnectWithoutContext(GetTraceSourceName(), callback);
556  if (ret)
557  {
558  NS_LOG_INFO(this << " successfully connected with node ID " << gwNode->GetId()
559  << " device #" << (*itDev)->GetIfIndex() << " RX carrier #"
560  << itCarrier->first);
561  }
562  else
563  {
564  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
565  << " of SatPhyRxCarrier"
566  << " at node ID " << gwNode->GetId()
567  << " device #" << (*itDev)->GetIfIndex()
568  << " RX carrier #" << itCarrier->first);
569  }
570 
571  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
572 
573  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
574 
575 } // end of `void InstallProbeOnGw (Ptr<Node>)`
576 
577 void
579 {
580  NS_LOG_FUNCTION(this << satNode->GetId());
581 
582  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(satNode);
583  Callback<void, uint32_t, const Address&, bool> callback =
584  MakeCallback(&SatStatsPacketErrorHelper::ErrorRxCallback, this);
585 
586  Ptr<SatPhy> satPhy;
587  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
588  NS_ASSERT(satOrbiterDev != nullptr);
589  std::map<uint32_t, Ptr<SatPhy>> satOrbiterFeederPhys = satOrbiterDev->GetFeederPhy();
590  for (std::map<uint32_t, Ptr<SatPhy>>::iterator itPhy = satOrbiterFeederPhys.begin();
591  itPhy != satOrbiterFeederPhys.end();
592  ++itPhy)
593  {
594  satPhy = itPhy->second;
595  NS_ASSERT(satPhy != nullptr);
596  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
597  NS_ASSERT(satPhyRx != nullptr);
598 
599  ObjectVectorValue carriers;
600  satPhyRx->GetAttribute("RxCarrierList", carriers);
601  NS_LOG_DEBUG(this << " Node ID " << satNode->GetId() << " device #" << dev->GetIfIndex()
602  << " has " << carriers.GetN() << " RX carriers");
603 
604  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
605  ++itCarrier)
606  {
607  if (DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType() !=
609  {
610  continue;
611  }
612  const bool ret =
613  itCarrier->second->TraceConnectWithoutContext(GetTraceSourceName(), callback);
614  if (ret)
615  {
616  NS_LOG_INFO(this << " successfully connected with node ID " << satNode->GetId()
617  << " device #" << dev->GetIfIndex() << " RX carrier #"
618  << itCarrier->first);
619  }
620  else
621  {
622  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
623  << " of SatPhyRxCarrier"
624  << " at node ID " << satNode->GetId()
625  << " device #" << dev->GetIfIndex()
626  << " RX carrier #" << itCarrier->first);
627  }
628 
629  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
630 
631  } // end of `for (std::map<uint32_t, Ptr<SatPhy>>::iterator itPhy = satOrbiterFeederPhys)`
632 
633 } // end of `void InstallProbeOnSatFeeder (Ptr<Node>)`
634 
635 void
637 {
638  NS_LOG_FUNCTION(this << satNode->GetId());
639 
640  Ptr<NetDevice> dev = GetSatSatOrbiterNetDevice(satNode);
641  Callback<void, uint32_t, const Address&, bool> callback =
642  MakeCallback(&SatStatsPacketErrorHelper::ErrorRxCallback, this);
643 
644  Ptr<SatPhy> satPhy;
645  Ptr<SatOrbiterNetDevice> satOrbiterDev = dev->GetObject<SatOrbiterNetDevice>();
646  NS_ASSERT(satOrbiterDev != nullptr);
647  std::map<uint32_t, Ptr<SatPhy>> satOrbiterUserPhys = satOrbiterDev->GetUserPhy();
648  for (std::map<uint32_t, Ptr<SatPhy>>::iterator itPhy = satOrbiterUserPhys.begin();
649  itPhy != satOrbiterUserPhys.end();
650  ++itPhy)
651  {
652  satPhy = itPhy->second;
653  NS_ASSERT(satPhy != nullptr);
654  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
655  NS_ASSERT(satPhyRx != nullptr);
656 
657  ObjectVectorValue carriers;
658  satPhyRx->GetAttribute("RxCarrierList", carriers);
659  NS_LOG_DEBUG(this << " Node ID " << satNode->GetId() << " device #" << dev->GetIfIndex()
660  << " has " << carriers.GetN() << " RX carriers");
661 
662  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
663  ++itCarrier)
664  {
665  if (DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType() !=
667  {
668  continue;
669  }
670  const bool ret =
671  itCarrier->second->TraceConnectWithoutContext(GetTraceSourceName(), callback);
672  if (ret)
673  {
674  NS_LOG_INFO(this << " successfully connected with node ID " << satNode->GetId()
675  << " device #" << dev->GetIfIndex() << " RX carrier #"
676  << itCarrier->first);
677  }
678  else
679  {
680  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
681  << " of SatPhyRxCarrier"
682  << " at node ID " << satNode->GetId()
683  << " device #" << dev->GetIfIndex()
684  << " RX carrier #" << itCarrier->first);
685  }
686 
687  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
688 
689  } // end of `for (std::map<uint32_t, Ptr<SatPhy>>::iterator itPhy = satOrbiterUserPhys)`
690 
691 } // end of `void InstallProbeOnSatUser (Ptr<Node>)`
692 
693 void
695 {
696  NS_LOG_FUNCTION(this << utNode->GetId());
697 
698  const int32_t utId = GetUtId(utNode);
699  NS_ASSERT_MSG(utId > 0, "Node " << utNode->GetId() << " is not a valid UT");
700  const uint32_t identifier = GetIdentifierForUt(utNode);
701 
702  // Create the probe.
703  std::ostringstream probeName;
704  probeName << utId;
705  Ptr<SatPhyRxCarrierPacketProbe> probe = CreateObject<SatPhyRxCarrierPacketProbe>();
706  probe->SetName(probeName.str());
707 
708  Ptr<NetDevice> dev = GetUtSatNetDevice(utNode);
709  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
710  NS_ASSERT(satDev != nullptr);
711  Ptr<SatPhy> satPhy = satDev->GetPhy();
712  NS_ASSERT(satPhy != nullptr);
713  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
714  NS_ASSERT(satPhyRx != nullptr);
715  ObjectVectorValue carriers;
716  satPhyRx->GetAttribute("RxCarrierList", carriers);
717  NS_LOG_DEBUG(this << " Node ID " << utNode->GetId() << " device #" << dev->GetIfIndex()
718  << " has " << carriers.GetN() << " RX carriers");
719 
720  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin(); itCarrier != carriers.End();
721  ++itCarrier)
722  {
723  if (DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType() !=
725  {
726  continue;
727  }
728  // Connect the object to the probe.
729  if (probe->ConnectByObject(GetTraceSourceName(), itCarrier->second) &&
730  ConnectProbeToCollector(probe, identifier))
731  {
732  m_probes.insert(
733  std::make_pair(probe->GetObject<Probe>(), std::make_pair(utNode, identifier)));
734 
735  } // end of `if (probe->ConnectByObject (GetTraceSourceName (), itCarrier->second))`
736  else
737  {
738  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
739  << " of SatPhyRxCarrier"
740  << " at node ID " << utNode->GetId()
741  << " device #" << dev->GetIfIndex()
742  << " RX carrier #" << itCarrier->first);
743  }
744 
745  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
746 
747 } // end of `void InstallProbeOnUt (Ptr<Node>)`
748 
749 // FORWARD FEEDER LINK DEDICATED ACCESS //////////////////////////////////////////////
750 
751 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdFeederDaPacketErrorHelper);
752 
754  Ptr<const SatHelper> satHelper)
755  : SatStatsPacketErrorHelper(satHelper)
756 {
757  NS_LOG_FUNCTION(this << satHelper);
758  SetTraceSourceName("DaRx");
761 }
762 
764 {
765  NS_LOG_FUNCTION(this);
766 }
767 
768 TypeId // static
770 {
771  static TypeId tid =
772  TypeId("ns3::SatStatsFwdFeederDaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
773  return tid;
774 }
775 
776 // FORWARD USER LINK DEDICATED ACCESS //////////////////////////////////////////////
777 
778 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdUserDaPacketErrorHelper);
779 
781  Ptr<const SatHelper> satHelper)
782  : SatStatsPacketErrorHelper(satHelper)
783 {
784  NS_LOG_FUNCTION(this << satHelper);
785  SetTraceSourceName("DaRx");
788 }
789 
791 {
792  NS_LOG_FUNCTION(this);
793 }
794 
795 TypeId // static
797 {
798  static TypeId tid =
799  TypeId("ns3::SatStatsFwdUserDaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
800  return tid;
801 }
802 
803 // RETURN FEEDER LINK DEDICATED ACCESS ///////////////////////////////////////////////
804 
805 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederDaPacketErrorHelper);
806 
808  Ptr<const SatHelper> satHelper)
809  : SatStatsPacketErrorHelper(satHelper)
810 {
811  NS_LOG_FUNCTION(this << satHelper);
812  SetTraceSourceName("DaRx");
815 }
816 
818 {
819  NS_LOG_FUNCTION(this);
820 }
821 
822 TypeId // static
824 {
825  static TypeId tid =
826  TypeId("ns3::SatStatsRtnFeederDaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
827  return tid;
828 }
829 
830 // RETURN USER LINK DEDICATED ACCESS ///////////////////////////////////////////////
831 
832 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnUserDaPacketErrorHelper);
833 
835  Ptr<const SatHelper> satHelper)
836  : SatStatsPacketErrorHelper(satHelper)
837 {
838  NS_LOG_FUNCTION(this << satHelper);
839  SetTraceSourceName("DaRx");
842 }
843 
845 {
846  NS_LOG_FUNCTION(this);
847 }
848 
849 TypeId // static
851 {
852  static TypeId tid =
853  TypeId("ns3::SatStatsRtnUserDaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
854  return tid;
855 }
856 
857 // FEEDER SLOTTED ALOHA //////////////////////////////////////////////////////////////
858 
859 NS_OBJECT_ENSURE_REGISTERED(SatStatsFeederSlottedAlohaPacketErrorHelper);
860 
862  Ptr<const SatHelper> satHelper)
863  : SatStatsPacketErrorHelper(satHelper)
864 {
865  NS_LOG_FUNCTION(this << satHelper);
866  SetTraceSourceName("SlottedAlohaRxError");
869 }
870 
872 {
873  NS_LOG_FUNCTION(this);
874 }
875 
876 TypeId // static
878 {
879  static TypeId tid = TypeId("ns3::SatStatsFeederSlottedAlohaPacketErrorHelper")
880  .SetParent<SatStatsPacketErrorHelper>();
881  return tid;
882 }
883 
884 // USER SLOTTED ALOHA //////////////////////////////////////////////////////////////
885 
886 NS_OBJECT_ENSURE_REGISTERED(SatStatsUserSlottedAlohaPacketErrorHelper);
887 
889  Ptr<const SatHelper> satHelper)
890  : SatStatsPacketErrorHelper(satHelper)
891 {
892  NS_LOG_FUNCTION(this << satHelper);
893  SetTraceSourceName("SlottedAlohaRxError");
896 }
897 
899 {
900  NS_LOG_FUNCTION(this);
901 }
902 
903 TypeId // static
905 {
906  static TypeId tid = TypeId("ns3::SatStatsUserSlottedAlohaPacketErrorHelper")
907  .SetParent<SatStatsPacketErrorHelper>();
908  return tid;
909 }
910 
911 // FEEDER CRDSA //////////////////////////////////////////////////////////////////////
912 
913 NS_OBJECT_ENSURE_REGISTERED(SatStatsFeederCrdsaPacketErrorHelper);
914 
916  Ptr<const SatHelper> satHelper)
917  : SatStatsPacketErrorHelper(satHelper)
918 {
919  NS_LOG_FUNCTION(this << satHelper);
920  SetTraceSourceName("CrdsaUniquePayloadRx");
923 }
924 
926 {
927  NS_LOG_FUNCTION(this);
928 }
929 
930 TypeId // static
932 {
933  static TypeId tid =
934  TypeId("ns3::SatStatsFeederCrdsaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
935  return tid;
936 }
937 
938 // USER CRDSA //////////////////////////////////////////////////////////////////////
939 
940 NS_OBJECT_ENSURE_REGISTERED(SatStatsUserCrdsaPacketErrorHelper);
941 
943  Ptr<const SatHelper> satHelper)
944  : SatStatsPacketErrorHelper(satHelper)
945 {
946  NS_LOG_FUNCTION(this << satHelper);
947  SetTraceSourceName("CrdsaUniquePayloadRx");
950 }
951 
953 {
954  NS_LOG_FUNCTION(this);
955 }
956 
957 TypeId // static
959 {
960  static TypeId tid =
961  TypeId("ns3::SatStatsUserCrdsaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
962  return tid;
963 }
964 
965 // FEEDER E-SSA //////////////////////////////////////////////////////////////////////
966 
967 NS_OBJECT_ENSURE_REGISTERED(SatStatsFeederEssaPacketErrorHelper);
968 
970  Ptr<const SatHelper> satHelper)
971  : SatStatsPacketErrorHelper(satHelper)
972 {
973  NS_LOG_FUNCTION(this << satHelper);
974  SetTraceSourceName("EssaRxError");
977 }
978 
980 {
981  NS_LOG_FUNCTION(this);
982 }
983 
984 TypeId // static
986 {
987  static TypeId tid =
988  TypeId("ns3::SatStatsFeederEssaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
989  return tid;
990 }
991 
992 // USER E-SSA //////////////////////////////////////////////////////////////////////
993 
994 NS_OBJECT_ENSURE_REGISTERED(SatStatsUserEssaPacketErrorHelper);
995 
997  : SatStatsPacketErrorHelper(satHelper)
998 {
999  NS_LOG_FUNCTION(this << satHelper);
1000  SetTraceSourceName("EssaRxError");
1003 }
1004 
1006 {
1007  NS_LOG_FUNCTION(this);
1008 }
1009 
1010 TypeId // static
1012 {
1013  static TypeId tid =
1014  TypeId("ns3::SatStatsUserEssaPacketErrorHelper").SetParent<SatStatsPacketErrorHelper>();
1015  return tid;
1016 }
1017 
1018 } // end of namespace ns3
SatEnums class is for simplifying the use of enumerators in the satellite module.
ChannelType_t
Types of channel.
static std::string GetChannelTypeName(ChannelType_t channelType)
SatNetDevice to be utilized in the UT and GW nodes.
SatOrbiterNetDevice to be utilized in geostationary satellite.
Produce packet error statistics of Random Access CRDSA on feeder link from a satellite module simulat...
SatStatsFeederCrdsaPacketErrorHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce packet error statistics of Random Access E-SSA on feeder link from a satellite module simulat...
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsFeederEssaPacketErrorHelper(Ptr< const SatHelper > satHelper)
Produce packet error statistics of Random Access Slotted ALOHA on feeder link from a satellite module...
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce packet error statistics of Dedicated Access in forward feeder link from a satellite module si...
SatStatsFwdFeederDaPacketErrorHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce packet error statistics of Dedicated Access in forward user link from a satellite module simu...
SatStatsFwdUserDaPacketErrorHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Parent abstract class of all satellite statistics helpers.
static Ptr< NetDevice > GetSatSatOrbiterNetDevice(Ptr< Node > satNode)
uint32_t GetIdentifierForUtUser(Ptr< Node > utUserNode) const
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 GetUtId(Ptr< Node > utNode) const
uint32_t CreateCollectorPerIdentifier(CollectorMap &collectorMap) const
Create one collector instance for each identifier in the simulation.
static Ptr< NetDevice > GetUtSatNetDevice(Ptr< Node > utNode)
OutputType_t GetOutputType() const
uint32_t GetIdentifierForUt(Ptr< Node > utNode) const
std::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
Base class for packet error statistics helpers.
static TypeId GetTypeId()
inherited from ObjectBase base class
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
std::string m_traceSourceName
Name of trace source of PHY RX carrier to listen to.
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
void InstallProbeOnGw(Ptr< Node > gwNode)
Set up several listeners on a GW node and connect them to the collectors.
std::map< Ptr< Probe >, std::pair< Ptr< Node >, uint32_t > > m_probes
Maintains a list of probes created by this helper (for forward link).
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
SatPhyRxCarrier::CarrierType GetValidCarrierType() const
Get the valid carrier type.
bool DisconnectProbeFromCollector(Ptr< Probe > probe, uint32_t identifier)
Disconnect the probe from the right collector.
SatStatsPacketErrorHelper(Ptr< const SatHelper > satHelper)
CollectorMap m_terminalCollectors
Maintains a list of collectors created by this helper.
void InstallProbeOnUt(Ptr< Node > utNode)
Set up several probes on a UT node and connect them to the collectors.
SatEnums::ChannelType_t m_channelType
Link where statistics are gathered from.
void InstallProbeOnSatUser(Ptr< Node > satNode)
Set up several listeners on a SAT user node and connect them to the collectors.
void SetChannelType(SatEnums::ChannelType_t channelType)
bool ConnectProbeToCollector(Ptr< Probe > probe, uint32_t identifier)
Connect the probe to the right collector.
void SetValidCarrierType(SatPhyRxCarrier::CarrierType carrierType)
Set valid carrier type for this statistics helper type.
void SetTraceSourceName(std::string traceSourceName)
void ErrorRxCallback(uint32_t nPackets, const Address &fromOrTo, bool isError)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
void InstallProbeOnSatFeeder(Ptr< Node > satNode)
Set up several listeners on a SAT feeder node and connect them to the collectors.
Produce packet error statistics of Dedicated Access in return feeder link from a satellite module sim...
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsRtnFeederDaPacketErrorHelper(Ptr< const SatHelper > satHelper)
Produce packet error statistics of Dedicated Access in return user link from a satellite module simul...
SatStatsRtnUserDaPacketErrorHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce packet error statistics of Random Access CRDSA on user link from a satellite module simulatio...
SatStatsUserCrdsaPacketErrorHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Produce packet error statistics of Random Access E-SSA on user link from a satellite module simulatio...
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsUserEssaPacketErrorHelper(Ptr< const SatHelper > satHelper)
Produce packet error statistics of Random Access Slotted ALOHA on user link from a satellite module s...
static TypeId GetTypeId()
inherited from ObjectBase base class
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.