satellite-stats-rbdc-request-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018 CNES
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: Mathias Ettinger <mettinger@toulouse.viveris.com>
19  */
20 
22 
23 #include <ns3/boolean.h>
24 #include <ns3/callback.h>
25 #include <ns3/data-collection-object.h>
26 #include <ns3/distribution-collector.h>
27 #include <ns3/enum.h>
28 #include <ns3/log.h>
29 #include <ns3/magister-gnuplot-aggregator.h>
30 #include <ns3/multi-file-aggregator.h>
31 #include <ns3/node-container.h>
32 #include <ns3/nstime.h>
33 #include <ns3/probe.h>
34 #include <ns3/satellite-helper.h>
35 #include <ns3/satellite-request-manager.h>
36 #include <ns3/satellite-ut-llc.h>
37 #include <ns3/scalar-collector.h>
38 #include <ns3/singleton.h>
39 #include <ns3/string.h>
40 #include <ns3/unit-conversion-collector.h>
41 
42 #include <sstream>
43 
44 NS_LOG_COMPONENT_DEFINE("SatStatsRbdcRequestHelper");
45 
46 namespace ns3
47 {
48 
49 NS_OBJECT_ENSURE_REGISTERED(SatStatsRbdcRequestHelper);
50 
52  : SatStatsHelper(satHelper),
53  m_averagingMode(false)
54 {
55  NS_LOG_FUNCTION(this << satHelper);
56 }
57 
59 {
60  NS_LOG_FUNCTION(this);
61 }
62 
63 TypeId
65 {
66  static TypeId tid =
67  TypeId("ns3::SatStatsRbdcRequestHelper")
68  .SetParent<SatStatsHelper>()
69  .AddAttribute("AveragingMode",
70  "If true, all samples will be averaged before passed to aggregator. "
71  "Only affects histogram, PDF, and CDF output types.",
72  BooleanValue(false),
75  MakeBooleanChecker());
76  return tid;
77 }
78 
79 void
81 {
82  NS_LOG_FUNCTION(this << averagingMode);
83  m_averagingMode = averagingMode;
84 }
85 
86 bool
88 {
89  NS_LOG_FUNCTION(this);
90  return m_averagingMode;
91 }
92 
93 void
94 SatStatsRbdcRequestHelper::RbdcRateCallback(std::string identifier, uint32_t rbdcTraceKbps)
95 {
96  std::stringstream ss(identifier);
97  uint32_t identifierNum;
98  if (!(ss >> identifierNum))
99  {
100  NS_FATAL_ERROR("Cannot convert '" << identifier << "' to number");
101  }
102  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifierNum);
103  NS_ASSERT_MSG(collector != nullptr,
104  "Unable to find collector with identifier " << identifierNum);
105 
106  switch (GetOutputType())
107  {
110  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
111  NS_ASSERT(c != nullptr);
112  c->TraceSinkUinteger32(0, rbdcTraceKbps);
113  break;
114  }
115 
118  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
119  NS_ASSERT(c != nullptr);
120  c->TraceSinkUinteger32(0, rbdcTraceKbps);
121  break;
122  }
123 
130  if (m_averagingMode)
131  {
132  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
133  NS_ASSERT(c != nullptr);
134  c->TraceSinkUinteger32(0, rbdcTraceKbps);
135  }
136  else
137  {
138  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
139  NS_ASSERT(c != nullptr);
140  c->TraceSinkUinteger32(0, rbdcTraceKbps);
141  }
142  break;
143 
144  default:
145  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
146  << " is not a valid output type for this statistics.");
147  break;
148  }
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION(this);
155 
156  switch (GetOutputType())
157  {
159  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
160  << " is not a valid output type for this statistics.");
161  break;
162 
164  // Setup aggregator.
165  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
166  "OutputFileName",
167  StringValue(GetOutputFileName()),
168  "MultiFileMode",
169  BooleanValue(false),
170  "EnableContextPrinting",
171  BooleanValue(true),
172  "GeneralHeading",
173  StringValue(GetIdentifierHeading("rbdc_Kbps")));
174 
175  // Setup collectors.
176  m_terminalCollectors.SetType("ns3::ScalarCollector");
177  m_terminalCollectors.SetAttribute("InputDataType",
178  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
179  m_terminalCollectors.SetAttribute(
180  "OutputType",
181  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
183  m_terminalCollectors.ConnectToAggregator("Output",
184  m_aggregator,
185  &MultiFileAggregator::Write1d);
186  break;
187  }
188 
190  // Setup aggregator.
191  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
192  "OutputFileName",
193  StringValue(GetOutputFileName()),
194  "GeneralHeading",
195  StringValue(GetTimeHeading("rbdc_Kbps")));
196 
197  // Setup collectors.
198  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
199  m_terminalCollectors.SetAttribute("ConversionType",
200  EnumValue(UnitConversionCollector::TRANSPARENT));
202  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
203  m_aggregator,
204  &MultiFileAggregator::Write2d);
205  break;
206  }
207 
211  if (m_averagingMode)
212  {
213  // Setup aggregator.
214  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
215  "OutputFileName",
216  StringValue(GetOutputFileName()),
217  "MultiFileMode",
218  BooleanValue(false),
219  "EnableContextPrinting",
220  BooleanValue(false),
221  "GeneralHeading",
222  StringValue(GetDistributionHeading("rbdc_Kbps")));
223  Ptr<MultiFileAggregator> fileAggregator =
224  m_aggregator->GetObject<MultiFileAggregator>();
225  NS_ASSERT(fileAggregator != nullptr);
226 
227  // Setup the final-level collector.
228  m_averagingCollector = CreateObject<DistributionCollector>();
229  DistributionCollector::OutputType_t outputType =
230  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
232  {
233  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
234  }
236  {
237  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
238  }
239  m_averagingCollector->SetOutputType(outputType);
240  m_averagingCollector->SetName("0");
241  m_averagingCollector->TraceConnect(
242  "Output",
243  "0",
244  MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
245  m_averagingCollector->TraceConnect(
246  "OutputString",
247  "0",
248  MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
249  m_averagingCollector->TraceConnect(
250  "Warning",
251  "0",
252  MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
253 
254  // Setup collectors.
255  m_terminalCollectors.SetType("ns3::ScalarCollector");
256  m_terminalCollectors.SetAttribute("InputDataType",
257  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
258  m_terminalCollectors.SetAttribute(
259  "OutputType",
260  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
262  Callback<void, double> callback =
263  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
264  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
265  it != m_terminalCollectors.End();
266  ++it)
267  {
268  it->second->TraceConnectWithoutContext("Output", callback);
269  }
270  }
271  else
272  {
273  // Setup aggregator.
274  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
275  "OutputFileName",
276  StringValue(GetOutputFileName()),
277  "GeneralHeading",
278  StringValue(GetDistributionHeading("rbdc_Kbps")));
279 
280  // Setup collectors.
281  m_terminalCollectors.SetType("ns3::DistributionCollector");
282  DistributionCollector::OutputType_t outputType =
283  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
285  {
286  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
287  }
289  {
290  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
291  }
292  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
294  m_terminalCollectors.ConnectToAggregator("Output",
295  m_aggregator,
296  &MultiFileAggregator::Write2d);
297  m_terminalCollectors.ConnectToAggregator("OutputString",
298  m_aggregator,
299  &MultiFileAggregator::AddContextHeading);
300  m_terminalCollectors.ConnectToAggregator("Warning",
301  m_aggregator,
302  &MultiFileAggregator::EnableContextWarning);
303  }
304 
305  break;
306  }
307 
310  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
311  << " is not a valid output type for this statistics.");
312  break;
313 
315  // Setup aggregator.
316  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
317  "OutputPath",
318  StringValue(GetOutputPath()),
319  "OutputFileName",
320  StringValue(GetName()));
321  Ptr<MagisterGnuplotAggregator> plotAggregator =
322  m_aggregator->GetObject<MagisterGnuplotAggregator>();
323  NS_ASSERT(plotAggregator != nullptr);
324  // plot->SetTitle ("");
325  plotAggregator->SetLegend("Time (in seconds)", "RBDC requested (in kbps)");
326  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
327 
328  // Setup collectors.
329  m_terminalCollectors.SetType("ns3::UnitConversionCollector");
330  m_terminalCollectors.SetAttribute("ConversionType",
331  EnumValue(UnitConversionCollector::TRANSPARENT));
333  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
334  it != m_terminalCollectors.End();
335  ++it)
336  {
337  const std::string context = it->second->GetName();
338  plotAggregator->Add2dDataset(context, context);
339  }
340  m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
341  m_aggregator,
342  &MagisterGnuplotAggregator::Write2d);
343  break;
344  }
345 
349  if (m_averagingMode)
350  {
351  // Setup aggregator.
352  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
353  "OutputPath",
354  StringValue(GetOutputPath()),
355  "OutputFileName",
356  StringValue(GetName()));
357  Ptr<MagisterGnuplotAggregator> plotAggregator =
358  m_aggregator->GetObject<MagisterGnuplotAggregator>();
359  NS_ASSERT(plotAggregator != nullptr);
360  // plot->SetTitle ("");
361  plotAggregator->SetLegend("RBDC requested (in kbps)", "Frequency");
362  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
363  plotAggregator->Add2dDataset(GetName(), GetName());
365 
366  // Setup the final-level collector.
367  m_averagingCollector = CreateObject<DistributionCollector>();
368  DistributionCollector::OutputType_t outputType =
369  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
371  {
372  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
373  }
375  {
376  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
377  }
378  m_averagingCollector->SetOutputType(outputType);
379  m_averagingCollector->SetName("0");
380  m_averagingCollector->TraceConnect(
381  "Output",
382  GetName(),
383  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
385 
386  // Setup collectors.
387  m_terminalCollectors.SetType("ns3::ScalarCollector");
388  m_terminalCollectors.SetAttribute("InputDataType",
389  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
390  m_terminalCollectors.SetAttribute(
391  "OutputType",
392  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
394  Callback<void, double> callback =
395  MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
396  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
397  it != m_terminalCollectors.End();
398  ++it)
399  {
400  it->second->TraceConnectWithoutContext("Output", callback);
401  }
402  }
403  else
404  {
405  // Setup aggregator.
406  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
407  "OutputPath",
408  StringValue(GetOutputPath()),
409  "OutputFileName",
410  StringValue(GetName()));
411  Ptr<MagisterGnuplotAggregator> plotAggregator =
412  m_aggregator->GetObject<MagisterGnuplotAggregator>();
413  NS_ASSERT(plotAggregator != nullptr);
414  // plot->SetTitle ("");
415  plotAggregator->SetLegend("RBDC requested (in kbps)", "Frequency");
416  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
417 
418  // Setup collectors.
419  m_terminalCollectors.SetType("ns3::DistributionCollector");
420  DistributionCollector::OutputType_t outputType =
421  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
423  {
424  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
425  }
427  {
428  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
429  }
430  m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
432  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
433  it != m_terminalCollectors.End();
434  ++it)
435  {
436  const std::string context = it->second->GetName();
437  plotAggregator->Add2dDataset(context, context);
438  }
439  m_terminalCollectors.ConnectToAggregator("Output",
440  m_aggregator,
441  &MagisterGnuplotAggregator::Write2d);
442  }
443 
444  break;
445  }
446 
447  default:
448  NS_FATAL_ERROR("SatStatsDelayHelper - Invalid output type");
449  break;
450  }
451 
452  // Setup probes and connect them to the collectors.
453  InstallProbes();
454 }
455 
456 void
458 {
459  NS_LOG_FUNCTION(this);
460 
461  Callback<void, std::string, uint32_t> callback =
462  MakeCallback(&SatStatsRbdcRequestHelper::RbdcRateCallback, this);
463 
464  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
465  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
466  {
467  std::ostringstream context;
468  switch (GetIdentifierType())
469  {
471  context << "0";
472  break;
476  context << GetIdentifierForUt(*it);
477  break;
478  default:
479  NS_FATAL_ERROR("SatStatsRbdcRequestHelper - Invalid identifier type");
480  break;
481  }
482 
483  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
484  Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
485  NS_ASSERT(satDev != nullptr);
486  Ptr<SatLlc> satLlc = satDev->GetLlc();
487  NS_ASSERT(satLlc != nullptr);
488  Ptr<SatUtLlc> utLlc = satLlc->GetObject<SatUtLlc>();
489  NS_ASSERT(utLlc != nullptr);
490  Ptr<SatRequestManager> requestManager = utLlc->GetRequestManager();
491 
492  const bool ret = requestManager->TraceConnect("RbdcTrace", context.str(), callback);
493  NS_ASSERT_MSG(ret, "Error connecting to CrTraceLog of node " << (*it)->GetId());
494  NS_LOG_INFO(this << " successfully connected"
495  << " with node ID " << (*it)->GetId());
496  }
497 }
498 
499 } // namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
Parent abstract class of all satellite statistics helpers.
Ptr< const SatHelper > GetSatHelper() const
IdentifierType_t GetIdentifierType() const
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
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
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
static TypeId GetTypeId()
inherited from ObjectBase base class
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
void InstallProbes()
Set up several probes or other means of listeners and connect them to the collectors.
SatStatsRbdcRequestHelper(Ptr< const SatHelper > satHelper)
void RbdcRateCallback(std::string identifier, uint32_t rbdcTraceKbps)
Receive inputs from trace sources.
CollectorMap m_terminalCollectors
Maintains a list of collectors created by this helper.
Ptr< DistributionCollector > m_averagingCollector
The final collector utilized in averaged output (histogram, PDF, and CDF).
SatUtLlc holds the UT implementation of LLC layer.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.