A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
bs-uplink-scheduler-rtps.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007,2008 INRIA
3 * 2009 TELEMATICS LAB, Politecnico di Bari
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Author: Giuseppe Piro <g.piro@poliba.it>
8 */
9
11
12#include "bandwidth-manager.h"
13#include "bs-link-manager.h"
14#include "bs-net-device.h"
16#include "cid.h"
17#include "service-flow-record.h"
18#include "service-flow.h"
19#include "ss-manager.h"
20#include "ss-record.h"
21
22#include "ns3/log.h"
23#include "ns3/simulator.h"
24#include "ns3/uinteger.h"
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("UplinkSchedulerRtps");
30
31NS_OBJECT_ENSURE_REGISTERED(UplinkSchedulerRtps);
32
43
54
60
63{
64 static TypeId tid = TypeId("ns3::UplinkSchedulerRtps")
66 .SetGroupName("Wimax")
67 .AddConstructor<UplinkSchedulerRtps>();
68 return tid;
69}
70
71std::list<OfdmUlMapIe>
76
77void
79 bool& updateUcd,
80 bool& sendDcd,
81 bool& sendUcd)
82{
83 /*DCD and UCD shall actually be updated when channel or burst profile definitions
84 change. burst profiles are updated based on number of SSs, network conditions and etc.
85 for now temporarily assuming DCD/UCD shall be updated every time */
86
88 if (randNr % 5 == 0 || GetBs()->GetNrDcdSent() == 0)
89 {
90 sendDcd = true;
91 }
92
93 randNr = rand();
94 if (randNr % 5 == 0 || GetBs()->GetNrUcdSent() == 0)
95 {
96 sendUcd = true;
97 }
98
99 // -------------------------------------
100 // additional, just to send more frequently
101 if (!sendDcd)
102 {
103 randNr = rand();
104 if (randNr % 4 == 0)
105 {
106 sendDcd = true;
107 }
108 }
109
110 if (!sendUcd)
111 {
112 randNr = rand();
113 if (randNr % 4 == 0)
114 {
115 sendUcd = true;
116 }
117 }
118 // -------------------------------------
119
122
123 if (timeSinceLastDcd > GetBs()->GetDcdInterval())
124 {
125 sendDcd = true;
127 }
128
129 if (timeSinceLastUcd > GetBs()->GetUcdInterval())
130 {
131 sendUcd = true;
133 }
134}
135
138{
139 return GetBs()->GetNrDlSymbols() * GetBs()->GetPhy()->GetPsPerSymbol() + GetBs()->GetTtg();
140}
141
142void
154
155void
157{
158 m_uplinkAllocations.clear();
161 bool allocationForDsa = false;
162
164 uint32_t allocationSize = 0; // size in symbols
165 uint32_t availableSymbols = GetBs()->GetNrUlSymbols();
166
168 Cid cid;
169
171
172 std::vector<SSRecord*>* ssRecords = GetBs()->GetSSManager()->GetSSRecords();
173 NS_LOG_INFO("UL Scheduler start, availableSymbols = " << availableSymbols);
174
175 for (auto iter = ssRecords->begin(); iter != ssRecords->end(); ++iter)
176 {
178 if (ssRecord->GetIsBroadcastSS())
179 {
180 continue;
181 }
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 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);
224 {
229 allocationForDsa = true;
230 }
231 else
232 {
233 break;
234 }
235 }
236 }
237 else
238 {
239 // all service flows associated to SS are established now
240
241 /*allocating grants for data transmission for UGS flows (Data Grant Burst Type
242 IEs, 6.3.7.4.3.3) (grant has been referred by different names e.g. transmission
243 opportunity, slot, uplink allocation, etc)*/
246 ulMapIe,
250
251 // allocate unicast polls for rtPS flows if bandwidth is available
253 {
256 ulMapIe,
260 }
261 // allocate unicast polls for nrtPS flows if bandwidth is available
263 {
266 ulMapIe,
270 }
271 // finally allocate unicast polls for BE flows if bandwidth is available
273 {
276 ulMapIe,
280 }
281 }
282 }
283 }
284
285 /*
286 * Uplink Scheduler for rtPS Connection
287 */
289 {
291 }
292
293 // UL Scheduler for nrtPS and BE flows
295 {
296 for (auto iter = ssRecords->begin(); iter != ssRecords->end(); ++iter)
297 {
299 if (ssRecord->GetIsBroadcastSS())
300 {
301 continue;
302 }
303 if (!ssRecord->GetPollForRanging() &&
304 ssRecord->GetRangingStatus() != WimaxNetDevice::RANGING_STATUS_CONTINUE &&
305 ssRecord->GetAreServiceFlowsAllocated())
306 {
308 cid = ssRecord->GetBasicCid();
310 modulationType = ssRecord->GetModulationType();
311 ulMapIe.SetUiuc(GetBs()->GetBurstProfileManager()->GetBurstProfile(
314
315 // allocate unicast polls for nrtPS flows if bandwidth is available
316
319 ulMapIe,
323
324 // finally allocate unicast polls for BE flows if bandwidth is available
326 {
329 ulMapIe,
333 }
334 }
335 }
336 }
337
340 ulMapIeEnd.SetStartTime(symbolsToAllocation);
342 ulMapIeEnd.SetDuration(0);
344
345 // setting DL/UL subframe allocation for the next frame
346 GetBs()->GetBandwidthManager()->SetSubframeRatio();
347}
348
349void
356{
357 uint32_t allocationSize = 0; // size in symbols
358 uint8_t uiuc = ulMapIe.GetUiuc(); // SS's burst profile
359 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
360
361 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
362 {
364
365 /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request
366 IEs, 6.3.7.4.3.1). in case of UGS, allocating grants for data transmission (Data Grant
367 Burst Type IEs, 6.3.7.4.3.3) (grant has been referred in this code by different names e.g.
368 transmission opportunity, slot, allocation, etc) */
369
371 GetBs()->GetBandwidthManager()->CalculateAllocationSize(ssRecord, serviceFlow);
372
373 // verifying that minimum reserved traffic rate of nrtPS flow is maintained
374 if (serviceFlow->GetSchedulingType() == ServiceFlow::SF_TYPE_NRTPS)
375 {
377 ServiceFlowRecord* record = serviceFlow->GetRecord();
378 if (currentTime - record->GetGrantTimeStamp() > Seconds(1))
379 {
380 uint32_t bps = (record->GetBwSinceLastExpiry() * 8);
381 if (bps < serviceFlow->GetMinReservedTrafficRate())
382 {
385 ulMapIe,
389 record->SetBwSinceLastExpiry(0);
390 record->SetGrantTimeStamp(currentTime);
391 }
392 }
393 }
394
396 {
397 break;
398 }
399
400 if (allocationSize > 0)
401 {
402 ulMapIe.SetStartTime(symbolsToAllocation);
403 if (serviceFlow->GetSchedulingType() != ServiceFlow::SF_TYPE_UGS)
404 {
405 // special burst profile with most robust modulation type is used for unicast polls
406 // (Request IEs)
408 }
409 }
410 else
411 {
412 continue;
413 }
414
415 if (serviceFlow->GetSchedulingType() == ServiceFlow::SF_TYPE_UGS)
416 {
417 NS_LOG_DEBUG("BS uplink scheduler, UGS allocation, size: " << allocationSize
418 << " symbols");
419 }
420 else
421 {
422 NS_LOG_DEBUG("BS uplink scheduler, " << serviceFlow->GetSchedulingTypeStr()
423 << " unicast poll, size: " << allocationSize
424 << " symbols"
425 << ", modulation: BPSK 1/2");
426 }
427
428 NS_LOG_DEBUG(", CID: " << serviceFlow->GetConnection()->GetCid()
429 << ", SFID: " << serviceFlow->GetSfid());
430
432 ulMapIe.SetUiuc(uiuc);
433 }
434}
435
436void
459
460bool
467{
470 uint16_t sduSize = 0;
471
472 ServiceFlowRecord* record = serviceFlow->GetRecord();
473 sduSize = serviceFlow->GetSduSize();
474
475 uint32_t requiredBandwidth = record->GetRequestedBandwidth() - record->GetGrantedBandwidth();
476 if (requiredBandwidth > 0)
477 {
478 if (sduSize > 0)
479 {
480 // if SDU size is mentioned, allocate grant of that size
482 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(sduSize, modulationType);
483 }
484 else
485 {
487 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(requiredBandwidth, modulationType);
488 }
489
491 {
492 NS_LOG_DEBUG("BS uplink scheduler, "
493 << serviceFlow->GetSchedulingTypeStr()
494 << " allocation, size: " << allocSizeSymbols << " symbols"
495 << ", CID: " << serviceFlow->GetConnection()->GetCid()
496 << ", SFID: " << serviceFlow->GetSfid()
497 << ", bw requested: " << record->GetRequestedBandwidth()
498 << ", bw granted: " << record->GetGrantedBandwidth());
499
500 record->UpdateGrantedBandwidth(allocSizeBytes);
501
503 {
504 record->SetBwSinceLastExpiry(allocSizeBytes);
505 }
506
508 }
509 else
510 {
511 return false;
512 }
513 }
514 return true;
515}
516
517void
520{
521 NS_LOG_INFO("\tUL Scheduler for rtPS flows");
522 NS_LOG_INFO("\t\tavailableSymbols = " << availableSymbols);
524 uint32_t allocSizeSymbols_[100]; // symbolsRequired for each SSRecord
529 int nbAllocation = 0;
532
533 Cid cid;
534 std::vector<SSRecord*>* ssRecords = GetBs()->GetSSManager()->GetSSRecords();
535
536 for (auto iter = ssRecords->begin(); iter != ssRecords->end(); ++iter)
537 {
539 if (ssRecord->GetIsBroadcastSS())
540 {
541 continue;
542 }
543 if (!ssRecord->GetPollForRanging() &&
544 ssRecord->GetRangingStatus() != WimaxNetDevice::RANGING_STATUS_CONTINUE &&
545 ssRecord->GetAreServiceFlowsAllocated())
546 {
548 ulMapIe.SetCid(cid);
549 modulationType = ssRecord->GetModulationType();
550 ulMapIe.SetUiuc(GetBs()->GetBurstProfileManager()->GetBurstProfile(
553
554 std::vector<ServiceFlow*> serviceFlows =
555 ssRecord->GetServiceFlows(ServiceFlow::SF_TYPE_RTPS);
556 for (auto iter2 = serviceFlows.begin(); iter2 != serviceFlows.end(); ++iter2)
557 {
558 record_[nbAllocation] = (*iter2)->GetRecord();
559 uint32_t requiredBandwidth = record_[nbAllocation]->GetRequestedBandwidth() -
560 record_[nbAllocation]->GetGrantedBandwidth();
561
562 if (requiredBandwidth > 0)
563 {
568 GetBs()->GetPhy()->GetNrSymbols(allocSizeBytes,
571
573 "\t\tUL Scheduler for CID = " << (*iter2)->GetConnection()->GetCid());
574 NS_LOG_INFO("\t\t\trequiredBandwidth = "
575 << record_[nbAllocation]->GetRequestedBandwidth()
576 << ", allocSizeSymbols = " << allocSizeSymbols_[nbAllocation]
577 << ", modulationType = " << modulationType_[nbAllocation]);
578
579 nbAllocation += 1;
580 }
581 }
582 }
583 }
584
585 NS_LOG_INFO("\t\ttotAllocSizeSymbols = " << totAllocSizeSymbols);
586
587 // Channel Saturation
589 {
590 NS_LOG_INFO("\tUL Channel Saturation: totAllocSizeSymbols > availableSymbols");
592 NS_LOG_INFO("\t\tdelta = " << delta);
594 for (int i = 0; i < nbAllocation; i++)
595 {
596 NS_LOG_INFO("\t\tprevious allocSizeSymbols_[" << i << "] = " << allocSizeSymbols_[i]);
597 allocSizeSymbols_[i] = (uint32_t)std::floor(allocSizeSymbols_[i] * delta);
599 NS_LOG_INFO("\t\tnew allocSizeSymbols_[" << i << "] = " << allocSizeSymbols_[i]);
600 }
601 NS_LOG_INFO("\t\ttotAllocSizeSymbols = " << totAllocSizeSymbols);
602 }
603
604 // Uplink Bandwidth Allocation
605 for (int i = 0; i < nbAllocation; i++)
606 {
611 allocSizeBytes = GetBs()->GetPhy()->GetNrBytes(allocSizeSymbols_[i], modulationType_[i]);
612 NS_LOG_INFO("\t\tUpdateGrantedBandwidth for " << i << " = " << allocSizeBytes);
613 if (record_[i]->GetRequestedBandwidth() < allocSizeBytes)
614 {
615 // the flow need new poll to set the newer requiredBandwidth
616 record_[i]->SetGrantedBandwidth(0);
617 record_[i]->SetRequestedBandwidth(0);
618 }
619 else
620 {
621 record_[i]->UpdateGrantedBandwidth(allocSizeBytes);
622 }
623 }
624}
625
626void
629{
631 Seconds(CalculateAllocationStartTime() * GetBs()->GetPsDuration().GetSeconds());
632 SetNrIrOppsAllocated(GetBs()->GetLinkManager()->CalculateRangingOppsToAllocate());
633 uint32_t allocationSize = GetNrIrOppsAllocated() * GetBs()->GetRangReqOppSize();
635
636 // adding one frame because may be the time has not elapsed now but will elapse before the next
637 // frame is sent
638 if (timeSinceLastIrInterval + GetBs()->GetPhy()->GetFrameDuration() >
639 GetBs()->GetInitialRangingInterval() &&
641 {
644 ulMapIeIr.SetCid(GetBs()->GetBroadcastConnection()->GetCid());
645 ulMapIeIr.SetStartTime(symbolsToAllocation);
647
648 NS_LOG_DEBUG("BS uplink scheduler, initial ranging allocation, size: "
649 << allocationSize << " symbols"
650 << ", modulation: BPSK 1/2");
651
652 // marking start and end of each TO, only for debugging
653 for (uint8_t i = 0; i < GetNrIrOppsAllocated(); i++)
654 {
655 GetBs()->MarkRangingOppStart(
657 Seconds(symbolsToAllocation * GetBs()->GetSymbolDuration().GetSeconds()) +
658 Seconds(i * GetBs()->GetRangReqOppSize() *
659 GetBs()->GetSymbolDuration().GetSeconds()));
660 }
661
664 }
665}
666
667void
669{
670 uint8_t delayNrFrames = 1;
671 uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate();
674 (uint32_t((double)(bitsPerSecond)*GetBs()->GetPhy()->GetFrameDuration().GetSeconds())) / 8;
675 uint32_t frameDurationMSec = GetBs()->GetPhy()->GetFrameDuration().GetMilliSeconds();
676
677 switch (serviceFlow->GetSchedulingType())
678 {
680 if (serviceFlow->GetIsMulticast())
681 {
682 modulation = serviceFlow->GetModulation();
683 }
684 else
685 {
686 modulation = ssRecord->GetModulationType();
687 }
688 uint32_t grantSize = GetBs()->GetPhy()->GetNrSymbols(bytesPerFrame, modulation);
689 serviceFlow->GetRecord()->SetGrantSize(grantSize);
690
691 uint32_t toleratedJitter = serviceFlow->GetToleratedJitter();
692
694 {
696 }
697
698 uint16_t interval = delayNrFrames * frameDurationMSec;
699 serviceFlow->SetUnsolicitedGrantInterval(interval);
700 }
701 break;
703 if (serviceFlow->GetSduSize() > bytesPerFrame)
704 {
705 delayNrFrames = (uint8_t)(serviceFlow->GetSduSize() / bytesPerFrame);
706 }
707
708 uint16_t interval = delayNrFrames * frameDurationMSec;
709 serviceFlow->SetUnsolicitedPollingInterval(interval);
710 }
711 break;
713 // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
715 // no real-time guarantees are given to BE, serviced based on available bandwidth
716 break;
717 default:
718 NS_FATAL_ERROR("Invalid scheduling type");
719 }
720}
721
722void
726
727void
731
732void
734{
735 // m_grantedBandwidth must be reset to zero
737 sfr->SetGrantedBandwidth(grantedBandwidth);
738}
739
740} // 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
Cid GetBasicCid() const
Get basic CID.
Definition ss-record.cc:84
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_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#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.