A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
bs-uplink-scheduler-rtps.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007,2008 INRIA
4  * 2009 TELEMATICS LAB, Politecnico di Bari
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Giuseppe Piro <g.piro@poliba.it>
20  */
21 
22 #include "bs-uplink-scheduler-rtps.h"
23 #include "bs-net-device.h"
24 #include "ns3/simulator.h"
25 #include "cid.h"
26 #include "burst-profile-manager.h"
27 #include "ss-manager.h"
28 #include "ns3/log.h"
29 #include "ns3/uinteger.h"
30 #include "ss-record.h"
31 #include "service-flow.h"
32 #include "service-flow-record.h"
33 #include "bs-link-manager.h"
34 #include "bandwidth-manager.h"
35 
36 NS_LOG_COMPONENT_DEFINE ("UplinkSchedulerRtps");
37 
38 namespace ns3 {
39 NS_OBJECT_ENSURE_REGISTERED ( UplinkSchedulerRtps);
40 
41 UplinkSchedulerRtps::UplinkSchedulerRtps ()
42 {
43  SetBs (0);
44  SetTimeStampIrInterval (Seconds (0));
45  SetNrIrOppsAllocated (0);
46  SetIsIrIntrvlAllocated (false);
47  SetIsInvIrIntrvlAllocated (false);
48  SetDcdTimeStamp (Simulator::Now ());
49  SetUcdTimeStamp (Simulator::Now ());
50 }
51 
52 UplinkSchedulerRtps::UplinkSchedulerRtps (Ptr<BaseStationNetDevice> bs)
53 {
54  SetBs (bs);
55  SetTimeStampIrInterval (Seconds (0));
56  SetNrIrOppsAllocated (0);
57  SetIsIrIntrvlAllocated (false);
58  SetIsInvIrIntrvlAllocated (false);
59  SetDcdTimeStamp (Simulator::Now ());
60  SetUcdTimeStamp (Simulator::Now ());
61 }
62 
63 UplinkSchedulerRtps::~UplinkSchedulerRtps (void)
64 {
65  SetBs (0);
66  m_uplinkAllocations.clear ();
67 }
68 
69 TypeId
70 UplinkSchedulerRtps::GetTypeId (void)
71 {
72  static TypeId tid = TypeId ("ns3::UplinkSchedulerRtps").SetParent<UplinkScheduler> ();
73  return tid;
74 }
75 
76 std::list<OfdmUlMapIe>
77 UplinkSchedulerRtps::GetUplinkAllocations (void) const
78 {
79  return m_uplinkAllocations;
80 }
81 
82 void
83 UplinkSchedulerRtps::GetChannelDescriptorsToUpdate (bool &updateDcd, bool &updateUcd, bool &sendDcd, bool &sendUcd)
84 {
85  /*DCD and UCD shall actually be updated when channel or burst profile definitions
86  change. burst profiles are updated based on number of SSs, network conditions and etc.
87  for now temporarily assuming DCD/UCD shall be updated everytime */
88 
89  uint32_t randNr = rand ();
90  if (randNr % 5 == 0 || GetBs ()->GetNrDcdSent () == 0)
91  {
92  sendDcd = true;
93  }
94 
95  randNr = rand ();
96  if (randNr % 5 == 0 || GetBs ()->GetNrUcdSent () == 0)
97  {
98  sendUcd = true;
99  }
100 
101  // -------------------------------------
102  // additional, just to send more frequently
103  if (!sendDcd)
104  {
105  randNr = rand ();
106  if (randNr % 4 == 0)
107  {
108  sendDcd = true;
109  }
110  }
111 
112  if (!sendUcd)
113  {
114  randNr = rand ();
115  if (randNr % 4 == 0)
116  {
117  sendUcd = true;
118  }
119  }
120  // -------------------------------------
121 
122  Time timeSinceLastDcd = Simulator::Now () - GetDcdTimeStamp ();
123  Time timeSinceLastUcd = Simulator::Now () - GetUcdTimeStamp ();
124 
125  if (timeSinceLastDcd > GetBs ()->GetDcdInterval ())
126  {
127  sendDcd = true;
128  SetDcdTimeStamp (Simulator::Now ());
129  }
130 
131  if (timeSinceLastUcd > GetBs ()->GetUcdInterval ())
132  {
133  sendUcd = true;
134  SetUcdTimeStamp (Simulator::Now ());
135  }
136 }
137 
138 uint32_t
139 UplinkSchedulerRtps::CalculateAllocationStartTime (void)
140 {
141  return GetBs ()->GetNrDlSymbols () * GetBs ()->GetPhy ()->GetPsPerSymbol () + GetBs ()->GetTtg ();
142 }
143 
144 void
145 UplinkSchedulerRtps::AddUplinkAllocation (OfdmUlMapIe &ulMapIe,
146  const uint32_t &allocationSize,
147  uint32_t &symbolsToAllocation,
148  uint32_t &availableSymbols)
149 {
150  ulMapIe.SetDuration (allocationSize);
151  ulMapIe.SetStartTime (symbolsToAllocation);
152  m_uplinkAllocations.push_back (ulMapIe);
153  symbolsToAllocation += allocationSize;
154  availableSymbols -= allocationSize;
155 }
156 
157 void
159 {
160  m_uplinkAllocations.clear ();
161  SetIsIrIntrvlAllocated (false);
162  SetIsInvIrIntrvlAllocated (false);
163  bool allocationForDsa = false;
164 
165  uint32_t symbolsToAllocation = 0;
166  uint32_t allocationSize = 0; // size in symbols
167  uint32_t availableSymbols = GetBs ()->GetNrUlSymbols ();
168 
169  WimaxPhy::ModulationType modulationType;
170  Cid cid;
171 
172  AllocateInitialRangingInterval (symbolsToAllocation, availableSymbols);
173 
174  std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
175  NS_LOG_INFO ("UL Scheduler start, availableSymbols = " << availableSymbols);
176 
177  for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
178  {
179  SSRecord *ssRecord = *iter;
180  if (ssRecord->GetIsBroadcastSS ())
181  {
182  continue;
183  }
184  cid = ssRecord->GetBasicCid ();
185  OfdmUlMapIe ulMapIe;
186  ulMapIe.SetCid (cid);
187 
188  if (ssRecord->GetPollForRanging () && ssRecord->GetRangingStatus () == WimaxNetDevice::RANGING_STATUS_CONTINUE)
189  {
190  // SS's ranging is not yet complete
191  // allocating invited initial ranging interval
192  ulMapIe.SetUiuc (OfdmUlBurstProfile::UIUC_INITIAL_RANGING);
193  allocationSize = GetBs ()->GetRangReqOppSize ();
194  SetIsInvIrIntrvlAllocated (true);
195 
196  if (availableSymbols >= allocationSize)
197  {
198  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
199  }
200  else
201  {
202  break;
203  }
204  }
205  else
206  {
207  modulationType = ssRecord->GetModulationType ();
208 
209  // need to update because modulation/FEC to UIUC mapping may vary over time
210  ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
211  WimaxNetDevice::DIRECTION_UPLINK));
212 
213  // establish service flows for SS
214  if (ssRecord->GetRangingStatus () == WimaxNetDevice::RANGING_STATUS_SUCCESS
215  && !ssRecord->GetAreServiceFlowsAllocated ())
216  {
217  // allocating grant (with arbitrary size) to allow SS to send DSA messages DSA-REQ and DSA-ACK
218  // only one DSA allocation per frame
219  if (!allocationForDsa)
220  {
221  allocationSize = GetBs ()->GetPhy ()->GetNrSymbols (sizeof(DsaReq), modulationType);
222  if (availableSymbols >= allocationSize)
223  {
224  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
225  allocationForDsa = true;
226  }
227  else
228  {
229  break;
230  }
231  }
232  }
233  else
234  {
235  // all service flows associated to SS are established now
236 
237  /*allocating grants for data transmission for UGS flows (Data Grant Burst Type IEs, 6.3.7.4.3.3)
238  (grant has been referred by different names e.g. transmission opportunity, slot, uplink allocation, etc)*/
239  ServiceUnsolicitedGrants (ssRecord,
240  ServiceFlow::SF_TYPE_UGS,
241  ulMapIe,
242  modulationType,
243  symbolsToAllocation,
244  availableSymbols);
245 
246  // allocate unicast polls for rtPS flows if bandwidth is available
247  if (availableSymbols)
248  {
249  ServiceUnsolicitedGrants (ssRecord,
250  ServiceFlow::SF_TYPE_RTPS,
251  ulMapIe,
252  modulationType,
253  symbolsToAllocation,
254  availableSymbols);
255  }
256  // allocate unicast polls for nrtPS flows if bandwidth is available
257  if (availableSymbols)
258  {
259  ServiceUnsolicitedGrants (ssRecord,
260  ServiceFlow::SF_TYPE_NRTPS,
261  ulMapIe,
262  modulationType,
263  symbolsToAllocation,
264  availableSymbols);
265  }
266  // finally allocate unicast polls for BE flows if bandwidth is available
267  if (availableSymbols)
268  {
269  ServiceUnsolicitedGrants (ssRecord,
270  ServiceFlow::SF_TYPE_BE,
271  ulMapIe,
272  modulationType,
273  symbolsToAllocation,
274  availableSymbols);
275  }
276  }
277  }
278  }
279 
280  /*
281  * Uplink Scheduler for rtPS Connection
282  */
283  if (availableSymbols)
284  {
285  ULSchedulerRTPSConnection (symbolsToAllocation, availableSymbols);
286  }
287 
288  // UL Scheduler for nrtPS and BE flows
289  if (availableSymbols)
290  {
291  for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
292  {
293  SSRecord *ssRecord = *iter;
294  if (ssRecord->GetIsBroadcastSS ())
295  {
296  continue;
297  }
298  if (!ssRecord->GetPollForRanging () && ssRecord->GetRangingStatus ()
299  != WimaxNetDevice::RANGING_STATUS_CONTINUE && ssRecord->GetAreServiceFlowsAllocated ())
300  {
301  OfdmUlMapIe ulMapIe;
302  cid = ssRecord->GetBasicCid ();
303  ulMapIe.SetCid (cid);
304  modulationType = ssRecord->GetModulationType ();
305  ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
306  WimaxNetDevice::DIRECTION_UPLINK));
307 
308  // allocate unicast polls for nrtPS flows if bandwidth is available
309  if (availableSymbols)
310  {
311  ServiceBandwidthRequests (ssRecord,
312  ServiceFlow::SF_TYPE_NRTPS,
313  ulMapIe,
314  modulationType,
315  symbolsToAllocation,
316  availableSymbols);
317  }
318  // finally allocate unicast polls for BE flows if bandwidth is available
319  if (availableSymbols)
320  {
321  ServiceBandwidthRequests (ssRecord,
322  ServiceFlow::SF_TYPE_BE,
323  ulMapIe,
324  modulationType,
325  symbolsToAllocation,
326  availableSymbols);
327  }
328  }
329  }
330  }
331 
332  OfdmUlMapIe ulMapIeEnd;
333  ulMapIeEnd.SetCid (Cid::InitialRanging ());
334  ulMapIeEnd.SetStartTime (symbolsToAllocation);
335  ulMapIeEnd.SetUiuc (OfdmUlBurstProfile::UIUC_END_OF_MAP);
336  ulMapIeEnd.SetDuration (0);
337  m_uplinkAllocations.push_back (ulMapIeEnd);
338 
339  // setting DL/UL subframe allocation for the next frame
340  GetBs ()->GetBandwidthManager ()->SetSubframeRatio ();
341 }
342 
343 void
344 UplinkSchedulerRtps::ServiceUnsolicitedGrants (const SSRecord *ssRecord,
345  enum ServiceFlow::SchedulingType schedulingType,
346  OfdmUlMapIe &ulMapIe,
347  const WimaxPhy::ModulationType modulationType,
348  uint32_t &symbolsToAllocation,
349  uint32_t &availableSymbols)
350 {
351  uint32_t allocationSize = 0; // size in symbols
352  uint8_t uiuc = ulMapIe.GetUiuc (); // SS's burst profile
353  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
354 
355  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
356  {
357  ServiceFlow *serviceFlow = *iter;
358 
359  /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request IEs, 6.3.7.4.3.1).
360  in case of UGS, allocating grants for data transmission (Data Grant Burst Type IEs, 6.3.7.4.3.3) (grant has
361  been referred in this code by different names e.g. transmission opportunity, slot, allocation, etc) */
362 
363  allocationSize = GetBs ()->GetBandwidthManager ()->CalculateAllocationSize (ssRecord, serviceFlow);
364 
365  // verifying that minimum reserved traffic rate of nrtPS flow is maintained
366  if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_NRTPS)
367  {
368  Time currentTime = Simulator::Now ();
369  ServiceFlowRecord *record = serviceFlow->GetRecord ();
370  if (currentTime - record->GetGrantTimeStamp () > Seconds (1))
371  {
372  uint32_t bps = (record->GetBwSinceLastExpiry () * 8);
373  if (bps < serviceFlow->GetMinReservedTrafficRate ())
374  {
375  ServiceBandwidthRequests (serviceFlow,
376  schedulingType,
377  ulMapIe,
378  modulationType,
379  symbolsToAllocation,
380  availableSymbols);
381  record->SetBwSinceLastExpiry (0);
382  record->SetGrantTimeStamp (currentTime);
383  }
384  }
385  }
386 
387  if (availableSymbols < allocationSize)
388  {
389  break;
390  }
391 
392  if (allocationSize > 0)
393  {
394  ulMapIe.SetStartTime (symbolsToAllocation);
395  if (serviceFlow->GetSchedulingType () != ServiceFlow::SF_TYPE_UGS)
396  {
397  // special burst profile with most robust modulation type is used for unicast polls (Request IEs)
398  ulMapIe.SetUiuc (OfdmUlBurstProfile::UIUC_REQ_REGION_FULL);
399  }
400  }
401  else
402  {
403  continue;
404  }
405 
406  if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_UGS)
407  {
408  NS_LOG_DEBUG ("BS uplink scheduler, UGS allocation, size: " << allocationSize << " symbols");
409  }
410  else
411  {
412  NS_LOG_DEBUG ("BS uplink scheduler, " << serviceFlow->GetSchedulingTypeStr () << " unicast poll, size: "
413  << allocationSize << " symbols" << ", modulation: BPSK 1/2");
414  }
415 
416  NS_LOG_DEBUG (", CID: " << serviceFlow->GetConnection ()->GetCid () << ", SFID: " << serviceFlow->GetSfid ());
417 
418  AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
419  ulMapIe.SetUiuc (uiuc);
420  }
421 }
422 
423 void
424 UplinkSchedulerRtps::ServiceBandwidthRequests (const SSRecord *ssRecord,
425  enum ServiceFlow::SchedulingType schedulingType,
426  OfdmUlMapIe &ulMapIe,
427  const WimaxPhy::ModulationType modulationType,
428  uint32_t &symbolsToAllocation,
429  uint32_t &availableSymbols)
430 {
431  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
432 
433  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
434  {
435  if (!ServiceBandwidthRequests (*iter,
436  schedulingType,
437  ulMapIe,
438  modulationType,
439  symbolsToAllocation,
440  availableSymbols))
441  {
442  break;
443  }
444  }
445 }
446 
447 bool
448 UplinkSchedulerRtps::ServiceBandwidthRequests (ServiceFlow *serviceFlow,
449  enum ServiceFlow::SchedulingType schedulingType,
450  OfdmUlMapIe &ulMapIe,
451  const WimaxPhy::ModulationType modulationType,
452  uint32_t &symbolsToAllocation,
453  uint32_t &availableSymbols)
454 {
455  uint32_t allocSizeBytes = 0;
456  uint32_t allocSizeSymbols = 0;
457  uint16_t sduSize = 0;
458 
459  ServiceFlowRecord *record = serviceFlow->GetRecord ();
460  sduSize = serviceFlow->GetSduSize ();
461 
462  uint32_t requiredBandwidth = record->GetRequestedBandwidth () - record->GetGrantedBandwidth ();
463  if (requiredBandwidth > 0)
464  {
465  if (sduSize > 0)
466  {
467  // if SDU size is mentioned, allocate grant of that size
468  allocSizeBytes = sduSize;
469  allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (sduSize, modulationType);
470  }
471  else
472  {
473  allocSizeBytes = requiredBandwidth;
474  allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (requiredBandwidth, modulationType);
475  }
476 
477  if (availableSymbols >= allocSizeSymbols)
478  {
479 
480  NS_LOG_DEBUG ("BS uplink scheduler, " << serviceFlow->GetSchedulingTypeStr () << " allocation, size: "
481  << allocSizeSymbols << " symbols" << ", CID: " << serviceFlow->GetConnection ()->GetCid () << ", SFID: "
482  << serviceFlow->GetSfid () << ", bw requested: " << record->GetRequestedBandwidth () << ", bw granted: "
483  << record->GetGrantedBandwidth ());
484 
485  record->UpdateGrantedBandwidth (allocSizeBytes);
486 
487  if (schedulingType == ServiceFlow::SF_TYPE_NRTPS)
488  {
489  record->SetBwSinceLastExpiry (allocSizeBytes);
490  }
491 
492  AddUplinkAllocation (ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
493  }
494  else
495  {
496  return false;
497  }
498  }
499  return true;
500 }
501 
502 void
503 UplinkSchedulerRtps::ULSchedulerRTPSConnection (uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
504 {
505  NS_LOG_INFO ("\tUL Scheduler for rtPS flows");
506  NS_LOG_INFO ("\t\tavailableSymbols = " << availableSymbols);
507  ServiceFlowRecord *record_[100];
508  uint32_t allocSizeSymbols_[100]; // symbolsRequired for each SSRecord
509  OfdmUlMapIe ulMapIe_[100];
510  OfdmUlMapIe ulMapIe;
511  WimaxPhy::ModulationType modulationType_[100];
512  WimaxPhy::ModulationType modulationType;
513  int nbAllocation = 0;
514  uint32_t allocSizeBytes;
515  uint32_t totAllocSizeSymbols = 0;
516 
517  Cid cid;
518  std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
519 
520  for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
521  {
522  SSRecord *ssRecord = *iter;
523  if (ssRecord->GetIsBroadcastSS ())
524  {
525  continue;
526  }
527  if (!ssRecord->GetPollForRanging () && ssRecord->GetRangingStatus () != WimaxNetDevice::RANGING_STATUS_CONTINUE
528  && ssRecord->GetAreServiceFlowsAllocated ())
529  {
530  cid = ssRecord->GetBasicCid ();
531  ulMapIe.SetCid (cid);
532  modulationType = ssRecord->GetModulationType ();
533  ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
534  WimaxNetDevice::DIRECTION_UPLINK));
535 
536  std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (ServiceFlow::SF_TYPE_RTPS);
537  for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows.begin (); iter2 != serviceFlows.end (); ++iter2)
538  {
539  record_[nbAllocation] = (*iter2)->GetRecord ();
540  uint32_t requiredBandwidth = record_[nbAllocation]->GetRequestedBandwidth ()
541  - record_[nbAllocation]->GetGrantedBandwidth ();
542 
543  if (requiredBandwidth > 0)
544  {
545  modulationType_[nbAllocation] = modulationType;
546  ulMapIe_[nbAllocation] = ulMapIe;
547  allocSizeBytes = requiredBandwidth;
548  allocSizeSymbols_[nbAllocation] = GetBs ()->GetPhy ()->GetNrSymbols (allocSizeBytes,
549  modulationType_[nbAllocation]);
550  totAllocSizeSymbols += allocSizeSymbols_[nbAllocation];
551 
552  NS_LOG_INFO ("\t\tUL Scheduler for CID = " << (*iter2)->GetConnection ()->GetCid ());
553  NS_LOG_INFO ("\t\t\trequiredBandwidth = " << record_[nbAllocation]->GetRequestedBandwidth ()
554  << ", allocSizeSymbols = " << allocSizeSymbols_[nbAllocation] << ", modulationType = "
555  << modulationType_[nbAllocation]);
556 
557  nbAllocation += 1;
558  }
559  }
560  }
561  }
562 
563  NS_LOG_INFO ("\t\ttotAllocSizeSymbols = " << totAllocSizeSymbols);
564 
565  // Channel Saturation
566  while (totAllocSizeSymbols > availableSymbols)
567  {
568  NS_LOG_INFO ("\tUL Channel Saturation: totAllocSizeSymbols > availableSymbols");
569  double delta = double(availableSymbols) / double(totAllocSizeSymbols);
570  NS_LOG_INFO ("\t\tdelta = " << delta);
571  totAllocSizeSymbols = 0;
572  for (int i = 0; i < nbAllocation; i++)
573  {
574  NS_LOG_INFO ("\t\tprevious allocSizeSymbols_[" << i << "] = " << allocSizeSymbols_[i]);
575  allocSizeSymbols_[i] = (uint32_t) std::floor (allocSizeSymbols_[i] * delta);
576  totAllocSizeSymbols += allocSizeSymbols_[i];
577  NS_LOG_INFO ("\t\tnew allocSizeSymbols_[" << i << "] = " << allocSizeSymbols_[i]);
578  }
579  NS_LOG_INFO ("\t\ttotAllocSizeSymbols = " << totAllocSizeSymbols);
580  }
581 
582  // Uplink Bandwidth Allocation
583  for (int i = 0; i < nbAllocation; i++)
584  {
585  AddUplinkAllocation (ulMapIe_[i], allocSizeSymbols_[i], symbolsToAllocation, availableSymbols);
586  allocSizeBytes = GetBs ()->GetPhy ()->GetNrBytes (allocSizeSymbols_[i], modulationType_[i]);
587  NS_LOG_INFO ("\t\tUpdateGrantedBandwidth for " << i << " = " << allocSizeBytes);
588  if (record_[i]->GetRequestedBandwidth () < allocSizeBytes)
589  {
590  // the flow need new poll to set the newer requredBandwidth
591  record_[i]->SetGrantedBandwidth (0);
592  record_[i]->SetRequestedBandwidth (0);
593  }
594  else
595  {
596  record_[i]->UpdateGrantedBandwidth (allocSizeBytes);
597  }
598  }
599 }
600 
601 void
602 UplinkSchedulerRtps::AllocateInitialRangingInterval (uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
603 {
604  Time ssUlStartTime = Seconds (CalculateAllocationStartTime () * GetBs ()->GetPsDuration ().GetSeconds ());
605  SetNrIrOppsAllocated (GetBs ()->GetLinkManager ()->CalculateRangingOppsToAllocate ());
606  uint32_t allocationSize = GetNrIrOppsAllocated () * GetBs ()->GetRangReqOppSize ();
607  Time timeSinceLastIrInterval = Simulator::Now () - GetTimeStampIrInterval ();
608 
609  // adding one frame because may be the time has not elapsed now but will elapse before the next frame is sent
610  if (timeSinceLastIrInterval + GetBs ()->GetPhy ()->GetFrameDuration () > GetBs ()->GetInitialRangingInterval ()
611  && availableSymbols >= allocationSize)
612  {
613  SetIsIrIntrvlAllocated (true);
614  OfdmUlMapIe ulMapIeIr;
615  ulMapIeIr.SetCid (GetBs ()->GetBroadcastConnection ()->GetCid ());
616  ulMapIeIr.SetStartTime (symbolsToAllocation);
617  ulMapIeIr.SetUiuc (OfdmUlBurstProfile::UIUC_INITIAL_RANGING);
618 
619  NS_LOG_DEBUG ("BS uplink scheduler, initial ranging allocation, size: " << allocationSize << " symbols"
620  << ", modulation: BPSK 1/2");
621 
622  // marking start and end of each TO, only for debugging
623  for (uint8_t i = 0; i < GetNrIrOppsAllocated (); i++)
624  {
625  GetBs ()->MarkRangingOppStart (ssUlStartTime + Seconds (symbolsToAllocation
626  * GetBs ()->GetSymbolDuration ().GetSeconds ()) + Seconds (i * GetBs ()->GetRangReqOppSize ()
627  * GetBs ()->GetSymbolDuration ().GetSeconds ()));
628  }
629 
630  AddUplinkAllocation (ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
631  SetTimeStampIrInterval (Simulator::Now ());
632  }
633 }
634 
635 void
636 UplinkSchedulerRtps::SetupServiceFlow (SSRecord *ssRecord, ServiceFlow *serviceFlow)
637 {
638  uint8_t delayNrFrames = 1;
639  uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate ();
640  WimaxPhy::ModulationType modulation;
641  uint32_t bytesPerFrame =
642  (uint32_t ((double)(bitsPerSecond) * GetBs ()->GetPhy ()->GetFrameDuration ().GetSeconds ())) / 8;
643  uint32_t frameDurationMSec = GetBs ()->GetPhy ()->GetFrameDuration ().GetMilliSeconds ();
644 
645  switch (serviceFlow->GetSchedulingType ())
646  {
647  case ServiceFlow::SF_TYPE_UGS:
648  {
649  if (serviceFlow->GetIsMulticast () == true)
650  {
651  modulation = serviceFlow->GetModulation ();
652  }
653  else
654  {
655  modulation = ssRecord->GetModulationType ();
656  }
657  uint32_t grantSize = GetBs ()->GetPhy ()->GetNrSymbols (bytesPerFrame, modulation);
658  serviceFlow->GetRecord ()->SetGrantSize (grantSize);
659 
660  uint32_t toleratedJitter = serviceFlow->GetToleratedJitter ();
661 
662  if (toleratedJitter > frameDurationMSec)
663  {
664  delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
665  }
666 
667  uint16_t interval = delayNrFrames * frameDurationMSec;
668  serviceFlow->SetUnsolicitedGrantInterval (interval);
669  }
670  break;
671  case ServiceFlow::SF_TYPE_RTPS:
672  {
673  if (serviceFlow->GetSduSize () > bytesPerFrame)
674  {
675  delayNrFrames = (uint8_t)(serviceFlow->GetSduSize () / bytesPerFrame);
676  }
677 
678  uint16_t interval = delayNrFrames * frameDurationMSec;
679  serviceFlow->SetUnsolicitedPollingInterval (interval);
680  }
681  break;
682  case ServiceFlow::SF_TYPE_NRTPS:
683  {
684  // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
685  }
686  break;
687  case ServiceFlow::SF_TYPE_BE:
688  {
689  // no real-time guarantees are given to BE, serviced based on available bandwidth
690  }
691  break;
692  default:
693  NS_FATAL_ERROR ("Invalid scheduling type");
694  }
695 }
696 
697 void
698 UplinkSchedulerRtps::InitOnce ()
699 {
700 }
701 
702 void
703 UplinkSchedulerRtps::ProcessBandwidthRequest (const BandwidthRequestHeader &bwRequestHdr)
704 {
705 }
706 
707 void
708 UplinkSchedulerRtps::OnSetRequestedBandwidth (ServiceFlowRecord *sfr)
709 {
710  // m_grantedBandwidth must be reset to zero
711  uint32_t grantedBandwidth = 0;
712  sfr->SetGrantedBandwidth (grantedBandwidth);
713 }
714 
715 } // namespace ns3
keep track of time unit.
Definition: nstime.h:149
this class implements a structure to manage some parameters and statistics related to a service flow ...
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_INFO(msg)
Definition: log.h:264
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Time GetGrantTimeStamp(void) const
static Cid InitialRanging(void)
Definition: cid.cc:82
void SetGrantTimeStamp(Time grantTimeStamp)
Set the grant time stamp. Used for data alocation for ugs flows, and unicast poll (bw request) for no...
Definition: cid.h:35
static Time Now(void)
Definition: simulator.cc:179
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
This class is used by the base station to store some information related to subscriber station in the...
Definition: ss-record.h:43