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/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("SatStatsMarsalaCorrelationHelper");
51 
52 namespace ns3
53 {
54 
55 // BASE CLASS /////////////////////////////////////////////////////////////////
56 
57 NS_OBJECT_ENSURE_REGISTERED(SatStatsMarsalaCorrelationHelper);
58 
60  : SatStatsHelper(satHelper)
61 {
62  NS_LOG_FUNCTION(this << satHelper);
63  SetTraceSourceName("MarsalaCorrelationRx");
65 }
66 
68 {
69  NS_LOG_FUNCTION(this);
70 }
71 
72 TypeId // static
74 {
75  static TypeId tid = TypeId("ns3::SatStatsMarsalaCorrelationHelper").SetParent<SatStatsHelper>();
76  return tid;
77 }
78 
79 void
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("correlations")));
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("correlations")));
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));
147  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
148  m_aggregator,
149  &MultiFileAggregator::Write2d);
150  m_terminalCollectors.ConnectToAggregator("OutputString",
151  m_aggregator,
152  &MultiFileAggregator::AddContextHeading);
153  break;
154  }
155 
159  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
160  << " is not a valid output type for this statistics.");
161  break;
162 
165  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
166  << " is not a valid output type for this statistics.");
167  break;
168 
170  // Setup aggregator.
171  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
172  "OutputPath",
173  StringValue(GetOutputPath()),
174  "OutputFileName",
175  StringValue(GetName()));
176  Ptr<MagisterGnuplotAggregator> plotAggregator =
177  m_aggregator->GetObject<MagisterGnuplotAggregator>();
178  NS_ASSERT(plotAggregator != nullptr);
179  // plot->SetTitle ("");
180  plotAggregator->SetLegend("Time (in seconds)", "Correlations");
181  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
182 
183  // Setup collectors.
184  m_terminalCollectors.SetType("ns3::IntervalRateCollector");
185  m_terminalCollectors.SetAttribute(
186  "InputDataType",
187  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_UINTEGER));
188  m_terminalCollectors.SetAttribute(
189  "OutputType",
190  EnumValue(IntervalRateCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
192  for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
193  it != m_terminalCollectors.End();
194  ++it)
195  {
196  const std::string context = it->second->GetName();
197  plotAggregator->Add2dDataset(context, context);
198  }
199  m_terminalCollectors.ConnectToAggregator("OutputWithTime",
200  m_aggregator,
201  &MagisterGnuplotAggregator::Write2d);
202  break;
203  }
204 
208  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
209  << " is not a valid output type for this statistics.");
210  break;
211 
212  default:
213  NS_FATAL_ERROR("SatStatsMarsalaCorrelationHelper - Invalid output type");
214  break;
215  }
216 
217  // Create a map of UT addresses and identifiers.
218  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
219  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); ++it)
220  {
222  }
223 
224  // Connect to trace sources at GW nodes.
225 
226  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
227  Callback<void, uint32_t, const Address&, bool> callback =
229 
230  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
231  {
232  NetDeviceContainer devs = GetGwSatNetDevice(*it);
233 
234  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
235  {
236  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
237  NS_ASSERT(satDev != nullptr);
238  Ptr<SatPhy> satPhy = satDev->GetPhy();
239  NS_ASSERT(satPhy != nullptr);
240  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
241  NS_ASSERT(satPhyRx != nullptr);
242  ObjectVectorValue carriers;
243  satPhyRx->GetAttribute("RxCarrierList", carriers);
244  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
245  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
246  << " RX carriers");
247 
248  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
249  itCarrier != carriers.End();
250  ++itCarrier)
251  {
252  Ptr<SatPhyRxCarrierMarsala> c =
253  DynamicCast<SatPhyRxCarrierMarsala>(itCarrier->second);
254  if (!c)
255  {
256  continue;
257  }
258 
260  DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType();
261  if (ct != GetValidCarrierType())
262  {
263  continue;
264  }
265 
266  const bool ret =
267  itCarrier->second->TraceConnectWithoutContext(GetTraceSourceName(), callback);
268  if (ret)
269  {
270  NS_LOG_INFO(this << " successfully connected with node ID " << (*it)->GetId()
271  << " device #" << (*itDev)->GetIfIndex() << " RX carrier #"
272  << itCarrier->first);
273  }
274  else
275  {
276  NS_FATAL_ERROR("Error connecting to " << GetTraceSourceName() << " trace source"
277  << " of SatPhyRxCarrier"
278  << " at node ID " << (*it)->GetId()
279  << " device #" << (*itDev)->GetIfIndex()
280  << " RX carrier #" << itCarrier->first);
281  }
282 
283  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
284 
285  } // end of `for (NetDeviceContainer::Iterator itDev = devs)`
286 
287  } // end of `for (NodeContainer::Iterator it = gws)`
288 
289 } // end of `void DoInstall ();`
290 
291 void
293  const Address& from,
294  bool isCollided)
295 {
296  NS_LOG_FUNCTION(this << nCorrelations << from << isCollided);
297 
298  if (from.IsInvalid())
299  {
300  NS_LOG_WARN(this << " discarding " << nCorrelations << " packets"
301  << " from statistics collection because of"
302  << " invalid sender address");
303  return;
304  }
305 
306  // Determine the identifier associated with the sender address.
307  std::map<const Address, uint32_t>::const_iterator it = m_identifierMap.find(from);
308 
309  if (it == m_identifierMap.end())
310  {
311  NS_LOG_WARN(this << " discarding " << nCorrelations << " packets"
312  << " from statistics collection because of"
313  << " unknown sender address " << from);
314  return;
315  }
316 
317  // Find the first-level collector with the right identifier.
318  Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(it->second);
319  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << it->second);
320 
321  switch (GetOutputType())
322  {
325  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
326  NS_ASSERT(c != nullptr);
327  c->TraceSinkUinteger32(0, nCorrelations);
328  break;
329  }
330 
333  Ptr<IntervalRateCollector> c = collector->GetObject<IntervalRateCollector>();
334  NS_ASSERT(c != nullptr);
335  c->TraceSinkUinteger32(0, nCorrelations);
336  break;
337  }
338 
339  default:
340  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
341  << " is not a valid output type for this statistics.");
342  break;
343  }
344 }
345 
346 } // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
CarrierType
Possible carrier types.
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
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.
SatPhyRxCarrier::CarrierType GetValidCarrierType() const
Get the valid carrier type.
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.