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/scalar-collector.h>
41 #include <ns3/singleton.h>
42 #include <ns3/string.h>
43 #include <ns3/unit-conversion-collector.h>
44 
45 #include <sstream>
46 
47 NS_LOG_COMPONENT_DEFINE("SatStatsSignallingLoadHelper");
48 
49 namespace ns3
50 {
51 
52 NS_OBJECT_ENSURE_REGISTERED(SatStatsSignallingLoadHelper);
53 
55  : SatStatsHelper(satHelper)
56 {
57  NS_LOG_FUNCTION(this << satHelper);
58 }
59 
61 {
62  NS_LOG_FUNCTION(this);
63 }
64 
65 TypeId // static
67 {
68  static TypeId tid = TypeId("ns3::SatStatsSignallingLoadHelper").SetParent<SatStatsHelper>();
69  return tid;
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION(this);
76 
77  switch (GetOutputType())
78  {
80  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
81  << " is not a valid output type for this statistics.");
82  break;
83 
85  // Setup aggregator.
86  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
87  "OutputFileName",
88  StringValue(GetOutputFileName()),
89  "MultiFileMode",
90  BooleanValue(false),
91  "EnableContextPrinting",
92  BooleanValue(true),
93  "GeneralHeading",
94  StringValue(GetIdentifierHeading("signalling_kbps")));
95 
96  // Setup second-level collectors.
97  m_terminalCollectors.SetType("ns3::ScalarCollector");
98  m_terminalCollectors.SetAttribute("InputDataType",
99  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
100  m_terminalCollectors.SetAttribute(
101  "OutputType",
102  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SECOND));
104  m_terminalCollectors.ConnectToAggregator("Output",
105  m_aggregator,
106  &MultiFileAggregator::Write1d);
107 
108  // Setup first-level collectors.
109  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
110  m_conversionCollectors.SetAttribute("ConversionType",
111  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
113  m_conversionCollectors.ConnectToCollector("Output",
115  &ScalarCollector::TraceSinkDouble);
116  break;
117  }
118 
120  // Setup aggregator.
121  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
122  "OutputFileName",
123  StringValue(GetOutputFileName()),
124  "GeneralHeading",
125  StringValue(GetTimeHeading("signalling_kbps")));
126 
127  // Setup second-level collectors.
128  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
129  m_terminalCollectors.SetAttribute("InputDataType",
130  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
132  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
133  m_aggregator,
134  &MultiFileAggregator::Write2d);
135  m_terminalCollectors.ConnectToAggregator("OutputString",
136  m_aggregator,
137  &MultiFileAggregator::AddContextHeading);
138 
139  // Setup first-level collectors.
140  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
141  m_conversionCollectors.SetAttribute("ConversionType",
142  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
144  m_conversionCollectors.ConnectToCollector("Output",
146  &IntervalRateCollector::TraceSinkDouble);
147  break;
148  }
149 
153  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
154  << " is not a valid output type for this statistics.");
155  break;
156 
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::MagisterGnuplotAggregator",
166  "OutputPath",
167  StringValue(GetOutputPath()),
168  "OutputFileName",
169  StringValue(GetName()));
170  Ptr<MagisterGnuplotAggregator> plotAggregator =
171  m_aggregator->GetObject<MagisterGnuplotAggregator>();
172  NS_ASSERT(plotAggregator != nullptr);
173  // plot->SetTitle ("");
174  plotAggregator->SetLegend("Time (in seconds)", "Signalling load (in kilobits per second)");
175  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
176 
177  // Setup second-level collectors.
178  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
179  m_terminalCollectors.SetAttribute("InputDataType",
180  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
182  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
183  it != m_terminalCollectors.End();
184  ++it)
185  {
186  const std::string context = it->second->GetName();
187  plotAggregator->Add2dDataset(context, context);
188  }
189  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
190  m_aggregator,
191  &MagisterGnuplotAggregator::Write2d);
192 
193  // Setup first-level collectors.
194  m_conversionCollectors.SetType("ns3::UnitConversionCollector");
195  m_conversionCollectors.SetAttribute("ConversionType",
196  EnumValue(UnitConversionCollector::FROM_BYTES_TO_KBIT));
198  m_conversionCollectors.ConnectToCollector("Output",
200  &IntervalRateCollector::TraceSinkDouble);
201  break;
202  }
203 
207  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
208  << " is not a valid output type for this statistics.");
209  break;
210 
211  default:
212  NS_FATAL_ERROR("SatStatsSignallingLoadHelper - Invalid output type");
213  break;
214  }
215 
216  // Setup probes and connect them to conversion collectors.
217  InstallProbes();
218 
219 } // end of `void DoInstall ();`
220 
221 void
223 {
224  NS_LOG_FUNCTION(this);
225 
226  // The method below is supposed to be implemented by the child class.
227  DoInstallProbes();
228 }
229 
230 void
231 SatStatsSignallingLoadHelper::SignallingTxCallback(Ptr<const Packet> packet, const Address& to)
232 {
233  // NS_LOG_FUNCTION (this << packet->GetSize () << from);
234 
235  if (to.IsInvalid())
236  {
237  NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
238  << " bytes)"
239  << " from statistics collection because of"
240  << " invalid sender address");
241  }
242  else
243  {
244  const Mac48Address addr = Mac48Address::ConvertFrom(to);
245 
246  if (addr.IsBroadcast())
247  {
248  NS_LOG_INFO(this << " broadcast control message packet");
249 
250  // Pass the sample to every first-level collectors.
251  for (CollectorMap::Iterator it = m_conversionCollectors.Begin();
252  it != m_conversionCollectors.End();
253  ++it)
254  {
255  Ptr<UnitConversionCollector> c = it->second->GetObject<UnitConversionCollector>();
256  NS_ASSERT(c != nullptr);
257  c->TraceSinkUinteger32(0, packet->GetSize());
258  }
259  }
260  else
261  {
262  // Determine the identifier associated with the sender address.
263  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(addr);
264 
265  if (it == m_identifierMap.end())
266  {
267  NS_LOG_WARN(this << " discarding packet " << packet << " (" << packet->GetSize()
268  << " bytes)"
269  << " from statistics collection because of"
270  << " unknown sender address " << addr);
271  }
272  else
273  {
274  // Find the first-level collector with the right identifier.
275  Ptr<DataCollectionObject> collector = m_conversionCollectors.Get(it->second);
276  NS_ASSERT_MSG(collector != nullptr,
277  "Unable to find collector with identifier " << it->second);
278  Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
279  NS_ASSERT(c != nullptr);
280 
281  // Pass the sample to the collector.
282  c->TraceSinkUinteger32(0, packet->GetSize());
283  }
284  }
285  }
286 
287 } // end of `void RxCallback (Ptr<const Packet>, const Address);`
288 
289 void
291 {
292  NS_LOG_FUNCTION(this << utNode->GetId());
293 
294  const SatIdMapper* satIdMapper = Singleton<SatIdMapper>::Get();
295  const Address addr = satIdMapper->GetUtMacWithNode(utNode);
296 
297  if (addr.IsInvalid())
298  {
299  NS_LOG_WARN(this << " Node " << utNode->GetId() << " is not a valid UT");
300  }
301  else
302  {
303  const uint32_t identifier = GetIdentifierForUt(utNode);
304  m_identifierMap[addr] = identifier;
305  NS_LOG_INFO(this << " associated address " << addr << " with identifier " << identifier);
306  }
307 }
308 
309 // FORWARD LINK ///////////////////////////////////////////////////////////////
310 
311 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdSignallingLoadHelper);
312 
314  : SatStatsSignallingLoadHelper(satHelper)
315 {
316  NS_LOG_FUNCTION(this << satHelper);
317 }
318 
320 {
321  NS_LOG_FUNCTION(this);
322 }
323 
324 TypeId // static
326 {
327  static TypeId tid =
328  TypeId("ns3::SatStatsFwdSignallingLoadHelper").SetParent<SatStatsSignallingLoadHelper>();
329  return tid;
330 }
331 
332 void
334 {
335  NS_LOG_FUNCTION(this);
336 
337  // Create a map of UT addresses and identifiers.
338  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
339  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
340  {
342  }
343 
344  // Connect to trace sources at GW nodes.
345 
346  NodeContainer gws = GetSatHelper()->GetBeamHelper()->GetGwNodes();
347  Callback<void, Ptr<const Packet>, const Address&> callback =
349 
350  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
351  {
352  NetDeviceContainer devs = GetGwSatNetDevice(*it);
353 
354  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
355  {
356  NS_ASSERT((*itDev)->GetObject<SatNetDevice>() != nullptr);
357 
358  if ((*itDev)->TraceConnectWithoutContext("SignallingTx", callback))
359  {
360  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
361  << " device #" << (*itDev)->GetIfIndex());
362  }
363  else
364  {
365  NS_FATAL_ERROR("Error connecting to SignallingTx trace source"
366  << " of SatNetDevice"
367  << " at node ID " << (*it)->GetId() << " device #"
368  << (*itDev)->GetIfIndex());
369  }
370 
371  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
372 
373  } // end of `for (NodeContainer::Iterator it = gws)`
374 
375 } // end of `void DoInstallProbes ();`
376 
377 // RETURN LINK ////////////////////////////////////////////////////////////////
378 
379 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnSignallingLoadHelper);
380 
382  : SatStatsSignallingLoadHelper(satHelper)
383 {
384  NS_LOG_FUNCTION(this << satHelper);
385 }
386 
388 {
389  NS_LOG_FUNCTION(this);
390 }
391 
392 TypeId // static
394 {
395  static TypeId tid =
396  TypeId("ns3::SatStatsRtnSignallingLoadHelper").SetParent<SatStatsSignallingLoadHelper>();
397  return tid;
398 }
399 
400 void
402 {
403  NS_LOG_FUNCTION(this);
404  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
405 
406  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
407  {
408  const int32_t utId = GetUtId(*it);
409  NS_ASSERT_MSG(utId > 0, "Node " << (*it)->GetId() << " is not a valid UT");
410  const uint32_t identifier = GetIdentifierForUt(*it);
411 
412  // Create the probe.
413  std::ostringstream probeName;
414  probeName << utId;
415  Ptr<ApplicationPacketProbe> probe = CreateObject<ApplicationPacketProbe>();
416  probe->SetName(probeName.str());
417 
418  Ptr<NetDevice> dev = GetUtSatNetDevice(*it);
419 
420  // Connect the object to the probe.
421  if (probe->ConnectByObject("SignallingTx", dev))
422  {
423  // Connect the probe to the right collector.
424  if (m_conversionCollectors.ConnectWithProbe(
425  probe->GetObject<Probe>(),
426  "OutputBytes",
427  identifier,
428  &UnitConversionCollector::TraceSinkUinteger32))
429  {
430  NS_LOG_INFO(this << " created probe " << probeName.str()
431  << ", connected to collector " << identifier);
432  m_probes.push_back(probe->GetObject<Probe>());
433  }
434  else
435  {
436  NS_LOG_WARN(this << " unable to connect probe " << probeName.str()
437  << " to collector " << identifier);
438  }
439 
440  } // end of `if (probe->ConnectByObject ("SignallingTx", dev))`
441  else
442  {
443  NS_FATAL_ERROR("Error connecting to SignallingTx trace source of SatNetDevice"
444  << " at node ID " << (*it)->GetId() << " device #2");
445  }
446 
447  } // end of `for (it = uts.Begin(); it != uts.End (); ++it)`
448 
449 } // end of `void DoInstallProbes ();`
450 
451 } // end of namespace ns3
Class for ID-mapper.
Address GetUtMacWithNode(Ptr< Node > utNode) const
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
Parent abstract class of all satellite statistics helpers.
Ptr< const SatHelper > GetSatHelper() const
static NetDeviceContainer GetGwSatNetDevice(Ptr< Node > gwNode)
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::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::list< Ptr< Probe > > m_probes
Maintains a list of probes created by this helper.
static TypeId GetTypeId()
inherited from ObjectBase base class
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 SaveAddressAndIdentifier(Ptr< Node > utNode)
Save the address and the proper identifier from the given UT node.
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)
std::map< const Address, uint32_t > m_identifierMap
Map of address and the identifier associated with it (for forward link).
CollectorMap m_conversionCollectors
Maintains a list of first-level collectors created by this helper.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.