satellite-random-access-container.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  * Copyright (c) 2018 CNES
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Frans Laakso <frans.laakso@magister.fi>
20  * Author: Mathias Ettinger <mettinger@toulouse.viveris.fr>
21  */
22 
24 
25 #include <ns3/log.h>
26 
27 NS_LOG_COMPONENT_DEFINE("SatRandomAccess");
28 
29 namespace ns3
30 {
31 
32 NS_OBJECT_ENSURE_REGISTERED(SatRandomAccess);
33 
34 TypeId
36 {
37  static TypeId tid =
38  TypeId("ns3::SatRandomAccess").SetParent<Object>().AddConstructor<SatRandomAccess>();
39  return tid;
40 }
41 
43  : m_uniformRandomVariable(),
44  m_randomAccessModel(SatEnums::RA_MODEL_OFF),
45  m_randomAccessConf(),
46  m_numOfAllocationChannels(),
47 
49  m_crdsaNewData(true)
50 {
51  NS_LOG_FUNCTION(this);
52 
53  NS_FATAL_ERROR("SatRandomAccess::SatRandomAccess - Constructor not in use");
54 }
55 
56 SatRandomAccess::SatRandomAccess(Ptr<SatRandomAccessConf> randomAccessConf,
57  SatEnums::RandomAccessModel_t randomAccessModel)
58  : m_uniformRandomVariable(),
59  m_randomAccessModel(randomAccessModel),
60  m_randomAccessConf(randomAccessConf),
61  m_numOfAllocationChannels(randomAccessConf->GetNumOfAllocationChannelsConfigurations()),
62 
64  m_crdsaNewData(true)
65 {
66  NS_LOG_FUNCTION(this);
67 
68  m_uniformRandomVariable = CreateObject<UniformRandomVariable>();
69 
70  if (m_randomAccessConf == NULL)
71  {
72  NS_FATAL_ERROR("SatRandomAccess::SatRandomAccess - Configuration object is NULL");
73  }
74 
75  SetRandomAccessModel(randomAccessModel);
76 }
77 
79 {
80  NS_LOG_FUNCTION(this);
81 
83  m_randomAccessConf = NULL;
84 
85  if (!m_isDamaAvailableCb.IsNull())
86  {
87  m_isDamaAvailableCb.Nullify();
88  }
89 
90  if (!m_areBuffersEmptyCb.IsNull())
91  {
92  m_areBuffersEmptyCb.Nullify();
93  }
94 }
95 
96 void
98 {
99  NS_LOG_FUNCTION(this);
100 
102  m_randomAccessConf = NULL;
103 
104  if (!m_isDamaAvailableCb.IsNull())
105  {
106  m_isDamaAvailableCb.Nullify();
107  }
108 
109  if (!m_areBuffersEmptyCb.IsNull())
110  {
111  m_areBuffersEmptyCb.Nullify();
112  }
113 }
114 
118 
119 void
121 {
122  NS_LOG_FUNCTION(this << SatEnums::GetRandomAccessModelName(randomAccessModel));
123 
124  m_randomAccessModel = randomAccessModel;
125 }
126 
127 bool
128 SatRandomAccess::IsCrdsaAllocationChannel(uint32_t allocationChannel)
129 {
130  NS_LOG_FUNCTION(this << allocationChannel);
131 
132  return m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
133  ->GetCrdsaAllowed();
134 }
135 
136 bool
138 {
139  NS_LOG_FUNCTION(this << allocationChannel);
140 
141  return m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
142  ->GetSlottedAlohaAllowed();
143 }
144 
145 bool
146 SatRandomAccess::IsEssaAllocationChannel(uint32_t allocationChannel)
147 {
148  NS_LOG_FUNCTION(this << allocationChannel);
149 
150  return m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
151  ->GetEssaAllowed();
152 }
153 
155 SatRandomAccess::DoRandomAccess(uint32_t allocationChannelId,
157 {
158  NS_LOG_FUNCTION(this << allocationChannelId
160 
162  RandomAccessTxOpportunities_s txOpportunities;
163 
165  txOpportunities.allocationChannel = allocationChannelId;
166  uint32_t allocationChannel = GetConfigurationIdForAllocationChannel(allocationChannelId);
167 
168  NS_LOG_INFO("------------------------------------");
169  NS_LOG_INFO("------ Starting Random Access ------");
170  NS_LOG_INFO("------------------------------------");
171 
173  if (triggerType == SatEnums::RA_TRIGGER_TYPE_CRDSA &&
176  {
177  NS_LOG_INFO("Only CRDSA enabled && CRDSA trigger, checking allocation channel");
178 
179  if (IsCrdsaAllocationChannel(allocationChannel))
180  {
181  NS_LOG_INFO("Valid CRDSA allocation channel, checking backoff status");
182 
183  if (CrdsaHasBackoffTimePassed(allocationChannel))
184  {
185  NS_LOG_INFO("CRDSA backoff period over, evaluating CRDSA");
186  txOpportunities = DoCrdsa(allocationChannel);
187  }
188  else
189  {
190  NS_LOG_INFO("CRDSA backoff period in effect, aborting");
193  }
194  }
195  else
196  {
197  NS_FATAL_ERROR(
198  "SatRandomAccess::DoRandomAccess - Invalid allocation channel for CRDSA");
199  }
200  }
203  triggerType == SatEnums::RA_TRIGGER_TYPE_ESSA)
204  {
205  NS_LOG_INFO(
206  "SatRandomAccess::DoRandomAccess - Only ESSA enabled, checking allocation channel");
207 
208  if (IsEssaAllocationChannel(allocationChannel))
209  {
210  NS_LOG_INFO(
211  "SatRandomAccess::DoRandomAccess - Valid allocation channel, evaluating ESSA");
212 
213  txOpportunities = DoEssa(allocationChannel);
214  }
215  else
216  {
217  NS_FATAL_ERROR("SatRandomAccess::DoRandomAccess - Invalid allocation channel for ESSA");
218  }
219  }
221  else if (triggerType == SatEnums::RA_TRIGGER_TYPE_SLOTTED_ALOHA &&
223  {
224  NS_LOG_INFO("Only SA enabled, checking allocation channel");
225 
226  if (IsSlottedAlohaAllocationChannel(allocationChannel))
227  {
228  NS_LOG_INFO("Valid allocation channel, evaluating Slotted ALOHA");
229 
230  txOpportunities = DoSlottedAloha();
231  }
232  else
233  {
234  NS_FATAL_ERROR(
235  "SatRandomAccess::DoRandomAccess - Invalid allocation channel for Slotted ALOHA");
236  }
237  }
241  {
242  NS_LOG_INFO("RA based on RCS2 specification enabled");
243 
244  if (m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
245  ->GetCrdsaNumOfInstances() < 2)
246  {
247  if (triggerType == SatEnums::RA_TRIGGER_TYPE_SLOTTED_ALOHA)
248  {
249  if (IsSlottedAlohaAllocationChannel(allocationChannel))
250  {
251  NS_LOG_INFO("Valid Slotted ALOHA allocation channel, evaluating Slotted ALOHA");
252  txOpportunities = DoSlottedAloha();
253  }
254  else
255  {
256  NS_FATAL_ERROR("SatRandomAccess::DoRandomAccess - Invalid allocation channel "
257  "for Slotted ALOHA");
258  }
259  }
260  else
261  {
262  NS_LOG_INFO("Number of instances is < 2, only Slotted ALOHA is in use");
263  }
264  }
265  else
266  {
267  if (triggerType == SatEnums::RA_TRIGGER_TYPE_CRDSA)
268  {
269  if (IsCrdsaAllocationChannel(allocationChannel))
270  {
271  NS_LOG_INFO("Valid CRDSA allocation channel, checking backoff status");
272 
273  if (CrdsaHasBackoffTimePassed(allocationChannel))
274  {
275  NS_LOG_INFO("CRDSA backoff period over, evaluating CRDSA");
276  txOpportunities = DoCrdsa(allocationChannel);
277  }
278  else
279  {
280  NS_LOG_INFO("CRDSA backoff period in effect, aborting");
283  }
284  }
285  else
286  {
287  NS_FATAL_ERROR(
288  "SatRandomAccess::DoRandomAccess - Invalid allocation channel for CRDSA");
289  }
290  }
291  else
292  {
293  NS_LOG_INFO("Number of instances is > 1, only CRDSA is in use");
294  }
295  }
296  }
297  else if (triggerType == SatEnums::RA_TRIGGER_TYPE_SLOTTED_ALOHA &&
299  {
300  NS_LOG_INFO("Slotted ALOHA is disabled");
301  }
302  else if (triggerType == SatEnums::RA_TRIGGER_TYPE_CRDSA &&
305  {
306  NS_LOG_INFO("CRDSA is disabled");
307  }
308 
313  {
314  std::map<uint32_t, std::set<uint32_t>>::iterator iter;
315  uint32_t uniquePacketId = 1;
316 
317  for (iter = txOpportunities.crdsaTxOpportunities.begin();
318  iter != txOpportunities.crdsaTxOpportunities.end();
319  iter++)
320  {
321  std::set<uint32_t>::iterator iterSet;
322  for (iterSet = iter->second.begin(); iterSet != iter->second.end(); iterSet++)
323  {
324  NS_LOG_INFO("CRDSA transmission opportunity for unique packet: "
325  << uniquePacketId << " at slot: " << (*iterSet));
326  }
327  uniquePacketId++;
328  }
329  }
331  {
332  NS_LOG_INFO("SA minimum time to wait: " << txOpportunities.slottedAlohaTxOpportunity
333  << " milliseconds");
334  }
335  else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_ESSA)
336  {
337  NS_LOG_INFO("SatRandomAccess::DoRandomAccess - ESSA minimum time to wait: "
338  << txOpportunities.slottedAlohaTxOpportunity << " milliseconds");
339  }
340  else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_DO_NOTHING)
341  {
342  NS_LOG_INFO("No Tx opportunity");
343  }
344  else
345  {
346  NS_FATAL_ERROR("SatRandomAccess::DoRandomAccess - Invalid result type");
347  }
348 
349  NS_LOG_INFO("------------------------------------");
350  NS_LOG_INFO("------ Random Access FINISHED ------");
351  NS_LOG_INFO("------------------------------------");
352 
353  return txOpportunities;
354 }
355 
356 void
358 {
359  NS_LOG_FUNCTION(this);
360 
361  NS_LOG_INFO("Simulation time: " << Now().GetSeconds() << " seconds");
362  NS_LOG_INFO("Num of allocation channels: " << m_numOfAllocationChannels);
363  NS_LOG_INFO("New data status: " << m_crdsaNewData);
364 
365  NS_LOG_INFO("---------------");
366 
367  for (uint32_t index = 0; index < m_numOfAllocationChannels; index++)
368  {
369  Ptr<SatRandomAccessAllocationChannel> allocationChannel =
370  m_randomAccessConf->GetAllocationChannelConfiguration(index);
371  NS_LOG_INFO("ALLOCATION CHANNEL: " << index);
372  NS_LOG_INFO("Backoff release at: "
373  << allocationChannel->GetCrdsaBackoffReleaseTime().GetSeconds() << " seconds");
374  NS_LOG_INFO("Backoff time: " << allocationChannel->GetCrdsaBackoffTimeInMilliSeconds()
375  << " milliseconds");
376  NS_LOG_INFO("Backoff probability: " << allocationChannel->GetCrdsaBackoffProbability() * 100
377  << " %");
378  NS_LOG_INFO("Slot randomization: "
379  << allocationChannel->GetCrdsaNumOfInstances() *
380  allocationChannel->GetCrdsaMaxUniquePayloadPerBlock()
381  << " Tx opportunities with range from "
382  << allocationChannel->GetCrdsaMinRandomizationValue() << " to "
383  << allocationChannel->GetCrdsaMaxRandomizationValue());
384  NS_LOG_INFO("Number of unique payloads per block: "
385  << allocationChannel->GetCrdsaMaxUniquePayloadPerBlock());
386  NS_LOG_INFO("Number of instances: " << allocationChannel->GetCrdsaNumOfInstances());
387  NS_LOG_INFO("Number of consecutive blocks accessed: "
388  << allocationChannel->GetCrdsaNumOfConsecutiveBlocksUsed() << "/"
389  << allocationChannel->GetCrdsaMaxConsecutiveBlocksAccessed());
390  NS_LOG_INFO("Number of idle blocks left: " << allocationChannel->GetCrdsaIdleBlocksLeft()
391  << "/"
392  << allocationChannel->GetCrdsaMinIdleBlocks());
393  }
394 }
395 
396 uint32_t
398 {
399  return m_randomAccessConf->GetAllocationChannelConfigurationId(allocationChannelId);
400 }
401 
402 void
403 SatRandomAccess::SetBackoffTime(uint32_t allocationChannel, uint32_t backoffTime)
404 {
405  NS_LOG_FUNCTION(this);
406 
407  switch (m_randomAccessModel)
408  {
410  SetFSimBackoffTimeInFrames(allocationChannel, backoffTime);
411  break;
412  }
415  SetCrdsaBackoffTimeInMilliSeconds(allocationChannel, backoffTime);
416  break;
417  }
418  default: {
419  NS_FATAL_ERROR("SatRandomAccess::SetBackoffTime - Wrong random access model in use");
420  break;
421  }
422  }
423 }
424 
425 void
426 SatRandomAccess::SetBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
427 {
428  NS_LOG_FUNCTION(this);
429 
430  switch (m_randomAccessModel)
431  {
433  SetFSimBackoffProbability(allocationChannel, backoffProbability);
434  break;
435  }
438  SetCrdsaBackoffProbability(allocationChannel, backoffProbability);
439  break;
440  }
441  default: {
442  NS_FATAL_ERROR("SatRandomAccess::SetBackoffProbability - Wrong random access model in use");
443  break;
444  }
445  }
446 }
447 
451 
452 uint32_t
454 {
455  return m_randomAccessConf->GetSlottedAlohaSignalingOverheadInBytes();
456 }
457 
458 void
460  uint32_t controlRandomizationIntervalInMilliSeconds)
461 {
462  NS_LOG_FUNCTION(this << controlRandomizationIntervalInMilliSeconds);
463 
466  {
467  m_randomAccessConf->SetSlottedAlohaControlRandomizationIntervalInMilliSeconds(
468  controlRandomizationIntervalInMilliSeconds);
469 
470  m_randomAccessConf->DoSlottedAlohaVariableSanityCheck();
471  }
472  else
473  {
474  NS_FATAL_ERROR("SatRandomAccess::SetSlottedAlohaControlRandomizationIntervalInMilliSeconds "
475  "- Wrong random access model in use");
476  }
477 
478  NS_LOG_INFO(
479  "New control randomization interval : " << controlRandomizationIntervalInMilliSeconds);
480 }
481 
484 {
485  NS_LOG_FUNCTION(this);
486 
487  RandomAccessTxOpportunities_s txOpportunity;
489 
490  NS_LOG_INFO("---------------------------------------------");
491  NS_LOG_INFO("------ Running Slotted ALOHA algorithm ------");
492  NS_LOG_INFO("---------------------------------------------");
493  NS_LOG_INFO("Slotted ALOHA control randomization interval: "
494  << m_randomAccessConf->GetSlottedAlohaControlRandomizationIntervalInMilliSeconds()
495  << " milliseconds");
496  NS_LOG_INFO("---------------------------------------------");
497 
498  NS_LOG_INFO("Checking if we have DAMA allocations");
499 
501  if (!m_isDamaAvailableCb())
502  {
503  NS_LOG_INFO("No DAMA -> Running Slotted ALOHA");
504 
508  }
509 
510  NS_LOG_INFO("----------------------------------------------");
511  NS_LOG_INFO("------ Slotted ALOHA algorithm FINISHED ------");
512  NS_LOG_INFO("----------------------------------------------");
513 
514  return txOpportunity;
515 }
516 
517 uint32_t
519 {
520  NS_LOG_FUNCTION(this);
521 
522  NS_LOG_INFO("Randomizing the release time...");
523 
524  uint32_t releaseTime = m_uniformRandomVariable->GetInteger(
525  0,
526  m_randomAccessConf->GetSlottedAlohaControlRandomizationIntervalInMilliSeconds());
527 
528  NS_LOG_INFO("TX opportunity in the next slot after " << releaseTime << " milliseconds");
529 
530  return releaseTime;
531 }
532 
536 void
538  uint32_t backoffTimeInFrames)
539 {
543  NS_LOG_FUNCTION(this);
544 
546  {
547  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
548  ->SetFSimBackoffTimeInFrames(backoffTimeInFrames);
549  }
550  else
551  {
552  NS_FATAL_ERROR(
553  "SatRandomAccess::SetFSimBackoffTimeInFrames - Wrong random access model in use");
554  }
555 }
556 
557 void
558 SatRandomAccess::SetFSimBackoffProbability(uint32_t allocationChannel, uint16_t backoffPersistence)
559 {
563  NS_LOG_FUNCTION(this);
564 
566  {
567  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
568  ->SetFSimBackoffProbability(backoffPersistence);
569  }
570  else
571  {
572  NS_FATAL_ERROR(
573  "SatRandomAccess::SetFSimBackoffProbability - Wrong random access model in use");
574  }
575 }
576 
578 SatRandomAccess::DoEssa(uint32_t allocationChannel)
579 {
580  NS_LOG_FUNCTION(this);
581 
582  RandomAccessTxOpportunities_s txOpportunity;
583 
584  NS_LOG_INFO("------------------------------------");
585  NS_LOG_INFO("------ Running ESSA algorithm ------");
586  NS_LOG_INFO("------------------------------------");
587 
589 
595  uint32_t numberOfBackoff = 0;
596  while (m_uniformRandomVariable->GetValue(0.0, 1.0) >
597  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
598  ->GetFSimBackoffProbability())
599  {
600  numberOfBackoff++;
601  }
603  txOpportunity.slottedAlohaTxOpportunity =
604  numberOfBackoff * m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
605  ->GetFSimBackoffTimeInMilliSeconds(); // NOTE: could rename variable
606 
607  NS_LOG_INFO("-------------------------------------");
608  NS_LOG_INFO("------ ESSA algorithm FINISHED ------");
609  NS_LOG_INFO("-------------------------------------");
610 
611  return txOpportunity;
612 }
613 
617 
618 void
620  uint32_t backoffTimeInMilliSeconds)
621 {
622  NS_LOG_FUNCTION(this);
623 
627  {
628  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
629  ->SetCrdsaBackoffTimeInMilliSeconds(backoffTimeInMilliSeconds);
630 
631  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
632  ->DoCrdsaVariableSanityCheck();
633  }
634  else
635  {
636  NS_FATAL_ERROR("SatRandomAccess::SetCrdsaBackoffTimeInMilliSeconds - Wrong random access "
637  "model in use");
638  }
639 }
640 
641 void
642 SatRandomAccess::SetCrdsaBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
643 {
644  NS_LOG_FUNCTION(this);
645 
649  {
650  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
651  ->SetCrdsaBackoffProbability(backoffProbability);
652 
653  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
654  ->DoCrdsaVariableSanityCheck();
655  }
656  else
657  {
658  NS_FATAL_ERROR(
659  "SatRandomAccess::SetCrdsaBackoffProbability - Wrong random access model in use");
660  }
661 }
662 
663 void
665  uint32_t minRandomizationValue,
666  uint32_t maxRandomizationValue,
667  uint32_t numOfInstances)
668 {
669  NS_LOG_FUNCTION(this);
670 
674  {
675  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
676  ->SetCrdsaMinRandomizationValue(minRandomizationValue);
677  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
678  ->SetCrdsaMaxRandomizationValue(maxRandomizationValue);
679  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
680  ->SetCrdsaNumOfInstances(numOfInstances);
681 
682  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
683  ->DoCrdsaVariableSanityCheck();
684  }
685  else
686  {
687  NS_FATAL_ERROR(
688  "SatRandomAccess::SetCrdsaRandomizationParameters - Wrong random access model in use");
689  }
690 }
691 
692 void
694  uint32_t maxUniquePayloadPerBlock,
695  uint32_t maxConsecutiveBlocksAccessed,
696  uint32_t minIdleBlocks)
697 {
698  NS_LOG_FUNCTION(this);
699 
703  {
704  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
705  ->SetCrdsaMaxUniquePayloadPerBlock(maxUniquePayloadPerBlock);
706  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
707  ->SetCrdsaMaxConsecutiveBlocksAccessed(maxConsecutiveBlocksAccessed);
708  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
709  ->SetCrdsaMinIdleBlocks(minIdleBlocks);
710 
711  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
712  ->DoCrdsaVariableSanityCheck();
713  }
714  else
715  {
716  NS_FATAL_ERROR("SatRandomAccess::SetCrdsaMaximumDataRateLimitationParameters - Wrong "
717  "random access model in use");
718  }
719 }
720 
721 uint32_t
723 {
724  NS_LOG_FUNCTION(this);
725 
726  return m_randomAccessConf->GetCrdsaSignalingOverheadInBytes();
727 }
728 
729 bool
730 SatRandomAccess::CrdsaHasBackoffTimePassed(uint32_t allocationChannel) const
731 {
732  NS_LOG_FUNCTION(this);
733 
734  bool hasCrdsaBackoffTimePassed = false;
735 
736  if ((Now() >= m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
737  ->GetCrdsaBackoffReleaseTime()))
738  {
739  hasCrdsaBackoffTimePassed = true;
740  }
741 
742  NS_LOG_INFO("For allocation channel " << allocationChannel << ": "
743  << hasCrdsaBackoffTimePassed);
744 
745  return hasCrdsaBackoffTimePassed;
746 }
747 
748 void
749 SatRandomAccess::CrdsaReduceIdleBlocks(uint32_t allocationChannel)
750 {
751  NS_LOG_FUNCTION(this);
752 
753  uint32_t idleBlocksLeft =
754  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
755  ->GetCrdsaIdleBlocksLeft();
756 
757  if (idleBlocksLeft > 0)
758  {
759  NS_LOG_INFO("Reducing allocation channel: " << allocationChannel << " idle blocks by one");
760  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
761  ->SetCrdsaIdleBlocksLeft(idleBlocksLeft - 1);
762  }
763 }
764 
765 void
767 {
768  NS_LOG_FUNCTION(this);
769 
770  for (uint32_t i = 0; i < m_numOfAllocationChannels; i++)
771  {
773  }
774 }
775 
776 void
778 {
779  NS_LOG_FUNCTION(this << allocationChannel);
780 
781  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
782  ->SetCrdsaNumOfConsecutiveBlocksUsed(0);
783 }
784 
785 void
787 {
788  NS_LOG_FUNCTION(this);
789 
790  for (uint32_t i = 0; i < m_numOfAllocationChannels; i++)
791  {
793  }
794 }
795 
796 bool
798 {
799  NS_LOG_FUNCTION(this);
800 
801  if (m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
802  ->GetCrdsaIdleBlocksLeft() > 0)
803  {
804  NS_LOG_INFO("Allocation channel: " << allocationChannel << " idle in effect");
805  return false;
806  }
807  NS_LOG_INFO("Allocation channel: " << allocationChannel << " free");
808  return true;
809 }
810 
811 bool
812 SatRandomAccess::CrdsaDoBackoff(uint32_t allocationChannel)
813 {
814  NS_LOG_FUNCTION(this);
815 
816  bool doCrdsaBackoff = false;
817 
818  if (m_uniformRandomVariable->GetValue(0.0, 1.0) <
819  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
820  ->GetCrdsaBackoffProbability())
821  {
822  doCrdsaBackoff = true;
823  }
824 
825  NS_LOG_INFO("For allocation channel " << allocationChannel << ": " << doCrdsaBackoff);
826 
827  return doCrdsaBackoff;
828 }
829 
830 void
831 SatRandomAccess::CrdsaSetBackoffTimer(uint32_t allocationChannel)
832 {
833  NS_LOG_FUNCTION(this << allocationChannel);
834 
835  uint32_t backoff = m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
836  ->GetCrdsaBackoffTimeInMilliSeconds();
837  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
838  ->SetCrdsaBackoffReleaseTime(Now() + MilliSeconds(backoff));
839 }
840 
842 SatRandomAccess::CrdsaPrepareToTransmit(uint32_t allocationChannel)
843 {
844  NS_LOG_FUNCTION(this);
845 
846  RandomAccessTxOpportunities_s txOpportunities;
848 
849  uint32_t maxUniquePackets =
850  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
851  ->GetCrdsaMaxUniquePayloadPerBlock();
852 
857 
861  std::pair<std::set<uint32_t>, std::set<uint32_t>> slots;
862 
863  for (uint32_t i = 0; i < maxUniquePackets; i++)
864  {
865  if (CrdsaDoBackoff(allocationChannel))
866  {
867  CrdsaSetBackoffTimer(allocationChannel);
868  break;
869  }
870  else
871  {
872  NS_LOG_INFO("New Tx candidate for allocation channel: " << allocationChannel);
873 
874  if (CrdsaIsAllocationChannelFree(allocationChannel))
875  {
876  NS_LOG_INFO(
877  "Preparing for transmission with allocation channel: " << allocationChannel);
878 
880  slots = CrdsaRandomizeTxOpportunities(allocationChannel, slots);
881 
883  txOpportunities.crdsaTxOpportunities.insert(
884  std::make_pair(*slots.second.begin(), slots.second));
885 
886  if (m_areBuffersEmptyCb())
887  {
888  m_crdsaNewData = true;
889  }
890 
893  }
894  }
895  }
896 
897  return txOpportunities;
898 }
899 
900 void
902 {
903  NS_LOG_FUNCTION(this << allocationChannel);
904 
905  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
906  ->SetCrdsaNumOfConsecutiveBlocksUsed(
907  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
908  ->GetCrdsaNumOfConsecutiveBlocksUsed() +
909  1);
910 
911  if (m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
912  ->GetCrdsaNumOfConsecutiveBlocksUsed() >=
913  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
914  ->GetCrdsaMaxConsecutiveBlocksAccessed())
915  {
916  NS_LOG_INFO("Maximum number of consecutive blocks reached, forcing idle blocks for "
917  "allocation channel: "
918  << allocationChannel);
919 
920  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
921  ->SetCrdsaIdleBlocksLeft(
922  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
923  ->GetCrdsaMinIdleBlocks());
924 
926  }
927 }
928 
929 void
931 {
932  NS_LOG_FUNCTION(this);
933 
934  for (uint32_t i = 0; i < m_numOfAllocationChannels; i++)
935  {
937  }
938 }
939 
941 SatRandomAccess::DoCrdsa(uint32_t allocationChannel)
942 {
943  NS_LOG_FUNCTION(this);
944 
945  RandomAccessTxOpportunities_s txOpportunities;
947 
948  NS_LOG_INFO("-------------------------------------");
949  NS_LOG_INFO("------ Running CRDSA algorithm ------");
950  NS_LOG_INFO("-------------------------------------");
951 
952  PrintVariables();
953 
954  NS_LOG_INFO("-------------------------------------");
955 
956  NS_LOG_INFO("Backoff period over, checking DAMA status...");
957 
958  if (!m_isDamaAvailableCb())
959  {
960  NS_LOG_INFO("No DAMA, checking buffer status...");
961 
962  if (!m_areBuffersEmptyCb())
963  {
964  NS_LOG_INFO("Data in buffer, continuing CRDSA");
965 
966  if (m_crdsaNewData)
967  {
968  m_crdsaNewData = false;
969 
970  NS_LOG_INFO("Evaluating back off...");
971 
972  if (CrdsaDoBackoff(allocationChannel))
973  {
974  NS_LOG_INFO("Initial new data backoff triggered");
975  CrdsaSetBackoffTimer(allocationChannel);
976  }
977  else
978  {
979  txOpportunities = CrdsaPrepareToTransmit(allocationChannel);
980  }
981  }
982  else
983  {
984  txOpportunities = CrdsaPrepareToTransmit(allocationChannel);
985  }
986 
988  {
989  NS_LOG_INFO("Tx opportunity, increasing consecutive blocks used");
990 
992  }
993  else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_DO_NOTHING)
994  {
995  NS_LOG_INFO(
996  "No Tx opportunity, reducing idle blocks & resetting consecutive blocks");
997 
1000  }
1001  }
1002  else
1003  {
1004  NS_LOG_INFO("Empty buffer, reducing idle blocks & resetting consecutive blocks, "
1005  "aborting CRDSA...");
1006 
1009  }
1010  }
1011  else
1012  {
1013  NS_LOG_INFO("DAMA allocation found, aborting CRDSA...");
1014 
1017  }
1018 
1019  NS_LOG_INFO("--------------------------------------");
1020  NS_LOG_INFO("------ CRDSA algorithm FINISHED ------");
1021  NS_LOG_INFO("------ Result: " << SatEnums::GetRandomAccessOpportunityTypeName(
1022  txOpportunities.txOpportunityType)
1023  << " ---------------------");
1024  NS_LOG_INFO("--------------------------------------");
1025 
1026  return txOpportunities;
1027 }
1028 
1029 std::pair<std::set<uint32_t>, std::set<uint32_t>>
1031  uint32_t allocationChannel,
1032  std::pair<std::set<uint32_t>, std::set<uint32_t>> slots)
1033 {
1034  NS_LOG_FUNCTION(this);
1035 
1036  std::pair<std::set<uint32_t>::iterator, bool> resultAllSlotsInFrame;
1037  std::pair<std::set<uint32_t>::iterator, bool> resultThisUniquePacket;
1038 
1039  std::set<uint32_t> emptySet;
1040  slots.second = emptySet;
1041 
1042  NS_LOG_INFO("Randomizing TX opportunities for allocation channel: " << allocationChannel);
1043 
1044  uint32_t successfulInserts = 0;
1045  uint32_t instances = m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
1046  ->GetCrdsaNumOfInstances();
1047  while (successfulInserts < instances)
1048  {
1049  uint32_t slot = m_uniformRandomVariable->GetInteger(
1050  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
1051  ->GetCrdsaMinRandomizationValue(),
1052  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
1053  ->GetCrdsaMaxRandomizationValue());
1054 
1055  resultAllSlotsInFrame = slots.first.insert(slot);
1056 
1057  if (resultAllSlotsInFrame.second)
1058  {
1059  successfulInserts++;
1060 
1061  resultThisUniquePacket = slots.second.insert(slot);
1062 
1063  if (!resultAllSlotsInFrame.second)
1064  {
1065  NS_FATAL_ERROR("SatRandomAccess::CrdsaRandomizeTxOpportunities - Slots out of "
1066  "sync, this should never happen");
1067  }
1068  }
1069 
1070  NS_LOG_INFO("Allocation channel: "
1071  << allocationChannel << " insert successful " << resultAllSlotsInFrame.second
1072  << " for TX opportunity slot: " << (*resultAllSlotsInFrame.first));
1073  }
1074 
1075  NS_LOG_INFO("Randomizing done");
1076 
1077  return slots;
1078 }
1079 
1080 void
1082 {
1083  NS_LOG_FUNCTION(this << &callback);
1084 
1085  m_isDamaAvailableCb = callback;
1086 }
1087 
1088 void
1090 {
1091  NS_LOG_FUNCTION(this << &callback);
1092 
1093  m_areBuffersEmptyCb = callback;
1094 }
1095 
1096 } // namespace ns3
SatEnums class is for simplifying the use of enumerators in the satellite module.
static std::string GetRandomAccessModelName(RandomAccessModel_t model)
static std::string GetRandomAccessTriggerTypeName(RandomAccessTriggerType_t triggerType)
static std::string GetRandomAccessOpportunityTypeName(RandomAccessTxOpportunityType_t opportunityType)
RandomAccessModel_t
The defined random access models.
RandomAccessTriggerType_t
The defined random access trigger types.
SatEnums::RandomAccessModel_t m_randomAccessModel
The used random access model.
void CrdsaResetConsecutiveBlocksUsedForAllAllocationChannels()
Function for resetting the number of consecutive blocks to zero for all allocation channels.
bool IsEssaAllocationChannel(uint32_t allocationChannel)
Function for checking if the allocation channel is ESSA allocation channel.
void PrintVariables()
Function for printing out various module variables to console.
void SetCrdsaMaximumDataRateLimitationParameters(uint32_t allocationChannel, uint32_t maxUniquePayloadPerBlock, uint32_t maxConsecutiveBlocksAccessed, uint32_t minIdleBlocks)
Function for setting the maximum rate limitation parameters.
SatRandomAccess::RandomAccessTxOpportunities_s DoEssa(uint32_t allocationChannel)
Main function for ESSA.
void SetCrdsaBackoffTimeInMilliSeconds(uint32_t allocationChannel, uint32_t backoffTimeInMilliSeconds)
Function for setting the backoff time in milliseconds.
IsDamaAvailableCallback m_isDamaAvailableCb
Callback for known DAMA status.
std::pair< std::set< uint32_t >, std::set< uint32_t > > CrdsaRandomizeTxOpportunities(uint32_t allocationChannel, std::pair< std::set< uint32_t >, std::set< uint32_t >> slots)
Function for randomizing the CRDSA Tx opportunities (slots) for each unique packet.
bool IsSlottedAlohaAllocationChannel(uint32_t allocationChannel)
Function for checking if the allocation channel is Slotted ALOHA allocation channel.
SatRandomAccess::RandomAccessTxOpportunities_s DoRandomAccess(uint32_t allocationChannel, SatEnums::RandomAccessTriggerType_t triggerType)
Main function of this module.
uint32_t m_numOfAllocationChannels
Number of allocation channels available.
void CrdsaIncreaseConsecutiveBlocksUsed(uint32_t allocationChannel)
Function for increasing the allocation channel specific count of consecutive used blocks.
uint32_t GetConfigurationIdForAllocationChannel(uint32_t allocationChannelId)
Function to convert a carrier allocation channel ID into its allocation channel configuration ID.
void CrdsaResetConsecutiveBlocksUsed(uint32_t allocationChannel)
Function for resetting the number of consecutive blocks to zero for a specific allocation channel.
SatRandomAccess::RandomAccessTxOpportunities_s CrdsaPrepareToTransmit(uint32_t allocationChannel)
Function for evaluating backoff for each unique CRDSA packet and calling the randomization of Tx oppo...
bool CrdsaIsAllocationChannelFree(uint32_t allocationChannel)
Function for checking if the allocation channel is free.
void CrdsaIncreaseConsecutiveBlocksUsedForAllAllocationChannels()
Function for increasing the count of consecutive used blocks for all allocation channels.
void SetSlottedAlohaControlRandomizationIntervalInMilliSeconds(uint32_t controlRandomizationIntervalInMilliSeconds)
Function for setting the Slotted ALOHA control randomization interval.
AreBuffersEmptyCallback m_areBuffersEmptyCb
Callback for buffer status.
static TypeId GetTypeId(void)
NS-3 type id function.
Callback< bool > AreBuffersEmptyCallback
Typedef of callback for buffer status.
void CrdsaSetBackoffTimer(uint32_t allocationChannel)
Function for setting the allocation channel specific backoff timer.
void SetFSimBackoffTimeInFrames(uint32_t allocationChannel, uint32_t backoffTimeInFrames)
Function for setting the backoff time in frames.
SatRandomAccess::RandomAccessTxOpportunities_s DoCrdsa(uint32_t allocationChannel)
Main function for CRDSA algorithm.
void SetFSimBackoffProbability(uint32_t allocationChannel, uint16_t backoffPersistence)
Function for setting the backoff probability.
void SetCrdsaRandomizationParameters(uint32_t allocationChannel, uint32_t minRandomizationValue, uint32_t maxRandomizationValue, uint32_t numOfInstances)
Function for setting the parameters related to CRDSA randomization.
Ptr< SatRandomAccessConf > m_randomAccessConf
A pointer to random access configuration.
bool CrdsaHasBackoffTimePassed(uint32_t allocationChannel) const
Function for checking whether the backoff time has passed for this allocation channel.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Uniform random variable object.
void SetAreBuffersEmptyCallback(SatRandomAccess::AreBuffersEmptyCallback callback)
Function for setting the AreBuffersEmpty callback.
void SetRandomAccessModel(SatEnums::RandomAccessModel_t randomAccessModel)
Function for setting the used random access model.
void SetIsDamaAvailableCallback(SatRandomAccess::IsDamaAvailableCallback callback)
Function for setting the IsDamaAvailable callback.
uint32_t GetSlottedAlohaSignalingOverheadInBytes()
Function for getting the Slotted ALOHA signaling overhead in bytes.
bool CrdsaDoBackoff(uint32_t allocationChannel)
Function for evaluating the backoff for this allocation channel.
SatRandomAccess::RandomAccessTxOpportunities_s DoSlottedAloha()
Main function for Slotted ALOHA.
uint32_t SlottedAlohaRandomizeReleaseTime()
Function for performing the Slotted ALOHA release time randomization, i.e., the time after which the ...
void CrdsaReduceIdleBlocksForAllAllocationChannels()
Function for reducing the idle blocks in effect for all allocation channels.
void SetBackoffTime(uint32_t allocationChannel, uint32_t backoffTime)
Function for setting the backoff time.
uint32_t GetCrdsaSignalingOverheadInBytes()
Function for getting the CRDSA signaling overhead in bytes.
bool m_crdsaNewData
A flag defining whether the buffers were emptied the last time RA was evaluated, i....
bool IsCrdsaAllocationChannel(uint32_t allocationChannel)
Function for checking if the allocation channel is CRDSA allocation channel.
void SetCrdsaBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
Function for setting the backoff probability.
void DoDispose()
Function for disposing the module and its variables.
void SetBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
Function for setting the backoff probability.
void CrdsaReduceIdleBlocks(uint32_t allocationChannel)
Function for reducing the allocation channel specific number of idle blocks in effect.
Callback< bool > IsDamaAvailableCallback
Typedef of callback for known DAMA status.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
std::map< uint32_t, std::set< uint32_t > > crdsaTxOpportunities