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