A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
bs-uplink-scheduler-simple.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007,2008 INRIA
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: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
19  */
20 
22 #include "bs-net-device.h"
23 #include "ns3/simulator.h"
24 #include "cid.h"
25 #include "burst-profile-manager.h"
26 #include "ss-manager.h"
27 #include "ns3/log.h"
28 #include "ns3/uinteger.h"
29 #include "ss-record.h"
30 #include "service-flow.h"
31 #include "service-flow-record.h"
32 #include "bs-link-manager.h"
33 #include "bandwidth-manager.h"
34 
35 NS_LOG_COMPONENT_DEFINE ("UplinkSchedulerSimple");
36 
37 namespace ns3 {
38 NS_OBJECT_ENSURE_REGISTERED (UplinkSchedulerSimple);
39 
41 {
42  SetBs (0);
43  SetTimeStampIrInterval (Seconds (0));
45  SetIsIrIntrvlAllocated (false);
49 }
50 
52 {
53  SetBs (bs);
54  SetTimeStampIrInterval (Seconds (0));
56  SetIsIrIntrvlAllocated (false);
60 }
61 
63 {
64  SetBs (0);
65  m_uplinkAllocations.clear ();
66 }
67 
68 void
70 {
71 
72 }
73 
74 TypeId
76 {
77  static TypeId tid = TypeId ("ns3::UplinkSchedulerSimple").SetParent<Object> ();
78  return tid;
79 }
80 
81 std::list<OfdmUlMapIe>
83 {
84  return m_uplinkAllocations;
85 }
86 
87 void
89  bool &updateUcd,
90  bool &sendDcd,
91  bool &sendUcd)
92 {
93  /*DCD and UCD shall actually be updated when channel or burst profile definitions
94  change. burst profiles are updated based on number of SSs, network conditions and etc.
95  for now temporarily assuming DCD/UCD shall be updated everytime */
96 
97  uint32_t randNr = rand ();
98  if (randNr % 5 == 0 || GetBs ()->GetNrDcdSent () == 0)
99  {
100  sendDcd = true;
101  }
102 
103  randNr = rand ();
104  if (randNr % 5 == 0 || GetBs ()->GetNrUcdSent () == 0)
105  {
106  sendUcd = true;
107  }
108 
109  // -------------------------------------
110  // additional, just to send more frequently
111  if (!sendDcd)
112  {
113  randNr = rand ();
114  if (randNr % 4 == 0)
115  {
116  sendDcd = true;
117  }
118  }
119 
120  if (!sendUcd)
121  {
122  randNr = rand ();
123  if (randNr % 4 == 0)
124  {
125  sendUcd = true;
126  }
127  }
128  // -------------------------------------
129 
130  Time timeSinceLastDcd = Simulator::Now () - GetDcdTimeStamp ();
131  Time timeSinceLastUcd = Simulator::Now () - GetUcdTimeStamp ();
132 
133  if (timeSinceLastDcd > GetBs ()->GetDcdInterval ())
134  {
135  sendDcd = true;
137  }
138 
139  if (timeSinceLastUcd > GetBs ()->GetUcdInterval ())
140  {
141  sendUcd = true;
143  }
144 }
145 
146 uint32_t
148 {
149  return GetBs ()->GetNrDlSymbols () * GetBs ()->GetPhy ()->GetPsPerSymbol () + GetBs ()->GetTtg ();
150 }
151 
152 void
154  const uint32_t &allocationSize,
155  uint32_t &symbolsToAllocation,
156  uint32_t &availableSymbols)
157 {
158  ulMapIe.SetDuration (allocationSize);
159  ulMapIe.SetStartTime (symbolsToAllocation);
160  m_uplinkAllocations.push_back (ulMapIe);
161  symbolsToAllocation += allocationSize;
162  availableSymbols -= allocationSize;
163 }
164 
165 void
167 {
168  m_uplinkAllocations.clear ();
169  SetIsIrIntrvlAllocated (false);
171  bool allocationForDsa = false;
172 
173  uint32_t symbolsToAllocation = 0;
174  uint32_t allocationSize = 0; // size in symbols
175  uint32_t availableSymbols = GetBs ()->GetNrUlSymbols ();
176 
177  AllocateInitialRangingInterval (symbolsToAllocation, availableSymbols);
178 
179  std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
180  for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
181  {
182  SSRecord *ssRecord = *iter;
183 
184  if (ssRecord->GetIsBroadcastSS ())
185  {
186  continue;
187  }
188  Cid cid = ssRecord->GetBasicCid ();
189  OfdmUlMapIe ulMapIe;
190  ulMapIe.SetCid (cid);
191 
193  {
194 
195  // SS's ranging is not yet complete
196  // allocating invited initial ranging interval
198  allocationSize = GetBs ()->GetRangReqOppSize ();
200 
201  if (availableSymbols >= allocationSize)
202  {
203  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
204  }
205  else
206  {
207 
208  break;
209  }
210  }
211  else
212  {
213  WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
214 
215  // need to update because modulation/FEC to UIUC mapping may vary over time
216  ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
218 
219  // establish service flows for SS
221  && !ssRecord->GetAreServiceFlowsAllocated ())
222  {
223 
224  // allocating grant (with arbitrary size) to allow SS to send DSA messages DSA-REQ and DSA-ACK
225  // only one DSA allocation per frame
226  if (!allocationForDsa)
227  {
228  allocationSize = GetBs ()->GetPhy ()->GetNrSymbols (sizeof(DsaReq), modulationType);
229 
230  if (availableSymbols >= allocationSize)
231  {
232  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
233  allocationForDsa = true;
234  }
235  else
236  {
237  break;
238  }
239  }
240  }
241  else
242  {
243  // all service flows associated to SS are established now
244 
245  /*allocating grants for data transmission for UGS flows (Data Grant Burst Type IEs, 6.3.7.4.3.3)
246  (grant has been referred by different names e.g. transmission opportunity, slot, uplink allocation, etc)*/
247  ServiceUnsolicitedGrants (ssRecord,
249  ulMapIe,
250  modulationType,
251  symbolsToAllocation,
252  availableSymbols);
253 
254  // allocate unicast polls for rtPS flows if bandwidth is available
255  if (availableSymbols)
256  {
257  ServiceUnsolicitedGrants (ssRecord,
259  ulMapIe,
260  modulationType,
261  symbolsToAllocation,
262  availableSymbols);
263  }
264  // allocate unicast polls for nrtPS flows if bandwidth is available
265  if (availableSymbols)
266  {
267  ServiceUnsolicitedGrants (ssRecord,
269  ulMapIe,
270  modulationType,
271  symbolsToAllocation,
272  availableSymbols);
273  }
274  // finally allocate unicast polls for BE flows if bandwidth is available
275  if (availableSymbols)
276  {
277  ServiceUnsolicitedGrants (ssRecord,
279  ulMapIe,
280  modulationType,
281  symbolsToAllocation,
282  availableSymbols);
283  }
284 
285  // now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
286 
287  if (availableSymbols)
288  {
289  ServiceBandwidthRequests (ssRecord,
291  ulMapIe,
292  modulationType,
293  symbolsToAllocation,
294  availableSymbols);
295  }
296  // allocate unicast polls for nrtPS flows if bandwidth is available
297  if (availableSymbols)
298  {
299  ServiceBandwidthRequests (ssRecord,
301  ulMapIe,
302  modulationType,
303  symbolsToAllocation,
304  availableSymbols);
305  }
306  // finally allocate unicast polls for BE flows if bandwidth is available
307  if (availableSymbols)
308  {
309  ServiceBandwidthRequests (ssRecord,
311  ulMapIe,
312  modulationType,
313  symbolsToAllocation,
314  availableSymbols);
315  }
316  }
317  }
318  }
319  OfdmUlMapIe ulMapIeEnd;
320 
321  ulMapIeEnd.SetCid (Cid::InitialRanging ());
322  ulMapIeEnd.SetStartTime (symbolsToAllocation);
324  ulMapIeEnd.SetDuration (0);
325  m_uplinkAllocations.push_back (ulMapIeEnd);
326 
327  // setting DL/UL subframe allocation for the next frame
328  GetBs ()->GetBandwidthManager ()->SetSubframeRatio ();
329 }
330 
331 void
333  enum ServiceFlow::SchedulingType schedulingType,
334  OfdmUlMapIe &ulMapIe,
335  const WimaxPhy::ModulationType modulationType,
336  uint32_t &symbolsToAllocation,
337  uint32_t &availableSymbols)
338 {
339  uint32_t allocationSize = 0; // size in symbols
340  uint8_t uiuc = ulMapIe.GetUiuc (); // SS's burst profile
341  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
342 
343  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
344  {
345  ServiceFlow *serviceFlow = *iter;
346 
347  /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request IEs, 6.3.7.4.3.1).
348  in case of UGS, allocating grants for data transmission (Data Grant Burst Type IEs, 6.3.7.4.3.3) (grant has
349  been referred in this code by different names e.g. transmission opportunity, slot, allocation, etc) */
350 
351  allocationSize = GetBs ()->GetBandwidthManager ()->CalculateAllocationSize (ssRecord, serviceFlow);
352  // verifying that minimum reserved traffic rate of nrtPS flow is maintained
353  if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_NRTPS)
354  {
355  Time currentTime = Simulator::Now ();
356  ServiceFlowRecord *record = serviceFlow->GetRecord ();
357  if (currentTime - record->GetGrantTimeStamp () > Seconds (1))
358  {
359  uint32_t bps = (record->GetBwSinceLastExpiry () * 8);
360  if (bps < serviceFlow->GetMinReservedTrafficRate ())
361  {
362  ServiceBandwidthRequests (serviceFlow,
363  schedulingType,
364  ulMapIe,
365  modulationType,
366  symbolsToAllocation,
367  availableSymbols);
368  record->SetBwSinceLastExpiry (0);
369  record->SetGrantTimeStamp (currentTime);
370  }
371  }
372  }
373 
374  if (availableSymbols < allocationSize)
375  {
376  break;
377  }
378 
379  if (allocationSize > 0)
380  {
381  ulMapIe.SetStartTime (symbolsToAllocation);
382  if (serviceFlow->GetSchedulingType () != ServiceFlow::SF_TYPE_UGS)
383  {
384  // special burst profile with most robust modulation type is used for unicast polls (Request IEs)
386  }
387  }
388  else
389  {
390  continue;
391  }
392 
393  NS_LOG_DEBUG (", CID: " << serviceFlow->GetConnection ()->GetCid () << ", SFID: " << serviceFlow->GetSfid ());
394 
395  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
396  ulMapIe.SetUiuc (uiuc);
397  }
398 }
399 
400 void
402  enum ServiceFlow::SchedulingType schedulingType,
403  OfdmUlMapIe &ulMapIe,
404  const WimaxPhy::ModulationType modulationType,
405  uint32_t &symbolsToAllocation,
406  uint32_t &availableSymbols)
407 {
408  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
409 
410  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
411  {
412  if (!ServiceBandwidthRequests (*iter,
413  schedulingType,
414  ulMapIe,
415  modulationType,
416  symbolsToAllocation,
417  availableSymbols))
418  {
419  break;
420  }
421  }
422 }
423 
424 bool
426  enum ServiceFlow::SchedulingType schedulingType,
427  OfdmUlMapIe &ulMapIe,
428  const WimaxPhy::ModulationType modulationType,
429  uint32_t &symbolsToAllocation,
430  uint32_t &availableSymbols)
431 {
432  uint32_t allocSizeBytes = 0;
433  uint32_t allocSizeSymbols = 0;
434  uint16_t sduSize = 0;
435 
436  ServiceFlowRecord *record = serviceFlow->GetRecord ();
437  sduSize = serviceFlow->GetSduSize ();
438 
439  uint32_t requiredBandwidth = record->GetRequestedBandwidth () - record->GetGrantedBandwidth ();
440  if (requiredBandwidth > 0)
441  {
442  if (sduSize > 0)
443  {
444  // if SDU size is mentioned, allocate grant of that size
445  allocSizeBytes = sduSize;
446  allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (sduSize, modulationType);
447  }
448  else
449  {
450  allocSizeBytes = requiredBandwidth;
451  allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (requiredBandwidth, modulationType);
452  }
453 
454  if (availableSymbols >= allocSizeSymbols)
455  {
456  record->UpdateGrantedBandwidth (allocSizeBytes);
457 
458  if (schedulingType == ServiceFlow::SF_TYPE_NRTPS)
459  {
460  record->SetBwSinceLastExpiry (allocSizeBytes);
461  }
462 
463  AddUplinkAllocation (ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
464  }
465  else
466  {
467  return false;
468  }
469  }
470  return true;
471 }
472 
473 void
474 UplinkSchedulerSimple::AllocateInitialRangingInterval (uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
475 {
476  Time ssUlStartTime = Seconds (CalculateAllocationStartTime () * GetBs ()->GetPsDuration ().GetSeconds ());
477  SetNrIrOppsAllocated (GetBs ()->GetLinkManager ()->CalculateRangingOppsToAllocate ());
478  uint32_t allocationSize = GetNrIrOppsAllocated () * GetBs ()->GetRangReqOppSize ();
479  Time timeSinceLastIrInterval = Simulator::Now () - GetTimeStampIrInterval ();
480 
481  // adding one frame because may be the time has not elapsed now but will elapse before the next frame is sent
482  if (timeSinceLastIrInterval + GetBs ()->GetPhy ()->GetFrameDuration () > GetBs ()->GetInitialRangingInterval ()
483  && availableSymbols >= allocationSize)
484  {
485  SetIsIrIntrvlAllocated (true);
486  OfdmUlMapIe ulMapIeIr;
487  ulMapIeIr.SetCid ((GetBs ()->GetBroadcastConnection ())->GetCid ());
488  ulMapIeIr.SetStartTime (symbolsToAllocation);
490 
491  NS_LOG_DEBUG ("BS uplink scheduler, initial ranging allocation, size: " << allocationSize << " symbols"
492  << ", modulation: BPSK 1/2");
493 
494  // marking start and end of each TO, only for debugging
495  for (uint8_t i = 0; i < GetNrIrOppsAllocated (); i++)
496  {
497  GetBs ()->MarkRangingOppStart (ssUlStartTime + Seconds (symbolsToAllocation
498  * GetBs ()->GetSymbolDuration ().GetSeconds ()) + Seconds (i * GetBs ()->GetRangReqOppSize ()
499  * GetBs ()->GetSymbolDuration ().GetSeconds ()));
500  }
501 
502  AddUplinkAllocation (ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
504  }
505 }
506 
507 void
509 {
510  uint8_t delayNrFrames = 1;
511  uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate ();
512  WimaxPhy::ModulationType modulation;
513  uint32_t bytesPerFrame =
514  (uint32_t ((double)(bitsPerSecond) * GetBs ()->GetPhy ()->GetFrameDuration ().GetSeconds ())) / 8;
515  uint32_t frameDurationMSec = GetBs ()->GetPhy ()->GetFrameDuration ().GetMilliSeconds ();
516 
517  switch (serviceFlow->GetSchedulingType ())
518  {
520  {
521  if (serviceFlow->GetIsMulticast () == true)
522  {
523  modulation = serviceFlow->GetModulation ();
524  }
525  else
526  {
527  modulation = ssRecord->GetModulationType ();
528  }
529  uint32_t grantSize = GetBs ()->GetPhy ()->GetNrSymbols (bytesPerFrame, modulation);
530  serviceFlow->GetRecord ()->SetGrantSize (grantSize);
531 
532  uint32_t toleratedJitter = serviceFlow->GetToleratedJitter ();
533 
534  if (toleratedJitter > frameDurationMSec)
535  {
536  delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
537  }
538 
539  uint16_t interval = delayNrFrames * frameDurationMSec;
540  serviceFlow->SetUnsolicitedGrantInterval (interval);
541  }
542  break;
544  {
545  if (serviceFlow->GetSduSize () > bytesPerFrame)
546  {
547  delayNrFrames = (uint8_t)(serviceFlow->GetSduSize () / bytesPerFrame);
548  }
549 
550  uint16_t interval = delayNrFrames * frameDurationMSec;
551  serviceFlow->SetUnsolicitedPollingInterval (interval);
552  }
553  break;
555  {
556  // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
557  }
558  break;
560  {
561  // no real-time guarantees are given to BE, serviced based on available bandwidth
562  }
563  break;
564  default:
565  NS_FATAL_ERROR ("Invalid scheduling type");
566  }
567 }
568 
569 void
571 {
572  // virtual function on UplinkScheduler
573  // this is not necessary on this implementation
574 }
575 
576 void
578 {
579  // m_grantedBandwidth must be reset to zero
580  uint32_t grantedBandwidth = 0;
581  sfr->SetGrantedBandwidth (grantedBandwidth);
582 }
583 
584 } // namespace ns3
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
enum WimaxPhy::ModulationType GetModulation(void) const
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
enum ServiceFlow::SchedulingType GetSchedulingType(void) const
void SetCid(Cid cid)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
Cid GetBasicCid(void) const
Definition: ss-record.cc:92
uint32_t GetRequestedBandwidth(void)
this class implements a structure to manage some parameters and statistics related to a service flow ...
bool GetAreServiceFlowsAllocated(void) const
Definition: ss-record.cc:206
void SetGrantedBandwidth(uint32_t grantedBandwidth)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
uint32_t GetSfid(void) const
WimaxNetDevice::RangingStatus GetRangingStatus(void) const
Definition: ss-record.cc:176
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
Ptr< WimaxConnection > GetConnection(void) const
uint32_t GetMinReservedTrafficRate(void) const
Time GetGrantTimeStamp(void) const
uint32_t GetBwSinceLastExpiry(void)
static Cid InitialRanging(void)
Definition: cid.cc:82
void SetGrantTimeStamp(Time grantTimeStamp)
Set the grant time stamp.
void SetUnsolicitedPollingInterval(uint16_t)
void SetDuration(uint16_t duration)
void SetGrantSize(uint32_t grantSize)
Set the grant size (only for UGS service flows)
void SetUnsolicitedGrantInterval(uint16_t)
std::vector< ServiceFlow * > GetServiceFlows(enum ServiceFlow::SchedulingType schedulingType) const
Definition: ss-record.cc:229
uint8_t GetUiuc(void) const
this class implements the bandwidth-request mac Header as described by IEEE Standard for Local and me...
Definition: cid.h:35
uint8_t GetSduSize(void) const
This class implements service flows as described by the IEEE-802.16 standard.
Definition: service-flow.h:39
void SetStartTime(uint16_t startTime)
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
ServiceFlowRecord * GetRecord(void) const
bool GetPollForRanging(void) const
Definition: ss-record.cc:194
bool GetIsBroadcastSS(void)
Definition: ss-record.cc:249
uint32_t GetToleratedJitter(void) const
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
bool GetIsMulticast(void) const
void SetBwSinceLastExpiry(uint32_t bwSinceLastExpiry)
This class is used by the base station to store some information related to subscriber station in the...
Definition: ss-record.h:43
a base class which provides memory management and object aggregation
Definition: object.h:64
void UpdateGrantedBandwidth(uint32_t grantedBandwidth)
uint32_t GetGrantedBandwidth(void)
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:262
a unique identifier for an interface.
Definition: type-id.h:49
void SetUiuc(uint8_t uiuc)
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
WimaxPhy::ModulationType GetModulationType(void) const
Definition: ss-record.cc:164