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 (std::vector<SSRecord*>::iterator iter = ssRecords->begin(); iter != ssRecords->end();
186 ++iter)
187 {
188 SSRecord* ssRecord = *iter;
189
190 if (ssRecord->GetIsBroadcastSS())
191 {
192 continue;
193 }
194 Cid cid = ssRecord->GetBasicCid();
195 OfdmUlMapIe ulMapIe;
196 ulMapIe.SetCid(cid);
197
198 if (ssRecord->GetPollForRanging() &&
200 {
201 // SS's ranging is not yet complete
202 // allocating invited initial ranging interval
204 allocationSize = GetBs()->GetRangReqOppSize();
206
207 if (availableSymbols >= allocationSize)
208 {
209 AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
210 }
211 else
212 {
213 break;
214 }
215 }
216 else
217 {
218 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType();
219
220 // need to update because modulation/FEC to UIUC mapping may vary over time
221 ulMapIe.SetUiuc(GetBs()->GetBurstProfileManager()->GetBurstProfile(
222 modulationType,
224
225 // establish service flows for SS
227 !ssRecord->GetAreServiceFlowsAllocated())
228 {
229 // allocating grant (with arbitrary size) to allow SS to send DSA messages DSA-REQ
230 // and DSA-ACK only one DSA allocation per frame
231 if (!allocationForDsa)
232 {
233 allocationSize =
234 GetBs()->GetPhy()->GetNrSymbols(sizeof(DsaReq), modulationType);
235
236 if (availableSymbols >= allocationSize)
237 {
238 AddUplinkAllocation(ulMapIe,
239 allocationSize,
240 symbolsToAllocation,
241 availableSymbols);
242 allocationForDsa = true;
243 }
244 else
245 {
246 break;
247 }
248 }
249 }
250 else
251 {
252 // all service flows associated to SS are established now
253
254 /*allocating grants for data transmission for UGS flows (Data Grant Burst Type
255 IEs, 6.3.7.4.3.3) (grant has been referred by different names e.g. transmission
256 opportunity, slot, uplink allocation, etc)*/
259 ulMapIe,
260 modulationType,
261 symbolsToAllocation,
262 availableSymbols);
263
264 // allocate unicast polls for rtPS flows if bandwidth is available
265 if (availableSymbols)
266 {
269 ulMapIe,
270 modulationType,
271 symbolsToAllocation,
272 availableSymbols);
273 }
274 // allocate unicast polls for nrtPS flows if bandwidth is available
275 if (availableSymbols)
276 {
279 ulMapIe,
280 modulationType,
281 symbolsToAllocation,
282 availableSymbols);
283 }
284 // finally allocate unicast polls for BE flows if bandwidth is available
285 if (availableSymbols)
286 {
289 ulMapIe,
290 modulationType,
291 symbolsToAllocation,
292 availableSymbols);
293 }
294
295 // now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
296
297 if (availableSymbols)
298 {
301 ulMapIe,
302 modulationType,
303 symbolsToAllocation,
304 availableSymbols);
305 }
306 // allocate unicast polls for nrtPS flows if bandwidth is available
307 if (availableSymbols)
308 {
311 ulMapIe,
312 modulationType,
313 symbolsToAllocation,
314 availableSymbols);
315 }
316 // finally allocate unicast polls for BE flows if bandwidth is available
317 if (availableSymbols)
318 {
321 ulMapIe,
322 modulationType,
323 symbolsToAllocation,
324 availableSymbols);
325 }
326 }
327 }
328 }
329 OfdmUlMapIe ulMapIeEnd;
330
331 ulMapIeEnd.SetCid(Cid::InitialRanging());
332 ulMapIeEnd.SetStartTime(symbolsToAllocation);
334 ulMapIeEnd.SetDuration(0);
335 m_uplinkAllocations.push_back(ulMapIeEnd);
336
337 // setting DL/UL subframe allocation for the next frame
338 GetBs()->GetBandwidthManager()->SetSubframeRatio();
339}
340
341void
343 ServiceFlow::SchedulingType schedulingType,
344 OfdmUlMapIe& ulMapIe,
345 const WimaxPhy::ModulationType modulationType,
346 uint32_t& symbolsToAllocation,
347 uint32_t& availableSymbols)
348{
349 uint32_t allocationSize = 0; // size in symbols
350 uint8_t uiuc = ulMapIe.GetUiuc(); // SS's burst profile
351 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
352
353 for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin();
354 iter != serviceFlows.end();
355 ++iter)
356 {
357 ServiceFlow* serviceFlow = *iter;
358
359 /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request
360 IEs, 6.3.7.4.3.1). in case of UGS, allocating grants for data transmission (Data Grant
361 Burst Type IEs, 6.3.7.4.3.3) (grant has been referred in this code by different names e.g.
362 transmission opportunity, slot, allocation, etc) */
363
364 allocationSize =
365 GetBs()->GetBandwidthManager()->CalculateAllocationSize(ssRecord, serviceFlow);
366 // verifying that minimum reserved traffic rate of nrtPS flow is maintained
367 if (serviceFlow->GetSchedulingType() == ServiceFlow::SF_TYPE_NRTPS)
368 {
369 Time currentTime = Simulator::Now();
370 ServiceFlowRecord* record = serviceFlow->GetRecord();
371 if (currentTime - record->GetGrantTimeStamp() > Seconds(1))
372 {
373 uint32_t bps = (record->GetBwSinceLastExpiry() * 8);
374 if (bps < serviceFlow->GetMinReservedTrafficRate())
375 {
376 ServiceBandwidthRequests(serviceFlow,
377 schedulingType,
378 ulMapIe,
379 modulationType,
380 symbolsToAllocation,
381 availableSymbols);
382 record->SetBwSinceLastExpiry(0);
383 record->SetGrantTimeStamp(currentTime);
384 }
385 }
386 }
387
388 if (availableSymbols < allocationSize)
389 {
390 break;
391 }
392
393 if (allocationSize > 0)
394 {
395 ulMapIe.SetStartTime(symbolsToAllocation);
396 if (serviceFlow->GetSchedulingType() != ServiceFlow::SF_TYPE_UGS)
397 {
398 // special burst profile with most robust modulation type is used for unicast polls
399 // (Request IEs)
401 }
402 }
403 else
404 {
405 continue;
406 }
407
408 NS_LOG_DEBUG(", CID: " << serviceFlow->GetConnection()->GetCid()
409 << ", SFID: " << serviceFlow->GetSfid());
410
411 AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
412 ulMapIe.SetUiuc(uiuc);
413 }
414}
415
416void
418 ServiceFlow::SchedulingType schedulingType,
419 OfdmUlMapIe& ulMapIe,
420 const WimaxPhy::ModulationType modulationType,
421 uint32_t& symbolsToAllocation,
422 uint32_t& availableSymbols)
423{
424 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows(schedulingType);
425
426 for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin();
427 iter != serviceFlows.end();
428 ++iter)
429 {
430 if (!ServiceBandwidthRequests(*iter,
431 schedulingType,
432 ulMapIe,
433 modulationType,
434 symbolsToAllocation,
435 availableSymbols))
436 {
437 break;
438 }
439 }
440}
441
442bool
444 ServiceFlow::SchedulingType schedulingType,
445 OfdmUlMapIe& ulMapIe,
446 const WimaxPhy::ModulationType modulationType,
447 uint32_t& symbolsToAllocation,
448 uint32_t& availableSymbols)
449{
450 uint32_t allocSizeBytes = 0;
451 uint32_t allocSizeSymbols = 0;
452 uint16_t sduSize = 0;
453
454 ServiceFlowRecord* record = serviceFlow->GetRecord();
455 sduSize = serviceFlow->GetSduSize();
456
457 uint32_t requiredBandwidth = record->GetRequestedBandwidth() - record->GetGrantedBandwidth();
458 if (requiredBandwidth > 0)
459 {
460 if (sduSize > 0)
461 {
462 // if SDU size is mentioned, allocate grant of that size
463 allocSizeBytes = sduSize;
464 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(sduSize, modulationType);
465 }
466 else
467 {
468 allocSizeBytes = requiredBandwidth;
469 allocSizeSymbols = GetBs()->GetPhy()->GetNrSymbols(requiredBandwidth, modulationType);
470 }
471
472 if (availableSymbols >= allocSizeSymbols)
473 {
474 record->UpdateGrantedBandwidth(allocSizeBytes);
475
476 if (schedulingType == ServiceFlow::SF_TYPE_NRTPS)
477 {
478 record->SetBwSinceLastExpiry(allocSizeBytes);
479 }
480
481 AddUplinkAllocation(ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
482 }
483 else
484 {
485 return false;
486 }
487 }
488 return true;
489}
490
491void
493 uint32_t& availableSymbols)
494{
495 Time ssUlStartTime =
496 Seconds(CalculateAllocationStartTime() * GetBs()->GetPsDuration().GetSeconds());
497 SetNrIrOppsAllocated(GetBs()->GetLinkManager()->CalculateRangingOppsToAllocate());
498 uint32_t allocationSize = GetNrIrOppsAllocated() * GetBs()->GetRangReqOppSize();
499 Time timeSinceLastIrInterval = Simulator::Now() - GetTimeStampIrInterval();
500
501 // adding one frame because may be the time has not elapsed now but will elapse before the next
502 // frame is sent
503 if (timeSinceLastIrInterval + GetBs()->GetPhy()->GetFrameDuration() >
504 GetBs()->GetInitialRangingInterval() &&
505 availableSymbols >= allocationSize)
506 {
508 OfdmUlMapIe ulMapIeIr;
509 ulMapIeIr.SetCid((GetBs()->GetBroadcastConnection())->GetCid());
510 ulMapIeIr.SetStartTime(symbolsToAllocation);
512
513 NS_LOG_DEBUG("BS uplink scheduler, initial ranging allocation, size: "
514 << allocationSize << " symbols"
515 << ", modulation: BPSK 1/2");
516
517 // marking start and end of each TO, only for debugging
518 for (uint8_t i = 0; i < GetNrIrOppsAllocated(); i++)
519 {
520 GetBs()->MarkRangingOppStart(
521 ssUlStartTime +
522 Seconds(symbolsToAllocation * GetBs()->GetSymbolDuration().GetSeconds()) +
523 Seconds(i * GetBs()->GetRangReqOppSize() *
524 GetBs()->GetSymbolDuration().GetSeconds()));
525 }
526
527 AddUplinkAllocation(ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
529 }
530}
531
532void
534{
535 uint8_t delayNrFrames = 1;
536 uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate();
537 WimaxPhy::ModulationType modulation;
538 uint32_t bytesPerFrame =
539 (uint32_t((double)(bitsPerSecond)*GetBs()->GetPhy()->GetFrameDuration().GetSeconds())) / 8;
540 uint32_t frameDurationMSec = GetBs()->GetPhy()->GetFrameDuration().GetMilliSeconds();
541
542 switch (serviceFlow->GetSchedulingType())
543 {
545 if (serviceFlow->GetIsMulticast())
546 {
547 modulation = serviceFlow->GetModulation();
548 }
549 else
550 {
551 modulation = ssRecord->GetModulationType();
552 }
553 uint32_t grantSize = GetBs()->GetPhy()->GetNrSymbols(bytesPerFrame, modulation);
554 serviceFlow->GetRecord()->SetGrantSize(grantSize);
555
556 uint32_t toleratedJitter = serviceFlow->GetToleratedJitter();
557
558 if (toleratedJitter > frameDurationMSec)
559 {
560 delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
561 }
562
563 uint16_t interval = delayNrFrames * frameDurationMSec;
564 serviceFlow->SetUnsolicitedGrantInterval(interval);
565 }
566 break;
568 if (serviceFlow->GetSduSize() > bytesPerFrame)
569 {
570 delayNrFrames = (uint8_t)(serviceFlow->GetSduSize() / bytesPerFrame);
571 }
572
573 uint16_t interval = delayNrFrames * frameDurationMSec;
574 serviceFlow->SetUnsolicitedPollingInterval(interval);
575 }
576 break;
578 // no real-time guarantees are given to NRTPS, serviced based on available bandwidth
579 }
580 break;
582 // no real-time guarantees are given to BE, serviced based on available bandwidth
583 }
584 break;
585 default:
586 NS_FATAL_ERROR("Invalid scheduling type");
587 }
588}
589
590void
592{
593 // virtual function on UplinkScheduler
594 // this is not necessary on this implementation
595}
596
597void
599{
600 // m_grantedBandwidth must be reset to zero
601 uint32_t grantedBandwidth = 0;
602 sfr->SetGrantedBandwidth(grantedBandwidth);
603}
604
605} // 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:78
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:256
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:199
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:936
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:1336
Every class exported by the ns3 library is enclosed in the ns3 namespace.