Loading...
Searching...
No Matches
satellite-stats-signalling-load-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-packet-probe.h"
25#include "ns3/boolean.h"
26#include "ns3/callback.h"
27#include "ns3/data-collection-object.h"
28#include "ns3/enum.h"
29#include "ns3/interval-rate-collector.h"
30#include "ns3/log.h"
31#include "ns3/mac48-address.h"
32#include "ns3/magister-gnuplot-aggregator.h"
33#include "ns3/multi-file-aggregator.h"
34#include "ns3/node-container.h"
35#include "ns3/packet.h"
36#include "ns3/probe.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-topology.h"
41#include "ns3/scalar-collector.h"
42#include "ns3/singleton.h"
43#include "ns3/string.h"
44#include "ns3/unit-conversion-collector.h"
45
46#include <map>
47#include <sstream>
48#include <string>
49#include <utility>
50
51NS_LOG_COMPONENT_DEFINE("SatStatsSignallingLoadHelper");
52
53namespace ns3
54{
55
56NS_OBJECT_ENSURE_REGISTERED(SatStatsSignallingLoadHelper);
57
59 : SatStatsHelper(satHelper)
60{
61 NS_LOG_FUNCTION(this << satHelper);
62}
63
68
69TypeId // static
71{
72 static TypeId tid = TypeId("ns3::SatStatsSignallingLoadHelper").SetParent<SatStatsHelper>();
73 return tid;
74}
75
76void
78{
79 NS_LOG_FUNCTION(this);
80
81 switch (GetOutputType())
82 {
84 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
85 << " is not a valid output type for this statistics.");
86 break;
87
89 // Setup aggregator.
90 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
91 "OutputFileName",
92 StringValue(GetOutputFileName()),
93 "MultiFileMode",
94 BooleanValue(false),
95 "EnableContextPrinting",
96 BooleanValue(true),
97 "GeneralHeading",
98 StringValue(GetIdentifierHeading("signalling_kbps")));
99
100 // Setup second-level collectors.
101 m_terminalCollectors.SetType("ns3::ScalarCollector");
102 m_terminalCollectors.SetAttribute("InputDataType",
103 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
104 m_terminalCollectors.SetAttribute(
105 "OutputType",
106 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SECOND));
108 m_terminalCollectors.ConnectToAggregator("Output",
110 &MultiFileAggregator::Write1d);
111
112 // Setup first-level collectors.
113 m_conversionCollectors.SetType("ns3::UnitConversionCollector");
114 m_conversionCollectors.SetAttribute("ConversionType",
115 EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
117 m_conversionCollectors.ConnectToCollector("Output",
119 &ScalarCollector::TraceSinkDouble);
120 break;
121 }
122
124 // Setup aggregator.
125 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
126 "OutputFileName",
127 StringValue(GetOutputFileName()),
128 "GeneralHeading",
129 StringValue(GetTimeHeading("signalling_kbps")));
130
131 // Setup second-level collectors.
132 m_terminalCollectors.SetType("ns3::IntervalRateCollector");
133 m_terminalCollectors.SetAttribute("InputDataType",
134 EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
136 m_terminalCollectors.ConnectToAggregator("OutputWithTime",
138 &MultiFileAggregator::Write2d);
139 m_terminalCollectors.ConnectToAggregator("OutputString",
141 &MultiFileAggregator::AddContextHeading);
142
143 // Setup first-level collectors.
144 m_conversionCollectors.SetType("ns3::UnitConversionCollector");
145 m_conversionCollectors.SetAttribute("ConversionType",
146 EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
148 m_conversionCollectors.ConnectToCollector("Output",
150 &IntervalRateCollector::TraceSinkDouble);
151 break;
152 }
153
157 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
158 << " is not a valid output type for this statistics.");
159 break;
160
163 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
164 << " is not a valid output type for this statistics.");
165 break;
166
168 // Setup aggregator.
169 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
170 "OutputPath",
171 StringValue(GetOutputPath()),
172 "OutputFileName",
173 StringValue(GetName()));
174 Ptr<MagisterGnuplotAggregator> plotAggregator =
175 m_aggregator->GetObject<MagisterGnuplotAggregator>();
176 NS_ASSERT(plotAggregator != nullptr);
177 // plot->SetTitle ("");
178 plotAggregator->SetLegend("Time (in seconds)", "Signalling load (in kilobits per second)");
179 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
180
181 // Setup second-level collectors.
182 m_terminalCollectors.SetType("ns3::IntervalRateCollector");
183 m_terminalCollectors.SetAttribute("InputDataType",
184 EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
186 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
187 it != m_terminalCollectors.End();
188 ++it)
189 {
190 const std::string context = it->second->GetName();
191 plotAggregator->Add2dDataset(context, context);
192 }
193 m_terminalCollectors.ConnectToAggregator("OutputWithTime",
195 &MagisterGnuplotAggregator::Write2d);
196
197 // Setup first-level collectors.
198 m_conversionCollectors.SetType("ns3::UnitConversionCollector");
199 m_conversionCollectors.SetAttribute("ConversionType",
200 EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
202 m_conversionCollectors.ConnectToCollector("Output",
204 &IntervalRateCollector::TraceSinkDouble);
205 break;
206 }
207
211 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
212 << " is not a valid output type for this statistics.");
213 break;
214
215 default:
216 NS_FATAL_ERROR("SatStatsSignallingLoadHelper - Invalid output type");
217 break;
218 }
219
220 // Setup probes and connect them to conversion collectors.
222
223} // end of `void DoInstall ();`
224
225void
227{
228 NS_LOG_FUNCTION(this);
229
230 // The method below is supposed to be implemented by the child class.
232}
233
234void
235SatStatsSignallingLoadHelper::SignallingTxCallback(Ptr<const Packet> packet, const Address& to)
236{
237 // NS_LOG_FUNCTION (this << packet->GetSize () << from);
238
239 if (to.IsInvalid())
240 {
241 NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
242 << " bytes)" << " from statistics collection because of"
243 << " invalid sender address");
244 }
245 else
246 {
247 const Mac48Address addr = Mac48Address::ConvertFrom(to);
248
249 if (addr.IsBroadcast())
250 {
251 NS_LOG_INFO(this << " broadcast control message packet");
252
253 // Pass the sample to every first-level collectors.
254 for (CollectorMap::Iterator it = m_conversionCollectors.Begin();
255 it != m_conversionCollectors.End();
256 ++it)
257 {
258 Ptr<UnitConversionCollector> c = it->second->GetObject<UnitConversionCollector>();
259 NS_ASSERT(c != nullptr);
260 c->TraceSinkUinteger32(0, packet->GetSize());
261 }
262 }
263 else
264 {
265 // Determine the identifier associated with the sender address.
266 std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(addr);
267
268 if (it == m_identifierMap.end())
269 {
270 NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
271 << " bytes)" << " from statistics collection because of"
272 << " unknown sender address " << addr);
273 }
274 else
275 {
276 // Find the first-level collector with the right identifier.
277 Ptr<DataCollectionObject> collector = m_conversionCollectors.Get(it->second);
278 NS_ASSERT_MSG(collector != nullptr,
279 "Unable to find collector with identifier " << it->second);
280 Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
281 NS_ASSERT(c != nullptr);
282
283 // Pass the sample to the collector.
284 c->TraceSinkUinteger32(0, packet->GetSize());
285 }
286 }
287 }
288
289} // end of `void RxCallback (Ptr<const Packet>, const Address);`
290
291// FORWARD LINK ///////////////////////////////////////////////////////////////
292
293NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdSignallingLoadHelper);
294
297{
298 NS_LOG_FUNCTION(this << satHelper);
299}
300
305
306TypeId // static
308{
309 static TypeId tid =
310 TypeId("ns3::SatStatsFwdSignallingLoadHelper").SetParent<SatStatsSignallingLoadHelper>();
311 return tid;
312}
313
314void
316{
317 NS_LOG_FUNCTION(this);
318
319 // Create a map of UT addresses and identifiers.
320 NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
321 for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
322 {
324 }
325
326 // Connect to trace sources at GW nodes.
327
328 NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
329 Callback<void, Ptr<const Packet>, const Address&> callback =
331
332 for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
333 {
334 NetDeviceContainer devs = GetGwSatNetDevice(*it);
335
336 for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
337 {
338 NS_ASSERT((*itDev)->GetObject<SatNetDevice>() != nullptr);
339
340 if ((*itDev)->TraceConnectWithoutContext("SignallingTx", callback))
341 {
342 NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
343 << " device #" << (*itDev)->GetIfIndex());
344 }
345 else
346 {
347 NS_FATAL_ERROR("Error connecting to SignallingTx trace source"
348 << " of SatNetDevice" << " at node ID " << (*it)->GetId()
349 << " device #" << (*itDev)->GetIfIndex());
350 }
351
352 } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
353
354 } // end of `for (NodeContainer::Iterator it = gws)`
355
356} // end of `void DoInstallProbes ();`
357
358// RETURN LINK ////////////////////////////////////////////////////////////////
359
360NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnSignallingLoadHelper);
361
364{
365 NS_LOG_FUNCTION(this << satHelper);
366}
367
372
373TypeId // static
375{
376 static TypeId tid =
377 TypeId("ns3::SatStatsRtnSignallingLoadHelper").SetParent<SatStatsSignallingLoadHelper>();
378 return tid;
379}
380
381void
383{
384 NS_LOG_FUNCTION(this);
385 NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
386
387 for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
388 {
389 const int32_t utId = GetUtId(*it);
390 NS_ASSERT_MSG(utId > 0, "Node " << (*it)->GetId() << " is not a valid UT");
391 const uint32_t identifier = GetIdentifierForUt(*it);
392
393 // Create the probe.
394 std::ostringstream probeName;
395 probeName << utId;
396 Ptr<ApplicationPacketProbe> probe = CreateObject<ApplicationPacketProbe>();
397 probe->SetName(probeName.str());
398
399 Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
400
401 // Connect the object to the probe.
402 if (probe->ConnectByObject("SignallingTx", dev))
403 {
404 // Connect the probe to the right collector.
405 if (m_conversionCollectors.ConnectWithProbe(
406 probe->GetObject<Probe>(),
407 "OutputBytes",
408 identifier,
409 &UnitConversionCollector::TraceSinkUinteger32))
410 {
411 NS_LOG_INFO(this << " created probe " << probeName.str()
412 << ", connected to collector " << identifier);
413 m_probes.insert(
414 std::make_pair(probe->GetObject<Probe>(), std::make_pair(*it, identifier)));
415 }
416 else
417 {
418 NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
419 << " to collector " << identifier);
420 }
421
422 } // end of `if (probe->ConnectByObject ("SignallingTx", dev))`
423 else
424 {
425 NS_FATAL_ERROR("Error connecting to SignallingTx trace source of SatNetDevice"
426 << " at node ID " << (*it)->GetId() << " device #2");
427 }
428
429 } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
430
431} // end of `void DoInstallProbes ();`
432
433void
435{
436 NS_LOG_FUNCTION(this);
437
438 std::map<Ptr<Probe>, std::pair<Ptr<Node>, uint32_t>>::iterator it;
439
440 for (it = m_probes.begin(); it != m_probes.end(); it++)
441 {
442 Ptr<Probe> probe = it->first;
443 Ptr<Node> node = it->second.first;
444 uint32_t identifier = it->second.second;
445
446 if (!m_conversionCollectors.DisconnectWithProbe(
447 probe->GetObject<Probe>(),
448 "OutputBytes",
449 identifier,
450 &UnitConversionCollector::TraceSinkUinteger32))
451 {
452 NS_FATAL_ERROR("Error disconnecting trace file on handover");
453 }
454
455 identifier = GetIdentifierForUtUser(node);
456
457 if (!m_conversionCollectors.ConnectWithProbe(probe->GetObject<Probe>(),
458 "OutputBytes",
459 identifier,
460 &UnitConversionCollector::TraceSinkUinteger32))
461 {
462 NS_FATAL_ERROR("Error connecting trace file on handover");
463 }
464
465 it->second.second = identifier;
466 }
467} // end of `void UpdateIdentifierOnProbes ();`
468
469} // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
Produce forward link signalling load statistics from a satellite module simulation.
SatStatsFwdSignallingLoadHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
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)
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 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
Produce return link signalling load statistics from a satellite module simulation.
SatStatsRtnSignallingLoadHelper(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.
static TypeId GetTypeId()
inherited from ObjectBase base class
virtual void UpdateIdentifierOnProbes()
Change identifier used on probes, when handovers occur.
Abstract class inherited by SatStatsFwdSignallingLoadHelper and SatStatsRtnSignallingLoadHelper.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
void InstallProbes()
Set up several probes or other means of listeners and connect them to the first-level collectors.
CollectorMap m_terminalCollectors
Maintains a list of second-level collectors created by this helper.
void SignallingTxCallback(Ptr< const Packet > packet, const Address &to)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatStatsSignallingLoadHelper(Ptr< const SatHelper > satHelper)
CollectorMap m_conversionCollectors
Maintains a list of first-level collectors created by this helper.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.