satellite-stats-marsala-correlation-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/scalar-collector.h>
42 #include <ns3/singleton.h>
43 #include <ns3/string.h>
44 
45 #include <sstream>
46 
47 NS_LOG_COMPONENT_DEFINE("SatStatsMarsalaCorrelationHelper");
48 
49 namespace ns3
50 {
51 
52 // BASE CLASS /////////////////////////////////////////////////////////////////
53 
54 NS_OBJECT_ENSURE_REGISTERED(SatStatsMarsalaCorrelationHelper);
55 
57  : SatStatsHelper(satHelper)
58 {
59  NS_LOG_FUNCTION(this << satHelper);
60  SetTraceSourceName("MarsalaCorrelationRx");
62 }
63 
65 {
66  NS_LOG_FUNCTION(this);
67 }
68 
69 TypeId // static
71 {
72  static TypeId tid = TypeId("ns3::SatStatsMarsalaCorrelationHelper").SetParent<SatStatsHelper>();
73  return tid;
74 }
75 
76 void
78 {
79  NS_LOG_FUNCTION(this << traceSourceName);
80  m_traceSourceName = traceSourceName;
81 }
82 
83 std::string
85 {
86  return m_traceSourceName;
87 }
88 
89 void
91 {
92  NS_LOG_FUNCTION(this);
93 
94  switch (GetOutputType())
95  {
97  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
98  << " is not a valid output type for this statistics.");
99  break;
100 
102  // Setup aggregator.
103  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
104  "OutputFileName",
105  StringValue(GetOutputFileName()),
106  "MultiFileMode",
107  BooleanValue(false),
108  "EnableContextPrinting",
109  BooleanValue(true),
110  "GeneralHeading",
111  StringValue(GetIdentifierHeading("correlations")));
112 
113  // Setup collectors.
114  m_terminalCollectors.SetType("ns3::ScalarCollector");
115  m_terminalCollectors.SetAttribute("InputDataType",
116  EnumValue(ScalarCollector::INPUT_DATA_TYPE_UINTEGER));
117  m_terminalCollectors.SetAttribute(
118  "OutputType",
119  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
121  m_terminalCollectors.ConnectToAggregator("Output",
122  m_aggregator,
123  &MultiFileAggregator::Write1d);
124  break;
125  }
126 
128  // Setup aggregator.
129  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
130  "OutputFileName",
131  StringValue(GetOutputFileName()),
132  "GeneralHeading",
133  StringValue(GetTimeHeading("correlations")));
134 
135  // Setup collectors.
136  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
137  m_terminalCollectors.SetAttribute(
138  "InputDataType",
139  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_UINTEGER));
140  m_terminalCollectors.SetAttribute(
141  "OutputType",
142  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
144  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
145  m_aggregator,
146  &MultiFileAggregator::Write2d);
147  m_terminalCollectors.ConnectToAggregator("OutputString",
148  m_aggregator,
149  &MultiFileAggregator::AddContextHeading);
150  break;
151  }
152 
156  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
157  << " is not a valid output type for this statistics.");
158  break;
159 
162  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
163  << " is not a valid output type for this statistics.");
164  break;
165 
167  // Setup aggregator.
168  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
169  "OutputPath",
170  StringValue(GetOutputPath()),
171  "OutputFileName",
172  StringValue(GetName()));
173  Ptr<MagisterGnuplotAggregator> plotAggregator =
174  m_aggregator->GetObject<MagisterGnuplotAggregator>();
175  NS_ASSERT(plotAggregator != nullptr);
176  // plot->SetTitle ("");
177  plotAggregator->SetLegend("Time (in seconds)", "Correlations");
178  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
179 
180  // Setup collectors.
181  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
182  m_terminalCollectors.SetAttribute(
183  "InputDataType",
184  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_UINTEGER));
185  m_terminalCollectors.SetAttribute(
186  "OutputType",
187  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
189  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
190  it != m_terminalCollectors.End();
191  ++it)
192  {
193  const std::string context = it->second->GetName();
194  plotAggregator->Add2dDataset(context, context);
195  }
196  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
197  m_aggregator,
198  &MagisterGnuplotAggregator::Write2d);
199  break;
200  }
201 
205  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
206  << " is not a valid output type for this statistics.");
207  break;
208 
209  default:
210  NS_FATAL_ERROR("SatStatsMarsalaCorrelationHelper - Invalid output type");
211  break;
212  }
213 
214  // Create a map of UT addresses and identifiers.
215  NodeContainer uts = GetSatHelper()->GetBeamHelper()->GetUtNodes();
216  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
217  {
219  }
220 
221  // Connect to trace sources at GW nodes.
222 
223  NodeContainer gws = GetSatHelper()->GetBeamHelper()->GetGwNodes();
224  Callback<void, uint32_t, const Address&, bool> callback =
226 
227  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
228  {
229  NetDeviceContainer devs = GetGwSatNetDevice(*it);
230 
231  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
232  {
233  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
234  NS_ASSERT(satDev != nullptr);
235  Ptr<SatPhy> satPhy = satDev->GetPhy();
236  NS_ASSERT(satPhy != nullptr);
237  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
238  NS_ASSERT(satPhyRx != nullptr);
239  ObjectVectorValue carriers;
240  satPhyRx->GetAttribute("RxCarrierList", carriers);
241  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
242  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
243  << " RX carriers");
244 
245  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
246  itCarrier != carriers.End();
247  ++itCarrier)
248  {
249  Ptr<SatPhyRxCarrierMarsala> c =
250  DynamicCast<SatPhyRxCarrierMarsala>(itCarrier->second);
251  if (!c)
252  {
253  continue;
254  }
255 
257  DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType();
258  if (ct != GetValidCarrierType())
259  {
260  continue;
261  }
262 
263  const bool ret =
264  itCarrier->second->TraceConnectWithoutContext(GetTraceSourceName(), callback);
265  if (ret)
266  {
267  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
268  << " device #" << (*itDev)->GetIfIndex() << " RX carrier #"
269  << itCarrier->first);
270  }
271  else
272  {
273  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
274  << " of SatPhyRxCarrier"
275  << " at node ID " << (*it)->GetId()
276  << " device #" << (*itDev)->GetIfIndex()
277  << " RX carrier #" << itCarrier->first);
278  }
279 
280  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
281 
282  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
283 
284  } // end of `for (NodeContainer::Iterator it = gws)`
285 
286 } // end of `void DoInstall ();`
287 
288 void
290  const Address& from,
291  bool isCollided)
292 {
293  NS_LOG_FUNCTION(this << nCorrelations << from << isCollided);
294 
295  if (from.IsInvalid())
296  {
297  NS_LOG_WARN(this << " discarding " << nCorrelations << " packets"
298  << " from statistics collection because of"
299  << " invalid sender address");
300  return;
301  }
302 
303  // Determine the identifier associated with the sender address.
304  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
305 
306  if (it == m_identifierMap.end())
307  {
308  NS_LOG_WARN(this << " discarding " << nCorrelations << " packets"
309  << " from statistics collection because of"
310  << " unknown sender address " << from);
311  return;
312  }
313 
314  // Find the first-level collector with the right identifier.
315  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(it->second);
316  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << it->second);
317 
318  switch (GetOutputType())
319  {
322  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
323  NS_ASSERT(c != nullptr);
324  c->TraceSinkUinteger32(0, nCorrelations);
325  break;
326  }
327 
330  Ptr<IntervalRateCollector> c = collector->GetObject<IntervalRateCollector>();
331  NS_ASSERT(c != nullptr);
332  c->TraceSinkUinteger32(0, nCorrelations);
333  break;
334  }
335 
336  default:
337  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
338  << " is not a valid output type for this statistics.");
339  break;
340  }
341 }
342 
343 void
345 {
346  NS_LOG_FUNCTION(this << utNode->GetId());
347 
348  const SatIdMapper* satIdMapper = Singleton<SatIdMapper>::Get();
349  const Address addr = satIdMapper->GetUtMacWithNode(utNode);
350 
351  if (addr.IsInvalid())
352  {
353  NS_LOG_WARN(this << " Node " << utNode->GetId() << " is not a valid UT");
354  }
355  else
356  {
357  const uint32_t identifier = GetIdentifierForUt(utNode);
358  m_identifierMap[addr] = identifier;
359  NS_LOG_INFO(this << " associated address " << addr << " with identifier " << identifier);
360  }
361 }
362 
363 } // end of namespace ns3
Class for ID-mapper.
Address GetUtMacWithNode(Ptr< Node > utNode) const
SatNetDevice to be utilized in the UT and GW nodes.
CarrierType
Possible carrier types.
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 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::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
void CorrelationRxCallback(uint32_t nPackets, const Address &from, bool isCollided)
Receive inputs from trace sources and determine the right collector to forward the inputs to.
void SaveAddressAndIdentifier(Ptr< Node > utNode)
Save the address and the proper identifier from the given UT node.
SatPhyRxCarrier::CarrierType GetValidCarrierType() const
Get the valid carrier type.
std::map< const Address, uint32_t > m_identifierMap
Map of address and the identifier associated with it (for forward link).
void SetValidCarrierType(SatPhyRxCarrier::CarrierType carrierType)
Set valid carrier type for this statistics helper type.
CollectorMap m_terminalCollectors
Maintains a list of collectors created by this helper.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.