satellite-stats-carrier-id-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/enum.h>
27 #include <ns3/interval-rate-collector.h>
28 #include <ns3/log.h>
29 #include <ns3/mac48-address.h>
30 #include <ns3/magister-gnuplot-aggregator.h>
31 #include <ns3/multi-file-aggregator.h>
32 #include <ns3/node-container.h>
33 #include <ns3/object-vector.h>
34 #include <ns3/satellite-helper.h>
35 #include <ns3/satellite-id-mapper.h>
36 #include <ns3/satellite-net-device.h>
37 #include <ns3/satellite-phy-rx-carrier-marsala.h>
38 #include <ns3/satellite-phy-rx-carrier.h>
39 #include <ns3/satellite-phy-rx.h>
40 #include <ns3/satellite-phy.h>
41 #include <ns3/satellite-topology.h>
42 #include <ns3/scalar-collector.h>
43 #include <ns3/singleton.h>
44 #include <ns3/string.h>
45 
46 #include <map>
47 #include <sstream>
48 #include <string>
49 
50 NS_LOG_COMPONENT_DEFINE("SatStatsCarrierIdHelper");
51 
52 namespace ns3
53 {
54 
55 // BASE CLASS /////////////////////////////////////////////////////////////////
56 
57 NS_OBJECT_ENSURE_REGISTERED(SatStatsCarrierIdHelper);
58 
59 SatStatsCarrierIdHelper::SatStatsCarrierIdHelper(Ptr<const SatHelper> satHelper)
60  : SatStatsHelper(satHelper)
61 {
62  NS_LOG_FUNCTION(this << satHelper);
63  SetTraceSourceName("DaRxCarrierId");
65 }
66 
68 {
69  NS_LOG_FUNCTION(this);
70 }
71 
72 TypeId // static
74 {
75  static TypeId tid = TypeId("ns3::SatStatsCarrierIdHelper").SetParent<SatStatsHelper>();
76  return tid;
77 }
78 
79 void
80 SatStatsCarrierIdHelper::SetTraceSourceName(std::string traceSourceName)
81 {
82  NS_LOG_FUNCTION(this << traceSourceName);
83  m_traceSourceName = traceSourceName;
84 }
85 
86 std::string
88 {
89  return m_traceSourceName;
90 }
91 
92 void
94 {
95  NS_LOG_FUNCTION(this);
96 
97  switch (GetOutputType())
98  {
100  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
101  << " is not a valid output type for this statistics.");
102  break;
103 
105  // Setup aggregator.
106  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
107  "OutputFileName",
108  StringValue(GetOutputFileName()),
109  "MultiFileMode",
110  BooleanValue(false),
111  "EnableContextPrinting",
112  BooleanValue(true),
113  "GeneralHeading",
114  StringValue(GetIdentifierHeading("carrier_id")));
115 
116  // Setup collectors.
117  m_terminalCollectors.SetType("ns3::ScalarCollector");
118  m_terminalCollectors.SetAttribute("InputDataType",
119  EnumValue(ScalarCollector::INPUT_DATA_TYPE_UINTEGER));
120  m_terminalCollectors.SetAttribute(
121  "OutputType",
122  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
124  m_terminalCollectors.ConnectToAggregator("Output",
125  m_aggregator,
126  &MultiFileAggregator::Write1d);
127  break;
128  }
129 
131  // Setup aggregator.
132  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
133  "OutputFileName",
134  StringValue(GetOutputFileName()),
135  "GeneralHeading",
136  StringValue(GetTimeHeading("carrier_id")));
137 
138  // Setup collectors.
139  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
140  m_terminalCollectors.SetAttribute(
141  "InputDataType",
142  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_UINTEGER));
143  m_terminalCollectors.SetAttribute(
144  "OutputType",
145  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
146  m_terminalCollectors.SetAttribute("IntervalLength", TimeValue(MilliSeconds(5)));
148  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
149  m_aggregator,
150  &MultiFileAggregator::Write2d);
151  m_terminalCollectors.ConnectToAggregator("OutputString",
152  m_aggregator,
153  &MultiFileAggregator::AddContextHeading);
154  break;
155  }
156 
160  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
161  << " is not a valid output type for this statistics.");
162  break;
163 
166  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
167  << " is not a valid output type for this statistics.");
168  break;
169 
171  // Setup aggregator.
172  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
173  "OutputPath",
174  StringValue(GetOutputPath()),
175  "OutputFileName",
176  StringValue(GetName()));
177  Ptr<MagisterGnuplotAggregator> plotAggregator =
178  m_aggregator->GetObject<MagisterGnuplotAggregator>();
179  NS_ASSERT(plotAggregator != nullptr);
180  // plot->SetTitle ("");
181  plotAggregator->SetLegend("Time (in seconds)", "Correlations");
182  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
183 
184  // Setup collectors.
185  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
186  m_terminalCollectors.SetAttribute(
187  "InputDataType",
188  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_UINTEGER));
189  m_terminalCollectors.SetAttribute(
190  "OutputType",
191  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
193  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
194  it != m_terminalCollectors.End();
195  ++it)
196  {
197  const std::string context = it->second->GetName();
198  plotAggregator->Add2dDataset(context, context);
199  }
200  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
201  m_aggregator,
202  &MagisterGnuplotAggregator::Write2d);
203  break;
204  }
205 
209  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
210  << " is not a valid output type for this statistics.");
211  break;
212 
213  default:
214  NS_FATAL_ERROR("SatStatsCarrierIdHelper - Invalid output type");
215  break;
216  }
217 
218  // Create a map of UT addresses and identifiers.
219  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
220  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
221  {
223  }
224 
225  // Connect to trace sources at GW nodes.
226 
227  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
228  Callback<void, uint32_t, const Address&> callback =
230 
231  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
232  {
233  NetDeviceContainer devs = GetGwSatNetDevice(*it);
234 
235  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
236  {
237  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
238  NS_ASSERT(satDev != nullptr);
239  Ptr<SatPhy> satPhy = satDev->GetPhy();
240  NS_ASSERT(satPhy != nullptr);
241  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
242  NS_ASSERT(satPhyRx != nullptr);
243  ObjectVectorValue carriers;
244  satPhyRx->GetAttribute("RxCarrierList", carriers);
245  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
246  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
247  << " RX carriers");
248 
249  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
250  itCarrier != carriers.End();
251  ++itCarrier)
252  {
253  Ptr<SatPhyRxCarrierPerSlot> c =
254  DynamicCast<SatPhyRxCarrierPerSlot>(itCarrier->second);
255  if (!c)
256  {
257  continue;
258  }
259 
261  DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType();
262  if (ct != GetValidCarrierType())
263  {
264  continue;
265  }
266 
267  const bool ret =
268  itCarrier->second->TraceConnectWithoutContext(GetTraceSourceName(), callback);
269  if (ret)
270  {
271  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
272  << " device #" << (*itDev)->GetIfIndex() << " RX carrier #"
273  << itCarrier->first);
274  }
275  else
276  {
277  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
278  << " of SatPhyRxCarrier"
279  << " at node ID " << (*it)->GetId()
280  << " device #" << (*itDev)->GetIfIndex()
281  << " RX carrier #" << itCarrier->first);
282  }
283 
284  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
285 
286  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
287 
288  } // end of `for (NodeContainer::Iterator it = gws)`
289 
290 } // end of `void DoInstall ();`
291 
292 void
293 SatStatsCarrierIdHelper::CarrierIdRxCallback(uint32_t carrierId, const Address& from)
294 {
295  NS_LOG_FUNCTION(this << carrierId << from);
296 
297  if (from.IsInvalid())
298  {
299  NS_LOG_WARN(this << " discarding a packet"
300  << " from statistics collection because of"
301  << " invalid sender address");
302  return;
303  }
304 
305  // Determine the identifier associated with the sender address.
306  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
307 
308  if (it == m_identifierMap.end())
309  {
310  NS_LOG_WARN(this << " discarding a packet"
311  << " from statistics collection because of"
312  << " unknown sender address " << from);
313  return;
314  }
315 
316  // Find the first-level collector with the right identifier.
317  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(it->second);
318  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << it->second);
319 
320  switch (GetOutputType())
321  {
324  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
325  NS_ASSERT(c != nullptr);
326  c->TraceSinkUinteger32(0, carrierId);
327  break;
328  }
329 
332  Ptr<IntervalRateCollector> c = collector->GetObject<IntervalRateCollector>();
333  NS_ASSERT(c != nullptr);
334  c->TraceSinkUinteger32(0, carrierId);
335  break;
336  }
337 
338  default:
339  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
340  << " is not a valid output type for this statistics.");
341  break;
342  }
343 }
344 
345 } // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
CarrierType
Possible carrier types.
SatStatsCarrierIdHelper(Ptr< const SatHelper > satHelper)
SatPhyRxCarrier::CarrierType GetValidCarrierType() const
Get the valid carrier type.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
void SetValidCarrierType(SatPhyRxCarrier::CarrierType carrierType)
Set valid carrier type for this statistics helper type.
static TypeId GetTypeId()
inherited from ObjectBase base class
void CarrierIdRxCallback(uint32_t carrierId, 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.
void SetTraceSourceName(std::string traceSourceName)
Parent abstract class of all satellite statistics helpers.
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)
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
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
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.