~ubuntu-branches/ubuntu/quantal/ns3/quantal

« back to all changes in this revision

Viewing changes to ns-3.13/src/wimax/model/bs-uplink-scheduler-rtps.cc

  • Committer: Package Import Robot
  • Author(s): YunQiang Su, Aron Xu, YunQiang Su, Upstream
  • Date: 2012-01-06 00:35:42 UTC
  • mfrom: (10.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20120106003542-vcn5g03mhapm991h
Tags: 3.13+dfsg-1
[ Aron Xu ]:
        add tag binary and binary-indep, 
  for not build doc when --binary-arch (Closes: #654493).
[ YunQiang Su ]
        add waf 1.5/1.6 source to debian directory, 
  and build waf from there (Closes: #642217).
[ Upstream ]
  Successfully link with --as-needed option (Closes: #642225).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
158
UplinkSchedulerRtps::Schedule (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) 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