satellite-stats-waveform-usage-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/boolean.h>
25 #include <ns3/callback.h>
26 #include <ns3/data-collection-object.h>
27 #include <ns3/enum.h>
28 #include <ns3/fatal-error.h>
29 #include <ns3/log.h>
30 #include <ns3/multi-file-aggregator.h>
31 #include <ns3/node-container.h>
32 #include <ns3/satellite-beam-helper.h>
33 #include <ns3/satellite-beam-scheduler.h>
34 #include <ns3/satellite-helper.h>
35 #include <ns3/satellite-ncc.h>
36 #include <ns3/satellite-topology.h>
37 #include <ns3/scalar-collector.h>
38 #include <ns3/singleton.h>
39 #include <ns3/string.h>
40 
41 #include <list>
42 #include <map>
43 #include <sstream>
44 #include <string>
45 #include <utility>
46 
47 NS_LOG_COMPONENT_DEFINE("SatStatsWaveformUsageHelper");
48 
49 namespace ns3
50 {
51 
52 NS_OBJECT_ENSURE_REGISTERED(SatStatsWaveformUsageHelper);
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::SatStatsWaveformUsageHelper").SetParent<SatStatsHelper>();
69  return tid;
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION(this);
76 
78  {
79  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
80  << " is not a valid output type for this statistics.");
81  }
82 
85  {
87  << " is not a valid identifier type for this statistics.");
88  }
89 
90  // Setup aggregator.
91  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
92  "OutputFileName",
93  StringValue(GetOutputFileName()),
94  "MultiFileMode",
95  BooleanValue(false),
96  "EnableContextPrinting",
97  BooleanValue(true),
98  "GeneralHeading",
99  StringValue(GetIdentifierHeading("usage_count")));
100 
101  Callback<void, std::string, uint32_t> waveformUsageCallback =
103 
104  // Setup probes.
105  Ptr<SatBeamHelper> beamHelper = GetSatHelper()->GetBeamHelper();
106  NS_ASSERT(beamHelper != nullptr);
107  Ptr<SatNcc> ncc = beamHelper->GetNcc();
108  NS_ASSERT(ncc != nullptr);
109  std::list<std::pair<uint32_t, uint32_t>> beams = beamHelper->GetBeams();
110 
111  for (std::list<std::pair<uint32_t, uint32_t>>::const_iterator it = beams.begin();
112  it != beams.end();
113  ++it)
114  {
115  std::ostringstream context;
116  context << GetIdentifierForBeam(it->first, it->second);
117 
118  Ptr<SatBeamScheduler> s = ncc->GetBeamScheduler(it->first, it->second);
119  NS_ASSERT_MSG(s != nullptr, "Error finding beam " << it->second);
120  const bool ret = s->TraceConnect("WaveformTrace", context.str(), waveformUsageCallback);
121  NS_ASSERT_MSG(ret, "Error connecting to WaveformTrace of beam " << it->second);
122  NS_LOG_INFO(this << " successfully connected"
123  << " with beam " << it->second);
124  }
125 
126 } // end of `void DoInstall ();`
127 
128 std::string
130 {
131  switch (GetIdentifierType())
132  {
134  return "% global waveform_id " + dataLabel;
135 
137  return "% gw_id waveform_id " + dataLabel;
138 
140  return "% beam_id waveform_id " + dataLabel;
141 
142  default:
143  NS_FATAL_ERROR("SatStatsWaveformUsageHelper - Invalid identifier type");
144  break;
145  }
146  return "";
147 }
148 
149 void
150 SatStatsWaveformUsageHelper::WaveformUsageCallback(std::string context, uint32_t waveformId)
151 {
152  NS_LOG_FUNCTION(this << context << waveformId);
153 
154  // convert context to number
155  std::stringstream ss(context);
156  uint32_t identifier;
157  if (!(ss >> identifier))
158  {
159  NS_FATAL_ERROR("Cannot convert '" << context << "' to number");
160  }
161 
162  std::map<uint32_t, CollectorMap>::iterator it = m_collectors.find(waveformId);
163  if (it == m_collectors.end())
164  {
165  // Newly discovered waveform ID
166  NS_LOG_INFO(this << " Creating new collectors for waveform ID " << waveformId);
167  CollectorMap collectorMap;
168  collectorMap.SetType("ns3::ScalarCollector");
169  collectorMap.SetAttribute("InputDataType",
170  EnumValue(ScalarCollector::INPUT_DATA_TYPE_UINTEGER));
171  collectorMap.SetAttribute("OutputType", EnumValue(ScalarCollector::OUTPUT_TYPE_SUM));
172  uint32_t n = 0;
173 
174  /*
175  * Create a new set of collectors. Its name consists of two integers:
176  * - the first is the identifier ID (beam ID, GW ID, or simply zero for
177  * global);
178  * - the second is the frame ID.
179  */
180  switch (GetIdentifierType())
181  {
183  std::ostringstream name;
184  name << "0 " << waveformId;
185  collectorMap.SetAttribute("Name", StringValue(name.str()));
186  collectorMap.Create(0);
187  n++;
188  break;
189  }
190 
192  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
193  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
194  {
195  const uint32_t gwId = GetGwId(*it);
196  std::ostringstream name;
197  name << gwId << " " << waveformId;
198  collectorMap.SetAttribute("Name", StringValue(name.str()));
199  collectorMap.Create(gwId);
200  n++;
201  }
202  break;
203  }
204 
206  std::list<std::pair<uint32_t, uint32_t>> beams =
207  GetSatHelper()->GetBeamHelper()->GetBeams();
208  for (std::list<std::pair<uint32_t, uint32_t>>::const_iterator it = beams.begin();
209  it != beams.end();
210  ++it)
211  {
212  const uint32_t satId = (it->first);
213  const uint32_t beamId = (it->second);
214  std::ostringstream name;
215  name << satId << "-" << beamId << " " << waveformId;
216  collectorMap.SetAttribute("Name", StringValue(name.str()));
217  collectorMap.Create(SatConstVariables::MAX_BEAMS_PER_SATELLITE * (satId + 1) +
218  beamId);
219  n++;
220  }
221  break;
222  }
223 
224  default:
225  NS_FATAL_ERROR("SatStatsWaveformUsageHelper - Invalid identifier type");
226  break;
227  }
228 
229  collectorMap.ConnectToAggregator("Output", m_aggregator, &MultiFileAggregator::Write1d);
230  NS_LOG_INFO(this << " created " << n << " instance(s)"
231  << " of " << collectorMap.GetType().GetName() << " for "
233 
234  std::pair<std::map<uint32_t, CollectorMap>::iterator, bool> ret;
235  ret = m_collectors.insert(std::make_pair(waveformId, collectorMap));
236  NS_ASSERT(ret.second);
237  it = ret.first;
238 
239  } // end of `if (it == m_collectors.end ())`
240 
241  NS_ASSERT(it != m_collectors.end());
242 
243  // Find the collector with the right identifier.
244  Ptr<DataCollectionObject> collector = it->second.Get(identifier);
245  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << identifier);
246  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
247  NS_ASSERT(c != nullptr);
248 
249  // Pass the sample to the collector.
250  c->TraceSinkUinteger32(0, 1);
251 
252 } // end of `void WaveformUsageCallback (std::string, uint32_t)`
253 
254 } // end of namespace ns3
Parent abstract class of all satellite statistics helpers.
uint32_t GetIdentifierForBeam(uint32_t satId, uint32_t beamId) const
Ptr< const SatHelper > GetSatHelper() const
IdentifierType_t GetIdentifierType() const
static std::string GetOutputTypeName(OutputType_t outputType)
static std::string GetIdentifierTypeName(IdentifierType_t identifierType)
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.
OutputType_t GetOutputType() const
uint32_t GetGwId(Ptr< Node > gwNode) const
SatStatsWaveformUsageHelper(Ptr< const SatHelper > satHelper)
std::map< uint32_t, CollectorMap > m_collectors
Two-dimensional map of collectors, indexed by the waveform ID and then by the identifier.
std::string GetIdentifierHeading(std::string dataLabel) const
void WaveformUsageCallback(std::string context, uint32_t waveformId)
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
constexpr uint32_t MAX_BEAMS_PER_SATELLITE
Maximum number of beams per satellite.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.