satellite-fwd-link-scheduler.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd
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: Sami Rantanen <sami.rantanen@magister.fi>
19  */
20 
22 
23 #include "satellite-enums.h"
24 #include "satellite-mac-tag.h"
26 
27 #include <ns3/boolean.h>
28 #include <ns3/double.h>
29 #include <ns3/enum.h>
30 #include <ns3/log.h>
31 #include <ns3/mac48-address.h>
32 #include <ns3/nstime.h>
33 #include <ns3/pointer.h>
34 #include <ns3/simulator.h>
35 #include <ns3/trace-source-accessor.h>
36 #include <ns3/uinteger.h>
37 
38 #include <algorithm>
39 
40 NS_LOG_COMPONENT_DEFINE("SatFwdLinkScheduler");
41 
42 namespace ns3
43 {
44 
45 NS_OBJECT_ENSURE_REGISTERED(SatFwdLinkScheduler);
46 
47 // #define SAT_FWD_LINK_SCHEDULER_PRINT_SORT_RESULT
48 
49 #ifdef SAT_FWD_LINK_SCHEDULER_PRINT_SORT_RESULT
50 static void
51 PrintSoContent(std::string context, std::vector<Ptr<SatSchedulingObject>>& so)
52 {
53  std::cout << context << std::endl;
54 
55  for (std::vector<Ptr<SatSchedulingObject>>::const_iterator it = so.begin(); it != so.end();
56  it++)
57  {
58  std::cout << "So-Content (ptr, priority, load, hol): " << (*it) << ", "
59  << (*it)->GetPriority() << ", " << (*it)->GetBufferedBytes() << ", "
60  << (*it)->GetHolDelay() << std::endl;
61  }
62 
63  std::cout << std::endl;
64 }
65 #endif
66 
67 bool
68 SatFwdLinkScheduler::CompareSoFlowId(Ptr<SatSchedulingObject> obj1, Ptr<SatSchedulingObject> obj2)
69 {
70  return (bool)(obj1->GetFlowId() < obj2->GetFlowId());
71 }
72 
73 bool
74 SatFwdLinkScheduler::CompareSoPriorityLoad(Ptr<SatSchedulingObject> obj1,
75  Ptr<SatSchedulingObject> obj2)
76 {
77  bool result = CompareSoFlowId(obj1, obj2);
78 
79  if (obj1->GetFlowId() == obj2->GetFlowId())
80  {
81  result = (bool)(obj1->GetBufferedBytes() > obj2->GetBufferedBytes());
82  }
83 
84  return result;
85 }
86 
87 bool
88 SatFwdLinkScheduler::CompareSoPriorityHol(Ptr<SatSchedulingObject> obj1,
89  Ptr<SatSchedulingObject> obj2)
90 {
91  bool result = CompareSoFlowId(obj1, obj2);
92 
93  if (obj1->GetFlowId() == obj2->GetFlowId())
94  {
95  result = (bool)(obj1->GetHolDelay() > obj2->GetHolDelay());
96  }
97 
98  return result;
99 }
100 
101 TypeId
103 {
104  static TypeId tid =
105  TypeId("ns3::SatFwdLinkScheduler")
106  .SetParent<Object>()
107  .AddConstructor<SatFwdLinkScheduler>()
108  .AddAttribute("Interval",
109  "The time for periodic scheduling",
110  TimeValue(MilliSeconds(20)),
111  MakeTimeAccessor(&SatFwdLinkScheduler::m_periodicInterval),
112  MakeTimeChecker())
113  .AddAttribute("BBFrameConf",
114  "BB Frame configuration for this scheduler.",
115  PointerValue(),
116  MakePointerAccessor(&SatFwdLinkScheduler::m_bbFrameConf),
117  MakePointerChecker<SatBbFrameConf>())
118  .AddAttribute("DummyFrameSendingEnabled",
119  "Flag to tell, if dummy frames are sent or not.",
120  BooleanValue(false),
122  MakeBooleanChecker())
123  .AddAttribute("AdditionalSortCriteria",
124  "Sorting criteria after priority for scheduling objects from LLC.",
125  EnumValue(SatFwdLinkScheduler::NO_SORT),
127  MakeEnumChecker(SatFwdLinkScheduler::NO_SORT,
128  "NoSorting",
130  "DelaySort",
132  "LoadSort"))
133  .AddAttribute("CnoEstimationMode",
134  "Mode of the C/N0 estimator",
135  EnumValue(SatCnoEstimator::LAST),
136  MakeEnumAccessor(&SatFwdLinkScheduler::m_cnoEstimatorMode),
137  MakeEnumChecker(SatCnoEstimator::LAST,
138  "LastValueInWindow",
140  "MinValueInWindow",
142  "AverageValueInWindow"))
143  .AddAttribute("CnoEstimationWindow",
144  "Time window for C/N0 estimation.",
145  TimeValue(Seconds(5000)),
147  MakeTimeChecker())
148  .AddTraceSource(
149  "SymbolRate",
150  "Scheduler symbol rate for a given packet",
151  MakeTraceSourceAccessor(&SatFwdLinkScheduler::m_schedulingSymbolRateTrace),
152  "ns3::SatTypedefs::FwdLinkSchedulerSymbolRateCallback")
153 
154  ;
155  return tid;
156 }
157 
158 TypeId
160 {
161  NS_LOG_FUNCTION(this);
162 
163  return GetTypeId();
164 }
165 
167  : m_additionalSortCriteria(SatFwdLinkScheduler::NO_SORT),
168  m_cnoEstimatorMode(SatCnoEstimator::LAST),
169  m_carrierBandwidthInHz(0.0)
170 {
171  NS_LOG_FUNCTION(this);
172  NS_FATAL_ERROR("Default constructor for SatFwdLinkScheduler not supported");
173 }
174 
176  Mac48Address address,
177  double carrierBandwidthInHz)
178  : m_macAddress(address),
179  m_bbFrameConf(conf),
180  m_additionalSortCriteria(SatFwdLinkScheduler::NO_SORT),
181  m_cnoEstimatorMode(SatCnoEstimator::LAST),
182  m_carrierBandwidthInHz(carrierBandwidthInHz)
183 {
184  NS_LOG_FUNCTION(this);
185 
186  ObjectBase::ConstructSelf(AttributeConstructionList());
187 
188  // Random variable used in scheduling
189  m_random = CreateObject<UniformRandomVariable>();
190 }
191 
193 {
194  NS_LOG_FUNCTION(this);
195 }
196 
197 void
199 {
200  NS_LOG_FUNCTION(this);
201  m_schedContextCallback.Nullify();
202  m_txOpportunityCallback.Nullify();
203  m_sendControlMsgCallback.Nullify();
204  m_cnoEstimatorContainer.clear();
205 }
206 
207 void
209 {
210  NS_LOG_FUNCTION(this << &cb);
212 }
213 
214 void
216 {
217  NS_LOG_FUNCTION(this << &cb);
219 }
220 
221 void
223 {
224  NS_LOG_FUNCTION(this << &cb);
226 }
227 
228 bool
229 SatFwdLinkScheduler::SendControlMsg(Ptr<SatControlMessage> message, const Address& dest) const
230 {
231  NS_LOG_FUNCTION(this << message << dest);
232  return m_sendControlMsgCallback(message, dest);
233 }
234 
235 std::pair<Ptr<SatBbFrame>, const Time>
237 {
238  NS_FATAL_ERROR("SatFwdLinkScheduler::GetNextFrame: should not be here");
239 
240  Ptr<SatBbFrame> f = NULL;
241 
242  return std::make_pair(f, m_bbFrameConf->GetDummyBbFrameDuration());
243 }
244 
245 void
246 SatFwdLinkScheduler::CnoInfoUpdated(Mac48Address utAddress, double cnoEstimate)
247 {
248  NS_LOG_FUNCTION(this << utAddress << cnoEstimate);
249 
250  CnoEstimatorMap_t::const_iterator it = m_cnoEstimatorContainer.find(utAddress);
251 
252  if (it == m_cnoEstimatorContainer.end())
253  {
254  Ptr<SatCnoEstimator> estimator = CreateCnoEstimator();
255 
256  std::pair<CnoEstimatorMap_t::const_iterator, bool> result =
257  m_cnoEstimatorContainer.insert(std::make_pair(utAddress, estimator));
258  it = result.first;
259 
260  if (result.second == false)
261  {
262  NS_FATAL_ERROR("Estimator cannot be added to container!!!");
263  }
264  }
265 
266  it->second->AddSample(cnoEstimate);
267 }
268 
269 Time
271 {
272  NS_LOG_FUNCTION(this);
273 
274  return m_bbFrameConf->GetBbFrameDuration(m_bbFrameConf->GetDefaultModCod(),
276 }
277 
278 void
280 {
281  m_dummyFrameSendingEnabled = dummyFrameSendingEnabled;
282 }
283 
284 void
286 {
287  NS_FATAL_ERROR("SatFwdLinkScheduler::ScheduleBbFrames: should not be here");
288 }
289 
290 void
292 {
293  NS_FATAL_ERROR("SatFwdLinkScheduler::SendAndClearSymbolsSentStat: should not be here");
294 }
295 
296 void
298 {
299  NS_FATAL_ERROR("SatFwdLinkScheduler::ScheduleBbFrames: should not be here");
300 }
301 
302 void
303 SatFwdLinkScheduler::GetSchedulingObjects(std::vector<Ptr<SatSchedulingObject>>& output)
304 {
305  NS_FATAL_ERROR("SatFwdLinkScheduler::GetSchedulingObjects: should not be here");
306 }
307 
308 void
309 SatFwdLinkScheduler::SortSchedulingObjects(std::vector<Ptr<SatSchedulingObject>>& so)
310 {
311  NS_LOG_FUNCTION(this);
312 
313  // sort only if there is need to sort
314  if ((so.empty() == false) && (so.size() > 1))
315  {
316 #ifdef SAT_FWD_LINK_SCHEDULER_PRINT_SORT_RESULT
317  PrintSoContent("Before sort", so);
318 #endif
319 
320  switch (m_additionalSortCriteria)
321  {
323  std::sort(so.begin(), so.end(), CompareSoFlowId);
324  break;
325 
327  std::sort(so.begin(), so.end(), CompareSoPriorityHol);
328  break;
329 
331  std::sort(so.begin(), so.end(), CompareSoPriorityLoad);
332  break;
333 
334  default:
335  NS_FATAL_ERROR("Not supported sorting criteria!!!");
336  break;
337  }
338 
339 #ifdef SAT_FWD_LINK_SCHEDULER_PRINT_SORT_RESULT
340  PrintSoContent("After sort", so);
341 #endif
342  }
343 }
344 
345 bool
346 SatFwdLinkScheduler::CnoMatchWithFrame(double cno, Ptr<SatBbFrame> frame) const
347 {
348  NS_LOG_FUNCTION(this << cno << frame);
349 
350  bool match = false;
351 
352  SatEnums::SatModcod_t modCod = m_bbFrameConf->GetBestModcod(cno, frame->GetFrameType());
353 
354  if (modCod >= frame->GetModcod())
355  {
356  match = true;
357  }
358 
359  return match;
360 }
361 
362 double
364 {
365  NS_LOG_FUNCTION(this << ob);
366 
367  double cno = NAN;
368 
369  CnoEstimatorMap_t::const_iterator it = m_cnoEstimatorContainer.find(ob->GetMacAddress());
370 
371  if (it != m_cnoEstimatorContainer.end())
372  {
373  cno = it->second->GetCnoEstimation();
374  }
375 
376  return cno;
377 }
378 
379 Ptr<SatCnoEstimator>
381 {
382  NS_LOG_FUNCTION(this);
383 
384  Ptr<SatCnoEstimator> estimator = NULL;
385 
386  switch (m_cnoEstimatorMode)
387  {
391  estimator = Create<SatBasicCnoEstimator>(m_cnoEstimatorMode, m_cnoEstimationWindow);
392  break;
393 
394  default:
395  NS_FATAL_ERROR("Not supported C/N0 estimation mode!!!");
396  break;
397  }
398 
399  return estimator;
400 }
401 
402 } // namespace ns3
SatCnoEstimator class defines interface for C/N0 estimators.
@ MINIMUM
Minimum value in the given window returned.
@ LAST
Last value in the given window returned.
@ AVERAGE
Average value in the given window returned.
SatModcod_t
Modulation scheme and coding rate for DVB-S2.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.