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  ;
40 
42 {
43  SetBs (0);
44  SetTimeStampIrInterval (Seconds (0));
46  SetIsIrIntrvlAllocated (false);
50 }
51 
53 {
54  SetBs (bs);
55  SetTimeStampIrInterval (Seconds (0));
57  SetIsIrIntrvlAllocated (false);
61 }
62 
64 {
65  SetBs (0);
66  m_uplinkAllocations.clear ();
67 }
68 
69 void
71 {
72 
73 }
74 
75 TypeId
77 {
78  static TypeId tid = TypeId ("ns3::UplinkSchedulerSimple").SetParent<Object> ();
79  return tid;
80 }
81 
82 std::list<OfdmUlMapIe>
84 {
85  return m_uplinkAllocations;
86 }
87 
88 void
90  bool &updateUcd,
91  bool &sendDcd,
92  bool &sendUcd)
93 {
94  /*DCD and UCD shall actually be updated when channel or burst profile definitions
95  change. burst profiles are updated based on number of SSs, network conditions and etc.
96  for now temporarily assuming DCD/UCD shall be updated everytime */
97 
98  uint32_t randNr = rand ();
99  if (randNr % 5 == 0 || GetBs ()->GetNrDcdSent () == 0)
100  {
101  sendDcd = true;
102  }
103 
104  randNr = rand ();
105  if (randNr % 5 == 0 || GetBs ()->GetNrUcdSent () == 0)
106  {
107  sendUcd = true;
108  }
109 
110  // -------------------------------------
111  // additional, just to send more frequently
112  if (!sendDcd)
113  {
114  randNr = rand ();
115  if (randNr % 4 == 0)
116  {
117  sendDcd = true;
118  }
119  }
120 
121  if (!sendUcd)
122  {
123  randNr = rand ();
124  if (randNr % 4 == 0)
125  {
126  sendUcd = true;
127  }
128  }
129  // -------------------------------------
130 
131  Time timeSinceLastDcd = Simulator::Now () - GetDcdTimeStamp ();
132  Time timeSinceLastUcd = Simulator::Now () - GetUcdTimeStamp ();
133 
134  if (timeSinceLastDcd > GetBs ()->GetDcdInterval ())
135  {
136  sendDcd = true;
138  }
139 
140  if (timeSinceLastUcd > GetBs ()->GetUcdInterval ())
141  {
142  sendUcd = true;
144  }
145 }
146 
147 uint32_t
149 {
150  return GetBs ()->GetNrDlSymbols () * GetBs ()->GetPhy ()->GetPsPerSymbol () + GetBs ()->GetTtg ();
151 }
152 
153 void
155  const uint32_t &allocationSize,
156  uint32_t &symbolsToAllocation,
157  uint32_t &availableSymbols)
158 {
159  ulMapIe.SetDuration (allocationSize);
160  ulMapIe.SetStartTime (symbolsToAllocation);
161  m_uplinkAllocations.push_back (ulMapIe);
162  symbolsToAllocation += allocationSize;
163  availableSymbols -= allocationSize;
164 }
165 
166 void
168 {
169  m_uplinkAllocations.clear ();
170  SetIsIrIntrvlAllocated (false);
172  bool allocationForDsa = false;
173 
174  uint32_t symbolsToAllocation = 0;
175  uint32_t allocationSize = 0; // size in symbols
176  uint32_t availableSymbols = GetBs ()->GetNrUlSymbols ();
177 
178  AllocateInitialRangingInterval (symbolsToAllocation, availableSymbols);
179 
180  std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
181  for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
182  {
183  SSRecord *ssRecord = *iter;
184 
185  if (ssRecord->GetIsBroadcastSS ())
186  {
187  continue;
188  }
189  Cid cid = ssRecord->GetBasicCid ();
190  OfdmUlMapIe ulMapIe;
191  ulMapIe.SetCid (cid);
192 
194  {
195 
196  // SS's ranging is not yet complete
197  // allocating invited initial ranging interval
199  allocationSize = GetBs ()->GetRangReqOppSize ();
201 
202  if (availableSymbols >= allocationSize)
203  {
204  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
205  }
206  else
207  {
208 
209  break;
210  }
211  }
212  else
213  {
214  WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
215 
216  // need to update because modulation/FEC to UIUC mapping may vary over time
217  ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
219 
220  // establish service flows for SS
222  && !ssRecord->GetAreServiceFlowsAllocated ())
223  {
224 
225  // allocating grant (with arbitrary size) to allow SS to send DSA messages DSA-REQ and DSA-ACK
226  // only one DSA allocation per frame
227  if (!allocationForDsa)
228  {
229  allocationSize = GetBs ()->GetPhy ()->GetNrSymbols (sizeof(DsaReq), modulationType);
230 
231  if (availableSymbols >= allocationSize)
232  {
233  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
234  allocationForDsa = true;
235  }
236  else
237  {
238  break;
239  }
240  }
241  }
242  else
243  {
244  // all service flows associated to SS are established now
245 
246  /*allocating grants for data transmission for UGS flows (Data Grant Burst Type IEs, 6.3.7.4.3.3)
247  (grant has been referred by different names e.g. transmission opportunity, slot, uplink allocation, etc)*/
248  ServiceUnsolicitedGrants (ssRecord,
250  ulMapIe,
251  modulationType,
252  symbolsToAllocation,
253  availableSymbols);
254 
255  // allocate unicast polls for rtPS flows if bandwidth is available
256  if (availableSymbols)
257  {
258  ServiceUnsolicitedGrants (ssRecord,
260  ulMapIe,
261  modulationType,
262  symbolsToAllocation,
263  availableSymbols);
264  }
265  // allocate unicast polls for nrtPS flows if bandwidth is available
266  if (availableSymbols)
267  {
268  ServiceUnsolicitedGrants (ssRecord,
270  ulMapIe,
271  modulationType,
272  symbolsToAllocation,
273  availableSymbols);
274  }
275  // finally allocate unicast polls for BE flows if bandwidth is available
276  if (availableSymbols)
277  {
278  ServiceUnsolicitedGrants (ssRecord,
280  ulMapIe,
281  modulationType,
282  symbolsToAllocation,
283  availableSymbols);
284  }
285 
286  // now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
287 
288  if (availableSymbols)
289  {
290  ServiceBandwidthRequests (ssRecord,
292  ulMapIe,
293  modulationType,
294  symbolsToAllocation,
295  availableSymbols);
296  }
297  // allocate unicast polls for nrtPS flows if bandwidth is available
298  if (availableSymbols)
299  {
300  ServiceBandwidthRequests (ssRecord,
302  ulMapIe,
303  modulationType,
304  symbolsToAllocation,
305  availableSymbols);
306  }
307  // finally allocate unicast polls for BE flows if bandwidth is available
308  if (availableSymbols)
309  {
310  ServiceBandwidthRequests (ssRecord,
312  ulMapIe,
313  modulationType,
314  symbolsToAllocation,
315  availableSymbols);
316  }
317  }
318  }
319  }
320  OfdmUlMapIe ulMapIeEnd;
321 
322  ulMapIeEnd.SetCid (Cid::InitialRanging ());
323  ulMapIeEnd.SetStartTime (symbolsToAllocation);
325  ulMapIeEnd.SetDuration (0);
326  m_uplinkAllocations.push_back (ulMapIeEnd);
327 
328  // setting DL/UL subframe allocation for the next frame
329  GetBs ()->GetBandwidthManager ()->SetSubframeRatio ();
330 }
331 
332 void
334  enum ServiceFlow::SchedulingType schedulingType,
335  OfdmUlMapIe &ulMapIe,
336  const WimaxPhy::ModulationType modulationType,
337  uint32_t &symbolsToAllocation,
338  uint32_t &availableSymbols)
339 {
340  uint32_t allocationSize = 0; // size in symbols
341  uint8_t uiuc = ulMapIe.GetUiuc (); // SS's burst profile
342  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
343 
344  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
345  {
346  ServiceFlow *serviceFlow = *iter;
347 
348  /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request IEs, 6.3.7.4.3.1).
349  in case of UGS, allocating grants for data transmission (Data Grant Burst Type IEs, 6.3.7.4.3.3) (grant has
350  been referred in this code by different names e.g. transmission opportunity, slot, allocation, etc) */
351 
352  allocationSize = GetBs ()->GetBandwidthManager ()->CalculateAllocationSize (ssRecord, serviceFlow);
353  // verifying that minimum reserved traffic rate of nrtPS flow is maintained
354  if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_NRTPS)
355  {
356  Time currentTime = Simulator::Now ();
357  ServiceFlowRecord *record = serviceFlow->GetRecord ();
358  if (currentTime - record->GetGrantTimeStamp () > Seconds (1))
359  {
360  uint32_t bps = (record->GetBwSinceLastExpiry () * 8);
361  if (bps < serviceFlow->GetMinReservedTrafficRate ())
362  {
363  ServiceBandwidthRequests (serviceFlow,
364  schedulingType,
365  ulMapIe,
366  modulationType,
367  symbolsToAllocation,
368  availableSymbols);
369  record->SetBwSinceLastExpiry (0);
370  record->SetGrantTimeStamp (currentTime);
371  }
372  }
373  }
374 
375  if (availableSymbols < allocationSize)
376  {
377  break;
378  }
379 
380  if (allocationSize > 0)
381  {
382  ulMapIe.SetStartTime (symbolsToAllocation);
383  if (serviceFlow->GetSchedulingType () != ServiceFlow::SF_TYPE_UGS)
384  {
385  // special burst profile with most robust modulation type is used for unicast polls (Request IEs)
387  }
388  }
389  else
390  {
391  continue;
392  }
393 
394  NS_LOG_DEBUG (", CID: " << serviceFlow->GetConnection ()->GetCid () << ", SFID: " << serviceFlow->GetSfid ());
395 
396  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
397  ulMapIe.SetUiuc (uiuc);
398  }
399 }
400 
401 void
403  enum ServiceFlow::SchedulingType schedulingType,
404  OfdmUlMapIe &ulMapIe,
405  const WimaxPhy::ModulationType modulationType,
406  uint32_t &symbolsToAllocation,
407  uint32_t &availableSymbols)
408 {
409  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
410 
411  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
412  {
413  if (!ServiceBandwidthRequests (*iter,
414  schedulingType,
415  ulMapIe,
416  modulationType,
417  symbolsToAllocation,
418  availableSymbols))
419  {
420  break;
421  }
422  }
423 }
424 
425 bool
427  enum ServiceFlow::SchedulingType schedulingType,
428  OfdmUlMapIe &ulMapIe,
429  const WimaxPhy::ModulationType modulationType,
430  uint32_t &symbolsToAllocation,
431  uint32_t &availableSymbols)
432 {
433  uint32_t allocSizeBytes = 0;
434  uint32_t allocSizeSymbols = 0;
435  uint16_t sduSize = 0;
436 
437  ServiceFlowRecord *record = serviceFlow->GetRecord ();
438  sduSize = serviceFlow->GetSduSize ();
439 
440  uint32_t requiredBandwidth = record->GetRequestedBandwidth () - record->GetGrantedBandwidth ();
441  if (requiredBandwidth > 0)
442  {
443  if (sduSize > 0)
444  {
445  // if SDU size is mentioned, allocate grant of that size
446  allocSizeBytes = sduSize;
447  allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (sduSize, modulationType);
448  }
449  else
450  {
451  allocSizeBytes = requiredBandwidth;
452  allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (requiredBandwidth, modulationType);
453  }
454 
455  if (availableSymbols >= allocSizeSymbols)
456  {
457  record->UpdateGrantedBandwidth (allocSizeBytes);
458 
459  if (schedulingType == ServiceFlow::SF_TYPE_NRTPS)
460  {
461  record->SetBwSinceLastExpiry (allocSizeBytes);
462  }
463 
464  AddUplinkAllocation (ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
465  }
466  else
467  {
468  return false;
469  }
470  }
471  return true;
472 }
473 
474 void
475 UplinkSchedulerSimple::AllocateInitialRangingInterval (uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
476 {
477  Time ssUlStartTime = Seconds (CalculateAllocationStartTime () * GetBs ()->GetPsDuration ().GetSeconds ());
478  SetNrIrOppsAllocated (GetBs ()->GetLinkManager ()->CalculateRangingOppsToAllocate ());
479  uint32_t allocationSize = GetNrIrOppsAllocated () * GetBs ()->GetRangReqOppSize ();
480  Time timeSinceLastIrInterval = Simulator::Now () - GetTimeStampIrInterval ();
481 
482  // adding one frame because may be the time has not elapsed now but will elapse before the next frame is sent
483  if (timeSinceLastIrInterval + GetBs ()->GetPhy ()->GetFrameDuration () > GetBs ()->GetInitialRangingInterval ()
484  && availableSymbols >= allocationSize)
485  {
486  SetIsIrIntrvlAllocated (true);
487  OfdmUlMapIe ulMapIeIr;
488  ulMapIeIr.SetCid ((GetBs ()->GetBroadcastConnection ())->GetCid ());
489  ulMapIeIr.SetStartTime (symbolsToAllocation);
491 
492  NS_LOG_DEBUG ("BS uplink scheduler, initial ranging allocation, size: " << allocationSize << " symbols"
493  << ", modulation: BPSK 1/2");
494 
495  // marking start and end of each TO, only for debugging
496  for (uint8_t i = 0; i < GetNrIrOppsAllocated (); i++)
497  {
498  GetBs ()->MarkRangingOppStart (ssUlStartTime + Seconds (symbolsToAllocation
499  * GetBs ()->GetSymbolDuration ().GetSeconds ()) + Seconds (i * GetBs ()->GetRangReqOppSize ()
500  * GetBs ()->GetSymbolDuration ().GetSeconds ()));
501  }
502 
503  AddUplinkAllocation (ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
505  }
506 }
507 
508 void
510 {
511  uint8_t delayNrFrames = 1;
512  uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate ();
513  WimaxPhy::ModulationType modulation;
514  uint32_t bytesPerFrame =
515  (uint32_t ((double)(bitsPerSecond) * GetBs ()->GetPhy ()->GetFrameDuration ().GetSeconds ())) / 8;
516  uint32_t frameDurationMSec = GetBs ()->GetPhy ()->GetFrameDuration ().GetMilliSeconds ();
517 
518  switch (serviceFlow->GetSchedulingType ())
519  {
521  {
522  if (serviceFlow->GetIsMulticast () == true)
523  {
524  modulation = serviceFlow->GetModulation ();
525  }
526  else
527  {
528  modulation = ssRecord->GetModulationType ();
529  }
530  uint32_t grantSize = GetBs ()->GetPhy ()->GetNrSymbols (bytesPerFrame, modulation);
531  serviceFlow->GetRecord ()->SetGrantSize (grantSize);
532 
533  uint32_t toleratedJitter = serviceFlow->GetToleratedJitter ();
534 
535  if (toleratedJitter > frameDurationMSec)
536  {
537  delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
538  }
539 
540  uint16_t interval = delayNrFrames * frameDurationMSec;
541  serviceFlow->SetUnsolicitedGrantInterval (interval);
542  }
543  break;
545  {
546  if (serviceFlow->GetSduSize () > bytesPerFrame)
547  {
548  delayNrFrames = (uint8_t)(serviceFlow->GetSduSize () / bytesPerFrame);
549  }
550 
551  uint16_t interval = delayNrFrames * frameDurationMSec;
552  serviceFlow->SetUnsolicitedPollingInterval (interval);
553  }
554  break;
556  {
557  // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
558  }
559  break;
561  {
562  // no real-time guarantees are given to BE, serviced based on available bandwidth
563  }
564  break;
565  default:
566  NS_FATAL_ERROR ("Invalid scheduling type");
567  }
568 }
569 
570 void
572 {
573  // virtual function on UplinkScheduler
574  // this is not necessary on this implementation
575 }
576 
577 void
579 {
580  // m_grantedBandwidth must be reset to zero
581  uint32_t grantedBandwidth = 0;
582  sfr->SetGrantedBandwidth (grantedBandwidth);
583 }
584 
585 } // namespace ns3
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
enum WimaxPhy::ModulationType GetModulation(void) const
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
enum ServiceFlow::SchedulingType GetSchedulingType(void) const
void SetCid(Cid cid)
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)
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
uint32_t GetSfid(void) const
WimaxNetDevice::RangingStatus GetRangingStatus(void) const
Definition: ss-record.cc:176
Ptr< WimaxConnection > GetConnection(void) const
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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)
Definition: log.h:289
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:63
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:611
WimaxPhy::ModulationType GetModulationType(void) const
Definition: ss-record.cc:164