Loading...
Searching...
No Matches
satellite-frame-allocator.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014 Magister Solutions Ltd
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Sami Rantanen <sami.rantanen@magister.fi>
19 */
20
22
23#include "satellite-utils.h"
24
25#include "ns3/boolean.h"
26#include "ns3/double.h"
27#include "ns3/log.h"
28
29#include <algorithm>
30#include <limits>
31#include <random>
32#include <utility>
33#include <vector>
34
35NS_LOG_COMPONENT_DEFINE("SatFrameAllocator");
36
37namespace ns3
38{
39
40// helper classes defined inside SatFrameAllocator
41
43 : m_ctrlSlotPresent(false),
44 m_craSymbols(0.0),
46 m_rbdcSymbols(0.0),
47 m_vbdcSymbols(0.0)
48{
49 NS_LOG_FUNCTION(this);
50}
51
53 : m_ctrlSlotPresent(false),
54 m_craSymbols(0.0),
56 m_rbdcSymbols(0.0),
57 m_vbdcSymbols(0.0)
58{
59 NS_LOG_FUNCTION(this << (uint32_t)countOfRcs);
60
62}
63
65 Ptr<SatWaveform> trcWaveForm,
66 bool ctrlSlotPresent,
67 double ctrlSlotLength)
68 : m_ctrlSlotPresent(ctrlSlotPresent),
69 m_craSymbols(0.0),
71 m_rbdcSymbols(0.0),
72 m_vbdcSymbols(0.0)
73{
74 NS_LOG_FUNCTION(this << ctrlSlotPresent << ctrlSlotLength);
75
76 for (SatFrameAllocReqItemContainer_t::const_iterator it = req.begin(); it != req.end(); it++)
77 {
78 SatFrameAllocInfoItem reqInSymbols;
79
80 reqInSymbols.m_craSymbols = trcWaveForm->GetBurstLengthInSymbols() * it->m_craBytes /
81 trcWaveForm->GetPayloadInBytes();
82 reqInSymbols.m_minRbdcSymbols = trcWaveForm->GetBurstLengthInSymbols() *
83 it->m_minRbdcBytes / trcWaveForm->GetPayloadInBytes();
84 reqInSymbols.m_rbdcSymbols = trcWaveForm->GetBurstLengthInSymbols() * it->m_rbdcBytes /
85 trcWaveForm->GetPayloadInBytes();
86 reqInSymbols.m_vbdcSymbols = trcWaveForm->GetBurstLengthInSymbols() * it->m_vbdcBytes /
87 trcWaveForm->GetPayloadInBytes();
88
89 // if control slot should be allocated and RC index is 0
90 // add symbols needed for control slot to CRA symbols
91 if (m_ctrlSlotPresent && (it == req.begin()))
92 {
93 reqInSymbols.m_craSymbols += ctrlSlotLength;
94 }
95
96 m_craSymbols += reqInSymbols.m_craSymbols;
97 m_minRbdcSymbols += reqInSymbols.m_minRbdcSymbols;
98 m_rbdcSymbols += reqInSymbols.m_rbdcSymbols;
99 m_vbdcSymbols += reqInSymbols.m_vbdcSymbols;
100
101 m_allocInfoPerRc.push_back(reqInSymbols);
102 }
103}
104
107{
108 NS_LOG_FUNCTION(this);
109
110 m_craSymbols = 0.0;
111 m_minRbdcSymbols = 0.0;
112 m_rbdcSymbols = 0.0;
113 m_vbdcSymbols = 0.0;
114
115 SatFrameAllocInfoItem totalReqs;
116
117 for (SatFrameAllocInfoItemContainer_t::const_iterator it = m_allocInfoPerRc.begin();
118 it != m_allocInfoPerRc.end();
119 it++)
120 {
121 SatFrameAllocInfoItem reqInSymbols;
122
123 m_craSymbols += it->m_craSymbols;
124 m_minRbdcSymbols += it->m_minRbdcSymbols;
125 m_rbdcSymbols += it->m_rbdcSymbols;
126 m_vbdcSymbols += it->m_vbdcSymbols;
127 }
128
129 totalReqs.m_craSymbols = m_craSymbols;
131 totalReqs.m_rbdcSymbols = m_rbdcSymbols;
132 totalReqs.m_vbdcSymbols = m_vbdcSymbols;
133
134 return totalReqs;
135}
136
137double
142
145 : m_utAllocContainer(utAllocContainer),
146 m_ccReqType(ccReqType)
147{
148}
149
150bool
152{
153 bool result = false;
154
155 switch (m_ccReqType)
156 {
157 case CC_TYPE_MIN_RBDC:
158 result = (m_utAllocContainer.at(rcAlloc1.first)
159 .m_request.m_allocInfoPerRc[rcAlloc1.second]
160 .m_minRbdcSymbols < m_utAllocContainer.at(rcAlloc2.first)
161 .m_request.m_allocInfoPerRc[rcAlloc2.second]
162 .m_minRbdcSymbols);
163 break;
164
165 case CC_TYPE_RBDC:
166 result = (m_utAllocContainer.at(rcAlloc1.first)
167 .m_request.m_allocInfoPerRc[rcAlloc1.second]
168 .m_rbdcSymbols < m_utAllocContainer.at(rcAlloc2.first)
169 .m_request.m_allocInfoPerRc[rcAlloc2.second]
170 .m_rbdcSymbols);
171 break;
172
173 case CC_TYPE_VBDC:
174 result = (m_utAllocContainer.at(rcAlloc1.first)
175 .m_request.m_allocInfoPerRc[rcAlloc1.second]
176 .m_vbdcSymbols < m_utAllocContainer.at(rcAlloc2.first)
177 .m_request.m_allocInfoPerRc[rcAlloc2.second]
178 .m_vbdcSymbols);
179 break;
180
181 default:
182 NS_FATAL_ERROR("Invalid CC type!!!");
183 break;
184 }
185
186 return result;
187}
188
189bool
191 const Ptr<SatFrameAllocator>& b) const
192{
193 double bandwidthA = a->m_frameConf->GetBandwidthHz();
194 double bandwidthB = b->m_frameConf->GetBandwidthHz();
195
196 if (bandwidthA == bandwidthB)
197 {
198 return a > b;
199 }
200 return bandwidthA > bandwidthB;
201}
202
203// SatFrameAllocator
204
206 : m_allocationDenied(true),
216 m_configType(SatSuperframeConf::CONFIG_TYPE_0),
217 m_frameId(0),
218 m_frameConf(nullptr),
219 m_parent(nullptr)
220{
221 NS_LOG_FUNCTION(this);
222 NS_FATAL_ERROR("Default constructor not supported!!!");
223}
224
225SatFrameAllocator::SatFrameAllocator(Ptr<SatFrameConf> frameConf,
226 uint8_t frameId,
228 Ptr<SatFrameAllocator> parent)
229 : m_allocationDenied(true),
232 m_configType(configType),
233 m_frameId(frameId),
234 m_frameConf(frameConf),
235 m_parent(parent)
236{
237 NS_LOG_FUNCTION(this << (uint32_t)frameId);
238
239 if (!m_frameConf->IsSubdivided())
240 {
241 m_maxCarrierCount = m_frameConf->GetCarrierCount();
242 }
243
244 m_waveformConf = m_frameConf->GetWaveformConf();
245 m_maxSymbolsPerCarrier = frameConf->GetCarrierMaxSymbols();
247 m_guardTimeSymbols = m_frameConf->GetGuardTimeSymbols();
248
249 switch (m_configType)
250 {
252 m_burstLenghts.push_back(m_waveformConf->GetDefaultBurstLength());
253 m_mostRobustWaveform = m_waveformConf->GetWaveform(m_waveformConf->GetDefaultWaveformId());
254 break;
255 }
256
258 m_burstLenghts.push_back(m_waveformConf->GetDefaultBurstLength());
259
260 uint32_t mostRobustWaveformId = 0;
261
262 if (m_waveformConf->GetMostRobustWaveformId(mostRobustWaveformId,
263 m_waveformConf->GetDefaultBurstLength()))
264 {
265 m_mostRobustWaveform = m_waveformConf->GetWaveform(mostRobustWaveformId);
266 }
267 else
268 {
269 NS_FATAL_ERROR("Most robust waveform not found, error in waveform configuration ???");
270 }
271 break;
272 }
273
276 if (frameConf->GetWaveformConf()->IsAcmEnabled())
277 {
278 m_burstLenghts = frameConf->GetWaveformConf()->GetSupportedBurstLengths();
279 }
280 else
281 {
282 m_burstLenghts.push_back(m_waveformConf->GetDefaultBurstLength());
283 }
284
285 uint32_t mostRobustWaveformId = 0;
286
287 if (m_waveformConf->GetMostRobustWaveformId(mostRobustWaveformId,
289 {
290 m_mostRobustWaveform = m_waveformConf->GetWaveform(mostRobustWaveformId);
291 }
292 else
293 {
294 NS_FATAL_ERROR("Most robust waveform not found, error in waveform configuration ???");
295 }
296 break;
297 }
298
299 default:
300 NS_FATAL_ERROR("Not supported configuration type");
301 break;
302 }
303
304 Reset();
305}
306
307void
324
325void
326SatFrameAllocator::SelectCarriers(uint16_t& count, uint16_t offset)
327{
328 NS_LOG_FUNCTION(this << count << offset);
329
330 uint16_t total = count + offset;
331 if (total > m_frameConf->GetCarrierCount())
332 {
333 NS_FATAL_ERROR("SatFrameAllocator::SetCarrierCount: Amount of carriers in use is greater "
334 "than the amount of carriers in frame.");
335 }
336
337 if (m_frameConf->IsSubdivided())
338 {
339 // Ensure that we get an even number of carriers on subdivided frames
340 if (total % 2)
341 {
342 ++count;
343 }
344 }
345 else
346 {
347 // Ensure that original frames uses their whole bandwidth
348 count = m_frameConf->GetCarrierCount() - offset;
349 }
350
351 m_maxCarrierCount = count;
352 m_carriersOffset = offset;
353
354 NS_LOG_INFO("Frame " << (uint32_t)m_frameId << " selected " << count
355 << " carriers from carrier ID " << offset);
356}
357
358double
360{
361 NS_LOG_FUNCTION(this << ccLevel);
362
363 double load = NAN;
364
365 switch (ccLevel)
366 {
367 case CC_LEVEL_CRA:
369 break;
370
373 break;
374
377 break;
378
382 break;
383
384 default:
385 NS_FATAL_ERROR("Not supported CC level!!!");
386 break;
387 }
388
389 return load;
390}
391
392bool
393SatFrameAllocator::GetBestWaveform(double cno, uint32_t& waveFormId, double& cnoThreshold) const
394{
395 NS_LOG_FUNCTION(this << cno << waveFormId);
396
397 bool cnoSupported = false;
398
399 switch (m_configType)
400 {
402 cnoSupported = true;
403 waveFormId = m_waveformConf->GetDefaultWaveformId();
404 break;
405
407 cnoSupported =
408 m_waveformConf->GetBestWaveformId(cno,
409 m_frameConf->GetBtuConf()->GetSymbolRateInBauds(),
410 waveFormId,
411 cnoThreshold,
412 m_waveformConf->GetDefaultBurstLength());
413 break;
414
417 cnoSupported =
418 m_waveformConf->GetBestWaveformId(cno,
419 m_frameConf->GetBtuConf()->GetSymbolRateInBauds(),
420 waveFormId,
421 cnoThreshold,
423 break;
424
425 default:
426 NS_FATAL_ERROR("Not supported configuration type");
427 break;
428 }
429
430 return cnoSupported;
431}
432
433bool
434SatFrameAllocator::Allocate(CcLevel_t ccLevel, SatFrameAllocReq* allocReq, uint32_t waveFormId)
435{
436 NS_LOG_FUNCTION(this << ccLevel << waveFormId);
437
438 bool allocated = false;
439
441 {
442 // convert request in bytes to symbols based on given waveform
445 m_waveformConf->GetWaveform(waveFormId),
446 allocReq->m_generateCtrlSlot,
447 m_mostRobustWaveform->GetBurstLengthInSymbols());
448 if (reqInSymbols.m_minRbdcSymbols > reqInSymbols.m_rbdcSymbols)
449 {
450 NS_FATAL_ERROR("Min RBDC bytes is greater than RBDC bytes!!!");
451 }
452
453 switch (ccLevel)
454 {
455 case CC_LEVEL_CRA: {
457
458 if ((reqInSymbols.m_craSymbols) <= m_maxSymbolsPerCarrier)
459 {
460 double symbolsLeftInCarrier = m_maxSymbolsPerCarrier - reqInSymbols.m_craSymbols;
461
463 std::min<double>(reqInSymbols.m_minRbdcSymbols, symbolsLeftInCarrier);
465 std::min<double>(reqInSymbols.m_rbdcSymbols, symbolsLeftInCarrier);
466
468 (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols))
469 {
470 double vbdcSymbolsInCarrier = m_maxSymbolsPerCarrier -
471 reqInSymbols.m_craSymbols -
472 reqInSymbols.m_rbdcSymbols;
474 std::min<double>(reqInSymbols.m_vbdcSymbols, vbdcSymbolsInCarrier);
475 }
476
477 allocated = true;
478 }
479 else
480 {
481 NS_FATAL_ERROR("CRA symbols exceeds carrier limit!!!");
482 }
483
484 allocated = true;
485 }
486 break;
487
489 double symbolsLeftInFrame =
491 double symbolsToUse = std::min<double>(symbolsLeftInFrame, m_maxSymbolsPerCarrier);
492
493 if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_minRbdcSymbols))
494 {
497
498 double symbolsLeftInCarrier = m_maxSymbolsPerCarrier - reqInSymbols.m_craSymbols -
499 reqInSymbols.m_minRbdcSymbols;
500
502 std::min<double>(reqInSymbols.m_rbdcSymbols,
503 symbolsLeftInCarrier + reqInSymbols.m_minRbdcSymbols);
504
505 if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols))
506 {
507 double vbdcSymbolsInCarrier = m_maxSymbolsPerCarrier -
508 reqInSymbols.m_craSymbols -
509 reqInSymbols.m_rbdcSymbols;
511 std::min<double>(reqInSymbols.m_vbdcSymbols, vbdcSymbolsInCarrier);
512 }
513
514 allocated = true;
515 }
516 }
517 break;
518
519 case CC_LEVEL_CRA_RBDC: {
520 double symbolsLeftInFrame =
522 double symbolsToUse = std::min<double>(symbolsLeftInFrame, m_maxSymbolsPerCarrier);
523
524 if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols))
525 {
526 double symbolsLeftInCarrier =
527 m_maxSymbolsPerCarrier - reqInSymbols.m_craSymbols - reqInSymbols.m_rbdcSymbols;
528
533 std::min<double>(reqInSymbols.m_vbdcSymbols, symbolsLeftInCarrier);
534
535 allocated = true;
536 }
537 }
538 break;
539
541 double symbolsLeftInFrame = m_totalSymbolsInFrame - m_preAllocatedCraSymbols -
543 double symbolsToUse = std::min<double>(symbolsLeftInFrame, m_maxSymbolsPerCarrier);
544
545 if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols +
546 reqInSymbols.m_vbdcSymbols))
547 {
552
553 allocated = true;
554 }
555 }
556 break;
557
558 default:
559 NS_FATAL_ERROR("Not supported CC level!!!");
560 break;
561 }
562
563 if (allocated)
564 {
565 // update request according to carrier limit and store allocation request
566 UpdateAndStoreAllocReq(allocReq->m_address, allocReq->m_cno, reqInSymbols);
567 }
568 }
569
570 return allocated;
571}
572
573void
574SatFrameAllocator::PreAllocateSymbols(double targetLoad, bool fcaEnabled)
575{
576 NS_LOG_FUNCTION(this << targetLoad << fcaEnabled);
577
579 {
580 if ((targetLoad >= 0) && (targetLoad <= 1))
581 {
583 ShareSymbols(fcaEnabled);
584 }
585 else
586 {
587 NS_FATAL_ERROR("target load must be between 0 and 1.");
588 }
589
590 m_allocationDenied = true;
591 }
592}
593
594void
596 uint32_t maxSizeInBytes,
597 UtAllocInfoContainer_t& utAllocContainer,
598 bool rcBasedAllocationEnabled,
599 TracedCallback<uint32_t> waveformTrace,
600 TracedCallback<uint32_t, uint32_t> utLoadTrace,
601 TracedCallback<uint32_t, double> loadTrace)
602{
603 NS_LOG_FUNCTION(this);
604
605 // variable to watch limit for maximum allowed time slot
606 uint32_t timeslotCount = 0;
607
608 if (tbtpContainer.empty())
609 {
610 NS_FATAL_ERROR("TBTP container must contain at least one message.");
611 }
612
613 Ptr<SatTbtpMessage> tbtpToFill = tbtpContainer.back();
614
615 // sort UTs
616 std::vector<Address> uts = SortUts();
617
618 // sort available carriers in the frame
619 std::vector<uint16_t> carriers = SortCarriers();
620
621 // go through all allocated UT until there is available carriers
622
623 std::vector<uint16_t>::const_iterator currentCarrier = carriers.begin();
624 int64_t carrierSymbolsToUse = m_maxSymbolsPerCarrier;
625 uint32_t utCount = 0;
626 uint32_t symbolsAllocated = 0;
627
628 for (std::vector<Address>::iterator it = uts.begin();
629 (it != uts.end()) && (currentCarrier != carriers.end());
630 it++)
631 {
632 // check before the first slot addition that frame info fit in TBTP in addition to time slot
633 if ((tbtpToFill->GetSizeInBytes() + tbtpToFill->GetTimeSlotInfoSizeInBytes() +
634 tbtpToFill->GetFrameInfoSize()) > maxSizeInBytes)
635 {
636 tbtpToFill = CreateNewTbtp(tbtpContainer);
637 }
638
639 // sort RCs in UT using random method.
640 std::vector<uint32_t> rcIndices = SortUtRcs(*it);
641 std::vector<uint32_t>::const_iterator currentRcIndex = rcIndices.begin();
642
643 int64_t rcSymbolsLeft =
644 m_utAllocs[*it].m_allocation.m_allocInfoPerRc[*currentRcIndex].GetTotalSymbols();
645
646 // generate slots here
647
648 int64_t utSymbolsLeft = m_utAllocs[*it].m_allocation.GetTotalSymbols();
649 int64_t utSymbolsToUse = m_maxSymbolsPerCarrier;
650
651 bool waveformIdTraced = false;
652
653 while (utSymbolsLeft > 0)
654 {
655 Ptr<SatTimeSlotConf> timeSlot = nullptr;
656
657 // try to first create Control slot if present in request and is not already created
658 // otherwise create TRC slot
659 if ((currentRcIndex == rcIndices.begin()) &&
660 m_utAllocs[*it].m_request.m_ctrlSlotPresent &&
661 (m_utAllocs[*it].m_allocation.m_ctrlSlotPresent == false))
662 {
663 timeSlot = CreateCtrlTimeSlot(*currentCarrier,
664 utSymbolsToUse,
665 carrierSymbolsToUse,
666 utSymbolsLeft,
667 rcSymbolsLeft,
668 rcBasedAllocationEnabled);
669
670 // if control slot creation fails try to allocate TRC slot,
671 // this i because control and TRC slot may use different waveforms (different amount
672 // of symbols)
673 if (timeSlot)
674 {
675 m_utAllocs[*it].m_allocation.m_ctrlSlotPresent = true;
676 }
677 else
678 {
679 timeSlot = CreateTimeSlot(*currentCarrier,
680 utSymbolsToUse,
681 carrierSymbolsToUse,
682 utSymbolsLeft,
683 rcSymbolsLeft,
684 m_utAllocs[*it].m_cno,
685 rcBasedAllocationEnabled);
686 }
687 }
688 else
689 {
690 timeSlot = CreateTimeSlot(*currentCarrier,
691 utSymbolsToUse,
692 carrierSymbolsToUse,
693 utSymbolsLeft,
694 rcSymbolsLeft,
695 m_utAllocs[*it].m_cno,
696 rcBasedAllocationEnabled);
697 }
698
699 // if creation succeeded, add slot to TBTP and update allocation info container
700 if (timeSlot)
701 {
702 // trace first used wave form per UT
703 if (!waveformIdTraced)
704 {
705 waveformIdTraced = true;
706 waveformTrace(timeSlot->GetWaveFormId());
707 utCount++;
708 }
709
710 if ((tbtpToFill->GetSizeInBytes() + tbtpToFill->GetTimeSlotInfoSizeInBytes()) >
711 maxSizeInBytes)
712 {
713 tbtpToFill = CreateNewTbtp(tbtpContainer);
714 }
715
716 timeSlot->SetRcIndex(*currentRcIndex);
717
718 if (timeslotCount > SatFrameConf::m_maxTimeSlotCount)
719 {
720 // NS_FATAL_ERROR ("Maximum limit for time slots in a frame reached. Check frame
721 // configuration!!!");
722 }
723
724 tbtpToFill->SetDaTimeslot(Mac48Address::ConvertFrom(*it), m_frameId, timeSlot);
725 timeslotCount++;
726
727 // store needed information to UT allocation container
728 Ptr<SatWaveform> waveform = m_waveformConf->GetWaveform(timeSlot->GetWaveFormId());
729
730 UtAllocInfoContainer_t::iterator utAlloc = GetUtAllocItem(utAllocContainer, *it);
731 utAlloc->second.first.at(*currentRcIndex) += waveform->GetPayloadInBytes();
732 utAlloc->second.second |= m_utAllocs[*it].m_allocation.m_ctrlSlotPresent;
733
734 symbolsAllocated += waveform->GetBurstLengthInSymbols();
735 }
736
737 // select new carrier to use
738 if (carrierSymbolsToUse <= 0)
739 {
740 carrierSymbolsToUse = m_maxSymbolsPerCarrier;
741 currentCarrier++;
742
743 if (currentCarrier == carriers.end())
744 {
745 // stop if no more carriers left
746 utSymbolsLeft = 0;
747 }
748 }
749
750 // select new RC to use
751 if (rcSymbolsLeft <= 0)
752 {
753 currentRcIndex++;
754
755 if (currentRcIndex == rcIndices.end())
756 {
757 // stop if last RC handled
758 utSymbolsLeft = 0;
759 }
760 else
761 {
762 rcSymbolsLeft = m_utAllocs[*it]
763 .m_allocation.m_allocInfoPerRc[*currentRcIndex]
764 .GetTotalSymbols();
765 }
766 }
767
768 // carrier limit for UT reached, so we need to stop because time slot cannot generated
769 // anymore
770 if ((utSymbolsToUse <= 0) || (currentCarrier == carriers.end()))
771 {
772 utSymbolsLeft = 0;
773 }
774 }
775
776 m_utAllocs[*it].m_allocation.m_ctrlSlotPresent = false;
777 }
778
779 // trace out frame UT load
780 utLoadTrace((uint32_t)m_frameId, utCount);
781
782 // trace out frame load
783 loadTrace((uint32_t)m_frameId, symbolsAllocated / m_totalSymbolsInFrame);
784}
785
786void
788{
789 NS_LOG_FUNCTION(this);
790
793 {
795
796 if (fcaEnabled)
797 {
798 // share additional VBDC resources
799
800 // calculate how many symbols left over
801 double vbdcSymbolsLeft = m_availableSymbolsInFrame - m_preAllocatedCraSymbols -
803
804 m_preAllocatedVdbcSymbols += vbdcSymbolsLeft;
805
806 // sort RCs according to VBDC requests
808 m_rcAllocs.sort(vbdcCompare);
809
810 uint32_t rcAllocsLeft = m_rcAllocs.size();
811
812 // do share by adding a share to all RC/VBDC allocations
813 for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
814 it != m_rcAllocs.end() && (vbdcSymbolsLeft > 0);
815 it++)
816 {
817 double freeUtSymbols =
818 std::max<double>(0.0,
820 m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
821 double symbolsToAdd =
822 std::min<double>(freeUtSymbols, (vbdcSymbolsLeft / rcAllocsLeft));
823
824 // only share symbols to RCs requested RBDC or VBDC
825 if ((m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_rbdcSymbols >
826 0) ||
827 (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_vbdcSymbols >
828 0))
829 {
830 m_utAllocs.at(it->first)
831 .m_allocation.m_allocInfoPerRc[it->second]
832 .m_vbdcSymbols += symbolsToAdd;
833 m_utAllocs.at(it->first).m_allocation.m_vbdcSymbols += symbolsToAdd;
834 vbdcSymbolsLeft -= symbolsToAdd;
835 }
836
837 rcAllocsLeft--;
838 }
839 }
840 }
842 {
843 // share VBDC resources
844
845 // calculate how many symbols left over
846 double vbdcSymbolsLeft =
848 m_preAllocatedVdbcSymbols = vbdcSymbolsLeft;
849
850 // sort RCs according to VBDC requests
852 m_rcAllocs.sort(vbdcCompare);
853
855
856 uint32_t rcAllocsLeft = m_rcAllocs.size();
857
858 // do share by setting a share to all RC/VBDC allocations
859 for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
860 it != m_rcAllocs.end() && (vbdcSymbolsLeft > 0);
861 it++)
862 {
863 double freeUtSymbols = std::max<double>(
864 0.0,
865 m_maxSymbolsPerCarrier - m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
866 double symbolsToAdd = std::min<double>(freeUtSymbols, (vbdcSymbolsLeft / rcAllocsLeft));
867
868 // only share symbols to RCs requested VBDC
869 if (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_vbdcSymbols > 0)
870 {
871 m_utAllocs.at(it->first).m_allocation.m_allocInfoPerRc[it->second].m_vbdcSymbols =
872 symbolsToAdd;
873 m_utAllocs.at(it->first).m_allocation.m_vbdcSymbols += symbolsToAdd;
874 vbdcSymbolsLeft -= symbolsToAdd;
875 }
876
877 rcAllocsLeft--;
878 }
879 }
881 {
882 // share RBDC resources
883
884 // calculate how many symbols left over
885 double rbdcSymbolsLeft =
887
889 m_preAllocatedRdbcSymbols = rbdcSymbolsLeft;
890
891 // sort RCs according to RBDC requests
893 m_rcAllocs.sort(rbdcCompare);
894
896
897 uint32_t rcAllocsLeft = m_rcAllocs.size();
898
899 // do share by setting a share to all RC/RBDC allocations
900 for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
901 it != m_rcAllocs.end() && (rbdcSymbolsLeft > 0);
902 it++)
903 {
904 double freeUtSymbols = std::max<double>(
905 0.0,
906 m_maxSymbolsPerCarrier - m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
907 double symbolsToAdd = std::min<double>(freeUtSymbols, (rbdcSymbolsLeft / rcAllocsLeft));
908
909 // only share symbols to RCs requested RBDC
910 if (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_rbdcSymbols > 0)
911 {
912 m_utAllocs.at(it->first).m_allocation.m_allocInfoPerRc[it->second].m_rbdcSymbols =
913 symbolsToAdd + m_utAllocs.at(it->first)
914 .m_allocation.m_allocInfoPerRc[it->second]
915 .m_minRbdcSymbols;
916 m_utAllocs.at(it->first).m_allocation.m_rbdcSymbols +=
917 symbolsToAdd + m_utAllocs.at(it->first)
918 .m_allocation.m_allocInfoPerRc[it->second]
919 .m_minRbdcSymbols;
920 rbdcSymbolsLeft -= symbolsToAdd;
921 }
922
923 rcAllocsLeft--;
924 }
925 }
927 {
928 // share minimum RBDC resources
929
930 // calculate how many symbols left over
931 double minRbdcSymbolsLeft = m_availableSymbolsInFrame - m_preAllocatedCraSymbols;
932
934 m_preAllocatedRdbcSymbols = minRbdcSymbolsLeft;
935 m_preAllocatedMinRdbcSymbols = minRbdcSymbolsLeft;
936
937 // sort RCs according to RBDC requests
939 m_rcAllocs.sort(minRbdcCompare);
940
942
943 uint32_t rcAllocsLeft = m_rcAllocs.size();
944
945 // do share by setting a share to all RC/Minimum RBDC and RC/RBDC allocations
946 for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
947 it != m_rcAllocs.end() && (minRbdcSymbolsLeft > 0);
948 it++)
949 {
950 double freeUtSymbols = std::max<double>(
951 0.0,
952 m_maxSymbolsPerCarrier - m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
953 double symbolsToAdd =
954 std::min<double>(freeUtSymbols, (minRbdcSymbolsLeft / rcAllocsLeft));
955
956 // only share symbols to RCs requested RBDC
957 if (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_rbdcSymbols > 0)
958 {
959 m_utAllocs.at(it->first)
960 .m_allocation.m_allocInfoPerRc[it->second]
961 .m_minRbdcSymbols = symbolsToAdd;
962 m_utAllocs.at(it->first).m_allocation.m_minRbdcSymbols += symbolsToAdd;
963
964 m_utAllocs.at(it->first).m_allocation.m_allocInfoPerRc[it->second].m_rbdcSymbols =
965 symbolsToAdd;
966 m_utAllocs.at(it->first).m_allocation.m_rbdcSymbols += symbolsToAdd;
967
968 minRbdcSymbolsLeft -= symbolsToAdd;
969 }
970
971 rcAllocsLeft--;
972 }
973 }
974 else
975 {
976 NS_FATAL_ERROR("CRAs don't fit to frame CAC or configuration error???");
977 }
978}
979
980Ptr<SatTimeSlotConf>
982 int64_t& utSymbolsToUse,
983 int64_t& carrierSymbolsToUse,
984 int64_t& utSymbolsLeft,
985 int64_t& rcSymbolsLeft,
986 double cno,
987 bool rcBasedAllocationEnabled)
988{
989 NS_LOG_FUNCTION(this << carrierId << cno << rcBasedAllocationEnabled);
990
991 Ptr<SatTimeSlotConf> timeSlotConf = nullptr;
992 int64_t symbolsToUse = std::min<int64_t>(carrierSymbolsToUse, utSymbolsToUse);
993 uint32_t waveformId = 0;
994 int64_t timeSlotSymbols = 0;
995
996 if (rcBasedAllocationEnabled || (symbolsToUse + m_guardTimeSymbols < utSymbolsLeft))
997 {
998 timeSlotSymbols =
999 GetOptimalBurtsLengthInSymbols(symbolsToUse, rcSymbolsLeft, cno, waveformId);
1000 }
1001 else
1002 {
1003 timeSlotSymbols =
1004 GetOptimalBurtsLengthInSymbols(symbolsToUse, utSymbolsLeft, cno, waveformId);
1005 }
1006
1007 if (timeSlotSymbols == 0)
1008 {
1009 if (rcSymbolsLeft > 0)
1010 {
1011 if (carrierSymbolsToUse + m_guardTimeSymbols <= utSymbolsToUse)
1012 {
1013 carrierSymbolsToUse -= symbolsToUse;
1014 carrierSymbolsToUse -= m_guardTimeSymbols;
1015 }
1016
1017 utSymbolsToUse -= symbolsToUse;
1018 utSymbolsToUse -= m_guardTimeSymbols;
1019 }
1020 }
1021 else if (rcSymbolsLeft > 0)
1022 {
1023 switch (m_configType)
1024 {
1026 uint16_t index = (m_maxSymbolsPerCarrier - carrierSymbolsToUse) / timeSlotSymbols;
1027 timeSlotConf = m_frameConf->GetTimeSlotConf(carrierId, index);
1028 }
1029 break;
1030
1034 Time startTime =
1035 Seconds((m_maxSymbolsPerCarrier - carrierSymbolsToUse + m_guardTimeSymbols / 2) /
1036 m_frameConf->GetBtuConf()->GetSymbolRateInBauds());
1037 timeSlotConf = Create<SatTimeSlotConf>(startTime,
1038 waveformId,
1039 carrierId,
1041 }
1042 break;
1043
1044 default:
1045 NS_FATAL_ERROR("Not supported configuration type!!!");
1046 break;
1047 }
1048
1049 if (timeSlotConf)
1050 {
1051 carrierSymbolsToUse -= timeSlotSymbols;
1052 utSymbolsToUse -= timeSlotSymbols;
1053
1054 carrierSymbolsToUse -= m_guardTimeSymbols;
1055 utSymbolsToUse -= m_guardTimeSymbols;
1056
1057 if (rcBasedAllocationEnabled)
1058 {
1059 utSymbolsLeft -= std::min(rcSymbolsLeft, timeSlotSymbols);
1060 }
1061 else
1062 {
1063 utSymbolsLeft -= timeSlotSymbols;
1064 }
1065
1066 rcSymbolsLeft -= timeSlotSymbols;
1067 }
1068 }
1069
1070 return timeSlotConf;
1071}
1072
1073Ptr<SatTimeSlotConf>
1075 int64_t& utSymbolsToUse,
1076 int64_t& carrierSymbolsToUse,
1077 int64_t& utSymbolsLeft,
1078 int64_t& rcSymbolsLeft,
1079 bool rcBasedAllocationEnabled)
1080{
1081 NS_LOG_FUNCTION(this);
1082
1083 Ptr<SatTimeSlotConf> timeSlotConf = nullptr;
1084 int64_t symbolsToUse = std::min<int64_t>(carrierSymbolsToUse, utSymbolsToUse);
1085
1086 int64_t timeSlotSymbols = m_mostRobustWaveform->GetBurstLengthInSymbols();
1087
1088 if (timeSlotSymbols + m_guardTimeSymbols <= symbolsToUse)
1089 {
1090 Time startTime =
1091 Seconds((m_maxSymbolsPerCarrier - carrierSymbolsToUse + m_guardTimeSymbols / 2) /
1092 m_frameConf->GetBtuConf()->GetSymbolRateInBauds());
1093 timeSlotConf = Create<SatTimeSlotConf>(startTime,
1094 m_mostRobustWaveform->GetWaveformId(),
1095 carrierId,
1097
1098 carrierSymbolsToUse -= timeSlotSymbols;
1099 utSymbolsToUse -= timeSlotSymbols;
1100
1101 carrierSymbolsToUse -= m_guardTimeSymbols;
1102 utSymbolsToUse -= m_guardTimeSymbols;
1103
1104 if (rcBasedAllocationEnabled)
1105 {
1106 utSymbolsLeft -= std::min(rcSymbolsLeft, timeSlotSymbols);
1107 }
1108 else
1109 {
1110 utSymbolsLeft -= timeSlotSymbols;
1111 }
1112
1113 rcSymbolsLeft -= timeSlotSymbols;
1114 }
1115
1116 return timeSlotConf;
1117}
1118
1119uint32_t
1121 int64_t symbolsLeft,
1122 double cno,
1123 uint32_t& waveformId)
1124{
1125 NS_LOG_FUNCTION(this);
1126
1127 uint32_t burstLength = 0;
1128
1129 for (SatWaveformConf::BurstLengthContainer_t::const_iterator it = m_burstLenghts.begin();
1130 it != m_burstLenghts.end();
1131 it++)
1132 {
1133 uint32_t newLength = *it;
1134 uint32_t selectedWaveformId = 0;
1135
1137 {
1138 waveformId = m_waveformConf->GetDefaultWaveformId();
1139 }
1140 else
1141 {
1142 double cnoThreshold = std::numeric_limits<double>::quiet_NaN();
1143 bool waveformFound =
1144 m_waveformConf->GetBestWaveformId(cno,
1145 m_frameConf->GetBtuConf()->GetSymbolRateInBauds(),
1146 selectedWaveformId,
1147 cnoThreshold,
1148 *it);
1149
1150 if (waveformFound)
1151 {
1152 newLength =
1153 m_waveformConf->GetWaveform(selectedWaveformId)->GetBurstLengthInSymbols();
1154 }
1155 }
1156
1157 if (symbolsToUse >= newLength)
1158 {
1159 if (burstLength < symbolsLeft)
1160 {
1161 if (burstLength < newLength)
1162 {
1163 burstLength = newLength;
1164 waveformId = selectedWaveformId;
1165 }
1166 }
1167 else if ((newLength - symbolsLeft) < (burstLength - symbolsLeft))
1168 {
1169 burstLength = newLength;
1170 waveformId = selectedWaveformId;
1171 }
1172 }
1173 }
1174
1175 return burstLength;
1176}
1177
1178void
1180{
1181 NS_LOG_FUNCTION(this);
1182
1183 for (UtAllocContainer_t::iterator it = m_utAllocs.begin(); it != m_utAllocs.end(); it++)
1184 {
1185 // accept first UT level total requests by updating allocation counters
1186 switch (ccLevel)
1187 {
1188 case CC_LEVEL_CRA:
1189 it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1190 it->second.m_allocation.m_minRbdcSymbols = 0.0;
1191 it->second.m_allocation.m_rbdcSymbols = 0.0;
1192 it->second.m_allocation.m_vbdcSymbols = 0.0;
1193 break;
1194
1196 it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1197 it->second.m_allocation.m_minRbdcSymbols = it->second.m_request.m_minRbdcSymbols;
1198 it->second.m_allocation.m_rbdcSymbols = 0.0;
1199 it->second.m_allocation.m_vbdcSymbols = 0.0;
1200 break;
1201
1202 case CC_LEVEL_CRA_RBDC:
1203 it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1204 it->second.m_allocation.m_minRbdcSymbols = it->second.m_request.m_minRbdcSymbols;
1205 it->second.m_allocation.m_rbdcSymbols = it->second.m_request.m_rbdcSymbols;
1206 it->second.m_allocation.m_vbdcSymbols = 0.0;
1207 break;
1208
1210 it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1211 it->second.m_allocation.m_minRbdcSymbols = it->second.m_request.m_minRbdcSymbols;
1212 it->second.m_allocation.m_rbdcSymbols = it->second.m_request.m_rbdcSymbols;
1213 it->second.m_allocation.m_vbdcSymbols = it->second.m_request.m_vbdcSymbols;
1214 break;
1215
1216 default:
1217 NS_FATAL_ERROR("Not supported CC level!!!");
1218 break;
1219 }
1220
1221 // accept first RC specific requests by updating allocation counters
1222 for (uint32_t i = 0; i < it->second.m_request.m_allocInfoPerRc.size(); i++)
1223 {
1224 switch (ccLevel)
1225 {
1226 case CC_LEVEL_CRA:
1227 it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1228 it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1229 it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols = 0.0;
1230 it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols = 0.0;
1231 it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols = 0.0;
1232 break;
1233
1235 it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1236 it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1237 it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols =
1238 it->second.m_request.m_allocInfoPerRc[i].m_minRbdcSymbols;
1239 it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols = 0.0;
1240 it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols = 0.0;
1241 break;
1242
1243 case CC_LEVEL_CRA_RBDC:
1244 it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1245 it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1246 it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols =
1247 it->second.m_request.m_allocInfoPerRc[i].m_minRbdcSymbols;
1248 it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols =
1249 it->second.m_request.m_allocInfoPerRc[i].m_rbdcSymbols;
1250 it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols = 0.0;
1251 break;
1252
1254 it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1255 it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1256 it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols =
1257 it->second.m_request.m_allocInfoPerRc[i].m_minRbdcSymbols;
1258 it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols =
1259 it->second.m_request.m_allocInfoPerRc[i].m_rbdcSymbols;
1260 it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols =
1261 it->second.m_request.m_allocInfoPerRc[i].m_vbdcSymbols;
1262 break;
1263
1264 default:
1265 NS_FATAL_ERROR("Not supported CC level!!!");
1266 break;
1267 }
1268 }
1269 }
1270}
1271
1272void
1274{
1275 NS_LOG_FUNCTION(this);
1276
1277 if ((m_maxSymbolsPerCarrier - req.m_craSymbols) < 0)
1278 {
1279 NS_FATAL_ERROR("CRA does not fit in to carrier. Error in configuration or CAC?");
1280 }
1281 else if ((m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_minRbdcSymbols) < 0)
1282 {
1283 double minRbdcSymbolsLeft = m_maxSymbolsPerCarrier - req.m_craSymbols;
1284
1285 // share symbols left between minimum RBDC requests in RCs in relation of the request
1286 for (SatFrameAllocInfoItemContainer_t::iterator it = req.m_allocInfoPerRc.begin();
1287 it != req.m_allocInfoPerRc.end();
1288 it++)
1289 {
1290 it->m_vbdcSymbols = 0.0;
1291 it->m_minRbdcSymbols =
1292 (it->m_minRbdcSymbols / req.m_minRbdcSymbols) * minRbdcSymbolsLeft;
1293 it->m_rbdcSymbols = it->m_minRbdcSymbols;
1294 }
1295
1296 // update UT total request
1297 req.m_minRbdcSymbols = minRbdcSymbolsLeft;
1298 req.m_rbdcSymbols = minRbdcSymbolsLeft;
1299 req.m_vbdcSymbols = 0;
1300 }
1301 else if ((m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_rbdcSymbols) < 0)
1302 {
1303 double rbdcSymbolsLeft = m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_minRbdcSymbols;
1304 double rbdcReqOverMinRbdc = req.m_rbdcSymbols - req.m_minRbdcSymbols;
1305
1306 if (rbdcReqOverMinRbdc > 0)
1307 {
1308 // share symbols left over minimum RBDC between RBDC requests in RCs in relation of the
1309 // request
1310 for (SatFrameAllocInfoItemContainer_t::iterator it = req.m_allocInfoPerRc.begin();
1311 it != req.m_allocInfoPerRc.end();
1312 it++)
1313 {
1314 it->m_vbdcSymbols = 0.0;
1315 double rcRbdcReqOverMinRbdc =
1316 std::max(0.0, (it->m_rbdcSymbols - it->m_minRbdcSymbols));
1317
1318 it->m_rbdcSymbols =
1319 ((rcRbdcReqOverMinRbdc / rbdcReqOverMinRbdc) * rbdcSymbolsLeft) +
1320 it->m_minRbdcSymbols;
1321 }
1322 }
1323
1324 // update UT total request
1325 req.m_rbdcSymbols = rbdcSymbolsLeft + req.m_minRbdcSymbols;
1326 req.m_vbdcSymbols = 0;
1327 }
1328 else if ((m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_rbdcSymbols - req.m_vbdcSymbols) <
1329 0)
1330 {
1331 double vbdcSymbolsLeft = m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_rbdcSymbols;
1332
1333 // share symbols left over RBDC between VBDC requests in RCs in relation of the request
1334 for (SatFrameAllocInfoItemContainer_t::iterator it = req.m_allocInfoPerRc.begin();
1335 it != req.m_allocInfoPerRc.end();
1336 it++)
1337 {
1338 it->m_vbdcSymbols = (it->m_vbdcSymbols / req.m_vbdcSymbols) * vbdcSymbolsLeft;
1339 }
1340
1341 req.m_vbdcSymbols = vbdcSymbolsLeft;
1342 }
1343
1344 // add request and empty allocation info container
1345 UtAllocItem_t utAlloc;
1346 utAlloc.m_request = req;
1347 utAlloc.m_allocation = SatFrameAllocInfo(req.m_allocInfoPerRc.size());
1348 utAlloc.m_cno = cno;
1349
1350 for (uint8_t i = 0; i < req.m_allocInfoPerRc.size(); i++)
1351 {
1352 RcAllocItem_t rcAlloc = std::make_pair(address, i);
1353 m_rcAllocs.push_back(rcAlloc);
1354 }
1355
1356 m_utAllocs.insert(std::make_pair(address, utAlloc));
1357}
1358
1359std::vector<Address>
1361{
1362 NS_LOG_FUNCTION(this);
1363
1364 std::vector<Address> uts;
1365
1366 for (UtAllocContainer_t::const_iterator it = m_utAllocs.begin(); it != m_utAllocs.end(); it++)
1367 {
1368 uts.push_back(it->first);
1369 }
1370
1371 // sort UTs using random method.
1372 std::default_random_engine rng = std::default_random_engine{};
1373 std::shuffle(uts.begin(), uts.end(), rng);
1374
1375 return uts;
1376}
1377
1378std::vector<uint16_t>
1380{
1381 NS_LOG_FUNCTION(this);
1382
1383 std::vector<uint16_t> carriers;
1384
1385 for (uint16_t i = 0; i < m_maxCarrierCount; ++i)
1386 {
1387 carriers.push_back(i + m_carriersOffset);
1388 }
1389
1390 // sort available carriers using random methods.
1391 std::default_random_engine rng = std::default_random_engine{};
1392 std::shuffle(carriers.begin(), carriers.end(), rng);
1393
1394 return carriers;
1395}
1396
1397std::vector<uint32_t>
1399{
1400 NS_LOG_FUNCTION(this);
1401 std::vector<uint32_t> rcIndices;
1402
1403 for (uint32_t i = 0; i < m_utAllocs[ut].m_allocation.m_allocInfoPerRc.size(); i++)
1404 {
1405 rcIndices.push_back(i);
1406 }
1407
1408 // we need to sort (or shuffle) only when there are at least two RCs in addition to RC 0,
1409 // because RC 0 is always first in the list
1410 if (rcIndices.size() > 2)
1411 {
1412 // sort RCs in UT using random method.
1413 std::default_random_engine rng = std::default_random_engine{};
1414 std::shuffle(rcIndices.begin() + 1, rcIndices.end(), rng);
1415 }
1416
1417 return rcIndices;
1418}
1419
1420SatFrameAllocator::UtAllocInfoContainer_t::iterator
1422{
1423 NS_LOG_FUNCTION(this);
1424 UtAllocInfoContainer_t::iterator utAlloc = allocContainer.find(ut);
1425
1426 if (utAlloc == allocContainer.end())
1427 {
1428 UtAllocInfoItem_t rcAllocs;
1429
1430 rcAllocs.second = false;
1431 rcAllocs.first =
1432 std::vector<uint32_t>(m_utAllocs[ut].m_allocation.m_allocInfoPerRc.size(), 0);
1433
1434 std::pair<UtAllocInfoContainer_t::iterator, bool> result =
1435 allocContainer.insert(std::make_pair(ut, rcAllocs));
1436
1437 if (result.second)
1438 {
1439 utAlloc = result.first;
1440 }
1441 else
1442 {
1443 NS_FATAL_ERROR("UT cannot be added to map!!!");
1444 }
1445 }
1446
1447 return utAlloc;
1448}
1449
1450Ptr<SatTbtpMessage>
1452{
1453 NS_LOG_FUNCTION(this);
1454
1455 if (tbtpContainer.empty())
1456 {
1457 NS_FATAL_ERROR("TBTP container is empty");
1458 }
1459
1460 Ptr<SatTbtpMessage> newTbtp =
1461 CreateObject<SatTbtpMessage>(tbtpContainer.back()->GetSuperframeSeqId());
1462 newTbtp->SetSuperframeCounter(tbtpContainer.back()->GetSuperframeCounter());
1463
1464 tbtpContainer.push_back(newTbtp);
1465
1466 return newTbtp;
1467}
1468
1469} // namespace ns3
CcReqCompare class for CC type comparisons.
CcReqType_t
Definition for different comparison types.
CcReqCompare(const UtAllocContainer_t &utAllocContainer, CcReqCompare::CcReqType_t ccReqType)
Construct CcReqCompare.
bool operator()(RcAllocItem_t rcAlloc1, RcAllocItem_t rcAlloc2)
Comparison operator to compare two RC allocations.
CcReqType_t m_ccReqType
Type used for comparisons.
const UtAllocContainer_t & m_utAllocContainer
Reference to UT allocation container.
SatFrameAllocInfo is used to hold a frame's allocation info in symbols.
SatFrameAllocInfoItemContainer_t m_allocInfoPerRc
Information for the RCs.
SatFrameAllocInfo()
Construct empty SatFrameAllocInfo.
double GetTotalSymbols()
Get total symbols of the item.
SatFrameAllocInfoItem UpdateTotalCounts()
Update total count of SatFrameAllocInfo from RCs.
Allocation information item for requests and allocations [symbols] used internally by SatFrameAllocat...
SatFrameAllocReq is used to define frame allocation parameters when requesting allocation from SatFra...
void ShareSymbols(bool fcaEnabled)
Share symbols between all UTs and RCs allocated to the frame.
std::vector< uint16_t > SortCarriers()
Sort carriers belonging to this frame.
Ptr< SatWaveform > m_mostRobustWaveform
double GetCcLoad(CcLevel_t ccLevel)
Get frame load by requested CC.
SatSuperframeConf::ConfigType_t m_configType
void SelectCarriers(uint16_t &amount, uint16_t offset)
Set the amount of carriers used in this frame.
std::map< Address, UtAllocItem_t > UtAllocContainer_t
Map container for UT allocation items.
SatFrameAllocator::UtAllocInfoContainer_t::iterator GetUtAllocItem(UtAllocInfoContainer_t &allocContainer, Address ut)
Get UT allocation item from given container.
bool Allocate(CcLevel_t ccLevel, SatFrameAllocReq *allocReq, uint32_t waveformId)
Allocate symbols to this frame, if criteria are fulfilled.
bool GetBestWaveform(double cno, uint32_t &waveFormId, double &cnoThreshold) const
Get the best waveform supported by this allocator based on given C/N0.
SatWaveformConf::BurstLengthContainer_t m_burstLenghts
Ptr< SatWaveformConf > m_waveformConf
void Reset()
Reset frame allocator.
SatFrameAllocator()
Default constructor (not in used).
std::vector< Address > SortUts()
Sort UTs allocated to this frame.
std::pair< std::vector< uint32_t >, bool > UtAllocInfoItem_t
Pair used to store UT allocation information.
Ptr< SatTimeSlotConf > CreateTimeSlot(uint16_t carrierId, int64_t &utSymbolsToUse, int64_t &carrierSymbolsToUse, int64_t &utSymbolsLeft, int64_t &rcSymbolsLeft, double cno, bool rcBasedAllocationEnabled)
Create time slot according to configuration type.
void UpdateAndStoreAllocReq(Address address, double cno, SatFrameAllocInfo &req)
Update RC/CC requested according to carrier limit.
void AcceptRequests(CcLevel_t ccLevel)
Accept UT/RC requests of the frame according to given CC level.
std::vector< SatFrameAllocInfoItem > SatFrameAllocInfoItemContainer_t
Container to store SatFrameAllocInfoItem items.
std::vector< Ptr< SatTbtpMessage > > TbtpMsgContainer_t
Container to store generated TBTP messages.
uint32_t GetOptimalBurtsLengthInSymbols(int64_t symbolsToUse, int64_t symbolsLeft, double cno, uint32_t &waveformId)
Get optimal burst length in symbols.
Ptr< SatFrameAllocator > m_parent
Ptr< SatTimeSlotConf > CreateCtrlTimeSlot(uint16_t carrierId, int64_t &utSymbolsToUse, int64_t &carrierSymbolsToUse, int64_t &utSymbolsLeft, int64_t &rcSymbolsLeft, bool rcBasedAllocationEnabled)
Create control time slot.
Ptr< SatTbtpMessage > CreateNewTbtp(TbtpMsgContainer_t &tbtpContainer)
Creates new TBTP to given container with information of the last TBTP in container.
void GenerateTimeSlots(SatFrameAllocator::TbtpMsgContainer_t &tbtpContainer, uint32_t maxSizeInBytes, UtAllocInfoContainer_t &utAllocContainer, bool rcBasedAllocationEnabled, TracedCallback< uint32_t > waveformTrace, TracedCallback< uint32_t, uint32_t > utLoadTrace, TracedCallback< uint32_t, double > loadTrace)
Generate time slots for UT/RCs i.e.
@ CC_LEVEL_CRA_RBDC
CC level CRA + RBDC.
@ CC_LEVEL_CRA_RBDC_VBDC
CC level CRA + RBDC + VBDC.
@ CC_LEVEL_CRA_MIN_RBDC
CC level CRA + Minimum RBDC.
std::map< Address, UtAllocInfoItem_t > UtAllocInfoContainer_t
Map container to store UT allocation information.
std::pair< Address, uint8_t > RcAllocItem_t
Pair used as RC allocation item.
void PreAllocateSymbols(double targetLoad, bool fcaEnabled)
Preallocate symbols for all UTs with RCs allocated to the frame.
std::vector< SatFrameAllocReqItem > SatFrameAllocReqItemContainer_t
Container to store SatFrameAllocReqItem items.
std::vector< uint32_t > SortUtRcs(Address ut)
Sort RCs in given UT.
static const uint16_t m_maxTimeSlotCount
This abstract class defines and implements interface of configuration for super frames.
ConfigType_t
Enum for configuration types.
@ CONFIG_TYPE_2
Configuration type 2.
@ CONFIG_TYPE_1
Configuration type 1.
@ CONFIG_TYPE_0
Configuration type 0.
@ CONFIG_TYPE_3
Configuration type 3.
@ SLOT_TYPE_TRC
Control or traffic slot.
static const uint32_t SHORT_BURST_LENGTH
Static variable defining short burst length.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
bool operator()(const Ptr< SatFrameAllocator > &a, const Ptr< SatFrameAllocator > &b) const