A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
bs-uplink-scheduler-simple.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007,2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
7 */
8
10
11#include "bandwidth-manager.h"
12#include "bs-link-manager.h"
13#include "bs-net-device.h"
15#include "cid.h"
16#include "service-flow-record.h"
17#include "service-flow.h"
18#include "ss-manager.h"
19#include "ss-record.h"
20
21#include "ns3/log.h"
22#include "ns3/simulator.h"
23#include "ns3/uinteger.h"
24
25namespace ns3
26{
27
28NS_LOG_COMPONENT_DEFINE("UplinkSchedulerSimple");
29
30NS_OBJECT_ENSURE_REGISTERED(UplinkSchedulerSimple);
31
42
53
59
60void
64
67{
68 static TypeId tid = TypeId("ns3::UplinkSchedulerSimple")
70 .SetGroupName("Wimax")
71 .AddConstructor<UplinkSchedulerSimple>();
72 return tid;
73}
74
75std::list<OfdmUlMapIe>
80
81void
83 bool& updateUcd,
84 bool& sendDcd,
85 bool& sendUcd)
86{
87 /*DCD and UCD shall actually be updated when channel or burst profile definitions
88 change. burst profiles are updated based on number of SSs, network conditions and etc.
89 for now temporarily assuming DCD/UCD shall be updated every time */
90
92 if (randNr % 5 == 0 || GetBs()->GetNrDcdSent() == 0)
93 {
94 sendDcd = true;
95 }
96
97 randNr = rand();
98 if (randNr % 5 == 0 || GetBs()->GetNrUcdSent() == 0)
99 {
100 sendUcd = true;
101 }
102
103 // -------------------------------------
104 // additional, just to send more frequently
105 if (!sendDcd)
106 {
107 randNr = rand();
108 if (randNr % 4 == 0)
109 {
110 sendDcd = true;
111 }
112 }
113
114 if (!sendUcd)
115 {
116 randNr = rand();
117 if (randNr % 4 == 0)
118 {
119 sendUcd = true;
120 }
121 }
122 // -------------------------------------
123
126
127 if (timeSinceLastDcd > GetBs()->GetDcdInterval())
128 {
129 sendDcd = true;
131 }
132
133 if (timeSinceLastUcd > GetBs()->GetUcdInterval())
134 {
135 sendUcd = true;
137 }
138}
139
142{
143 return GetBs()->GetNrDlSymbols() * GetBs()->GetPhy()->GetPsPerSymbol() + GetBs()->GetTtg();
144}
145
146void
158
159void
161{
162 m_uplinkAllocations.clear();
165 bool allocationForDsa = false;
166
168 uint32_t allocationSize = 0; // size in symbols
169 uint32_t availableSymbols = GetBs()->GetNrUlSymbols();
170
172
173 std::vector<SSRecord*>* ssRecords = GetBs()->GetSSManager()->GetSSRecords();
174 for (auto iter = ssRecords->begin(); iter != ssRecords->end(); ++iter)
175 {
177
178 if (ssRecord->GetIsBroadcastSS())
179 {
180 continue;
181 }
182 Cid cid = ssRecord->GetBasicCid();
185
186 if (ssRecord->GetPollForRanging() &&
188 {
189 // SS's ranging is not yet complete
190 // allocating invited initial ranging interval
192 allocationSize = GetBs()->GetRangReqOppSize();
194
196 {
198 }
199 else
200 {
201 break;
202 }
203 }
204 else
205 {
206 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType();
207
208 // need to update because modulation/FEC to UIUC mapping may vary over time
209 ulMapIe.SetUiuc(GetBs()->GetBurstProfileManager()->GetBurstProfile(
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
218 // and DSA-ACK only one DSA allocation per frame
219 if (!allocationForDsa)
220 {
222 GetBs()->GetPhy()->GetNrSymbols(sizeof(DsaReq), modulationType);
223
225 {
230 allocationForDsa = true;
231 }
232 else
233 {
234 break;
235 }
236 }
237 }
238 else
239 {
240 // all service flows associated to SS are established now
241
242 /*allocating grants for data transmission for UGS flows (Data Grant Burst Type
243 IEs, 6.3.7.4.3.3) (grant has been referred by different names e.g. transmission
244 opportunity, slot, uplink allocation, etc)*/
247 ulMapIe,
251
252 // allocate unicast polls for rtPS flows if bandwidth is available
254 {
257 ulMapIe,
261 }
262 // allocate unicast polls for nrtPS flows if bandwidth is available
264 {
267 ulMapIe,
271 }
272 // finally allocate unicast polls for BE flows if bandwidth is available
274 {
277 ulMapIe,
281 }
282
283 // now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
284
286 {
289 ulMapIe,
293 }
294 // allocate unicast polls for nrtPS flows if bandwidth is available
296 {
299 ulMapIe,
303 }
304 // finally allocate unicast polls for BE flows if bandwidth is available
306 {
309 ulMapIe,
313 }
314 }
315 }
316 }
318
320 ulMapIeEnd.SetStartTime(symbolsToAllocation);
322 ulMapIeEnd.SetDuration(0);
324
325 // setting DL/UL subframe allocation for the next frame
326 GetBs()->GetBandwidthManager()->SetSubframeRatio();
327}
328
329void
336{
337 uint32_t allocationSize = 0; // size in symbols
338 uint8_t uiuc = ulMapIe.GetUiuc(); // SS's burst profile
339 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
340
341 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
342 {
344
345 /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request
346 IEs, 6.3.7.4.3.1). in case of UGS, allocating grants for data transmission (Data Grant
347 Burst Type IEs, 6.3.7.4.3.3) (grant has been referred in this code by different names e.g.
348 transmission opportunity, slot, allocation, etc) */
349
351 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 {
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 {
364 ulMapIe,
368 record->SetBwSinceLastExpiry(0);
369 record->SetGrantTimeStamp(currentTime);
370 }
371 }
372 }
373
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
385 // (Request IEs)
387 }
388 }
389 else
390 {
391 continue;
392 }
393
394 NS_LOG_DEBUG(", CID: " << serviceFlow->GetConnection()->GetCid()
395 << ", SFID: " << serviceFlow->GetSfid());
396
398 ulMapIe.SetUiuc(uiuc);
399 }
400}
401
402void
425
426bool
433{
436 uint16_t sduSize = 0;
437
438 ServiceFlowRecord* record = serviceFlow->GetRecord();
439 sduSize = serviceFlow->GetSduSize();
440
441 uint32_t requiredBandwidth = record->GetRequestedBandwidth() - record->GetGrantedBandwidth();
442 if (requiredBandwidth > 0)
443 {
444 if (sduSize > 0)
445 {
446 // if SDU size is mentioned, allocate grant of that size
448 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(sduSize, modulationType);
449 }
450 else
451 {
453 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(requiredBandwidth, modulationType);
454 }
455
457 {
458 record->UpdateGrantedBandwidth(allocSizeBytes);
459
461 {
462 record->SetBwSinceLastExpiry(allocSizeBytes);
463 }
464
466 }
467 else
468 {
469 return false;
470 }
471 }
472 return true;
473}
474
475void
478{
480 Seconds(CalculateAllocationStartTime() * GetBs()->GetPsDuration().GetSeconds());
481 SetNrIrOppsAllocated(GetBs()->GetLinkManager()->CalculateRangingOppsToAllocate());
482 uint32_t allocationSize = GetNrIrOppsAllocated() * GetBs()->GetRangReqOppSize();
484
485 // adding one frame because may be the time has not elapsed now but will elapse before the next
486 // frame is sent
487 if (timeSinceLastIrInterval + GetBs()->GetPhy()->GetFrameDuration() >
488 GetBs()->GetInitialRangingInterval() &&
490 {
493 ulMapIeIr.SetCid((GetBs()->GetBroadcastConnection())->GetCid());
494 ulMapIeIr.SetStartTime(symbolsToAllocation);
496
497 NS_LOG_DEBUG("BS uplink scheduler, initial ranging allocation, size: "
498 << allocationSize << " symbols"
499 << ", modulation: BPSK 1/2");
500
501 // marking start and end of each TO, only for debugging
502 for (uint8_t i = 0; i < GetNrIrOppsAllocated(); i++)
503 {
504 GetBs()->MarkRangingOppStart(
506 Seconds(symbolsToAllocation * GetBs()->GetSymbolDuration().GetSeconds()) +
507 Seconds(i * GetBs()->GetRangReqOppSize() *
508 GetBs()->GetSymbolDuration().GetSeconds()));
509 }
510
513 }
514}
515
516void
518{
519 uint8_t delayNrFrames = 1;
520 uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate();
523 (uint32_t((double)(bitsPerSecond)*GetBs()->GetPhy()->GetFrameDuration().GetSeconds())) / 8;
524 uint32_t frameDurationMSec = GetBs()->GetPhy()->GetFrameDuration().GetMilliSeconds();
525
526 switch (serviceFlow->GetSchedulingType())
527 {
529 if (serviceFlow->GetIsMulticast())
530 {
531 modulation = serviceFlow->GetModulation();
532 }
533 else
534 {
535 modulation = ssRecord->GetModulationType();
536 }
537 uint32_t grantSize = GetBs()->GetPhy()->GetNrSymbols(bytesPerFrame, modulation);
538 serviceFlow->GetRecord()->SetGrantSize(grantSize);
539
540 uint32_t toleratedJitter = serviceFlow->GetToleratedJitter();
541
543 {
545 }
546
547 uint16_t interval = delayNrFrames * frameDurationMSec;
548 serviceFlow->SetUnsolicitedGrantInterval(interval);
549 }
550 break;
552 if (serviceFlow->GetSduSize() > bytesPerFrame)
553 {
554 delayNrFrames = (uint8_t)(serviceFlow->GetSduSize() / bytesPerFrame);
555 }
556
557 uint16_t interval = delayNrFrames * frameDurationMSec;
558 serviceFlow->SetUnsolicitedPollingInterval(interval);
559 }
560 break;
562 // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
564 // no real-time guarantees are given to BE, serviced based on available bandwidth
565 break;
566 default:
567 NS_FATAL_ERROR("Invalid scheduling type");
568 }
569}
570
571void
573{
574 // virtual function on UplinkScheduler
575 // this is not necessary on this implementation
576}
577
578void
580{
581 // m_grantedBandwidth must be reset to zero
583 sfr->SetGrantedBandwidth(grantedBandwidth);
584}
585
586} // namespace ns3
This class implements the bandwidth-request mac Header as described by IEEE Standard for Local and me...
Cid class.
Definition cid.h:26
static Cid InitialRanging()
Definition cid.cc:76
This class implements the DSA-REQ message described by "IEEE Standard for Local and metropolitan area...
This class implements the UL-MAP_IE message as described by "IEEE Standard for Local and metropolitan...
void SetCid(const Cid &cid)
Set CID.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
This class is used by the base station to store some information related to subscriber station in the...
Definition ss-record.h:35
This class implements service flows as described by the IEEE-802.16 standard.
SchedulingType
section 11.13.11 Service flow scheduling type, page 701
this class implements a structure to manage some parameters and statistics related to a service flow
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
ModulationType
ModulationType enumeration.
Definition wimax-phy.h:43
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Every class exported by the ns3 library is enclosed in the ns3 namespace.