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
91 uint32_t randNr = rand();
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
124 Time timeSinceLastDcd = Simulator::Now() - GetDcdTimeStamp();
125 Time timeSinceLastUcd = Simulator::Now() - GetUcdTimeStamp();
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
148 const uint32_t& allocationSize,
149 uint32_t& symbolsToAllocation,
150 uint32_t& availableSymbols)
151{
152 ulMapIe.SetDuration(allocationSize);
153 ulMapIe.SetStartTime(symbolsToAllocation);
154 m_uplinkAllocations.push_back(ulMapIe);
155 symbolsToAllocation += allocationSize;
156 availableSymbols -= allocationSize;
157}
158
159void
161{
162 m_uplinkAllocations.clear();
165 bool allocationForDsa = false;
166
167 uint32_t symbolsToAllocation = 0;
168 uint32_t allocationSize = 0; // size in symbols
169 uint32_t availableSymbols = GetBs()->GetNrUlSymbols();
170
171 AllocateInitialRangingInterval(symbolsToAllocation, availableSymbols);
172
173 std::vector<SSRecord*>* ssRecords = GetBs()->GetSSManager()->GetSSRecords();
174 for (auto iter = ssRecords->begin(); iter != ssRecords->end(); ++iter)
175 {
176 SSRecord* ssRecord = *iter;
177
178 if (ssRecord->GetIsBroadcastSS())
179 {
180 continue;
181 }
182 Cid cid = ssRecord->GetBasicCid();
183 OfdmUlMapIe ulMapIe;
184 ulMapIe.SetCid(cid);
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
195 if (availableSymbols >= allocationSize)
196 {
197 AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
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(
210 modulationType,
212
213 // establish service flows for SS
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 {
221 allocationSize =
222 GetBs()->GetPhy()->GetNrSymbols(sizeof(DsaReq), modulationType);
223
224 if (availableSymbols >= allocationSize)
225 {
226 AddUplinkAllocation(ulMapIe,
227 allocationSize,
228 symbolsToAllocation,
229 availableSymbols);
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,
248 modulationType,
249 symbolsToAllocation,
250 availableSymbols);
251
252 // allocate unicast polls for rtPS flows if bandwidth is available
253 if (availableSymbols)
254 {
257 ulMapIe,
258 modulationType,
259 symbolsToAllocation,
260 availableSymbols);
261 }
262 // allocate unicast polls for nrtPS flows if bandwidth is available
263 if (availableSymbols)
264 {
267 ulMapIe,
268 modulationType,
269 symbolsToAllocation,
270 availableSymbols);
271 }
272 // finally allocate unicast polls for BE flows if bandwidth is available
273 if (availableSymbols)
274 {
277 ulMapIe,
278 modulationType,
279 symbolsToAllocation,
280 availableSymbols);
281 }
282
283 // now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
284
285 if (availableSymbols)
286 {
289 ulMapIe,
290 modulationType,
291 symbolsToAllocation,
292 availableSymbols);
293 }
294 // allocate unicast polls for nrtPS flows if bandwidth is available
295 if (availableSymbols)
296 {
299 ulMapIe,
300 modulationType,
301 symbolsToAllocation,
302 availableSymbols);
303 }
304 // finally allocate unicast polls for BE flows if bandwidth is available
305 if (availableSymbols)
306 {
309 ulMapIe,
310 modulationType,
311 symbolsToAllocation,
312 availableSymbols);
313 }
314 }
315 }
316 }
317 OfdmUlMapIe ulMapIeEnd;
318
319 ulMapIeEnd.SetCid(Cid::InitialRanging());
320 ulMapIeEnd.SetStartTime(symbolsToAllocation);
322 ulMapIeEnd.SetDuration(0);
323 m_uplinkAllocations.push_back(ulMapIeEnd);
324
325 // setting DL/UL subframe allocation for the next frame
326 GetBs()->GetBandwidthManager()->SetSubframeRatio();
327}
328
329void
331 ServiceFlow::SchedulingType schedulingType,
332 OfdmUlMapIe& ulMapIe,
333 const WimaxPhy::ModulationType modulationType,
334 uint32_t& symbolsToAllocation,
335 uint32_t& availableSymbols)
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 {
343 ServiceFlow* serviceFlow = *iter;
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
350 allocationSize =
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 {
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
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
397 AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
398 ulMapIe.SetUiuc(uiuc);
399 }
400}
401
402void
404 ServiceFlow::SchedulingType schedulingType,
405 OfdmUlMapIe& ulMapIe,
406 const WimaxPhy::ModulationType modulationType,
407 uint32_t& symbolsToAllocation,
408 uint32_t& availableSymbols)
409{
410 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
411
412 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
413 {
414 if (!ServiceBandwidthRequests(*iter,
415 schedulingType,
416 ulMapIe,
417 modulationType,
418 symbolsToAllocation,
419 availableSymbols))
420 {
421 break;
422 }
423 }
424}
425
426bool
428 ServiceFlow::SchedulingType schedulingType,
429 OfdmUlMapIe& ulMapIe,
430 const WimaxPhy::ModulationType modulationType,
431 uint32_t& symbolsToAllocation,
432 uint32_t& availableSymbols)
433{
434 uint32_t allocSizeBytes = 0;
435 uint32_t allocSizeSymbols = 0;
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
447 allocSizeBytes = sduSize;
448 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(sduSize, modulationType);
449 }
450 else
451 {
452 allocSizeBytes = requiredBandwidth;
453 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(requiredBandwidth, modulationType);
454 }
455
456 if (availableSymbols >= allocSizeSymbols)
457 {
458 record->UpdateGrantedBandwidth(allocSizeBytes);
459
460 if (schedulingType == ServiceFlow::SF_TYPE_NRTPS)
461 {
462 record->SetBwSinceLastExpiry(allocSizeBytes);
463 }
464
465 AddUplinkAllocation(ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
466 }
467 else
468 {
469 return false;
470 }
471 }
472 return true;
473}
474
475void
477 uint32_t& availableSymbols)
478{
479 Time ssUlStartTime =
480 Seconds(CalculateAllocationStartTime() * GetBs()->GetPsDuration().GetSeconds());
481 SetNrIrOppsAllocated(GetBs()->GetLinkManager()->CalculateRangingOppsToAllocate());
482 uint32_t allocationSize = GetNrIrOppsAllocated() * GetBs()->GetRangReqOppSize();
483 Time timeSinceLastIrInterval = Simulator::Now() - GetTimeStampIrInterval();
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() &&
489 availableSymbols >= allocationSize)
490 {
492 OfdmUlMapIe ulMapIeIr;
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(
505 ssUlStartTime +
506 Seconds(symbolsToAllocation * GetBs()->GetSymbolDuration().GetSeconds()) +
507 Seconds(i * GetBs()->GetRangReqOppSize() *
508 GetBs()->GetSymbolDuration().GetSeconds()));
509 }
510
511 AddUplinkAllocation(ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
513 }
514}
515
516void
518{
519 uint8_t delayNrFrames = 1;
520 uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate();
521 WimaxPhy::ModulationType modulation;
522 uint32_t bytesPerFrame =
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
542 if (toleratedJitter > frameDurationMSec)
543 {
544 delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
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
582 uint32_t grantedBandwidth = 0;
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 forLocal and metropolitan area ...
This class implements the UL-MAP_IE message as described by "IEEE Standard forLocal and metropolitan ...
void SetStartTime(uint16_t startTime)
Set start time.
uint8_t GetUiuc() const
Get UIUC.
void SetDuration(uint16_t duration)
Set duration.
void SetCid(const Cid &cid)
Set CID.
void SetUiuc(uint8_t uiuc)
Set UIUC.
Smart pointer class similar to boost::intrusive_ptr.
This class is used by the base station to store some information related to subscriber station in the...
Definition ss-record.h:35
Cid GetBasicCid() const
Get basic CID.
Definition ss-record.cc:84
WimaxNetDevice::RangingStatus GetRangingStatus() const
Get ranging status.
Definition ss-record.cc:168
bool GetPollForRanging() const
Get poll for ranging.
Definition ss-record.cc:186
std::vector< ServiceFlow * > GetServiceFlows(ServiceFlow::SchedulingType schedulingType) const
Get service flows.
Definition ss-record.cc:222
bool GetAreServiceFlowsAllocated() const
Check if service flows are allocated.
Definition ss-record.cc:198
bool GetIsBroadcastSS() const
Get is broadcast SS.
Definition ss-record.cc:243
WimaxPhy::ModulationType GetModulationType() const
Get modulation type.
Definition ss-record.cc:156
This class implements service flows as described by the IEEE-802.16 standard.
uint32_t GetSfid() const
Get SFID.
ServiceFlow::SchedulingType GetSchedulingType() const
Get scheduling type.
SchedulingType
section 11.13.11 Service flow scheduling type, page 701
uint32_t GetMinReservedTrafficRate() const
Get minimum reserved traffic rate.
uint8_t GetSduSize() const
Get SDU size.
WimaxPhy::ModulationType GetModulation() const
Get modulation.
void SetUnsolicitedGrantInterval(uint16_t unsolicitedGrantInterval)
Set unsolicited grant interval.
ServiceFlowRecord * GetRecord() const
Get service flow record.
void SetUnsolicitedPollingInterval(uint16_t unsolicitedPollingInterval)
Set unsolicited polling interval.
bool GetIsMulticast() const
Get is multicast.
uint32_t GetToleratedJitter() const
Get tolerated jitter.
Ptr< WimaxConnection > GetConnection() const
Can return a null connection is this service flow has not been associated yet to a connection.
this class implements a structure to manage some parameters and statistics related to a service flow
uint32_t GetRequestedBandwidth() const
void SetGrantSize(uint32_t grantSize)
Set the grant size (only for UGS service flows)
uint32_t GetGrantedBandwidth() const
void SetBwSinceLastExpiry(uint32_t bwSinceLastExpiry)
set BW since last expiry
void UpdateGrantedBandwidth(uint32_t grantedBandwidth)
update the granted bandwidth
uint32_t GetBwSinceLastExpiry() const
void SetGrantTimeStamp(Time grantTimeStamp)
Set the grant time stamp.
void SetGrantedBandwidth(uint32_t grantedBandwidth)
set the granted bandwidth
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:48
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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.