Loading...
Searching...
No Matches
satellite-stats-plt-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
24#include "ns3/application-delay-probe.h"
25#include "ns3/application.h"
26#include "ns3/boolean.h"
27#include "ns3/callback.h"
28#include "ns3/data-collection-object.h"
29#include "ns3/distribution-collector.h"
30#include "ns3/enum.h"
31#include "ns3/inet-socket-address.h"
32#include "ns3/ipv4.h"
33#include "ns3/log.h"
34#include "ns3/mac48-address.h"
35#include "ns3/magister-gnuplot-aggregator.h"
36#include "ns3/multi-file-aggregator.h"
37#include "ns3/net-device.h"
38#include "ns3/node-container.h"
39#include "ns3/nstime.h"
40#include "ns3/probe.h"
41#include "ns3/satellite-helper.h"
42#include "ns3/satellite-id-mapper.h"
43#include "ns3/satellite-mac.h"
44#include "ns3/satellite-net-device.h"
45#include "ns3/satellite-phy.h"
46#include "ns3/satellite-time-tag.h"
47#include "ns3/satellite-topology.h"
48#include "ns3/scalar-collector.h"
49#include "ns3/singleton.h"
50#include "ns3/string.h"
51#include "ns3/traffic-time-tag.h"
52#include "ns3/unit-conversion-collector.h"
53
54#include <map>
55#include <sstream>
56#include <string>
57#include <utility>
58
59NS_LOG_COMPONENT_DEFINE("SatStatsPltHelper");
60
61namespace ns3
62{
63
64NS_OBJECT_ENSURE_REGISTERED(SatStatsPltHelper);
65
66SatStatsPltHelper::SatStatsPltHelper(Ptr<const SatHelper> satHelper)
67 : SatStatsHelper(satHelper),
68 m_averagingMode(false)
69{
70 NS_LOG_FUNCTION(this << satHelper);
71}
72
74{
75 NS_LOG_FUNCTION(this);
76}
77
78TypeId // static
80{
81 static TypeId tid =
82 TypeId("ns3::SatStatsPltHelper")
83 .SetParent<SatStatsHelper>()
84 .AddAttribute("AveragingMode",
85 "If true, all samples will be averaged before passed to aggregator. "
86 "Only affects histogram, PDF, and CDF output types.",
87 BooleanValue(false),
88 MakeBooleanAccessor(&SatStatsPltHelper::SetAveragingMode,
90 MakeBooleanChecker());
91 return tid;
92}
93
94void
96{
97 NS_LOG_FUNCTION(this << averagingMode);
98 m_averagingMode = averagingMode;
99}
100
101bool
106
107void
109{
110 NS_LOG_FUNCTION(this);
111
112 switch (GetOutputType())
113 {
115 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
116 << " is not a valid output type for this statistics.");
117 break;
118
120 // Setup aggregator.
121 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
122 "OutputFileName",
123 StringValue(GetOutputFileName()),
124 "MultiFileMode",
125 BooleanValue(false),
126 "EnableContextPrinting",
127 BooleanValue(true),
128 "GeneralHeading",
129 StringValue(GetIdentifierHeading("plt_sec")));
130
131 // Setup collectors.
132 m_terminalCollectors.SetType("ns3::ScalarCollector");
133 m_terminalCollectors.SetAttribute("InputDataType",
134 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
135 m_terminalCollectors.SetAttribute(
136 "OutputType",
137 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
139 m_terminalCollectors.ConnectToAggregator("Output",
141 &MultiFileAggregator::Write1d);
142 break;
143 }
144
146 // Setup aggregator.
147 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
148 "OutputFileName",
149 StringValue(GetOutputFileName()),
150 "GeneralHeading",
151 StringValue(GetTimeHeading("plt_sec")));
152
153 // Setup collectors.
154 m_terminalCollectors.SetType("ns3::UnitConversionCollector");
155 m_terminalCollectors.SetAttribute("ConversionType",
156 EnumValue(UnitConversionCollector::TRANSPARENT));
158 m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
160 &MultiFileAggregator::Write2d);
161 break;
162 }
163
167 if (m_averagingMode)
168 {
169 // Setup aggregator.
170 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
171 "OutputFileName",
172 StringValue(GetOutputFileName()),
173 "MultiFileMode",
174 BooleanValue(false),
175 "EnableContextPrinting",
176 BooleanValue(false),
177 "GeneralHeading",
178 StringValue(GetDistributionHeading("plt_sec")));
179 Ptr<MultiFileAggregator> fileAggregator =
180 m_aggregator->GetObject<MultiFileAggregator>();
181 NS_ASSERT(fileAggregator != nullptr);
182
183 // Setup the final-level collector.
184 m_averagingCollector = CreateObject<DistributionCollector>();
185 DistributionCollector::OutputType_t outputType =
186 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
188 {
189 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
190 }
192 {
193 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
194 }
195 m_averagingCollector->SetOutputType(outputType);
196 m_averagingCollector->SetName("0");
197 m_averagingCollector->TraceConnect(
198 "Output",
199 "0",
200 MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
201 m_averagingCollector->TraceConnect(
202 "OutputString",
203 "0",
204 MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
205 m_averagingCollector->TraceConnect(
206 "Warning",
207 "0",
208 MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
209
210 // Setup collectors.
211 m_terminalCollectors.SetType("ns3::ScalarCollector");
212 m_terminalCollectors.SetAttribute("InputDataType",
213 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
214 m_terminalCollectors.SetAttribute(
215 "OutputType",
216 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
218 Callback<void, double> callback =
219 MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
220 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
221 it != m_terminalCollectors.End();
222 ++it)
223 {
224 it->second->TraceConnectWithoutContext("Output", callback);
225 }
226 }
227 else
228 {
229 // Setup aggregator.
230 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
231 "OutputFileName",
232 StringValue(GetOutputFileName()),
233 "GeneralHeading",
234 StringValue(GetDistributionHeading("plt_sec")));
235
236 // Setup collectors.
237 m_terminalCollectors.SetType("ns3::DistributionCollector");
238 DistributionCollector::OutputType_t outputType =
239 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
241 {
242 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
243 }
245 {
246 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
247 }
248 m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
250 m_terminalCollectors.ConnectToAggregator("Output",
252 &MultiFileAggregator::Write2d);
253 m_terminalCollectors.ConnectToAggregator("OutputString",
255 &MultiFileAggregator::AddContextHeading);
256 m_terminalCollectors.ConnectToAggregator("Warning",
258 &MultiFileAggregator::EnableContextWarning);
259 }
260
261 break;
262 }
263
266 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
267 << " is not a valid output type for this statistics.");
268 break;
269
271 // Setup aggregator.
272 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
273 "OutputPath",
274 StringValue(GetOutputPath()),
275 "OutputFileName",
276 StringValue(GetName()));
277 Ptr<MagisterGnuplotAggregator> plotAggregator =
278 m_aggregator->GetObject<MagisterGnuplotAggregator>();
279 NS_ASSERT(plotAggregator != nullptr);
280 // plot->SetTitle ("");
281 plotAggregator->SetLegend("Time (in seconds)", "Object PLT (in seconds)");
282 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
283
284 // Setup collectors.
285 m_terminalCollectors.SetType("ns3::UnitConversionCollector");
286 m_terminalCollectors.SetAttribute("ConversionType",
287 EnumValue(UnitConversionCollector::TRANSPARENT));
289 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
290 it != m_terminalCollectors.End();
291 ++it)
292 {
293 const std::string context = it->second->GetName();
294 plotAggregator->Add2dDataset(context, context);
295 }
296 m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
298 &MagisterGnuplotAggregator::Write2d);
299 break;
300 }
301
305 if (m_averagingMode)
306 {
307 // Setup aggregator.
308 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
309 "OutputPath",
310 StringValue(GetOutputPath()),
311 "OutputFileName",
312 StringValue(GetName()));
313 Ptr<MagisterGnuplotAggregator> plotAggregator =
314 m_aggregator->GetObject<MagisterGnuplotAggregator>();
315 NS_ASSERT(plotAggregator != nullptr);
316 // plot->SetTitle ("");
317 plotAggregator->SetLegend("Object PLT (in seconds)", "Frequency");
318 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
319 plotAggregator->Add2dDataset(GetName(), GetName());
321
322 // Setup the final-level collector.
323 m_averagingCollector = CreateObject<DistributionCollector>();
324 DistributionCollector::OutputType_t outputType =
325 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
327 {
328 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
329 }
331 {
332 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
333 }
334 m_averagingCollector->SetOutputType(outputType);
335 m_averagingCollector->SetName("0");
336 m_averagingCollector->TraceConnect(
337 "Output",
338 GetName(),
339 MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
341
342 // Setup collectors.
343 m_terminalCollectors.SetType("ns3::ScalarCollector");
344 m_terminalCollectors.SetAttribute("InputDataType",
345 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
346 m_terminalCollectors.SetAttribute(
347 "OutputType",
348 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
350 Callback<void, double> callback =
351 MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
352 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
353 it != m_terminalCollectors.End();
354 ++it)
355 {
356 it->second->TraceConnectWithoutContext("Output", callback);
357 }
358 }
359 else
360 {
361 // Setup aggregator.
362 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
363 "OutputPath",
364 StringValue(GetOutputPath()),
365 "OutputFileName",
366 StringValue(GetName()));
367 Ptr<MagisterGnuplotAggregator> plotAggregator =
368 m_aggregator->GetObject<MagisterGnuplotAggregator>();
369 NS_ASSERT(plotAggregator != nullptr);
370 // plot->SetTitle ("");
371 plotAggregator->SetLegend("Object PLT (in seconds)", "Frequency");
372 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
373
374 // Setup collectors.
375 m_terminalCollectors.SetType("ns3::DistributionCollector");
376 DistributionCollector::OutputType_t outputType =
377 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
379 {
380 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
381 }
383 {
384 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
385 }
386 m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
388 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
389 it != m_terminalCollectors.End();
390 ++it)
391 {
392 const std::string context = it->second->GetName();
393 plotAggregator->Add2dDataset(context, context);
394 }
395 m_terminalCollectors.ConnectToAggregator("Output",
397 &MagisterGnuplotAggregator::Write2d);
398 }
399
400 break;
401 }
402
403 default:
404 NS_FATAL_ERROR("SatStatsPltHelper - Invalid output type");
405 break;
406 }
407
408 // Setup probes and connect them to the collectors.
410
411} // end of `void DoInstall ();`
412
413void
415{
416 // The method below is supposed to be implemented by the child class.
418}
419
420void
421SatStatsPltHelper::RxPltCallback(const Time& plt, const Address& from)
422{
423 // NS_LOG_FUNCTION (this << plt.GetSeconds () << from);
424
425 if (from.IsInvalid())
426 {
427 NS_LOG_WARN(this << " discarding a object PLT of " << plt.GetSeconds()
428 << " from statistics collection because of" << " invalid sender address");
429 }
430 else
431 {
432 // Determine the identifier associated with the sender address.
433 std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
434
435 if (it != m_identifierMap.end())
436 {
437 PassSampleToCollector(plt, it->second);
438 }
439 else
440 {
441 NS_LOG_WARN(this << " discarding a object PLT of " << plt.GetSeconds()
442 << " from statistics collection because of"
443 << " unknown sender address " << from);
444 }
445 }
446}
447
448bool
449SatStatsPltHelper::ConnectProbeToCollector(Ptr<Probe> probe, uint32_t identifier)
450{
451 NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
452
453 bool ret = false;
454 switch (GetOutputType())
455 {
458 ret = m_terminalCollectors.ConnectWithProbe(probe,
459 "OutputSeconds",
460 identifier,
461 &ScalarCollector::TraceSinkDouble);
462 break;
463
466 ret = m_terminalCollectors.ConnectWithProbe(probe,
467 "OutputSeconds",
468 identifier,
469 &UnitConversionCollector::TraceSinkDouble);
470 break;
471
478 if (m_averagingMode)
479 {
480 ret = m_terminalCollectors.ConnectWithProbe(probe,
481 "OutputSeconds",
482 identifier,
483 &ScalarCollector::TraceSinkDouble);
484 }
485 else
486 {
487 ret = m_terminalCollectors.ConnectWithProbe(probe,
488 "OutputSeconds",
489 identifier,
490 &DistributionCollector::TraceSinkDouble);
491 }
492 break;
493
494 default:
495 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
496 << " is not a valid output type for this statistics.");
497 break;
498 }
499
500 if (ret)
501 {
502 NS_LOG_INFO(this << " created probe " << probe->GetName() << ", connected to collector "
503 << identifier);
504 }
505 else
506 {
507 NS_LOG_WARN(this << " unable to connect probe " << probe->GetName() << " to collector "
508 << identifier);
509 }
510
511 return ret;
512}
513
514bool
515SatStatsPltHelper::DisconnectProbeFromCollector(Ptr<Probe> probe, uint32_t identifier)
516{
517 NS_LOG_FUNCTION(this << probe << probe->GetName() << identifier);
518
519 bool ret = false;
520 switch (GetOutputType())
521 {
524 ret = m_terminalCollectors.DisconnectWithProbe(probe,
525 "OutputSeconds",
526 identifier,
527 &ScalarCollector::TraceSinkDouble);
528 break;
529
532 ret = m_terminalCollectors.DisconnectWithProbe(probe,
533 "OutputSeconds",
534 identifier,
535 &UnitConversionCollector::TraceSinkDouble);
536 break;
537
544 if (m_averagingMode)
545 {
546 ret = m_terminalCollectors.DisconnectWithProbe(probe,
547 "OutputSeconds",
548 identifier,
549 &ScalarCollector::TraceSinkDouble);
550 }
551 else
552 {
553 ret = m_terminalCollectors.DisconnectWithProbe(probe,
554 "OutputSeconds",
555 identifier,
556 &DistributionCollector::TraceSinkDouble);
557 }
558 break;
559
560 default:
561 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
562 << " is not a valid output type for this statistics.");
563 break;
564 }
565
566 if (ret)
567 {
568 NS_LOG_INFO(this << " probe " << probe->GetName() << ", disconnected from collector "
569 << identifier);
570 }
571 else
572 {
573 NS_LOG_WARN(this << " unable to disconnect probe " << probe->GetName() << " from collector "
574 << identifier);
575 }
576
577 return ret;
578}
579
580void
581SatStatsPltHelper::PassSampleToCollector(const Time& plt, uint32_t identifier)
582{
583 // NS_LOG_FUNCTION (this << plt.GetSeconds () << identifier);
584
585 Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifier);
586 NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << identifier);
587
588 switch (GetOutputType())
589 {
592 Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
593 NS_ASSERT(c != nullptr);
594 c->TraceSinkDouble(0.0, plt.GetSeconds());
595 break;
596 }
597
600 Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
601 NS_ASSERT(c != nullptr);
602 c->TraceSinkDouble(0.0, plt.GetSeconds());
603 break;
604 }
605
612 if (m_averagingMode)
613 {
614 Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
615 NS_ASSERT(c != nullptr);
616 c->TraceSinkDouble(0.0, plt.GetSeconds());
617 }
618 else
619 {
620 Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
621 NS_ASSERT(c != nullptr);
622 c->TraceSinkDouble(0.0, plt.GetSeconds());
623 }
624 break;
625
626 default:
627 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
628 << " is not a valid output type for this statistics.");
629 break;
630
631 } // end of `switch (GetOutputType ())`
632
633} // end of `void PassSampleToCollector (Time, uint32_t)`
634
635// FORWARD LINK APPLICATION-LEVEL /////////////////////////////////////////////
636
637NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdAppPltHelper);
638
640 : SatStatsPltHelper(satHelper)
641{
642 NS_LOG_FUNCTION(this << satHelper);
643}
644
646{
647 NS_LOG_FUNCTION(this);
648}
649
650TypeId // static
652{
653 static TypeId tid = TypeId("ns3::SatStatsFwdAppPltHelper").SetParent<SatStatsPltHelper>();
654 return tid;
655}
656
657void
659{
660 NS_LOG_FUNCTION(this);
661 NodeContainer utUsers = Singleton<SatTopology>::Get()->GetUtUserNodes();
662
663 for (NodeContainer::Iterator it = utUsers.Begin(); it != utUsers.End(); ++it)
664 {
665 const int32_t utUserId = GetUtUserId(*it);
666 NS_ASSERT_MSG(utUserId > 0, "Node " << (*it)->GetId() << " is not a valid UT user");
667 const uint32_t identifier = GetIdentifierForUtUser(*it);
668
669 for (uint32_t i = 0; i < (*it)->GetNApplications(); i++)
670 {
671 Ptr<Application> app = (*it)->GetApplication(i);
672 bool isConnected = false;
673
674 if (app->GetInstanceTypeId().LookupTraceSourceByName("RxPlt") != nullptr)
675 {
676 NS_LOG_INFO(this << " attempt to connect using RxPlt");
677
678 // Create the probe.
679 std::ostringstream probeName;
680 probeName << utUserId << "-" << i;
681 Ptr<ApplicationDelayProbe> probe = CreateObject<ApplicationDelayProbe>();
682 probe->SetName(probeName.str());
683
684 // Connect the object to the probe.
685 if (probe->ConnectByObject("RxPlt", app))
686 {
687 isConnected = ConnectProbeToCollector(probe, identifier);
688 m_probes.insert(
689 std::make_pair(probe->GetObject<Probe>(), std::make_pair(*it, identifier)));
690 }
691 }
692
693 if (isConnected)
694 {
695 NS_LOG_INFO(this << " successfully connected" << " with node ID " << (*it)->GetId()
696 << " application #" << i);
697 }
698 else
699 {
700 /*
701 * We're being tolerant here by only logging a warning, because
702 * not every kind of Application is equipped with the expected
703 * RxPlt or Rx trace source.
704 */
705 NS_LOG_WARN(this << " unable to connect" << " with node ID " << (*it)->GetId()
706 << " application #" << i);
707 }
708
709 } // end of `for (i = 0; i < (*it)->GetNApplications (); i++)`
710
711 } // end of `for (it = utUsers.Begin(); it != utUsers.End (); ++it)`
712
713} // end of `void DoInstallProbes ();`
714
715void
717{
718 NS_LOG_FUNCTION(this);
719
720 std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
721
722 for (it = m_probes.begin(); it != m_probes.end(); it++)
723 {
724 Ptr<Probe> probe = it->first;
725 Ptr<Node> node = it->second.first;
726 uint32_t identifier = it->second.second;
727
728 if (!DisconnectProbeFromCollector(probe, identifier))
729 {
730 NS_FATAL_ERROR("Error disconnecting trace file on handover");
731 }
732
733 identifier = GetIdentifierForUt(node);
734
735 if (!ConnectProbeToCollector(probe, identifier))
736 {
737 NS_FATAL_ERROR("Error connecting trace file on handover");
738 }
739
740 it->second.second = identifier;
741 }
742} // end of `void UpdateIdentifierOnProbes ();`
743
744// RETURN LINK APPLICATION-LEVEL //////////////////////////////////////////////
745
746NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnAppPltHelper);
747
749 : SatStatsPltHelper(satHelper)
750{
751 NS_LOG_FUNCTION(this << satHelper);
752}
753
755{
756 NS_LOG_FUNCTION(this);
757}
758
759TypeId // static
761{
762 static TypeId tid = TypeId("ns3::SatStatsRtnAppPltHelper").SetParent<SatStatsPltHelper>();
763 return tid;
764}
765
766void
768{
769 NS_LOG_FUNCTION(this);
770
771 // Connect to trace sources at GW user node's applications.
772 NodeContainer gwUsers = Singleton<SatTopology>::Get()->GetGwUserNodes();
773 Callback<void, const Time&, const Address&> rxPltCallback =
774 MakeCallback(&SatStatsRtnAppPltHelper::Ipv4Callback, this);
775
776 for (NodeContainer::Iterator it = gwUsers.Begin(); it != gwUsers.End(); ++it)
777 {
778 for (uint32_t i = 0; i < (*it)->GetNApplications(); i++)
779 {
780 Ptr<Application> app = (*it)->GetApplication(i);
781 bool isConnected = false;
782
783 if (app->GetInstanceTypeId().LookupTraceSourceByName("RxPlt") != nullptr)
784 {
785 isConnected = app->TraceConnectWithoutContext("RxPlt", rxPltCallback);
786 }
787
788 if (isConnected)
789 {
790 NS_LOG_INFO(this << " successfully connected" << " with node ID " << (*it)->GetId()
791 << " application #" << i);
792 }
793 else
794 {
795 /*
796 * We're being tolerant here by only logging a warning, because
797 * not every kind of Application is equipped with the expected
798 * RxPlt or Rx trace source.
799 */
800 NS_LOG_WARN(this << " unable to connect" << " with node ID " << (*it)->GetId()
801 << " application #" << i);
802 }
803
804 } // end of `for (i = 0; i < (*it)->GetNApplications (); i++)`
805
806 } // end of `for (NodeContainer::Iterator it: gwUsers)`
807
808} // end of `void DoInstallProbes ();`
809
810void
811SatStatsRtnAppPltHelper::Ipv4Callback(const Time& plt, const Address& from)
812{
813 // NS_LOG_FUNCTION (this << Time.GetSeconds () << from);
814
815 if (InetSocketAddress::IsMatchingType(from))
816 {
817 // Determine the identifier associated with the sender address.
818 const Address ipv4Addr = InetSocketAddress::ConvertFrom(from).GetIpv4();
819 std::map<const Address, uint32_t>::const_iterator it1 = m_identifierMap.find(ipv4Addr);
820
821 if (it1 == m_identifierMap.end())
822 {
823 NS_LOG_WARN(this << " discarding a object PLT of " << plt.GetSeconds()
824 << " from statistics collection because of"
825 << " unknown sender IPV4 address " << ipv4Addr);
826 }
827 else
828 {
829 PassSampleToCollector(plt, it1->second);
830 }
831 }
832 else
833 {
834 NS_LOG_WARN(this << " discarding a object PLT of " << plt.GetSeconds()
835 << " from statistics collection" << " because it comes from sender "
836 << from << " without valid InetSocketAddress");
837 }
838}
839
840void
842{
843 NS_LOG_FUNCTION(this << utUserNode->GetId());
844
845 Ptr<Ipv4> ipv4 = utUserNode->GetObject<Ipv4>();
846
847 if (ipv4 == nullptr)
848 {
849 NS_LOG_INFO(this << " Node " << utUserNode->GetId() << " does not support IPv4 protocol");
850 }
851 else if (ipv4->GetNInterfaces() >= 2)
852 {
853 const uint32_t identifier = GetIdentifierForUtUser(utUserNode);
854
855 /*
856 * Assuming that #0 is for loopback interface and #1 is for subscriber
857 * network interface.
858 */
859 for (uint32_t i = 0; i < ipv4->GetNAddresses(1); i++)
860 {
861 const Address addr = ipv4->GetAddress(1, i).GetLocal();
862 m_identifierMap[addr] = identifier;
863 NS_LOG_INFO(this << " associated address " << addr << " with identifier "
864 << identifier);
865 }
866 }
867 else
868 {
869 NS_LOG_WARN(this << " Node " << utUserNode->GetId() << " is not a valid UT user");
870 }
871}
872
873} // end of namespace ns3
virtual ~SatStatsFwdAppPltHelper()
Destructor for SatStatsFwdAppPltHelper.
SatStatsFwdAppPltHelper(Ptr< const SatHelper > satHelper)
std::map< Ptr< Probe >, std::pair< Ptr< Node >, uint32_t > > m_probes
Maintains a list of probes created by this helper.
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
static TypeId GetTypeId()
inherited from ObjectBase base class
uint32_t GetIdentifierForUtUser(Ptr< Node > utUserNode) 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.
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.
uint32_t GetUtUserId(Ptr< Node > utUserNode) const
std::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
virtual std::string GetDistributionHeading(std::string dataLabel) const
Base class for PLT statistics helpers.
static TypeId GetTypeId()
inherited from ObjectBase base class
virtual void DoInstallProbes()=0
void RxPltCallback(const Time &plt, const Address &from)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
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).
bool ConnectProbeToCollector(Ptr< Probe > probe, uint32_t identifier)
Connect the probe to the right collector.
bool m_averagingMode
AveragingMode attribute.
void SetAveragingMode(bool averagingMode)
bool DisconnectProbeFromCollector(Ptr< Probe > probe, uint32_t identifier)
Disconnect the probe from the right collector.
virtual ~SatStatsPltHelper()
/ Destructor.
SatStatsPltHelper(Ptr< const SatHelper > satHelper)
void InstallProbes()
Set up several probes or other means of listeners and connect them to the collectors.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
void PassSampleToCollector(const Time &plt, uint32_t identifier)
Find a collector with the right identifier and pass a sample data to it.
void Ipv4Callback(const Time &plt, const Address &from)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
virtual ~SatStatsRtnAppPltHelper()
/ Destructor.
void SaveIpv4AddressAndIdentifier(Ptr< Node > utUserNode)
Save the IPv4 address and the proper identifier from the given UT user node.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsRtnAppPltHelper(Ptr< const SatHelper > satHelper)
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.