Loading...
Searching...
No Matches
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-topology.h"
37#include "ns3/satellite-ut-llc.h"
38#include "ns3/scalar-collector.h"
39#include "ns3/singleton.h"
40#include "ns3/string.h"
41#include "ns3/unit-conversion-collector.h"
42
43#include <sstream>
44#include <string>
45
46NS_LOG_COMPONENT_DEFINE("SatStatsRbdcRequestHelper");
47
48namespace ns3
49{
50
51NS_OBJECT_ENSURE_REGISTERED(SatStatsRbdcRequestHelper);
52
54 : SatStatsHelper(satHelper),
55 m_averagingMode(false)
56{
57 NS_LOG_FUNCTION(this << satHelper);
58}
59
64
65TypeId
67{
68 static TypeId tid =
69 TypeId("ns3::SatStatsRbdcRequestHelper")
70 .SetParent<SatStatsHelper>()
71 .AddAttribute("AveragingMode",
72 "If true, all samples will be averaged before passed to aggregator. "
73 "Only affects histogram, PDF, and CDF output types.",
74 BooleanValue(false),
77 MakeBooleanChecker());
78 return tid;
79}
80
81void
83{
84 NS_LOG_FUNCTION(this << averagingMode);
85 m_averagingMode = averagingMode;
86}
87
88bool
90{
91 NS_LOG_FUNCTION(this);
92 return m_averagingMode;
93}
94
95void
96SatStatsRbdcRequestHelper::RbdcRateCallback(std::string identifier, uint32_t rbdcTraceKbps)
97{
98 std::stringstream ss(identifier);
99 uint32_t identifierNum;
100 if (!(ss >> identifierNum))
101 {
102 NS_FATAL_ERROR("Cannot convert '" << identifier << "' to number");
103 }
104 Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifierNum);
105 NS_ASSERT_MSG(collector != nullptr,
106 "Unable to find collector with identifier " << identifierNum);
107
108 switch (GetOutputType())
109 {
112 Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
113 NS_ASSERT(c != nullptr);
114 c->TraceSinkUinteger32(0, rbdcTraceKbps);
115 break;
116 }
117
120 Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
121 NS_ASSERT(c != nullptr);
122 c->TraceSinkUinteger32(0, rbdcTraceKbps);
123 break;
124 }
125
132 if (m_averagingMode)
133 {
134 Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
135 NS_ASSERT(c != nullptr);
136 c->TraceSinkUinteger32(0, rbdcTraceKbps);
137 }
138 else
139 {
140 Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
141 NS_ASSERT(c != nullptr);
142 c->TraceSinkUinteger32(0, rbdcTraceKbps);
143 }
144 break;
145
146 default:
147 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
148 << " is not a valid output type for this statistics.");
149 break;
150 }
151}
152
153void
155{
156 NS_LOG_FUNCTION(this);
157
158 switch (GetOutputType())
159 {
161 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
162 << " is not a valid output type for this statistics.");
163 break;
164
166 // Setup aggregator.
167 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
168 "OutputFileName",
169 StringValue(GetOutputFileName()),
170 "MultiFileMode",
171 BooleanValue(false),
172 "EnableContextPrinting",
173 BooleanValue(true),
174 "GeneralHeading",
175 StringValue(GetIdentifierHeading("rbdc_Kbps")));
176
177 // Setup collectors.
178 m_terminalCollectors.SetType("ns3::ScalarCollector");
179 m_terminalCollectors.SetAttribute("InputDataType",
180 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
181 m_terminalCollectors.SetAttribute(
182 "OutputType",
183 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
185 m_terminalCollectors.ConnectToAggregator("Output",
187 &MultiFileAggregator::Write1d);
188 break;
189 }
190
192 // Setup aggregator.
193 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
194 "OutputFileName",
195 StringValue(GetOutputFileName()),
196 "GeneralHeading",
197 StringValue(GetTimeHeading("rbdc_Kbps")));
198
199 // Setup collectors.
200 m_terminalCollectors.SetType("ns3::UnitConversionCollector");
201 m_terminalCollectors.SetAttribute("ConversionType",
202 EnumValue(UnitConversionCollector::TRANSPARENT));
204 m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
206 &MultiFileAggregator::Write2d);
207 break;
208 }
209
213 if (m_averagingMode)
214 {
215 // Setup aggregator.
216 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
217 "OutputFileName",
218 StringValue(GetOutputFileName()),
219 "MultiFileMode",
220 BooleanValue(false),
221 "EnableContextPrinting",
222 BooleanValue(false),
223 "GeneralHeading",
224 StringValue(GetDistributionHeading("rbdc_Kbps")));
225 Ptr<MultiFileAggregator> fileAggregator =
226 m_aggregator->GetObject<MultiFileAggregator>();
227 NS_ASSERT(fileAggregator != nullptr);
228
229 // Setup the final-level collector.
230 m_averagingCollector = CreateObject<DistributionCollector>();
231 DistributionCollector::OutputType_t outputType =
232 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
234 {
235 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
236 }
238 {
239 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
240 }
241 m_averagingCollector->SetOutputType(outputType);
242 m_averagingCollector->SetName("0");
243 m_averagingCollector->TraceConnect(
244 "Output",
245 "0",
246 MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
247 m_averagingCollector->TraceConnect(
248 "OutputString",
249 "0",
250 MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
251 m_averagingCollector->TraceConnect(
252 "Warning",
253 "0",
254 MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
255
256 // Setup collectors.
257 m_terminalCollectors.SetType("ns3::ScalarCollector");
258 m_terminalCollectors.SetAttribute("InputDataType",
259 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
260 m_terminalCollectors.SetAttribute(
261 "OutputType",
262 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
264 Callback<void, double> callback =
265 MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
266 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
267 it != m_terminalCollectors.End();
268 ++it)
269 {
270 it->second->TraceConnectWithoutContext("Output", callback);
271 }
272 }
273 else
274 {
275 // Setup aggregator.
276 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
277 "OutputFileName",
278 StringValue(GetOutputFileName()),
279 "GeneralHeading",
280 StringValue(GetDistributionHeading("rbdc_Kbps")));
281
282 // Setup collectors.
283 m_terminalCollectors.SetType("ns3::DistributionCollector");
284 DistributionCollector::OutputType_t outputType =
285 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
287 {
288 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
289 }
291 {
292 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
293 }
294 m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
296 m_terminalCollectors.ConnectToAggregator("Output",
298 &MultiFileAggregator::Write2d);
299 m_terminalCollectors.ConnectToAggregator("OutputString",
301 &MultiFileAggregator::AddContextHeading);
302 m_terminalCollectors.ConnectToAggregator("Warning",
304 &MultiFileAggregator::EnableContextWarning);
305 }
306
307 break;
308 }
309
312 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
313 << " is not a valid output type for this statistics.");
314 break;
315
317 // Setup aggregator.
318 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
319 "OutputPath",
320 StringValue(GetOutputPath()),
321 "OutputFileName",
322 StringValue(GetName()));
323 Ptr<MagisterGnuplotAggregator> plotAggregator =
324 m_aggregator->GetObject<MagisterGnuplotAggregator>();
325 NS_ASSERT(plotAggregator != nullptr);
326 // plot->SetTitle ("");
327 plotAggregator->SetLegend("Time (in seconds)", "RBDC requested (in kbps)");
328 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
329
330 // Setup collectors.
331 m_terminalCollectors.SetType("ns3::UnitConversionCollector");
332 m_terminalCollectors.SetAttribute("ConversionType",
333 EnumValue(UnitConversionCollector::TRANSPARENT));
335 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
336 it != m_terminalCollectors.End();
337 ++it)
338 {
339 const std::string context = it->second->GetName();
340 plotAggregator->Add2dDataset(context, context);
341 }
342 m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
344 &MagisterGnuplotAggregator::Write2d);
345 break;
346 }
347
351 if (m_averagingMode)
352 {
353 // Setup aggregator.
354 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
355 "OutputPath",
356 StringValue(GetOutputPath()),
357 "OutputFileName",
358 StringValue(GetName()));
359 Ptr<MagisterGnuplotAggregator> plotAggregator =
360 m_aggregator->GetObject<MagisterGnuplotAggregator>();
361 NS_ASSERT(plotAggregator != nullptr);
362 // plot->SetTitle ("");
363 plotAggregator->SetLegend("RBDC requested (in kbps)", "Frequency");
364 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
365 plotAggregator->Add2dDataset(GetName(), GetName());
367
368 // Setup the final-level collector.
369 m_averagingCollector = CreateObject<DistributionCollector>();
370 DistributionCollector::OutputType_t outputType =
371 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
373 {
374 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
375 }
377 {
378 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
379 }
380 m_averagingCollector->SetOutputType(outputType);
381 m_averagingCollector->SetName("0");
382 m_averagingCollector->TraceConnect(
383 "Output",
384 GetName(),
385 MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
387
388 // Setup collectors.
389 m_terminalCollectors.SetType("ns3::ScalarCollector");
390 m_terminalCollectors.SetAttribute("InputDataType",
391 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
392 m_terminalCollectors.SetAttribute(
393 "OutputType",
394 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
396 Callback<void, double> callback =
397 MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
398 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
399 it != m_terminalCollectors.End();
400 ++it)
401 {
402 it->second->TraceConnectWithoutContext("Output", callback);
403 }
404 }
405 else
406 {
407 // Setup aggregator.
408 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
409 "OutputPath",
410 StringValue(GetOutputPath()),
411 "OutputFileName",
412 StringValue(GetName()));
413 Ptr<MagisterGnuplotAggregator> plotAggregator =
414 m_aggregator->GetObject<MagisterGnuplotAggregator>();
415 NS_ASSERT(plotAggregator != nullptr);
416 // plot->SetTitle ("");
417 plotAggregator->SetLegend("RBDC requested (in kbps)", "Frequency");
418 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
419
420 // Setup collectors.
421 m_terminalCollectors.SetType("ns3::DistributionCollector");
422 DistributionCollector::OutputType_t outputType =
423 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
425 {
426 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
427 }
429 {
430 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
431 }
432 m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
434 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
435 it != m_terminalCollectors.End();
436 ++it)
437 {
438 const std::string context = it->second->GetName();
439 plotAggregator->Add2dDataset(context, context);
440 }
441 m_terminalCollectors.ConnectToAggregator("Output",
443 &MagisterGnuplotAggregator::Write2d);
444 }
445
446 break;
447 }
448
449 default:
450 NS_FATAL_ERROR("SatStatsDelayHelper - Invalid output type");
451 break;
452 }
453
454 // Setup probes and connect them to the collectors.
456}
457
458void
460{
461 NS_LOG_FUNCTION(this);
462
463 Callback<void, std::string, uint32_t> callback =
465
466 NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
467 for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
468 {
469 std::ostringstream context;
470 switch (GetIdentifierType())
471 {
473 context << "0";
474 break;
478 context << GetIdentifierForUt(*it);
479 break;
480 default:
481 NS_FATAL_ERROR("SatStatsRbdcRequestHelper - Invalid identifier type");
482 break;
483 }
484
485 Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
486 Ptr<SatNetDevice> satDev = dev->GetObject<SatNetDevice>();
487 NS_ASSERT(satDev != nullptr);
488 Ptr<SatLlc> satLlc = satDev->GetLlc();
489 NS_ASSERT(satLlc != nullptr);
490 Ptr<SatUtLlc> utLlc = satLlc->GetObject<SatUtLlc>();
491 NS_ASSERT(utLlc != nullptr);
492 Ptr<SatRequestManager> requestManager = utLlc->GetRequestManager();
493
494 const bool ret = requestManager->TraceConnect("RbdcTrace", context.str(), callback);
495 NS_ASSERT_MSG(ret, "Error connecting to CrTraceLog of node " << (*it)->GetId());
496 NS_LOG_INFO(this << " successfully connected" << " with node ID " << (*it)->GetId());
497 }
498}
499
500} // namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
IdentifierType_t GetIdentifierType() const
static std::string GetOutputTypeName(OutputType_t outputType)
SatStatsHelper(Ptr< const SatHelper > satHelper)
Creates a new helper instance.
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
Base class for RBDC requests statistics helpers.
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.