18 #include "bs-uplink-scheduler-mbqos.h"
19 #include "bs-net-device.h"
20 #include "ns3/simulator.h"
22 #include "burst-profile-manager.h"
23 #include "ss-manager.h"
25 #include "ns3/uinteger.h"
26 #include "service-flow.h"
27 #include "service-flow-record.h"
28 #include "bs-link-manager.h"
29 #include "bandwidth-manager.h"
30 #include "connection-manager.h"
36 NS_OBJECT_ENSURE_REGISTERED (UplinkSchedulerMBQoS);
38 UplinkSchedulerMBQoS::UplinkSchedulerMBQoS ()
42 UplinkSchedulerMBQoS::UplinkSchedulerMBQoS (Time time)
43 : m_windowInterval (time)
48 UplinkSchedulerMBQoS::~UplinkSchedulerMBQoS (
void)
51 m_uplinkAllocations.clear ();
55 UplinkSchedulerMBQoS::GetTypeId (
void)
57 static TypeId tid = TypeId (
"ns3::UplinkSchedulerMBQoS")
59 .SetParent<UplinkScheduler> ()
61 .AddAttribute (
"WindowInterval",
62 "The time to wait to reset window",
64 MakeTimeAccessor (&UplinkSchedulerMBQoS::m_windowInterval),
75 std::list<OfdmUlMapIe>
76 UplinkSchedulerMBQoS::GetUplinkAllocations (
void)
const
78 return m_uplinkAllocations;
91 uint32_t randNr = rand ();
92 if (randNr % 5 == 0 || GetBs ()->GetNrDcdSent () == 0)
98 if (randNr % 5 == 0 || GetBs ()->GetNrUcdSent () == 0)
127 if (timeSinceLastDcd > GetBs ()->GetDcdInterval ())
133 if (timeSinceLastUcd > GetBs ()->GetUcdInterval ())
141 UplinkSchedulerMBQoS::CalculateAllocationStartTime (
void)
143 return GetBs ()->GetNrDlSymbols () * GetBs ()->GetPhy ()->GetPsPerSymbol () + GetBs ()->GetTtg ();
147 UplinkSchedulerMBQoS::AddUplinkAllocation (OfdmUlMapIe &ulMapIe,
148 const uint32_t &allocationSize,
149 uint32_t &symbolsToAllocation,
150 uint32_t &availableSymbols)
152 ulMapIe.SetDuration (allocationSize);
153 ulMapIe.SetStartTime (symbolsToAllocation);
154 m_uplinkAllocations.push_back (ulMapIe);
155 symbolsToAllocation += allocationSize;
156 availableSymbols -= allocationSize;
167 if (!GetBs ()->GetSSManager ())
173 std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
176 for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
179 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (ServiceFlow::SF_TYPE_ALL);
182 for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows.begin (); iter2 != serviceFlows.end (); ++iter2)
185 if ((serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_RTPS) || (serviceFlow->GetSchedulingType ()
186 == ServiceFlow::SF_TYPE_NRTPS))
188 min_bw = (int) ceil (serviceFlow->GetMinReservedTrafficRate ());
191 if ((serviceFlow->GetRecord ()->GetBacklogged () > 0)
192 && (serviceFlow->GetRecord ()->GetBwSinceLastExpiry () < min_bw))
194 serviceFlow->GetRecord ()->UpdateBwSinceLastExpiry (-min_bw);
197 if (serviceFlow->GetRecord ()->GetBacklogged ()
198 < (serviceFlow->GetRecord ()->GetBwSinceLastExpiry ()))
200 serviceFlow->GetRecord ()->SetBwSinceLastExpiry (-serviceFlow->GetRecord ()->GetBacklogged ());
205 serviceFlow->GetRecord ()->SetBwSinceLastExpiry (0);
216 UplinkSchedulerMBQoS::Schedule (
void)
218 m_uplinkAllocations.clear ();
219 SetIsIrIntrvlAllocated (
false);
220 SetIsInvIrIntrvlAllocated (
false);
221 bool allocationForDsa =
false;
223 uint32_t symbolsToAllocation = 0;
224 uint32_t allocationSize = 0;
225 uint32_t availableSymbols = GetBs ()->GetNrUlSymbols ();
226 uint32_t availableSymbolsAux = GetBs ()->GetNrUlSymbols ();
228 AllocateInitialRangingInterval (symbolsToAllocation, availableSymbols);
230 std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
231 for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
235 if (ssRecord->GetIsBroadcastSS ())
239 Cid cid = ssRecord->GetBasicCid ();
241 ulMapIe.SetCid (cid);
243 if (ssRecord->GetPollForRanging () && ssRecord->GetRangingStatus () == WimaxNetDevice::RANGING_STATUS_CONTINUE)
247 ulMapIe.SetUiuc (OfdmUlBurstProfile::UIUC_INITIAL_RANGING);
248 allocationSize = GetBs ()->GetRangReqOppSize ();
249 SetIsInvIrIntrvlAllocated (
true);
251 if (availableSymbols >= allocationSize)
253 AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
262 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
265 ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
266 WimaxNetDevice::DIRECTION_UPLINK));
269 if (ssRecord->GetRangingStatus () == WimaxNetDevice::RANGING_STATUS_SUCCESS
270 && !ssRecord->GetAreServiceFlowsAllocated ())
275 if (!allocationForDsa)
277 allocationSize = GetBs ()->GetPhy ()->GetNrSymbols (
sizeof(DsaReq), modulationType);
279 if (availableSymbols >= allocationSize)
281 AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
282 allocationForDsa =
true;
300 if (availableSymbols)
304 if (ssRecord->GetHasServiceFlowUgs ())
308 Time frame_duration = GetBs ()->GetPhy ()->GetFrameDuration ();
311 (*(ssRecord->GetServiceFlows (ServiceFlow::SF_TYPE_UGS).begin ()))->GetRecord ()->GetLastGrantTime ()
312 +
MilliSeconds ((*(ssRecord->GetServiceFlows (ServiceFlow::SF_TYPE_UGS).begin ()))->GetUnsolicitedGrantInterval ());
314 Time frame = Time ((timestamp -
Simulator::Now ()) / frame_duration);
320 ServiceUnsolicitedGrants (ssRecord,
321 ServiceFlow::SF_TYPE_UGS,
330 if (ssRecord->GetHasServiceFlowRtps ())
333 Ptr<UlJob> jobRTPSPoll =
CreateUlJob (ssRecord, ServiceFlow::SF_TYPE_RTPS, UNICAST_POLLING);
337 if (ssRecord->GetHasServiceFlowNrtps ())
341 Ptr<UlJob> jobNRTPSPoll =
CreateUlJob (ssRecord, ServiceFlow::SF_TYPE_NRTPS, UNICAST_POLLING);
345 if (ssRecord->GetHasServiceFlowBe ())
349 Ptr<UlJob> jobBEPoll =
CreateUlJob (ssRecord, ServiceFlow::SF_TYPE_BE, UNICAST_POLLING);
356 NS_LOG_DEBUG (
"At " <<
Simulator::Now ().GetSeconds ()<<
" high queue has " << m_uplinkJobs_high.size ()<<
" jobs - after sched");
358 availableSymbolsAux = availableSymbols;
359 uint32_t symbolsUsed = 0;
362 availableSymbolsAux -= symbolsUsed;
372 while ((availableSymbols) && (!m_uplinkJobs_high.empty ()))
375 Ptr<UlJob> job = m_uplinkJobs_high.front ();
377 SSRecord * ssRecord = job->GetSsRecord ();
378 enum ServiceFlow::SchedulingType schedulingType = job->GetSchedulingType ();
380 Cid cid = ssRecord->GetBasicCid ();
381 ulMapIe.SetCid (cid);
382 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
384 ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
385 WimaxNetDevice::DIRECTION_UPLINK));
387 ReqType reqType = job->GetType ();
389 if (reqType == UNICAST_POLLING)
391 ServiceUnsolicitedGrants (ssRecord,
398 else if (reqType == DATA)
400 ServiceFlow *serviceFlow = job->GetServiceFlow ();
401 uint32_t allocSizeBytes = job->GetSize ();
402 ServiceBandwidthRequestsBytes (serviceFlow,
410 m_uplinkJobs_high.pop_front ();
415 while ((availableSymbols) && (!m_uplinkJobs_inter.empty ()))
418 Ptr<UlJob> job = m_uplinkJobs_inter.front ();
420 SSRecord * ssRecord = job->GetSsRecord ();
421 enum ServiceFlow::SchedulingType schedulingType = job->GetSchedulingType ();
423 Cid cid = ssRecord->GetBasicCid ();
424 ulMapIe.SetCid (cid);
425 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
427 ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
428 WimaxNetDevice::DIRECTION_UPLINK));
430 ReqType reqType = job->GetType ();
434 ServiceBandwidthRequests (ssRecord,
443 NS_FATAL_ERROR (
"Intermediate priority queue only should enqueue data packets.");
445 m_uplinkJobs_inter.pop_front ();
449 while ((availableSymbols) && (!m_uplinkJobs_low.empty ()))
452 Ptr<UlJob> job = m_uplinkJobs_low.front ();
454 SSRecord * ssRecord = job->GetSsRecord ();
455 enum ServiceFlow::SchedulingType schedulingType = job->GetSchedulingType ();
457 Cid cid = ssRecord->GetBasicCid ();
458 ulMapIe.SetCid (cid);
459 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
461 ulMapIe.SetUiuc (GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
462 WimaxNetDevice::DIRECTION_UPLINK));
464 ReqType reqType = job->GetType ();
468 ServiceBandwidthRequests (ssRecord,
477 NS_FATAL_ERROR (
"Low priority queue only should enqueue data packets.");
479 m_uplinkJobs_low.pop_front ();
482 OfdmUlMapIe ulMapIeEnd;
483 ulMapIeEnd.SetCid (*(
new Cid (0)));
484 ulMapIeEnd.SetStartTime (symbolsToAllocation);
485 ulMapIeEnd.SetUiuc (OfdmUlBurstProfile::UIUC_END_OF_MAP);
486 ulMapIeEnd.SetDuration (0);
487 m_uplinkAllocations.push_back (ulMapIeEnd);
490 GetBs ()->GetBandwidthManager ()->SetSubframeRatio ();
493 bool UplinkSchedulerMBQoS::ServiceBandwidthRequestsBytes (ServiceFlow *serviceFlow,
494 enum ServiceFlow::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
495 const WimaxPhy::ModulationType modulationType,
496 uint32_t &symbolsToAllocation, uint32_t &availableSymbols, uint32_t allocationSizeBytes)
498 uint32_t allocSizeBytes = allocationSizeBytes;
499 uint32_t allocSizeSymbols = 0;
501 ServiceFlowRecord *record = serviceFlow->GetRecord ();
503 uint32_t requiredBandwidth = record->GetRequestedBandwidth ();
505 if (requiredBandwidth > 0)
507 allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (allocSizeBytes, modulationType);
509 if (availableSymbols < allocSizeSymbols)
511 allocSizeSymbols = availableSymbols;
514 if (availableSymbols >= allocSizeSymbols)
517 "At " <<
Simulator::Now ().GetSeconds ()<<
" BS uplink scheduler, "
518 << serviceFlow->GetSchedulingTypeStr ()
519 <<
" allocation, size: " << allocSizeSymbols <<
" symbols"
521 << serviceFlow->GetConnection ()->GetCid ()
522 <<
", SFID: " << serviceFlow->GetSfid ()
523 <<
", bw requested: " << record->GetRequestedBandwidth ()
524 <<
", bw granted: " << allocSizeBytes
527 record->UpdateGrantedBandwidthTemp (allocSizeBytes);
528 record->UpdateGrantedBandwidth (allocSizeBytes);
529 record->UpdateRequestedBandwidth (-allocSizeBytes);
531 record->UpdateBwSinceLastExpiry (allocSizeBytes);
534 AddUplinkAllocation (ulMapIe, allocSizeSymbols, symbolsToAllocation,
547 uint32_t symbols = 0;
548 for (std::list<
Ptr<UlJob> >::iterator iter = jobs.begin (); iter != jobs.end (); ++iter)
562 job->SetSsRecord (ssRecord);
563 job->SetSchedulingType (schedType);
564 job->SetServiceFlow (*(ssRecord->GetServiceFlows (schedType).begin ()));
565 job->SetType (reqType);
572 SSRecord *ssRecord = job->GetSsRecord ();
574 uint32_t allocationSize = 0;
576 if (job->GetType () == UNICAST_POLLING)
581 if ((currentTime - serviceFlow->GetRecord ()->
GetGrantTimeStamp ()).GetMilliSeconds ()
582 >= serviceFlow->GetUnsolicitedPollingInterval ())
584 allocationSize = GetBs ()->GetBwReqOppSize ();
590 uint16_t sduSize = serviceFlow->GetSduSize ();
592 uint32_t requiredBandwidth = record->GetRequestedBandwidth () - record->GetGrantedBandwidth ();
593 if (requiredBandwidth > 0)
595 WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
599 allocationSize = GetBs ()->GetPhy ()->GetNrSymbols (sduSize, modulationType);
603 allocationSize = GetBs ()->GetPhy ()->GetNrSymbols (requiredBandwidth, modulationType);
607 return allocationSize;
616 m_uplinkJobs_high.push_back (job);
618 case UlJob::INTERMEDIATE:
619 m_uplinkJobs_inter.push_back (job);
622 m_uplinkJobs_low.push_back (job);
633 job_front = m_uplinkJobs_high.front ();
634 m_uplinkJobs_high.pop_front ();
636 case UlJob::INTERMEDIATE:
637 job_front = m_uplinkJobs_inter.front ();
638 m_uplinkJobs_inter.pop_front ();
641 job_front = m_uplinkJobs_low.front ();
642 m_uplinkJobs_low.pop_front ();
651 if (m_uplinkJobs_inter.size () > 0)
653 std::list<Ptr<UlJob> >::iterator iter = m_uplinkJobs_inter.begin ();
655 while (iter != m_uplinkJobs_inter.end () && availableSymbols)
660 if (job->GetSchedulingType () == ServiceFlow::SF_TYPE_RTPS)
662 Time deadline = job->GetDeadline ();
663 Time frame_duration = GetBs ()->GetPhy ()->GetFrameDuration ();
668 << job->GetServiceFlow ()->GetMinReservedTrafficRate ()
669 <<
" deadline: "<<job->GetDeadline ().GetSeconds () <<
" frame start: "<<GetBs ()->m_frameStartTime.GetSeconds ()
670 <<
" frame duration: "<< frame_duration );
676 if (availableSymbols)
678 uint32_t availableBytes = GetBs ()->GetPhy ()->GetNrBytes (availableSymbols,job->GetSsRecord ()->GetModulationType ());
679 uint32_t allocationSize = job->GetSize ();
680 if (allocationSize > availableBytes)
682 allocationSize = availableBytes;
686 if (allocationSize == 0)
691 uint32_t symbolsToAllocate = GetBs ()->GetPhy ()->GetNrSymbols (allocationSize, job->GetSsRecord ()->GetModulationType ());
692 if (symbolsToAllocate > availableSymbols)
694 symbolsToAllocate = availableSymbols;
695 allocationSize = GetBs ()->GetPhy ()->GetNrBytes (symbolsToAllocate,job->GetSsRecord ()->GetModulationType ());
698 job->SetSize (job->GetSize () - allocationSize);
702 newJob->SetSsRecord (job->GetSsRecord ());
703 newJob->SetServiceFlow (job->GetServiceFlow ());
704 newJob->SetSize (allocationSize);
705 newJob->SetDeadline (job->GetDeadline ());
706 newJob->SetReleaseTime (job->GetReleaseTime ());
707 newJob->SetSchedulingType (job->GetSchedulingType ());
708 newJob->SetPeriod (job->GetPeriod ());
709 newJob->SetType (job->GetType ());
715 if ((job->GetSize () - allocationSize) == 0)
717 m_uplinkJobs_inter.remove (job);
738 std::list<Ptr<PriorityUlJob> > priorityUlJobs;
741 std::vector<SSRecord*> *ssRecords = GetBs ()->GetSSManager ()->GetSSRecords ();
742 for (std::vector<SSRecord*>::iterator iter = ssRecords->begin (); iter != ssRecords->end (); ++iter)
745 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (ServiceFlow::SF_TYPE_ALL);
746 for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows.begin (); iter2 != serviceFlows.end (); ++iter2)
749 if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_RTPS || serviceFlow->GetSchedulingType ()
750 == ServiceFlow::SF_TYPE_NRTPS)
752 serviceFlow->GetRecord ()->SetBackloggedTemp (serviceFlow->GetRecord ()->GetBacklogged ());
753 serviceFlow->GetRecord ()->SetGrantedBandwidthTemp (serviceFlow->GetRecord ()->GetBwSinceLastExpiry ());
759 for (std::list<
Ptr<UlJob> >::const_iterator iter = m_uplinkJobs_inter.begin (); iter != m_uplinkJobs_inter.end (); ++iter)
764 if ((job->GetSchedulingType () == ServiceFlow::SF_TYPE_RTPS || job->GetSchedulingType ()
765 == ServiceFlow::SF_TYPE_NRTPS) && (serviceFlow->GetRecord ()->GetBacklogged () > 0))
767 uint32_t minReservedTrafficRate = serviceFlow->GetMinReservedTrafficRate ();
768 uint32_t grantedBandwidth = serviceFlow->GetRecord ()->GetBwSinceLastExpiry ();
771 priorityUlJob->SetUlJob (job);
773 if (minReservedTrafficRate <= grantedBandwidth)
775 priorityUlJob->SetPriority (-10000);
779 uint32_t allocationSize = serviceFlow->GetRecord ()->GetRequestedBandwidth ()
780 - serviceFlow->GetRecord ()->GetGrantedBandwidth ();
781 uint32_t sduSize = serviceFlow->GetSduSize ();
783 if (allocationSize > 0)
788 allocationSize = sduSize;
791 int priority = serviceFlow->GetRecord ()->GetBackloggedTemp ()
792 - (serviceFlow->GetRecord ()->GetGrantedBandwidthTemp () - minReservedTrafficRate);
793 priorityUlJob->SetPriority (priority);
794 serviceFlow->GetRecord ()->SetGrantedBandwidthTemp (serviceFlow->GetRecord ()->GetGrantedBandwidthTemp ()
796 serviceFlow->GetRecord ()->SetBackloggedTemp (serviceFlow->GetRecord ()->GetBackloggedTemp ()
800 priorityUlJobs.push_back (priorityUlJob);
806 for (std::list<
Ptr<PriorityUlJob> >::const_iterator iter = priorityUlJobs.begin (); iter != priorityUlJobs.end (); ++iter)
809 Ptr<UlJob> job_priority = priorityUlJob->GetUlJob ();
811 if (availableSymbols)
815 m_uplinkJobs_inter.remove (job);
822 UplinkSchedulerMBQoS::ServiceUnsolicitedGrants (
const SSRecord *ssRecord,
823 enum ServiceFlow::SchedulingType schedulingType,
825 const WimaxPhy::ModulationType modulationType,
826 uint32_t &symbolsToAllocation,
827 uint32_t &availableSymbols)
829 uint32_t allocationSize = 0;
830 uint8_t uiuc = ulMapIe.GetUiuc ();
831 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
833 for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
841 allocationSize = GetBs ()->GetBandwidthManager ()->CalculateAllocationSize (ssRecord, serviceFlow);
843 if (availableSymbols < allocationSize)
848 if (allocationSize > 0)
850 ulMapIe.SetStartTime (symbolsToAllocation);
851 if (serviceFlow->GetSchedulingType () != ServiceFlow::SF_TYPE_UGS)
854 ulMapIe.SetUiuc (OfdmUlBurstProfile::UIUC_REQ_REGION_FULL);
862 if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_UGS)
864 NS_LOG_DEBUG (
"BS uplink scheduler, UGS allocation, size: " << allocationSize <<
" symbols");
868 NS_LOG_DEBUG (
"BS uplink scheduler, " << serviceFlow->GetSchedulingTypeStr () <<
" unicast poll, size: "
869 << allocationSize <<
" symbols" <<
", modulation: BPSK 1/2");
872 NS_LOG_DEBUG (
", CID: " << serviceFlow->GetConnection ()->GetCid () <<
", SFID: " << serviceFlow->GetSfid ());
875 AddUplinkAllocation (ulMapIe, allocationSize, symbolsToAllocation, availableSymbols);
876 ulMapIe.SetUiuc (uiuc);
881 UplinkSchedulerMBQoS::ServiceBandwidthRequests (
const SSRecord *ssRecord,
882 enum ServiceFlow::SchedulingType schedulingType,
883 OfdmUlMapIe &ulMapIe,
884 const WimaxPhy::ModulationType modulationType,
885 uint32_t &symbolsToAllocation,
886 uint32_t &availableSymbols)
888 std::vector<ServiceFlow*> serviceFlows = ssRecord->GetServiceFlows (schedulingType);
890 for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
892 if (!ServiceBandwidthRequests (*iter,
905 UplinkSchedulerMBQoS::ServiceBandwidthRequests (ServiceFlow *serviceFlow,
906 enum ServiceFlow::SchedulingType schedulingType,
907 OfdmUlMapIe &ulMapIe,
908 const WimaxPhy::ModulationType modulationType,
909 uint32_t &symbolsToAllocation,
910 uint32_t &availableSymbols)
912 uint32_t allocSizeBytes = 0;
913 uint32_t allocSizeSymbols = 0;
914 uint16_t sduSize = 0;
916 ServiceFlowRecord *record = serviceFlow->GetRecord ();
917 sduSize = serviceFlow->GetSduSize ();
919 uint32_t requiredBandwidth = record->GetRequestedBandwidth () - record->GetGrantedBandwidth ();
920 if (requiredBandwidth > 0)
925 allocSizeBytes = sduSize;
926 allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (sduSize, modulationType);
931 allocSizeBytes = requiredBandwidth;
932 allocSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (requiredBandwidth, modulationType);
935 if (availableSymbols >= allocSizeSymbols)
937 NS_LOG_DEBUG (
"BS uplink scheduler, " << serviceFlow->GetSchedulingTypeStr () <<
" allocation, size: "
938 << allocSizeSymbols <<
" symbols" <<
", CID: " << serviceFlow->GetConnection ()->GetCid () <<
", SFID: "
939 << serviceFlow->GetSfid () <<
", bw requested: " << record->GetRequestedBandwidth () <<
", bw granted: "
940 << record->GetGrantedBandwidth ());
942 record->UpdateGrantedBandwidth (allocSizeBytes);
944 record->SetBwSinceLastExpiry (allocSizeBytes);
946 if (serviceFlow->GetRecord ()->GetBacklogged () < allocSizeBytes)
948 serviceFlow->GetRecord ()->SetBacklogged (0);
952 serviceFlow->GetRecord ()->IncreaseBacklogged (-allocSizeBytes);
956 AddUplinkAllocation (ulMapIe, allocSizeSymbols, symbolsToAllocation, availableSymbols);
967 UplinkSchedulerMBQoS::AllocateInitialRangingInterval (uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
969 Time ssUlStartTime =
Seconds (CalculateAllocationStartTime () * GetBs ()->GetPsDuration ().GetSeconds ());
970 SetNrIrOppsAllocated (GetBs ()->GetLinkManager ()->CalculateRangingOppsToAllocate ());
971 uint32_t allocationSize = GetNrIrOppsAllocated () * GetBs ()->GetRangReqOppSize ();
972 Time timeSinceLastIrInterval =
Simulator::Now () - GetTimeStampIrInterval ();
975 if (timeSinceLastIrInterval + GetBs ()->GetPhy ()->GetFrameDuration () > GetBs ()->GetInitialRangingInterval ()
976 && availableSymbols >= allocationSize)
978 SetIsIrIntrvlAllocated (
true);
979 OfdmUlMapIe ulMapIeIr;
980 ulMapIeIr.SetCid ((GetBs ()->GetBroadcastConnection ())->GetCid ());
981 ulMapIeIr.SetStartTime (symbolsToAllocation);
982 ulMapIeIr.SetUiuc (OfdmUlBurstProfile::UIUC_INITIAL_RANGING);
984 NS_LOG_DEBUG (
"BS uplink scheduler, initial ranging allocation, size: " << allocationSize <<
" symbols"
985 <<
", modulation: BPSK 1/2" );
988 for (uint8_t i = 0; i < GetNrIrOppsAllocated (); i++)
990 GetBs ()->MarkRangingOppStart (ssUlStartTime +
Seconds (symbolsToAllocation
991 * GetBs ()->GetSymbolDuration ().GetSeconds ()) +
Seconds (i * GetBs ()->GetRangReqOppSize ()
992 * GetBs ()->GetSymbolDuration ().GetSeconds ()));
995 AddUplinkAllocation (ulMapIeIr, allocationSize, symbolsToAllocation, availableSymbols);
1001 UplinkSchedulerMBQoS::SetupServiceFlow (SSRecord *ssRecord, ServiceFlow *serviceFlow)
1003 uint8_t delayNrFrames = 1;
1004 uint32_t bitsPerSecond = serviceFlow->GetMinReservedTrafficRate ();
1005 WimaxPhy::ModulationType modulation;
1006 uint32_t bytesPerFrame =
1007 (uint32_t ((
double)(bitsPerSecond) * GetBs ()->GetPhy ()->GetFrameDuration ().GetSeconds ())) / 8;
1008 uint32_t frameDurationMSec = GetBs ()->GetPhy ()->GetFrameDuration ().GetMilliSeconds ();
1010 switch (serviceFlow->GetSchedulingType ())
1012 case ServiceFlow::SF_TYPE_UGS:
1014 if (serviceFlow->GetIsMulticast () ==
true)
1016 modulation = serviceFlow->GetModulation ();
1020 modulation = ssRecord->GetModulationType ();
1022 uint32_t grantSize = GetBs ()->GetPhy ()->GetNrSymbols (bytesPerFrame, modulation);
1023 serviceFlow->GetRecord ()->SetGrantSize (grantSize);
1025 uint32_t toleratedJitter = serviceFlow->GetToleratedJitter ();
1027 if (toleratedJitter > frameDurationMSec)
1029 delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
1032 uint16_t interval = delayNrFrames * frameDurationMSec;
1033 serviceFlow->SetUnsolicitedGrantInterval (interval);
1036 case ServiceFlow::SF_TYPE_RTPS:
1038 serviceFlow->SetUnsolicitedPollingInterval (20);
1041 case ServiceFlow::SF_TYPE_NRTPS:
1044 uint16_t interval = 1000;
1045 serviceFlow->SetUnsolicitedPollingInterval (interval);
1048 case ServiceFlow::SF_TYPE_BE:
1058 uint32_t UplinkSchedulerMBQoS::GetPendingSize (ServiceFlow* serviceFlow)
1061 std::list<Ptr <PriorityUlJob> > priorityUlJobs;
1064 for (std::list<Ptr<UlJob> >::const_iterator iter = m_uplinkJobs_inter.begin (); iter
1065 != m_uplinkJobs_inter.end (); ++iter)
1067 Ptr<UlJob> job = *iter;
1069 ServiceFlow *serviceFlowJob = job->GetServiceFlow ();
1071 if (serviceFlowJob == serviceFlow)
1073 size += job->GetSize ();
1080 UplinkSchedulerMBQoS::ProcessBandwidthRequest (
const BandwidthRequestHeader &bwRequestHdr)
1083 Ptr<UlJob> job = CreateObject <UlJob> ();
1084 Ptr<WimaxConnection> connection = GetBs ()->GetConnectionManager ()->GetConnection (bwRequestHdr.GetCid ());
1085 SSRecord *ssRecord = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ());
1086 ServiceFlow *serviceFlow = connection->GetServiceFlow ();
1088 uint32_t size = bwRequestHdr.GetBr ();
1089 uint32_t pendingSize = GetPendingSize (serviceFlow);
1091 if (size > pendingSize)
1093 size -= pendingSize;
1108 Time period = deadline;
1111 ssRecord->GetMacAddress () <<
" and sf " << serviceFlow->GetSchedulingType () <<
" with deadline in " << deadline.
GetSeconds () <<
" and size " << size <<
" aggreg size " << bwRequestHdr.GetBr ());
1114 job->SetSsRecord (ssRecord);
1115 job->SetServiceFlow (serviceFlow);
1116 job->SetSize (size);
1117 job->SetDeadline (deadline);
1118 job->SetReleaseTime (currentTime);
1119 job->SetSchedulingType (serviceFlow->GetSchedulingType ());
1120 job->SetPeriod (period);
1121 job->SetType (DATA);
1124 switch (serviceFlow->GetSchedulingType ())
1126 case ServiceFlow::SF_TYPE_RTPS:
1129 case ServiceFlow::SF_TYPE_NRTPS:
1132 case ServiceFlow::SF_TYPE_BE:
1147 uint32_t latency = serviceFlow->GetMaximumLatency ();
1148 Time lastGrantTime = serviceFlow->GetRecord ()->GetLastGrantTime ();
Ptr< UlJob > DequeueJob(UlJob::JobPriority priority)
Dequeue a job from a priority queue.
smart pointer class similar to boost::intrusive_ptr
void GetChannelDescriptorsToUpdate(bool &, bool &, bool &, bool &)
uint32_t CountSymbolsJobs(Ptr< UlJob > job)
this class implements a structure to manage some parameters and statistics related to a service flow ...
#define NS_LOG_COMPONENT_DEFINE(name)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
#define NS_FATAL_ERROR(msg)
fatal error handling
double GetSeconds(void) const
Time GetGrantTimeStamp(void) const
uint32_t CountSymbolsQueue(std::list< Ptr< UlJob > > jobs)
void UplinkSchedWindowTimer(void)
Reset the current window. According to a configured time, reset the window.
#define NS_LOG(level, msg)
void CheckMinimumBandwidth(uint32_t &availableSymbols)
Check if Minimum bandwidth is guarantee. Migrate requests if necessary.
void EnqueueJob(UlJob::JobPriority priority, Ptr< UlJob > job)
Enqueue a job in a priority queue.
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Ptr< UlJob > CreateUlJob(SSRecord *ssRecord, enum ServiceFlow::SchedulingType schedType, ReqType reqType)
#define NS_LOG_DEBUG(msg)
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
This class is used by the base station to store some information related to subscriber station in the...
Time DetermineDeadline(ServiceFlow *serviceFlow)
Calculates deadline of a request.
void CheckDeadline(uint32_t &availableSymbols)
Check deadline from jobs. Migrate requests if necessary.