satellite-stats-frame-type-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: Lauri Sormunen <lauri.sormunen@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/distribution-collector.h>
28 #include <ns3/enum.h>
29 #include <ns3/fatal-error.h>
30 #include <ns3/log.h>
31 #include <ns3/multi-file-aggregator.h>
32 #include <ns3/node-container.h>
33 #include <ns3/satellite-beam-helper.h>
34 #include <ns3/satellite-beam-scheduler.h>
35 #include <ns3/satellite-gw-mac.h>
36 #include <ns3/satellite-helper.h>
37 #include <ns3/satellite-ncc.h>
38 #include <ns3/scalar-collector.h>
39 #include <ns3/string.h>
40 
41 #include <list>
42 #include <sstream>
43 #include <utility>
44 
45 NS_LOG_COMPONENT_DEFINE("SatStatsFrameTypeUsageHelper");
46 
47 namespace ns3
48 {
49 
50 NS_OBJECT_ENSURE_REGISTERED(SatStatsFrameTypeUsageHelper);
51 
52 const std::map<SatEnums::SatBbFrameType_t, uint32_t> SatStatsFrameTypeUsageHelper::frameTypeIdMap =
57 
59  : SatStatsHelper(satHelper),
60  m_usePercentage(false)
61 {
62  NS_LOG_FUNCTION(this << satHelper);
63 }
64 
66 {
67  NS_LOG_FUNCTION(this);
68 }
69 
70 TypeId // static
72 {
73  static TypeId tid =
74  TypeId("ns3::SatStatsFrameTypeUsageHelper")
75  .SetParent<SatStatsHelper>()
76  .AddAttribute("Percentage",
77  "Use percentage of each frame type instead of sum per identifier.",
78  BooleanValue(false),
80  MakeBooleanChecker());
81  return tid;
82 }
83 
84 void
86 {
87  NS_LOG_FUNCTION(this);
88 
90  {
91  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
92  << " is not a valid output type for this statistics.");
93  }
94 
97  {
99  << " is not a valid identifier type for this statistics.");
100  }
101 
102  // Setup aggregator.
103  std::string dataLabel;
104  if (m_usePercentage)
105  dataLabel = "usage_percentage";
106  else
107  dataLabel = "usage_count";
108 
109  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
110  "OutputFileName",
111  StringValue(GetOutputFileName()),
112  "MultiFileMode",
113  BooleanValue(false),
114  "EnableContextPrinting",
115  BooleanValue(true),
116  "GeneralHeading",
117  StringValue(GetIdentifierHeading(dataLabel)));
118 
119  // For each frame type ID, create a CollectorMap instance
120  for (auto it : frameTypeIdMap)
121  {
122  uint32_t frameTypeId = it.second;
123  // Newly discovered waveform ID
124  NS_LOG_INFO(this << " Creating new collectors for frame type ID " << frameTypeId);
125 
126  CollectorMap collectorMap;
127  ScalarCollector::OutputType_t opType;
128  if (m_usePercentage)
129  opType = ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE;
130  else
131  opType = ScalarCollector::OUTPUT_TYPE_SUM;
132 
133  collectorMap.SetType("ns3::ScalarCollector");
134  collectorMap.SetAttribute("OutputType", EnumValue(opType));
135  collectorMap.SetAttribute("InputDataType",
136  EnumValue(ScalarCollector::INPUT_DATA_TYPE_UINTEGER));
137  uint32_t n = 0;
138  /*
139  * Create a new set of collectors. Its name consists of two integers:
140  * - the first is the identifier ID (beam ID, GW ID, or simply zero for
141  * global);
142  * - the second is the frame ID.
143  */
144  switch (GetIdentifierType())
145  {
147  std::ostringstream name;
148  name << "0 " << frameTypeId;
149  collectorMap.SetAttribute("Name", StringValue(name.str()));
150  collectorMap.Create(0);
151  n++;
152  break;
153  }
154 
156  NodeContainer gws = GetSatHelper()->GetBeamHelper()->GetGwNodes();
157  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
158  {
159  const uint32_t gwId = GetGwId(*it);
160  std::ostringstream name;
161  name << gwId << " " << frameTypeId;
162  collectorMap.SetAttribute("Name", StringValue(name.str()));
163  collectorMap.Create(gwId);
164  n++;
165  }
166  break;
167  }
168 
170  std::list<std::pair<uint32_t, uint32_t>> beams =
171  GetSatHelper()->GetBeamHelper()->GetBeams();
172  for (std::list<std::pair<uint32_t, uint32_t>>::const_iterator it = beams.begin();
173  it != beams.end();
174  ++it)
175  {
176  const uint32_t satId = (it->first);
177  const uint32_t beamId = (it->second);
178  std::ostringstream name;
179  name << satId << "-" << beamId << " " << frameTypeId;
180  collectorMap.SetAttribute("Name", StringValue(name.str()));
181  collectorMap.Create(SatConstVariables::MAX_BEAMS_PER_SATELLITE * (satId + 1) +
182  beamId);
183  n++;
184  }
185  break;
186  }
187 
188  default:
189  NS_FATAL_ERROR("SatStatsWaveformUsageHelper - Invalid identifier type");
190  break;
191  }
192 
193  collectorMap.ConnectToAggregator("Output", m_aggregator, &MultiFileAggregator::Write1d);
194 
195  NS_LOG_INFO(this << " created " << n << " instance(s)"
196  << " of " << collectorMap.GetType().GetName() << " for "
198 
199  std::pair<std::map<uint32_t, CollectorMap>::iterator, bool> ret;
200  ret = m_collectors.insert(std::make_pair(frameTypeId, collectorMap));
201  NS_ASSERT(ret.second);
202  }
203 
204  // Create the callback for trace source
205  Callback<void, std::string, Ptr<SatBbFrame>> frameTypeUsageCallback =
207 
208  // Connect SatGwMac of each beam by identifier (global, gw, beam) to callback
209  NodeContainer gwNodes = GetSatHelper()->GetBeamHelper()->GetGwNodes();
210  for (auto node = gwNodes.Begin(); node != gwNodes.End(); node++)
211  {
212  for (uint32_t i = 0; i < (*node)->GetNDevices(); i++)
213  {
214  Ptr<SatNetDevice> dev = DynamicCast<SatNetDevice>((*node)->GetDevice(i));
215  if (dev == NULL)
216  continue;
217  Ptr<SatGwMac> mac = DynamicCast<SatGwMac>(dev->GetMac());
218  if (mac == NULL)
219  continue;
220 
221  // Connect the trace source
222  uint32_t beamId = mac->GetBeamId();
223  uint32_t satId = mac->GetSatId();
224  std::ostringstream context;
225  context << GetIdentifierForBeam(satId, beamId);
226  const bool ret =
227  mac->TraceConnect("BBFrameTxTrace", context.str(), frameTypeUsageCallback);
228  NS_ASSERT_MSG(ret, "Error connecting to BBFrameTxTrace of beam " << beamId);
229  NS_LOG_INFO(this << " successfully connected"
230  << " with beam " << beamId);
231  }
232  }
233 
234 } // end of `void DoInstall ();`
235 
236 std::string
238 {
239  switch (GetIdentifierType())
240  {
242  return "% global frame_type " + dataLabel;
243 
245  return "% gw_id frame_type " + dataLabel;
246 
248  return "% beam_id frame_type " + dataLabel;
249 
250  default:
251  NS_FATAL_ERROR("SatStatsFrameTypeUsageHelper - Invalid identifier type");
252  break;
253  }
254  return "";
255 }
256 
257 // static
258 uint32_t
260 {
261  auto it = frameTypeIdMap.find(frameType);
262  NS_ASSERT(it != frameTypeIdMap.end());
263  return it->second;
264 }
265 
266 void
267 SatStatsFrameTypeUsageHelper::FrameTypeUsageCallback(std::string context, Ptr<SatBbFrame> bbFrame)
268 {
269  SatEnums::SatBbFrameType_t frameType =
270  bbFrame ? bbFrame->GetFrameType() : SatEnums::DUMMY_FRAME;
271  NS_LOG_FUNCTION(this << context << SatEnums::GetFrameTypeName(frameType));
272 
273  // convert context to number
274  std::stringstream ss(context);
275  uint32_t identifier;
276  if (!(ss >> identifier))
277  {
278  NS_FATAL_ERROR("Cannot convert '" << context << "' to number");
279  }
280  uint32_t frameTypeId = GetFrameTypeId(frameType);
281 
282  std::map<uint32_t, CollectorMap>::iterator it = m_collectors.find(frameTypeId);
283 
284  NS_ASSERT(it != m_collectors.end());
285  if (!m_usePercentage)
286  {
287  // Find the collector with the right identifier.
288  Ptr<DataCollectionObject> collector = it->second.Get(identifier);
289  NS_ASSERT_MSG(collector != nullptr,
290  "Unable to find collector with identifier " << identifier);
291 
292  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
293  NS_ASSERT(c != nullptr);
294 
295  // Pass the sample to the collector.
296  c->TraceSinkUinteger32(0, 1);
297  }
298  else
299  {
300  // Push 0 to all other frame type collectors of the beam/gw/global identifier
301  // and 1 to the collector of the right frame type
302  for (auto it : m_collectors)
303  {
304  Ptr<DataCollectionObject> collector = it.second.Get(identifier);
305  NS_ASSERT_MSG(collector != nullptr,
306  "Unable to find collector with identifier " << identifier);
307  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
308  NS_ASSERT(c != nullptr);
309  if (it.first == frameTypeId)
310  c->TraceSinkUinteger32(0, 1);
311  else
312  c->TraceSinkUinteger32(0, 0);
313  }
314  }
315 
316 } // end of `void FrameTypeUsageCallback (std::string, uint32_t)`
317 
318 } // end of namespace ns3
SatBbFrameType_t
BB frame type used in DVB-S2 FWD link.
static std::string GetFrameTypeName(SatBbFrameType_t frameType)
SatStatsFrameTypeUsageHelper(Ptr< const SatHelper > satHelper)
Constructor.
std::string GetIdentifierHeading(std::string dataLabel) const
Get identifier header for file.
void FrameTypeUsageCallback(std::string context, Ptr< SatBbFrame > bbFrame)
static const std::map< SatEnums::SatBbFrameType_t, uint32_t > frameTypeIdMap
Mapping for frame type IDs to integers, in case that SatBbFrameType_t enums are assigned.
std::map< uint32_t, CollectorMap > m_collectors
Two-dimensional map of collectors, indexed first by the the frame type identifier and second by the g...
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
static uint32_t GetFrameTypeId(SatEnums::SatBbFrameType_t frameType)
Get frame type ID.
bool m_usePercentage
Flag for using percentage of the frame types in beam/in gw/globally instead of sum by type.
static TypeId GetTypeId()
inherited from ObjectBase base class
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
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
constexpr uint32_t MAX_BEAMS_PER_SATELLITE
Maximum number of beams per satellite.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.