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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
18 */
19
21
22#include "bandwidth-manager.h"
23#include "bs-link-manager.h"
24#include "bs-net-device.h"
26#include "cid.h"
27#include "service-flow-record.h"
28#include "service-flow.h"
29#include "ss-manager.h"
30#include "ss-record.h"
31
32#include "ns3/log.h"
33#include "ns3/simulator.h"
34#include "ns3/uinteger.h"
35
36namespace ns3
37{
38
39NS_LOG_COMPONENT_DEFINE("UplinkSchedulerSimple");
40
41NS_OBJECT_ENSURE_REGISTERED(UplinkSchedulerSimple);
42
44{
45 SetBs(nullptr);
52}
53
55{
56 SetBs(bs);
63}
64
66{
67 SetBs(nullptr);
68 m_uplinkAllocations.clear();
69}
70
71void
73{
74}
75
78{
79 static TypeId tid = TypeId("ns3::UplinkSchedulerSimple")
81 .SetGroupName("Wimax")
82 .AddConstructor<UplinkSchedulerSimple>();
83 return tid;
84}
85
86std::list<OfdmUlMapIe>
88{
90}
91
92void
94 bool& updateUcd,
95 bool& sendDcd,
96 bool& sendUcd)
97{
98 /*DCD and UCD shall actually be updated when channel or burst profile definitions
99 change. burst profiles are updated based on number of SSs, network conditions and etc.
100 for now temporarily assuming DCD/UCD shall be updated every time */
101
102 uint32_t randNr = rand();
103 if (randNr % 5 == 0 || GetBs()->GetNrDcdSent() == 0)
104 {
105 sendDcd = true;
106 }
107
108 randNr = rand();
109 if (randNr % 5 == 0 || GetBs()->GetNrUcdSent() == 0)
110 {
111 sendUcd = true;
112 }
113
114 // -------------------------------------
115 // additional, just to send more frequently
116 if (!sendDcd)
117 {
118 randNr = rand();
119 if (randNr % 4 == 0)
120 {
121 sendDcd = true;
122 }
123 }
124
125 if (!sendUcd)
126 {
127 randNr = rand();
128 if (randNr % 4 == 0)
129 {
130 sendUcd = true;
131 }
132 }
133 // -------------------------------------
134
135 Time timeSinceLastDcd = Simulator::Now() - GetDcdTimeStamp();
136 Time timeSinceLastUcd = Simulator::Now() - GetUcdTimeStamp();
137
138 if (timeSinceLastDcd > GetBs()->GetDcdInterval())
139 {
140 sendDcd = true;
142 }
143
144 if (timeSinceLastUcd > GetBs()->GetUcdInterval())
145 {
146 sendUcd = true;
148 }
149}
150
153{
154 return GetBs()->GetNrDlSymbols() * GetBs()->GetPhy()->GetPsPerSymbol() + GetBs()->GetTtg();
155}
156
157void
159 const uint32_t& allocationSize,
160 uint32_t& symbolsToAllocation,
161 uint32_t& availableSymbols)
162{
163 ulMapIe.SetDuration(allocationSize);
164 ulMapIe.SetStartTime(symbolsToAllocation);
165 m_uplinkAllocations.push_back(ulMapIe);
166 symbolsToAllocation += allocationSize;
167 availableSymbols -= allocationSize;
168}
169
170void
172{
173 m_uplinkAllocations.clear();
176 bool allocationForDsa = false;
177
178 uint32_t symbolsToAllocation = 0;
179 uint32_t allocationSize = 0; // size in symbols
180 uint32_t availableSymbols = GetBs()->GetNrUlSymbols();
181
182 AllocateInitialRangingInterval(symbolsToAllocation, availableSymbols);
183
184 std::vector<SSRecord*>* ssRecords = GetBs()->GetSSManager()->GetSSRecords();
185 for (auto iter = ssRecords->begin(); iter != ssRecords->end(); ++iter)
186 {
187 SSRecord* ssRecord = *iter;
188
189 if (ssRecord->GetIsBroadcastSS())
190 {
191 continue;
192 }
193 Cid cid = ssRecord->GetBasicCid();
194 OfdmUlMapIe ulMapIe;
195 ulMapIe.SetCid(cid);
196
197 if (ssRecord->GetPollForRanging() &&
199 {
200 // SS's ranging is not yet complete
201 // allocating invited initial ranging interval
203 allocationSize = GetBs()->GetRangReqOppSize();
205
206 if (availableSymbols >= allocationSize)
207 {
208 AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
209 }
210 else
211 {
212 break;
213 }
214 }
215 else
216 {
217 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType();
218
219 // need to update because modulation/FEC to UIUC mapping may vary over time
220 ulMapIe.SetUiuc(GetBs()->GetBurstProfileManager()->GetBurstProfile(
221 modulationType,
223
224 // establish service flows for SS
226 !ssRecord->GetAreServiceFlowsAllocated())
227 {
228 // allocating grant (with arbitrary size) to allow SS to send DSA messages DSA-REQ
229 // and DSA-ACK only one DSA allocation per frame
230 if (!allocationForDsa)
231 {
232 allocationSize =
233 GetBs()->GetPhy()->GetNrSymbols(sizeof(DsaReq), modulationType);
234
235 if (availableSymbols >= allocationSize)
236 {
237 AddUplinkAllocation(ulMapIe,
238 allocationSize,
239 symbolsToAllocation,
240 availableSymbols);
241 allocationForDsa = true;
242 }
243 else
244 {
245 break;
246 }
247 }
248 }
249 else
250 {
251 // all service flows associated to SS are established now
252
253 /*allocating grants for data transmission for UGS flows (Data Grant Burst Type
254 IEs, 6.3.7.4.3.3) (grant has been referred by different names e.g. transmission
255 opportunity, slot, uplink allocation, etc)*/
258 ulMapIe,
259 modulationType,
260 symbolsToAllocation,
261 availableSymbols);
262
263 // allocate unicast polls for rtPS flows if bandwidth is available
264 if (availableSymbols)
265 {
268 ulMapIe,
269 modulationType,
270 symbolsToAllocation,
271 availableSymbols);
272 }
273 // allocate unicast polls for nrtPS flows if bandwidth is available
274 if (availableSymbols)
275 {
278 ulMapIe,
279 modulationType,
280 symbolsToAllocation,
281 availableSymbols);
282 }
283 // finally allocate unicast polls for BE flows if bandwidth is available
284 if (availableSymbols)
285 {
288 ulMapIe,
289 modulationType,
290 symbolsToAllocation,
291 availableSymbols);
292 }
293
294 // now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
295
296 if (availableSymbols)
297 {
300 ulMapIe,
301 modulationType,
302 symbolsToAllocation,
303 availableSymbols);
304 }
305 // allocate unicast polls for nrtPS flows if bandwidth is available
306 if (availableSymbols)
307 {
310 ulMapIe,
311 modulationType,
312 symbolsToAllocation,
313 availableSymbols);
314 }
315 // finally allocate unicast polls for BE flows if bandwidth is available
316 if (availableSymbols)
317 {
320 ulMapIe,
321 modulationType,
322 symbolsToAllocation,
323 availableSymbols);
324 }
325 }
326 }
327 }
328 OfdmUlMapIe ulMapIeEnd;
329
330 ulMapIeEnd.SetCid(Cid::InitialRanging());
331 ulMapIeEnd.SetStartTime(symbolsToAllocation);
333 ulMapIeEnd.SetDuration(0);
334 m_uplinkAllocations.push_back(ulMapIeEnd);
335
336 // setting DL/UL subframe allocation for the next frame
337 GetBs()->GetBandwidthManager()->SetSubframeRatio();
338}
339
340void
342 ServiceFlow::SchedulingType schedulingType,
343 OfdmUlMapIe& ulMapIe,
344 const WimaxPhy::ModulationType modulationType,
345 uint32_t& symbolsToAllocation,
346 uint32_t& availableSymbols)
347{
348 uint32_t allocationSize = 0; // size in symbols
349 uint8_t uiuc = ulMapIe.GetUiuc(); // SS's burst profile
350 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
351
352 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
353 {
354 ServiceFlow* serviceFlow = *iter;
355
356 /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request
357 IEs, 6.3.7.4.3.1). in case of UGS, allocating grants for data transmission (Data Grant
358 Burst Type IEs, 6.3.7.4.3.3) (grant has been referred in this code by different names e.g.
359 transmission opportunity, slot, allocation, etc) */
360
361 allocationSize =
362 GetBs()->GetBandwidthManager()->CalculateAllocationSize(ssRecord, serviceFlow);
363 // verifying that minimum reserved traffic rate of nrtPS flow is maintained
364 if (serviceFlow->GetSchedulingType() == ServiceFlow::SF_TYPE_NRTPS)
365 {
366 Time currentTime = Simulator::Now();
367 ServiceFlowRecord* record = serviceFlow->GetRecord();
368 if (currentTime - record->GetGrantTimeStamp() > Seconds(1))
369 {
370 uint32_t bps = (record->GetBwSinceLastExpiry() * 8);
371 if (bps < serviceFlow->GetMinReservedTrafficRate())
372 {
373 ServiceBandwidthRequests(serviceFlow,
374 schedulingType,
375 ulMapIe,
376 modulationType,
377 symbolsToAllocation,
378 availableSymbols);
379 record->SetBwSinceLastExpiry(0);
380 record->SetGrantTimeStamp(currentTime);
381 }
382 }
383 }
384
385 if (availableSymbols < allocationSize)
386 {
387 break;
388 }
389
390 if (allocationSize > 0)
391 {
392 ulMapIe.SetStartTime(symbolsToAllocation);
393 if (serviceFlow->GetSchedulingType() != ServiceFlow::SF_TYPE_UGS)
394 {
395 // special burst profile with most robust modulation type is used for unicast polls
396 // (Request IEs)
398 }
399 }
400 else
401 {
402 continue;
403 }
404
405 NS_LOG_DEBUG(", CID: " << serviceFlow->GetConnection()->GetCid()
406 << ", SFID: " << serviceFlow->GetSfid());
407
408 AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
409 ulMapIe.SetUiuc(uiuc);
410 }
411}
412
413void
415 ServiceFlow::SchedulingType schedulingType,
416 OfdmUlMapIe& ulMapIe,
417 const WimaxPhy::ModulationType modulationType,
418 uint32_t& symbolsToAllocation,
419 uint32_t& availableSymbols)
420{
421 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
422
423 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
424 {
425 if (!ServiceBandwidthRequests(*iter,
426 schedulingType,
427 ulMapIe,
428 modulationType,
429 symbolsToAllocation,
430 availableSymbols))
431 {
432 break;
433 }
434 }
435}
436
437bool
439 ServiceFlow::SchedulingType schedulingType,
440 OfdmUlMapIe& ulMapIe,
441 const WimaxPhy::ModulationType modulationType,
442 uint32_t& symbolsToAllocation,
443 uint32_t& availableSymbols)
444{
445 uint32_t allocSizeBytes = 0;
446 uint32_t allocSizeSymbols = 0;
447 uint16_t sduSize = 0;
448
449 ServiceFlowRecord* record = serviceFlow->GetRecord();
450 sduSize = serviceFlow->GetSduSize();
451
452 uint32_t requiredBandwidth = record->GetRequestedBandwidth() - record->GetGrantedBandwidth();
453 if (requiredBandwidth > 0)
454 {
455 if (sduSize > 0)
456 {
457 // if SDU size is mentioned, allocate grant of that size
458 allocSizeBytes = sduSize;
459 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(sduSize, modulationType);
460 }
461 else
462 {
463 allocSizeBytes = requiredBandwidth;
464 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(requiredBandwidth, modulationType);
465 }
466
467 if (availableSymbols >= allocSizeSymbols)
468 {
469 record->UpdateGrantedBandwidth(allocSizeBytes);
470
471 if (schedulingType == ServiceFlow::SF_TYPE_NRTPS)
472 {
473 record->SetBwSinceLastExpiry(allocSizeBytes);
474 }
475
476 AddUplinkAllocation(ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
477 }
478 else
479 {
480 return false;
481 }
482 }
483 return true;
484}
485
486void
488 uint32_t& availableSymbols)
489{
490 Time ssUlStartTime =
491 Seconds(CalculateAllocationStartTime() * GetBs()->GetPsDuration().GetSeconds());
492 SetNrIrOppsAllocated(GetBs()->GetLinkManager()->CalculateRangingOppsToAllocate());
493 uint32_t allocationSize = GetNrIrOppsAllocated() * GetBs()->GetRangReqOppSize();
494 Time timeSinceLastIrInterval = Simulator::Now() - GetTimeStampIrInterval();
495
496 // adding one frame because may be the time has not elapsed now but will elapse before the next
497 // frame is sent
498 if (timeSinceLastIrInterval + GetBs()->GetPhy()->GetFrameDuration() >
499 GetBs()->GetInitialRangingInterval() &&
500 availableSymbols >= allocationSize)
501 {
503 OfdmUlMapIe ulMapIeIr;
504 ulMapIeIr.SetCid((GetBs()->GetBroadcastConnection())->GetCid());
505 ulMapIeIr.SetStartTime(symbolsToAllocation);
507
508 NS_LOG_DEBUG("BS uplink scheduler, initial ranging allocation, size: "
509 << allocationSize << " symbols"
510 << ", modulation: BPSK 1/2");
511
512 // marking start and end of each TO, only for debugging
513 for (uint8_t i = 0; i < GetNrIrOppsAllocated(); i++)
514 {
515 GetBs()->MarkRangingOppStart(
516 ssUlStartTime +
517 Seconds(symbolsToAllocation * GetBs()->GetSymbolDuration().GetSeconds()) +
518 Seconds(i * GetBs()->GetRangReqOppSize() *
519 GetBs()->GetSymbolDuration().GetSeconds()));
520 }
521
522 AddUplinkAllocation(ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
524 }
525}
526
527void
529{
530 uint8_t delayNrFrames = 1;
531 uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate();
532 WimaxPhy::ModulationType modulation;
533 uint32_t bytesPerFrame =
534 (uint32_t((double)(bitsPerSecond)*GetBs()->GetPhy()->GetFrameDuration().GetSeconds())) / 8;
535 uint32_t frameDurationMSec = GetBs()->GetPhy()->GetFrameDuration().GetMilliSeconds();
536
537 switch (serviceFlow->GetSchedulingType())
538 {
540 if (serviceFlow->GetIsMulticast())
541 {
542 modulation = serviceFlow->GetModulation();
543 }
544 else
545 {
546 modulation = ssRecord->GetModulationType();
547 }
548 uint32_t grantSize = GetBs()->GetPhy()->GetNrSymbols(bytesPerFrame, modulation);
549 serviceFlow->GetRecord()->SetGrantSize(grantSize);
550
551 uint32_t toleratedJitter = serviceFlow->GetToleratedJitter();
552
553 if (toleratedJitter > frameDurationMSec)
554 {
555 delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
556 }
557
558 uint16_t interval = delayNrFrames * frameDurationMSec;
559 serviceFlow->SetUnsolicitedGrantInterval(interval);
560 }
561 break;
563 if (serviceFlow->GetSduSize() > bytesPerFrame)
564 {
565 delayNrFrames = (uint8_t)(serviceFlow->GetSduSize() / bytesPerFrame);
566 }
567
568 uint16_t interval = delayNrFrames * frameDurationMSec;
569 serviceFlow->SetUnsolicitedPollingInterval(interval);
570 }
571 break;
573 // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
574 }
575 break;
577 // no real-time guarantees are given to BE, serviced based on available bandwidth
578 }
579 break;
580 default:
581 NS_FATAL_ERROR("Invalid scheduling type");
582 }
583}
584
585void
587{
588 // virtual function on UplinkScheduler
589 // this is not necessary on this implementation
590}
591
592void
594{
595 // m_grantedBandwidth must be reset to zero
596 uint32_t grantedBandwidth = 0;
597 sfr->SetGrantedBandwidth(grantedBandwidth);
598}
599
600} // namespace ns3
This class implements the bandwidth-request mac Header as described by IEEE Standard for Local and me...
Cid class.
Definition: cid.h:37
static Cid InitialRanging()
Definition: cid.cc:87
This class implements the DSA-REQ message described by "IEEE Standard for Local and metropolitan area...
Definition: mac-messages.h:386
This class implements the UL-MAP_IE message as described by "IEEE Standard for Local 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.
Definition: ptr.h:77
This class is used by the base station to store some information related to subscriber station in the...
Definition: ss-record.h:46
Cid GetBasicCid() const
Get basic CID.
Definition: ss-record.cc:95
WimaxNetDevice::RangingStatus GetRangingStatus() const
Get ranging status.
Definition: ss-record.cc:179
bool GetPollForRanging() const
Get poll for ranging.
Definition: ss-record.cc:197
std::vector< ServiceFlow * > GetServiceFlows(ServiceFlow::SchedulingType schedulingType) const
Get service flows.
Definition: ss-record.cc:233
bool GetAreServiceFlowsAllocated() const
Check if service flows are allocated.
Definition: ss-record.cc:209
bool GetIsBroadcastSS() const
Get is broadcast SS.
Definition: ss-record.cc:254
WimaxPhy::ModulationType GetModulationType() const
Get modulation type.
Definition: ss-record.cc:167
This class implements service flows as described by the IEEE-802.16 standard.
Definition: service-flow.h:43
uint32_t GetSfid() const
Get SFID.
ServiceFlow::SchedulingType GetSchedulingType() const
Get scheduling type.
SchedulingType
section 11.13.11 Service flow scheduling type, page 701
Definition: service-flow.h:62
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:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
ModulationType
ModulationType enumeration.
Definition: wimax-phy.h:54
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Every class exported by the ns3 library is enclosed in the ns3 namespace.