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