Loading...
Searching...
No Matches
satellite-ut-mac.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: Sami Rantanen <sami.rantanen@magister.fi>
20 * Author: Mathias Ettinger <mettinger@toulouse.viveris.fr>
21 */
22
23#include "satellite-ut-mac.h"
24
31#include "satellite-id-mapper.h"
32#include "satellite-log.h"
33#include "satellite-node-info.h"
37#include "satellite-topology.h"
38#include "satellite-utils.h"
40
41#include "ns3/boolean.h"
42#include "ns3/log.h"
43#include "ns3/mac48-address.h"
44#include "ns3/packet.h"
45#include "ns3/pointer.h"
46#include "ns3/random-variable-stream.h"
47#include "ns3/simulator.h"
48#include "ns3/singleton.h"
49
50#include <iostream>
51#include <map>
52#include <set>
53#include <sstream>
54#include <utility>
55#include <vector>
56
57NS_LOG_COMPONENT_DEFINE("SatUtMac");
58
59namespace ns3
60{
61
62NS_OBJECT_ENSURE_REGISTERED(SatUtMac);
63
64TypeId
66{
67 static TypeId tid =
68 TypeId("ns3::SatUtMac")
69 .SetParent<SatMac>()
70 .AddConstructor<SatUtMac>()
71 .AddAttribute("MaxHandoverMessages",
72 "Max amount of handover messages to send without a handover response "
73 "before loging off",
74 UintegerValue(20),
75 MakeUintegerAccessor(&SatUtMac::m_maxHandoverMessagesSent),
76 MakeUintegerChecker<uint32_t>())
77 .AddAttribute("SuperframeSequence",
78 "Superframe sequence containing information of superframes.",
79 PointerValue(),
80 MakePointerAccessor(&SatUtMac::m_superframeSeq),
81 MakePointerChecker<SatSuperframeSeq>())
82 .AddAttribute("GuardTime",
83 "Guard time in return link",
84 TimeValue(MicroSeconds(1)),
85 MakeTimeAccessor(&SatUtMac::m_guardTime),
86 MakeTimeChecker())
87 .AddAttribute("Scheduler",
88 "UT scheduler used by this Sat UT MAC.",
89 PointerValue(),
90 MakePointerAccessor(&SatUtMac::m_utScheduler),
91 MakePointerChecker<SatUtScheduler>())
92 .AddAttribute("WindowInitLogon",
93 "The initial window for logon waiting time before transmission.",
94 TimeValue(Seconds(20)),
95 MakeTimeAccessor(&SatUtMac::m_windowInitLogon),
96 MakeTimeChecker())
97 .AddAttribute("MaxWaitingTimeLogonResponse",
98 "Timeout for waiting for a response for a logon message.",
99 TimeValue(Seconds(1)),
101 MakeTimeChecker())
102 .AddAttribute("ClockDrift",
103 "Clock drift (number of ticks per second).",
104 IntegerValue(0),
105 MakeIntegerAccessor(&SatUtMac::m_clockDrift),
106 MakeIntegerChecker<int32_t>())
107 .AddTraceSource("DaResourcesTrace",
108 "Assigned dedicated access resources in return link to this UT.",
109 MakeTraceSourceAccessor(&SatUtMac::m_tbtpResourcesTrace),
110 "ns3::SatUtMac::TbtpResourcesTraceCallback");
111 return tid;
112}
113
115 : SatMac(),
116 m_satId(0),
117 m_beamId(),
120 m_randomAccess(nullptr),
121 m_guardTime(MicroSeconds(1)),
122 m_raChannel(0),
124 m_loggedOn(true),
125 m_useLogon(false),
127 m_windowInitLogon(Seconds(20)),
129 m_waitingTimeLogonRng(CreateObject<UniformRandomVariable>()),
133 m_nextPacketTime(Now()),
135 m_timuInfo(0),
137 m_lastNcrDateReceived(Seconds(0)),
138 m_ncr(0),
139 m_deltaNcr(0),
140 m_clockDrift(0),
151{
152 NS_LOG_FUNCTION(this);
153
154 // default constructor should not be used
155 NS_FATAL_ERROR("SatUtMac::SatUtMac - Constructor not in use");
156}
157
158SatUtMac::SatUtMac(Ptr<Node> node,
159 uint32_t satId,
160 uint32_t beamId,
161 Ptr<SatSuperframeSeq> seq,
162 bool crdsaOnlyForControl)
163 : SatMac(satId, beamId),
164 m_node(node),
165 m_satId(satId),
166 m_beamId(beamId),
167 m_superframeSeq(seq),
169 m_guardTime(MicroSeconds(1)),
170 m_raChannel(0),
172 m_loggedOn(true),
173 m_useLogon(false),
175 m_windowInitLogon(Seconds(20)),
177 m_waitingTimeLogonRng(CreateObject<UniformRandomVariable>()),
180 m_crdsaOnlyForControl(crdsaOnlyForControl),
181 m_nextPacketTime(Now()),
183 m_timuInfo(0),
185 m_lastNcrDateReceived(Seconds(0)),
186 m_ncr(0),
187 m_deltaNcr(0),
188 m_clockDrift(0),
199{
200 NS_LOG_FUNCTION(this);
201
202 m_uniformRandomVariable = CreateObject<UniformRandomVariable>();
203 m_tbtpContainer = CreateObject<SatTbtpContainer>(m_superframeSeq);
204}
205
207{
208 NS_LOG_FUNCTION(this);
209
210 m_randomAccess = nullptr;
211 m_tbtpContainer = nullptr;
212 m_timuInfo = nullptr;
213}
214
215void
217{
218 NS_LOG_FUNCTION(this);
219
220 m_timingAdvanceCb.Nullify();
221 m_handoverCallback.Nullify();
222 m_gatewayUpdateCallback.Nullify();
223 m_txCheckCallback.Nullify();
225 m_sendLogonCallback.Nullify();
227 m_tbtpContainer->DoDispose();
228 m_utScheduler->DoDispose();
229 m_utScheduler = nullptr;
230
232}
233
234void
236{
237 NS_LOG_FUNCTION(this << &cb);
239}
240
241void
247
248void
254
255void
257{
258 NS_LOG_FUNCTION(this << &cb);
259
261}
262
263void
270
271void
273{
274 NS_LOG_FUNCTION(this << &cb);
275
277}
278
279void
286
287void
288SatUtMac::SetSatelliteAddress(Address satelliteAddress)
289{
290 m_satelliteAddress = satelliteAddress;
291 m_isRegenerative = true;
292}
293
294Mac48Address
296{
297 NS_LOG_FUNCTION(this);
298
299 return m_gwAddress;
300}
301
302void
303SatUtMac::SetGwAddress(Mac48Address gwAddress)
304{
305 NS_LOG_FUNCTION(this << gwAddress);
306
307 m_gatewayUpdateCallback(gwAddress);
308 m_gwAddress = gwAddress;
309}
310
311void
312SatUtMac::SetNodeInfo(Ptr<SatNodeInfo> nodeInfo)
313{
314 NS_LOG_FUNCTION(this << nodeInfo);
315
316 m_tbtpContainer->SetMacAddress(nodeInfo->GetMacAddress());
317 m_utScheduler->SetNodeInfo(nodeInfo);
318 SatMac::SetNodeInfo(nodeInfo);
319}
320
321void
323{
324 NS_LOG_FUNCTION(this);
325 m_loggedOn = false;
327 m_rcstState.SwitchToOffStandby();
328}
329
330void
331SatUtMac::SetLogonChannel(uint32_t channelId)
332{
333 NS_LOG_FUNCTION(this);
334 m_logonChannel = channelId;
335 m_useLogon = true;
336}
337
338void
339SatUtMac::SetRaChannel(uint32_t raChannel)
340{
341 NS_LOG_FUNCTION(this << raChannel);
342
343 m_raChannel = raChannel;
344}
345
346uint32_t
348{
349 NS_LOG_FUNCTION(this);
350
351 return m_raChannel;
352}
353
354void
355SatUtMac::SetRandomAccess(Ptr<SatRandomAccess> randomAccess)
356{
357 NS_LOG_FUNCTION(this);
358
359 m_randomAccess = randomAccess;
360 m_randomAccess->SetIsDamaAvailableCallback(
362}
363
364bool
366{
367 NS_LOG_FUNCTION(this);
368
369 bool da = m_tbtpContainer->HasScheduledTimeSlots();
370 bool ra = (m_randomAccess != nullptr);
371 if (m_useLogon)
372 {
373 ra = ra && (m_raChannel != m_logonChannel);
374 }
375 return da || ra;
376}
377
378bool
380{
381 NS_LOG_FUNCTION(this);
382
383 bool stateCorrect = (m_rcstState.GetState() == SatUtMacState::RcstState_t::READY_FOR_LOGON);
384 bool ncrReceived = !m_rcstState.IsNcrTimeout();
385
386 return m_useLogon && stateCorrect && ncrReceived;
387}
388
389void
391{
392 NS_LOG_FUNCTION(this << &cb);
393
395
398
399 if (Now() >= nextSuperFrameTxTime)
400 {
401 NS_FATAL_ERROR("Scheduling next superframe start time to the past!");
402 }
403
404 Time schedulingDelay = nextSuperFrameTxTime - Now();
405
406 Simulator::Schedule(GetRealSendingTime(schedulingDelay), &SatUtMac::DoFrameStart, this);
407}
408
409void
416
417Time
418SatUtMac::GetNextSuperFrameTxTime(uint8_t superFrameSeqId) const
419{
420 NS_LOG_FUNCTION(this << (uint32_t)superFrameSeqId);
421
422 Time timingAdvance = m_timingAdvanceCb();
423 Time txTime =
424 Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameTxTime(superFrameSeqId, timingAdvance);
425 return txTime;
426}
427
428Time
429SatUtMac::GetCurrentSuperFrameStartTime(uint8_t superFrameSeqId) const
430{
431 NS_LOG_FUNCTION(this << (uint32_t)superFrameSeqId);
432
433 Time timingAdvance = m_timingAdvanceCb();
434 Time txTime = Singleton<SatRtnLinkTime>::Get()->GetCurrentSuperFrameTxTime(superFrameSeqId,
435 timingAdvance);
436 return txTime;
437}
438
439uint32_t
440SatUtMac::GetCurrentSuperFrameId(uint8_t superFrameSeqId) const
441{
442 NS_LOG_FUNCTION(this << (uint32_t)superFrameSeqId);
443
444 return Singleton<SatRtnLinkTime>::Get()->GetCurrentSuperFrameCount(superFrameSeqId,
446}
447
448void
449SatUtMac::ScheduleTimeSlots(Ptr<SatTbtpMessage> tbtp)
450{
451 NS_LOG_FUNCTION(this << tbtp);
452 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " received TBTP "
453 << tbtp->GetSuperframeCounter());
454
461
465 ->GetConfigType() == SatSuperframeConf::CONFIG_TYPE_4)
466 {
467 return;
468 }
469
470 Time timingAdvance = m_timingAdvanceCb();
471 Time txTime =
472 Singleton<SatRtnLinkTime>::Get()->GetSuperFrameTxTime(tbtp->GetSuperframeSeqId(),
473 tbtp->GetSuperframeCounter(),
474 timingAdvance);
475
476 // The delay compared to Now when to start the transmission of this superframe
477 Time startDelay = txTime - Simulator::Now();
478
479 // Add TBTP to a specific container
480 m_tbtpContainer->Add(txTime, tbtp);
481
482 // if the calculated start time of the superframe is already in the past
483 if (txTime < Simulator::Now())
484 {
485 NS_FATAL_ERROR("UT: " << m_nodeInfo->GetMacAddress() << " received TBTP "
486 << tbtp->GetSuperframeCounter()
487 << ", which should have been sent already in the past");
488 }
489
490 NS_LOG_INFO("Time to start sending the superframe for this UT: " << txTime.GetSeconds());
491 NS_LOG_INFO("Waiting delay before the superframe start: " << startDelay.GetSeconds());
492
493 SatTbtpMessage::DaTimeSlotInfoItem_t info = tbtp->GetDaTimeslots(m_nodeInfo->GetMacAddress());
494
495 // Counters for allocated TBTP resources
496 uint32_t payloadSumInSuperFrame = 0;
497 uint32_t payloadSumPerRcIndex[SatEnums::NUM_FIDS] = {};
498
499 if (!info.second.empty())
500 {
501 NS_LOG_INFO("TBTP contains " << info.second.size()
502 << " timeslots for UT: " << m_nodeInfo->GetMacAddress());
503
504 uint8_t frameId = info.first;
505
506 // schedule time slots
507 for (SatTbtpMessage::DaTimeSlotConfContainer_t::iterator it = info.second.begin();
508 it != info.second.end();
509 it++)
510 {
511 Ptr<SatSuperframeConf> superframeConf =
513 Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
514 Ptr<SatTimeSlotConf> timeSlotConf = *it;
515
516 // Start time
517 Time slotDelay = startDelay + timeSlotConf->GetStartTime();
518 NS_LOG_INFO("Slot start delay: " << slotDelay.GetSeconds());
519
520 // Duration
521 Ptr<SatWaveform> wf =
522 m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
523 Time duration = wf->GetBurstDuration(frameConf->GetBtuConf()->GetSymbolRateInBauds());
524
525 bool drop = false;
526 if (timeSlotConf->GetSlotType() == SatTimeSlotConf::SLOT_TYPE_C)
527 {
528 wf = m_superframeSeq->GetWaveformConf()->GetWaveform(2);
529 duration = wf->GetBurstDuration(frameConf->GetBtuConf()->GetSymbolRateInBauds());
532 {
533 drop = true;
534 }
535 }
536
537 // Carrier
538 uint32_t carrierId =
539 m_superframeSeq->GetCarrierId(0, frameId, timeSlotConf->GetCarrierId());
540
541 if (!drop)
542 {
543 // Schedule individual time slot
544 ScheduleDaTxOpportunity(slotDelay, duration, wf, timeSlotConf, carrierId);
545
546 payloadSumInSuperFrame += wf->GetPayloadInBytes();
547 payloadSumPerRcIndex[timeSlotConf->GetRcIndex()] += wf->GetPayloadInBytes();
548 }
549 }
550 }
551
552 // Assigned TBTP resources
553 m_tbtpResourcesTrace(payloadSumInSuperFrame);
554
555 // Update the allocated TBTP resources for each RC index
556 for (uint32_t i = 0; i < SatEnums::NUM_FIDS; ++i)
557 {
558 m_assignedDaResourcesCallback(i, payloadSumPerRcIndex[i]);
559 }
560}
561
562void
564 Time duration,
565 Ptr<SatWaveform> wf,
566 Ptr<SatTimeSlotConf> tsConf,
567 uint32_t carrierId)
568{
569 NS_LOG_FUNCTION(this << transmitDelay.GetSeconds() << duration.GetSeconds()
570 << wf->GetPayloadInBytes() << (uint32_t)(tsConf->GetRcIndex())
571 << carrierId);
572 NS_LOG_INFO("After delay: " << transmitDelay.GetSeconds() << " duration: "
573 << duration.GetSeconds() << ", payload: " << wf->GetPayloadInBytes()
574 << ", rcIndex: " << (uint32_t)(tsConf->GetRcIndex())
575 << ", carrier: " << carrierId);
576
577 transmitDelay = GetRealSendingTime(transmitDelay);
578
579 if (transmitDelay >= Seconds(0))
580 {
581 Simulator::Schedule(transmitDelay,
583 this,
584 duration,
585 carrierId,
586 wf,
587 tsConf,
589 }
590}
591
592void
594 uint32_t carrierId,
595 Ptr<SatWaveform> wf,
596 Ptr<SatTimeSlotConf> tsConf,
598{
599 NS_LOG_FUNCTION(this << duration.GetSeconds() << wf->GetPayloadInBytes() << carrierId
600 << (uint32_t)(tsConf->GetRcIndex()));
601
602 if (!m_txCheckCallback())
603 {
604 NS_LOG_INFO("Tx is unavailable");
605 m_rcstState.SwitchToHoldStandby();
606 return;
607 }
608
610 (tsConf->GetSlotType() != SatTimeSlotConf::SLOT_TYPE_C) && m_useLogon)
611 {
612 return;
613 }
614
616 FetchPackets(wf->GetPayloadInBytes(), tsConf->GetSlotType(), tsConf->GetRcIndex(), policy);
617
618 if (wf == m_superframeSeq->GetWaveformConf()->GetWaveform(2))
619 {
620 if (packets.size() == 0)
621 {
622 Ptr<Packet> p = Create<Packet>(wf->GetPayloadInBytes());
623
624 // Mark the PDU with FULL_PDU tag
627 p->AddPacketTag(tag);
628
629 // Add MAC tag to identify the packet in lower layers
630 SatMacTag mTag;
633 {
634 mTag.SetDestAddress(Mac48Address::ConvertFrom(m_satelliteAddress));
635 }
636 else
637 {
639 }
640 mTag.SetSourceAddress(m_nodeInfo->GetMacAddress());
641 p->AddPacketTag(mTag);
642
643 // Add MAC tag to identify the packet in lower layers
644 SatAddressE2ETag addressE2ETag;
645 addressE2ETag.SetE2EDestAddress(m_gwAddress);
646 addressE2ETag.SetE2ESourceAddress(m_nodeInfo->GetMacAddress());
647 p->AddPacketTag(addressE2ETag);
648
649 packets.push_back(p);
650 }
651 }
652
653 NS_LOG_INFO("DA Tx opportunity for UT: "
654 << m_nodeInfo->GetMacAddress() << " duration: " << duration.GetSeconds()
655 << ", payload: " << wf->GetPayloadInBytes() << ", carrier: " << carrierId
656 << ", RC index: " << (uint32_t)(tsConf->GetRcIndex()));
657
660 txInfo.modCod = wf->GetModCod();
661 txInfo.fecBlockSizeInBytes = wf->GetPayloadInBytes();
663 txInfo.waveformId = wf->GetWaveformId();
664
665 if (txInfo.waveformId == 2 && tsConf->GetSlotType() != SatTimeSlotConf::SLOT_TYPE_C)
666 {
667 NS_FATAL_ERROR("WF02 should only be used for control bursts");
668 }
669
670 TransmitPackets(packets, duration, carrierId, txInfo);
671}
672
673void
675 Ptr<SatWaveform> waveform,
676 uint32_t carrierId,
677 uint8_t rcIndex,
679{
680 NS_LOG_FUNCTION(this << duration.GetSeconds() << waveform->GetPayloadInBytes() << carrierId
681 << (uint32_t)(rcIndex));
682 NS_LOG_INFO("Tx opportunity for UT: "
683 << m_nodeInfo->GetMacAddress() << " duration: " << duration.GetSeconds()
684 << ", payload: " << waveform->GetPayloadInBytes() << ", carrier: " << carrierId
685 << ", RC index: " << (uint32_t)(rcIndex));
686
688
690 uint32_t payloadBytes = waveform->GetPayloadInBytes();
691
693 payloadBytes -= m_randomAccess->GetSlottedAlohaSignalingOverheadInBytes();
694
695 if (payloadBytes < 1)
696 {
697 NS_FATAL_ERROR(
698 "SatUtMac::DoSlottedAlohaTransmit - Not enough capacity in Slotted ALOHA payload");
699 }
700
702 payloadBytes,
704 rcIndex,
705 policy,
706 true);
707
708 if (!packets.empty())
709 {
710 NS_LOG_INFO("Number of packets sent in a slotted ALOHA slot: " << packets.size());
711
712 for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
713 ++it)
714 {
715 // Add packet trace entry:
716 m_packetTrace(Simulator::Now(),
718 m_nodeInfo->GetNodeType(),
719 m_nodeInfo->GetNodeId(),
720 m_nodeInfo->GetMacAddress(),
724 }
725
728 txInfo.modCod = waveform->GetModCod();
729 txInfo.fecBlockSizeInBytes = waveform->GetPayloadInBytes();
731 txInfo.waveformId = waveform->GetWaveformId();
732
733 TransmitPackets(packets, duration, carrierId, txInfo);
734 }
735}
736
737void
739 Ptr<SatWaveform> waveform,
740 uint32_t carrierId,
741 uint8_t rcIndex,
743{
744 NS_LOG_FUNCTION(this << duration.GetSeconds() << waveform->GetPayloadInBytes() << carrierId
745 << (uint32_t)(rcIndex));
746 NS_LOG_INFO("SatUtMac::DoEssaTransmit - Tx opportunity for UT: "
747 << m_nodeInfo->GetMacAddress() << " at time: " << Simulator::Now().GetSeconds()
748 << " duration: " << duration.GetSeconds()
749 << ", payload: " << waveform->GetPayloadInBytes() << ", carrier: " << carrierId
750 << ", RC index: " << (uint32_t)(rcIndex));
751
753 uint32_t payloadBytes = waveform->GetPayloadInBytes();
754
757 m_utScheduler->DoScheduling(packets,
758 payloadBytes,
760 rcIndex,
761 policy);
762
763 if (!packets.empty())
764 {
765 NS_LOG_INFO("Number of packets sent in a ESSA frame: " << packets.size());
766
767 for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
768 ++it)
769 {
770 // Add packet trace entry:
771 m_packetTrace(Simulator::Now(),
773 m_nodeInfo->GetNodeType(),
774 m_nodeInfo->GetNodeId(),
775 m_nodeInfo->GetMacAddress(),
779 }
780
784 txInfo.modCod = waveform->GetModCod();
785 txInfo.fecBlockSizeInBytes = waveform->GetPayloadInBytes();
787 txInfo.waveformId = waveform->GetWaveformId();
788 txInfo.crdsaUniquePacketId =
789 m_crdsaUniquePacketId; // reuse the crdsaUniquePacketId to identify ESSA frames
790
791 TransmitPackets(packets, duration, carrierId, txInfo);
795 Now() + duration; // TODO: this doesn't take into account the guard bands !!
798 duration = GetRealSendingTime(duration);
799 if (duration >= Seconds(0))
800 {
801 Simulator::Schedule(duration,
803 this,
805 }
807 }
808 else
809 {
811 }
812}
813
815SatUtMac::FetchPackets(uint32_t payloadBytes,
817 uint8_t rcIndex,
819{
820 NS_LOG_FUNCTION(this << payloadBytes << (uint32_t)(rcIndex));
821
828
829 if (payloadBytes <= 0)
830 {
831 NS_FATAL_ERROR("SatUtMac::FetchPackets - unvalid slot payload: " << payloadBytes);
832 }
833
834 ExtractPacketsToSchedule(packets, payloadBytes, type, rcIndex, policy, false);
835
836 // A valid packet received
837 if (!packets.empty())
838 {
839 NS_LOG_INFO("Number of packets: " << packets.size());
840
841 for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
842 ++it)
843 {
844 // Add packet trace entry:
845 m_packetTrace(Simulator::Now(),
847 m_nodeInfo->GetNodeType(),
848 m_nodeInfo->GetNodeId(),
849 m_nodeInfo->GetMacAddress(),
853 }
854 }
855
856 NS_LOG_INFO("The Frame PDU holds " << packets.size() << " RLE PDUs");
857
858 return packets;
859}
860
861void
863 Time duration,
864 uint32_t carrierId,
866{
867 NS_LOG_FUNCTION(this << packets.size() << duration.GetSeconds() << carrierId);
868
870 {
871 m_rcstState.SwitchToOffStandby();
872 }
873
875 {
876 m_rcstState.SwitchToTdmaSync();
877 }
878
879 // If there are packets to send
880 if (!packets.empty())
881 {
882 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << ", transmitting " << packets.size()
883 << " packets, duration: " << duration.GetSeconds()
884 << ", carrier: " << carrierId);
885
886 // Decrease a guard time from time slot duration.
887 Time durationWithoutGuardPeriod(duration - m_guardTime);
888 NS_LOG_INFO("Duration: " << duration.GetSeconds() << " duration with guard period: "
889 << durationWithoutGuardPeriod.GetSeconds());
890 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " send packet");
891
892 SendPacket(packets, carrierId, durationWithoutGuardPeriod, txInfo);
893 }
894}
895
896void
898{
899 NS_LOG_FUNCTION(this << event << (uint32_t)rcIndex);
900
901 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " Queue: " << (uint32_t)rcIndex);
902
903 // Check only the queue events from the control queue
904 if (rcIndex == SatEnums::CONTROL_FID)
905 {
907 {
908 NS_LOG_INFO("Buffered packet event received");
909
910 if (m_randomAccess != nullptr)
911 {
912 NS_LOG_INFO("Doing Slotted ALOHA");
913
915 }
916 }
917 }
918}
919
920void
922{
923 NS_LOG_FUNCTION(this << event << (uint32_t)rcIndex);
924
925 NS_LOG_INFO("SatUtMac::ReceiveQueueEventEssa - UT: " << m_nodeInfo->GetMacAddress()
926 << " time: " << Now().GetSeconds()
927 << " Queue: " << (uint32_t)rcIndex);
928
929 // DoRandomAccess only if it is not scheduled yet
930 // NOTE: could use m_nextPacketTime to do the check
932 {
934 {
935 NS_LOG_INFO("SatUtMac::ReceiveQueueEventEssa - Buffered packet event received");
936
937 if (m_randomAccess != nullptr)
938 {
939 NS_LOG_INFO("SatUtMac::ReceiveQueueEventEssa - Doing ESSA");
940
942 }
943 }
944 }
945}
946
947void
948SatUtMac::SendLogon(Ptr<Packet> packet)
949{
951 packets.push_back(packet);
952
953 Ptr<SatSuperframeConf> superframeConf =
955 uint8_t frameId = superframeConf->GetRaChannelFrameId(m_logonChannel);
956 Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
957
958 Ptr<SatTimeSlotConf> timeSlotConf = frameConf->GetTimeSlotConf(0);
959
960 Ptr<SatWaveform> wf =
961 m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
962 Time duration = wf->GetBurstDuration(frameConf->GetBtuConf()->GetSymbolRateInBauds());
963
964 uint32_t carrierId = m_superframeSeq->GetCarrierId(SatConstVariables::SUPERFRAME_SEQUENCE,
965 frameId,
966 timeSlotConf->GetCarrierId());
967
970 txInfo.modCod = wf->GetModCod();
971 txInfo.sliceId = 0;
972 txInfo.fecBlockSizeInBytes = wf->GetPayloadInBytes();
974 txInfo.waveformId = wf->GetWaveformId();
975
976 Time waitingTime = Seconds(m_waitingTimeLogonRng->GetValue(0.0,
977 pow(1 + m_sendLogonTries, 2) *
978 m_windowInitLogon.GetSeconds()));
980 waitingTime = GetRealSendingTime(waitingTime);
981 if (waitingTime >= Seconds(0))
982 {
983 Simulator::Schedule(waitingTime,
985 this,
986 packets,
987 duration,
988 carrierId,
989 txInfo);
990 }
991
993 Simulator::Now() + m_maxWaitingTimeLogonResponse + waitingTime;
994}
995
996void
997SatUtMac::Receive(SatPhy::PacketContainer_t packets, Ptr<SatSignalParameters> /*rxParams*/)
998{
999 NS_LOG_FUNCTION(this << packets.size());
1000
1001 // Add packet trace entry:
1002 m_packetTrace(Simulator::Now(),
1004 m_nodeInfo->GetNodeType(),
1005 m_nodeInfo->GetNodeId(),
1006 m_nodeInfo->GetMacAddress(),
1009 SatUtils::GetPacketInfo(packets));
1010
1011 // Invoke the `Rx` and `RxDelay` trace sources.
1012 RxTraces(packets);
1013
1014 m_receptionDates.push(Simulator::Now());
1015 if (m_receptionDates.size() > 3)
1016 {
1017 m_receptionDates.pop();
1018 }
1019
1020 for (SatPhy::PacketContainer_t::iterator i = packets.begin(); i != packets.end(); i++)
1021 {
1022 // Remove packet tag
1023 SatMacTag macTag;
1024 bool mSuccess = (*i)->PeekPacketTag(macTag);
1025 if (!mSuccess)
1026 {
1027 NS_FATAL_ERROR("MAC tag was not found from the packet!");
1028 }
1029
1030 SatAddressE2ETag addressE2ETag;
1031 mSuccess = (*i)->PeekPacketTag(addressE2ETag);
1032 if (!mSuccess)
1033 {
1034 NS_FATAL_ERROR("SatAddressE2ETag was not found from the packet!");
1035 }
1036
1037 NS_LOG_INFO("Packet from " << macTag.GetSourceAddress() << " to "
1038 << macTag.GetDestAddress());
1039 NS_LOG_INFO("Receiver " << m_nodeInfo->GetMacAddress());
1040
1041 Mac48Address destAddress = macTag.GetDestAddress();
1042 if (destAddress == m_nodeInfo->GetMacAddress() || destAddress.IsBroadcast() ||
1043 destAddress.IsGroup())
1044 {
1045 // Remove control msg tag
1046 SatControlMsgTag ctrlTag;
1047 bool cSuccess = (*i)->PeekPacketTag(ctrlTag);
1048
1049 if (cSuccess)
1050 {
1052
1054 {
1056 }
1057 else
1058 {
1059 NS_FATAL_ERROR("A control message received with not valid msg type!");
1060 }
1061 }
1062 else if (destAddress.IsBroadcast())
1063 {
1064 // TODO: dummy frames and other broadcast needed to handle
1065 // dummy frames should ignored already in Phy layer
1066 }
1067 // Control msg tag not found, send the packet to higher layer
1068 else
1069 {
1070 // Pass the receiver address to LLC
1071 m_rxCallback(*i,
1072 addressE2ETag.GetE2ESourceAddress(),
1073 addressE2ETag.GetE2EDestAddress());
1074 }
1075 }
1076 }
1077}
1078
1079void
1081{
1082 NS_LOG_FUNCTION(this);
1083
1084 // Remove the mac tag
1085 SatMacTag macTag;
1086 packet->PeekPacketTag(macTag);
1087
1088 SatAddressE2ETag addressE2ETag;
1089 packet->PeekPacketTag(addressE2ETag);
1090
1091 // Peek control msg tag
1092 SatControlMsgTag ctrlTag;
1093 bool cSuccess = packet->PeekPacketTag(ctrlTag);
1094
1095 if (!cSuccess)
1096 {
1097 NS_FATAL_ERROR("SatControlMsgTag not found in the packet!");
1098 }
1099
1100 switch (ctrlTag.GetMsgType())
1101 {
1103 uint32_t tbtpId = ctrlTag.GetMsgId();
1104
1105 Ptr<SatTbtpMessage> tbtp = DynamicCast<SatTbtpMessage>(m_readCtrlCallback(tbtpId));
1106
1112 if (tbtp == nullptr)
1113 {
1114 NS_FATAL_ERROR("TBTP not found, check SatBeamHelper::CtrlMsgStoreTimeInFwdLink "
1115 "attribute is long enough!");
1116 }
1117
1119 {
1121 m_firstTransmittableSuperframeId = tbtp->GetSuperframeCounter();
1122 }
1123 ScheduleTimeSlots(tbtp);
1124
1125 packet->RemovePacketTag(macTag);
1126 packet->RemovePacketTag(addressE2ETag);
1127 packet->RemovePacketTag(ctrlTag);
1128
1129 break;
1130 }
1132 // ARQ ACK messages are forwarded to LLC, since they may be fragmented
1133 m_rxCallback(packet, addressE2ETag.GetE2ESourceAddress(), macTag.GetDestAddress());
1134 break;
1135 }
1137 uint32_t raCtrlId = ctrlTag.GetMsgId();
1138 Ptr<SatRaMessage> raMsg = DynamicCast<SatRaMessage>(m_readCtrlCallback(raCtrlId));
1139
1140 if (raMsg != nullptr)
1141 {
1142 uint32_t allocationChannelId = raMsg->GetAllocationChannelId();
1143 uint16_t backoffProbability = raMsg->GetBackoffProbability();
1144 uint16_t backoffTime = raMsg->GetBackoffTime();
1145
1146 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress()
1147 << " Updating RA backoff probability for AC: "
1148 << allocationChannelId << " to: " << backoffProbability);
1149
1150 m_randomAccess->SetBackoffProbability(allocationChannelId, backoffProbability);
1151 m_randomAccess->SetBackoffTime(allocationChannelId, backoffTime);
1152
1153 packet->RemovePacketTag(macTag);
1154 packet->RemovePacketTag(addressE2ETag);
1155 packet->RemovePacketTag(ctrlTag);
1156 }
1157 else
1158 {
1164 std::stringstream msg;
1165 msg << "Control message " << ctrlTag.GetMsgType()
1166 << " is not found from the FWD link control msg container!";
1167 msg << " at: " << Now().GetSeconds() << "s";
1168 Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
1169 }
1170 break;
1171 }
1173 uint32_t timuCtrlId = ctrlTag.GetMsgId();
1174 Ptr<SatTimuMessage> timuMsg = DynamicCast<SatTimuMessage>(m_readCtrlCallback(timuCtrlId));
1175
1176 if (timuMsg != nullptr)
1177 {
1178 uint32_t beamId = timuMsg->GetAllocatedBeamId();
1179 uint32_t satId = timuMsg->GetAllocatedSatId();
1180 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " switching from beam " << m_beamId
1181 << " to beam " << beamId);
1182 if (m_beamId != beamId)
1183 {
1184 NS_LOG_INFO("Storing TIM-U information internally for later");
1185 m_timuInfo = Create<SatTimuInfo>(beamId,
1186 satId,
1187 timuMsg->GetSatAddress(),
1188 timuMsg->GetGwAddress());
1189 }
1190 }
1191 else
1192 {
1198 std::stringstream msg;
1199 msg << "Control message " << ctrlTag.GetMsgType()
1200 << " is not found from the FWD link control msg container!";
1201 msg << " at: " << Now().GetSeconds() << "s";
1202 Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
1203 }
1204 break;
1205 }
1207 uint32_t sliceCtrlId = ctrlTag.GetMsgId();
1208 Ptr<SatSliceSubscriptionMessage> sliceMsg =
1209 DynamicCast<SatSliceSubscriptionMessage>(m_readCtrlCallback(sliceCtrlId));
1210
1211 if (sliceMsg != nullptr)
1212 {
1213 if (m_nodeInfo->GetMacAddress() == sliceMsg->GetAddress())
1214 {
1215 m_sliceSubscriptionCallback(sliceMsg->GetSliceId());
1216 }
1217 }
1218 else
1219 {
1225 std::stringstream msg;
1226 msg << "Control message " << ctrlTag.GetMsgType()
1227 << " is not found from the FWD link control msg container!";
1228 msg << " at: " << Now().GetSeconds() << "s";
1229 Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
1230 }
1231 break;
1232 }
1234 uint32_t logonId = ctrlTag.GetMsgId();
1235 Ptr<SatLogonResponseMessage> logonMsg =
1236 DynamicCast<SatLogonResponseMessage>(m_readCtrlCallback(logonId));
1237
1238 if (logonMsg != nullptr)
1239 {
1240 m_raChannel = logonMsg->GetRaChannel();
1241 m_loggedOn = true;
1242 m_sendLogonTries = 0;
1243 m_rcstState.SetLogOffCallback(MakeCallback(&SatUtMac::LogOff, this));
1244 m_rcstState.SwitchToReadyForTdmaSync();
1245 m_deltaNcr = Simulator::Now().GetMicroSeconds() * m_clockDrift / 1000000.0;
1246 }
1247 else
1248 {
1254 std::stringstream msg;
1255 msg << "Control message " << ctrlTag.GetMsgType()
1256 << " is not found from the FWD link control msg container!";
1257 msg << " at: " << Now().GetSeconds() << "s";
1258 Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
1259 }
1260 break;
1261 }
1263 uint32_t ncrCtrlId = ctrlTag.GetMsgId();
1264 Ptr<SatNcrMessage> ncrMsg = DynamicCast<SatNcrMessage>(m_readCtrlCallback(ncrCtrlId));
1265
1266 m_lastNcrDateReceived = m_ncrV2 ? m_receptionDates.front() : Simulator::Now();
1267 m_ncr = ncrMsg->GetNcrDate();
1268 m_rcstState.NcrControlMessageReceived();
1269
1271 {
1273 {
1274 m_rcstState.SwitchToReadyForTdmaSync();
1275 }
1276 else
1277 {
1278 m_rcstState.SwitchToReadyForLogon();
1279 }
1280 }
1281 break;
1282 }
1284 uint32_t cmtCtrlId = ctrlTag.GetMsgId();
1285 Ptr<SatCmtMessage> cmtMsg = DynamicCast<SatCmtMessage>(m_readCtrlCallback(cmtCtrlId));
1286 int16_t burstTimeCorrection = cmtMsg->GetBurstTimeCorrection();
1287 m_deltaNcr -= burstTimeCorrection;
1288 break;
1289 }
1291 uint32_t logoffCtrlId = ctrlTag.GetMsgId();
1292 Ptr<SatLogoffMessage> logoffMsg =
1293 DynamicCast<SatLogoffMessage>(m_readCtrlCallback(logoffCtrlId));
1294 LogOff();
1295 break;
1296 }
1297 default: {
1298 NS_FATAL_ERROR("SatUtMac received a non-supported control packet!");
1299 break;
1300 }
1301 }
1302}
1303
1304void
1306{
1307 NS_LOG_FUNCTION(this << randomAccessTriggerType);
1308
1309 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress());
1310
1312 {
1313 return;
1314 }
1315
1319
1321
1323 uint32_t allocationChannel = GetNextRandomAccessAllocationChannel();
1324
1325 if (m_useLogon && allocationChannel == m_logonChannel)
1326 {
1327 NS_LOG_INFO("Logon channel cannot be used for RA transmition");
1328 return;
1329 }
1330
1332 txOpportunities = m_randomAccess->DoRandomAccess(allocationChannel, randomAccessTriggerType);
1333
1336 {
1337 Time txOpportunity = GetRealSendingTime(
1338 Time::FromInteger(txOpportunities.slottedAlohaTxOpportunity, Time::MS));
1339
1340 NS_LOG_INFO("Processing Slotted ALOHA results, Tx evaluation @: "
1341 << (Now() + txOpportunity).GetSeconds() << " seconds");
1342
1344 if (txOpportunity >= Seconds(0))
1345 {
1346 Simulator::Schedule(txOpportunity,
1348 this,
1349 allocationChannel);
1350 }
1351 }
1353 else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_CRDSA)
1354 {
1355 NS_LOG_INFO("Processing CRDSA results");
1356
1358 ScheduleCrdsaTransmission(allocationChannel, txOpportunities);
1359 }
1361 else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_ESSA)
1362 {
1363 NS_LOG_INFO("SatUtMac::DoRandomAccess - Processing ESSA results");
1368 Time txOpportunity = GetRealSendingTime(
1369 Time::FromInteger(txOpportunities.slottedAlohaTxOpportunity, Time::MS));
1370
1372 if (txOpportunity >= Seconds(0))
1373 {
1374 Simulator::Schedule(txOpportunity,
1376 this,
1377 allocationChannel);
1378 }
1379 }
1380}
1381
1382uint32_t
1384{
1385 NS_LOG_FUNCTION(this);
1386
1387 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " has allocation channel " << m_raChannel);
1388
1390 return m_raChannel;
1391}
1392
1393void
1395{
1396 NS_LOG_FUNCTION(this << allocationChannel);
1397
1398 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " AC: " << allocationChannel);
1399
1403 if (!m_tbtpContainer->HasScheduledTimeSlots())
1404 {
1405 NS_LOG_INFO("No known DAMA, selecting a slot for Slotted ALOHA");
1406
1407 Ptr<SatSuperframeConf> superframeConf =
1409 uint8_t frameId = superframeConf->GetRaChannelFrameId(allocationChannel);
1410 Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
1411 uint32_t timeSlotCount = frameConf->GetTimeSlotCount();
1412
1413 std::pair<bool, uint32_t> result = std::make_pair(false, 0);
1414 Time superframeStartTime =
1416
1417 if (Now() < superframeStartTime)
1418 {
1419 NS_FATAL_ERROR("SatUtMac::ScheduleSlottedAlohaTransmission - Invalid SF start time");
1420 }
1421
1423
1424 NS_LOG_INFO("Searching for next available slot");
1425
1428 while (!result.first)
1429 {
1430 NS_LOG_INFO("SuperFrameId: " << superFrameId << ", superframeStartTime: "
1431 << superframeStartTime.GetSeconds());
1432
1433 result = SearchFrameForAvailableSlot(superframeStartTime,
1434 frameConf,
1435 timeSlotCount,
1436 superFrameId,
1437 allocationChannel);
1438
1439 if (!result.first)
1440 {
1441 NS_LOG_INFO("Increasing frame offset!");
1442 superFrameId++;
1443 superframeStartTime += frameConf->GetDuration();
1444 }
1445 }
1446
1448 Ptr<SatTimeSlotConf> timeSlotConf = frameConf->GetTimeSlotConf(result.second);
1449
1451 Time slotStartTime = superframeStartTime + timeSlotConf->GetStartTime();
1452 Time offset = slotStartTime - Now();
1453
1454 if (offset.IsStrictlyNegative())
1455 {
1456 NS_FATAL_ERROR("SatUtMac::ScheduleSlottedAlohaTransmission - Invalid transmit time: "
1457 << offset.GetSeconds());
1458 }
1459
1461 Ptr<SatWaveform> wf =
1462 m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
1463 Time duration = wf->GetBurstDuration(frameConf->GetBtuConf()->GetSymbolRateInBauds());
1464
1466 uint32_t carrierId =
1467 m_superframeSeq->GetCarrierId(0, frameId, timeSlotConf->GetCarrierId());
1468
1469 NS_LOG_INFO("Starting to schedule, SF ID: "
1470 << superFrameId << " slot: " << result.second
1471 << " SF start: " << superframeStartTime.GetSeconds()
1472 << " Tx start: " << (Now() + offset).GetSeconds()
1473 << " duration: " << duration.GetSeconds() << " carrier ID: " << carrierId
1474 << " payload in bytes: " << wf->GetPayloadInBytes());
1475
1477 offset = GetRealSendingTime(offset);
1478 if (offset >= Seconds(0))
1479 {
1480 Simulator::Schedule(offset,
1482 this,
1483 duration,
1484 wf,
1485 carrierId,
1486 uint8_t(SatEnums::CONTROL_FID),
1488 }
1489 }
1490 else
1491 {
1492 NS_LOG_INFO("UT has known DAMA, aborting Slotted ALOHA");
1493 }
1494}
1495
1496std::pair<bool, uint32_t>
1498 Ptr<SatFrameConf> frameConf,
1499 uint32_t timeSlotCount,
1500 uint32_t superFrameId,
1501 uint32_t allocationChannel)
1502{
1503 NS_LOG_FUNCTION(this << superframeStartTime << timeSlotCount << superFrameId
1504 << allocationChannel);
1505
1506 Time opportunityOffset = Now() - superframeStartTime;
1507
1508 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress()
1509 << " offset: " << opportunityOffset.GetSeconds());
1510
1513 if (opportunityOffset.IsStrictlyNegative())
1514 {
1515 opportunityOffset = Seconds(0);
1516 }
1517
1518 return FindNextAvailableRandomAccessSlot(opportunityOffset,
1519 frameConf,
1520 timeSlotCount,
1521 superFrameId,
1522 allocationChannel);
1523}
1524
1525std::pair<bool, uint32_t>
1527 Ptr<SatFrameConf> frameConf,
1528 uint32_t timeSlotCount,
1529 uint32_t superFrameId,
1530 uint32_t allocationChannel)
1531{
1532 NS_LOG_FUNCTION(this << opportunityOffset << timeSlotCount << superFrameId
1533 << allocationChannel);
1534
1535 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress());
1536
1537 Ptr<SatTimeSlotConf> slotConf;
1538 uint32_t slotId;
1539 bool availableSlotFound = false;
1540
1542 for (slotId = 0; slotId < timeSlotCount; slotId++)
1543 {
1544 slotConf = frameConf->GetTimeSlotConf(slotId);
1545
1546 // NS_LOG_INFO ("Slot: " << slotId <<
1547 // " slot offset: " << slotConf->GetStartTime.GetSeconds () <<
1548 // " opportunity offset: " << opportunityOffset.GetSeconds ());
1549
1552 if (slotConf->GetStartTime() >= opportunityOffset)
1553 {
1555 if (UpdateUsedRandomAccessSlots(superFrameId, allocationChannel, slotId))
1556 {
1557 availableSlotFound = true;
1558 break;
1559 }
1560 }
1561 }
1562
1563 NS_LOG_INFO("Success: " << availableSlotFound << " SF: " << superFrameId << " AC: "
1564 << allocationChannel << " slot: " << slotId << "/" << timeSlotCount);
1565
1566 return std::make_pair(availableSlotFound, slotId);
1567}
1568
1569void
1570SatUtMac::ScheduleEssaTransmission(uint32_t allocationChannel)
1571{
1572 // TODO: do we really need the allocationChannel ???
1573 NS_LOG_FUNCTION(this << allocationChannel);
1574
1575 NS_LOG_INFO("SatUtMac::ScheduleEssaTransmission - UT: " << m_nodeInfo->GetMacAddress()
1576 << " time: " << Now().GetSeconds()
1577 << " AC: " << allocationChannel);
1578
1580 Time offset = m_nextPacketTime - Now();
1581
1582 if (offset.IsStrictlyNegative())
1583 {
1585 offset = Seconds(0);
1586 }
1587
1589 Ptr<SatSuperframeConf> superframeConf =
1591 uint8_t frameId = superframeConf->GetRaChannelFrameId(allocationChannel);
1592 Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
1593 Ptr<SatTimeSlotConf> timeSlotConf = frameConf->GetTimeSlotConf(0); // only one timeslot on ESSA
1594
1595 Ptr<SatWaveform> wf =
1596 m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
1597 Time duration = wf->GetBurstDuration(frameConf->GetBtuConf()->GetSymbolRateInBauds());
1598
1599 NS_LOG_INFO("SatUtMac::ScheduleEssaTransmission - Starting to schedule @ "
1600 << Now().GetSeconds() << " Tx start: " << (Now() + offset).GetSeconds()
1601 << " duration: " << duration.GetSeconds()
1602 << " payload in bytes: " << wf->GetPayloadInBytes());
1603
1605 uint32_t carrierId = 0; // TODO: for now we use 0 as we have a single carrier
1606
1608 offset = GetRealSendingTime(offset);
1609 if (offset >= Seconds(0))
1610 {
1611 Simulator::Schedule(offset,
1613 this,
1614 duration,
1615 wf,
1616 carrierId,
1617 uint8_t(SatEnums::CONTROL_FID),
1619 }
1620}
1621
1622void
1623SatUtMac::ScheduleCrdsaTransmission(uint32_t allocationChannel,
1625{
1626 NS_LOG_FUNCTION(this << allocationChannel);
1627
1628 // get current superframe ID
1629 Time now = Simulator::Now();
1632 NS_LOG_INFO("Checking for CRDSA transmission at "
1633 << now.GetMilliSeconds() - superFrameStart.GetMilliSeconds()
1634 << " milliseconds into superframe " << superFrameId);
1635
1636 // TODO: check we didn't already scheduled packets for this superframe
1637 // (because we are moving so fast, for instance, that we are now at the end of the
1638 // window for this "past" superframe instead of the beginning of the next one)
1639
1640 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " AC: " << allocationChannel
1641 << ", SF: " << superFrameId << ", num of opportunities: "
1642 << txOpportunities.crdsaTxOpportunities.size());
1643
1644 std::map<uint32_t, std::set<uint32_t>>::iterator iter;
1645
1647 for (iter = txOpportunities.crdsaTxOpportunities.begin();
1648 iter != txOpportunities.crdsaTxOpportunities.end();
1649 iter++)
1650 {
1651 std::set<uint32_t>::iterator iterSet;
1652
1654 for (iterSet = iter->second.begin(); iterSet != iter->second.end(); iterSet++)
1655 {
1657 if (!UpdateUsedRandomAccessSlots(superFrameId, allocationChannel, *iterSet))
1658 {
1661 NS_FATAL_ERROR(
1662 "SatUtMac::ScheduleCrdsaTransmission - Slot unavailable: " << *iterSet);
1663 }
1664 }
1665
1667 NS_LOG_INFO("Creating replicas for packet " << (uint32_t)m_crdsaUniquePacketId);
1668 CreateCrdsaPacketInstances(allocationChannel, iter->second);
1669 }
1670}
1671
1672void
1673SatUtMac::CreateCrdsaPacketInstances(uint32_t allocationChannel, std::set<uint32_t> slots)
1674{
1675 NS_LOG_FUNCTION(this << allocationChannel);
1676
1677 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " AC: " << allocationChannel);
1678
1679 Ptr<SatSuperframeConf> superframeConf =
1681 uint8_t frameId = superframeConf->GetRaChannelFrameId(allocationChannel);
1682 Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
1683
1686 Time superframeStartTime = Now();
1687
1689 uint32_t payloadBytes = superframeConf->GetRaChannelTimeSlotPayloadInBytes(allocationChannel);
1690
1692 payloadBytes -= m_randomAccess->GetCrdsaSignalingOverheadInBytes();
1693
1694 if (payloadBytes < 1)
1695 {
1696 NS_FATAL_ERROR(
1697 "SatUtMac::CreateCrdsaPacketInstances - Not enough capacity in CRDSA payload");
1698 }
1699
1704 {
1705 policy = SatUtScheduler::STRICT;
1706 }
1707 else
1708 {
1709 policy = SatUtScheduler::LOOSE;
1710 }
1711
1715 payloadBytes,
1717 uint8_t(SatEnums::CONTROL_FID),
1718 policy,
1719 true);
1720
1721 NS_LOG_INFO("Processing the packet container, fragments: " << uniq.size());
1722
1723 if (!uniq.empty())
1724 {
1725 std::vector<std::pair<uint16_t, SatPhy::PacketContainer_t>> replicas;
1726 std::map<uint16_t, SatCrdsaReplicaTag> tags;
1727 std::set<uint32_t>::iterator iterSet;
1728
1729 NS_LOG_INFO("Creating replicas for a packet");
1730
1732 for (iterSet = slots.begin(); iterSet != slots.end(); iterSet++)
1733 {
1735 SatPhy::PacketContainer_t::const_iterator it = uniq.begin();
1736
1737 for (; it != uniq.end(); ++it)
1738 {
1739 rep.push_back((*it)->Copy());
1740 NS_LOG_INFO(
1741 "Replica in slot: "
1742 << (*iterSet) << ", original (HL packet) fragment UID: " << (*it)->GetUid()
1743 << ", copied replica fragment (HL packet) UID: " << rep.back()->GetUid());
1744 }
1745
1746 NS_LOG_INFO("One replica created");
1747
1748 replicas.push_back(std::make_pair(*iterSet, rep));
1749 }
1750
1751 NS_LOG_INFO("Creating replica tags");
1752
1754 for (uint32_t i = 0; i < replicas.size(); i++)
1755 {
1756 SatCrdsaReplicaTag replicaTag;
1757
1758 replicaTag.AddSlotId(replicas[i].first);
1759
1760 NS_LOG_INFO("Own packet tag: " << replicas[i].first);
1761
1762 for (uint32_t j = 0; j < replicas.size(); j++)
1763 {
1764 if (i != j)
1765 {
1766 replicaTag.AddSlotId(replicas[j].first);
1767
1768 NS_LOG_INFO("Other packet tag: " << replicas[j].first);
1769 }
1770 }
1771 tags.insert(std::make_pair(replicas[i].first, replicaTag));
1772 }
1773
1774 NS_LOG_INFO("Scheduling replicas");
1775
1777 for (uint32_t i = 0; i < replicas.size(); i++)
1778 {
1779 for (uint32_t j = 0; j < replicas[i].second.size(); j++)
1780 {
1781 NS_LOG_INFO("Replica: " << i << ", fragment: " << j
1782 << ", key: " << replicas[i].first << ", tag: "
1783 << tags.at(replicas[i].first).GetSlotIds().at(0)
1784 << ", fragment (HL packet) UID: "
1785 << replicas[i].second.at(j)->GetUid());
1786
1788 replicas[i].second.at(j)->AddPacketTag(tags.at(replicas[i].first));
1789 }
1790
1792 Ptr<SatTimeSlotConf> timeSlotConf = frameConf->GetTimeSlotConf(replicas[i].first);
1793
1795 Time slotDelay = superframeStartTime + timeSlotConf->GetStartTime();
1796 Time offset = slotDelay - Now();
1797
1798 if (offset.IsStrictlyNegative())
1799 {
1800 NS_FATAL_ERROR("SatUtMac::CreateCrdsaPacketInstances - Invalid transmit time: "
1801 << offset.GetSeconds());
1802 }
1803
1805 Ptr<SatWaveform> wf =
1806 m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
1807 Time duration = wf->GetBurstDuration(frameConf->GetBtuConf()->GetSymbolRateInBauds());
1808
1810 uint32_t carrierId =
1812 frameId,
1813 timeSlotConf->GetCarrierId());
1814
1818 txInfo.modCod = wf->GetModCod();
1819 txInfo.sliceId = 0;
1820 txInfo.fecBlockSizeInBytes = wf->GetPayloadInBytes();
1822 txInfo.waveformId = wf->GetWaveformId();
1824
1826 offset = GetRealSendingTime(offset);
1827 if (offset >= Seconds(0))
1828 {
1829 Simulator::Schedule(offset,
1831 this,
1832 replicas[i].second,
1833 duration,
1834 carrierId,
1835 txInfo);
1836 }
1837 NS_LOG_INFO("Scheduled a replica in slot " << replicas[i].first << " with offset "
1838 << offset.GetSeconds());
1839 }
1840 replicas.clear();
1841 tags.clear();
1842
1844 }
1845}
1846
1847bool
1849 uint32_t allocationChannelId,
1850 uint32_t slotId)
1851{
1852 NS_LOG_FUNCTION(this << superFrameId << allocationChannelId << slotId);
1853
1854 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " SF: " << superFrameId
1855 << " AC: " << allocationChannelId << " slot: " << slotId);
1856
1857 std::map<std::pair<uint32_t, uint32_t>, std::set<uint32_t>>::iterator iter;
1858 bool isSlotFree = false;
1859
1861 RemovePastRandomAccessSlots(superFrameId);
1862
1863 std::pair<uint32_t, uint32_t> key = std::make_pair(superFrameId, allocationChannelId);
1864
1865 iter = m_usedRandomAccessSlots.find(key);
1866
1867 if (iter == m_usedRandomAccessSlots.end())
1868 {
1869 std::set<uint32_t> txOpportunities{{slotId}};
1870 std::pair<std::map<std::pair<uint32_t, uint32_t>, std::set<uint32_t>>::iterator, bool>
1871 result;
1872 result = m_usedRandomAccessSlots.insert(std::make_pair(key, txOpportunities));
1873
1874 if (result.second)
1875 {
1876 isSlotFree = true;
1877 NS_LOG_INFO("No saved SF, slot " << slotId << " saved in SF " << superFrameId);
1878 }
1879 else
1880 {
1881 NS_LOG_WARN("No saved SF but unable to create one");
1882 }
1883 }
1884 else
1885 {
1886 std::pair<std::set<uint32_t>::iterator, bool> result;
1887 result = iter->second.insert(slotId);
1888
1889 if (result.second)
1890 {
1891 isSlotFree = true;
1892 NS_LOG_INFO("Saved SF exist, slot " << slotId << " saved in SF " << superFrameId);
1893 }
1894 else
1895 {
1896 NS_LOG_WARN("Saved SF exist but unable to add slot " << slotId);
1897 }
1898 }
1899 return isSlotFree;
1900}
1901
1902void
1904{
1905 NS_LOG_FUNCTION(this << superFrameId);
1906
1907 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress() << " SF: " << superFrameId);
1908
1909 std::map<std::pair<uint32_t, uint32_t>, std::set<uint32_t>>::iterator iter;
1910
1911 for (iter = m_usedRandomAccessSlots.begin(); iter != m_usedRandomAccessSlots.end();)
1912 {
1913 if (iter->first.first < superFrameId)
1914 {
1915 iter = m_usedRandomAccessSlots.erase(iter);
1916 }
1917 else
1918 {
1919 ++iter;
1920 }
1921 }
1922}
1923
1924void
1926{
1927 NS_LOG_FUNCTION(this);
1928
1929 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress());
1930 std::cout << "UT: " << m_nodeInfo->GetMacAddress() << std::endl;
1931
1932 for (auto& iter : m_usedRandomAccessSlots)
1933 {
1934 for (auto& slot : iter.second)
1935 {
1936 std::cout << "SF: " << iter.first.first << " AC: " << iter.first.second
1937 << " slot: " << slot << std::endl;
1938 }
1939 }
1940}
1941
1942void
1944{
1945 NS_LOG_FUNCTION(this);
1946
1947 NS_LOG_INFO("UT: " << m_nodeInfo->GetMacAddress());
1948
1949 if (m_timuInfo != nullptr)
1950 {
1951 NS_LOG_INFO("Applying TIM-U parameters received during the previous frame");
1952
1953 Ptr<SatBeamScheduler> srcScheduler = m_beamSchedulerCallback(m_satId, m_beamId);
1954
1955 NS_LOG_INFO("UT handover, old satellite is " << m_satId << ", old beam is " << m_beamId);
1956
1957 m_beamId = m_timuInfo->GetBeamId();
1958 m_satId = m_timuInfo->GetSatId();
1959
1960 NS_LOG_INFO("UT handover, new satellite is " << m_satId << ", new beam is " << m_beamId);
1961
1964
1965 Address satAddress = m_timuInfo->GetSatAddress();
1966 Mac48Address satAddress48 = Mac48Address::ConvertFrom(satAddress);
1967 if (satAddress48 != m_satelliteAddress)
1968 {
1969 SetSatelliteAddress(satAddress48);
1970 }
1971
1972 Ptr<SatTopology> satTopology = Singleton<SatTopology>::Get();
1973
1974 satTopology->UpdateUtSatAndBeam(m_node, m_satId, m_beamId);
1975 Ptr<Node> gwNode = satTopology->GetGwFromBeam(m_beamId);
1976 satTopology->UpdateGwConnectedToUt(m_node, gwNode);
1977
1978 Mac48Address gwAddress =
1979 Singleton<SatTopology>::Get()->GetGwAddressInUt(m_nodeInfo->GetNodeId());
1980 SetGwAddress(gwAddress);
1982
1984
1985 Ptr<SatBeamScheduler> dstScheduler = m_beamSchedulerCallback(m_satId, m_beamId);
1986 srcScheduler->DisconnectUt(m_nodeInfo->GetMacAddress());
1987 dstScheduler->ConnectUt(m_nodeInfo->GetMacAddress());
1988
1989 Ptr<SatIdMapper> satIdMapper = Singleton<SatIdMapper>::Get();
1990 satIdMapper->UpdateMacToSatId(m_nodeInfo->GetMacAddress(), m_satId);
1991 satIdMapper->UpdateMacToBeamId(m_nodeInfo->GetMacAddress(), m_beamId);
1992 satTopology->UpdateUtSatAndBeam(m_node, m_satId, m_beamId);
1994
1996 {
1998 }
1999
2000 m_handoverModule->HandoverFinished();
2001
2002 m_tbtpContainer->Clear();
2004 m_timuInfo = nullptr;
2005 }
2006 else if (m_txCheckCallback())
2007 {
2008 NS_LOG_INFO("Tx is permitted");
2009
2011 {
2012 m_rcstState.SwitchToOffStandby();
2013 }
2014
2015 if (m_loggedOn && m_handoverModule != nullptr)
2016 {
2017 NS_LOG_INFO("UT checking for beam handover recommendation");
2018 if (m_handoverModule->CheckForHandoverRecommendation(m_satId, m_beamId))
2019 {
2021 {
2024 }
2026 {
2028 }
2030 {
2032 LogOff();
2033
2034 Ptr<SatBeamScheduler> srcScheduler = m_beamSchedulerCallback(m_satId, m_beamId);
2035
2036 m_satId = m_handoverModule->GetAskedSatId();
2037 m_beamId = m_handoverModule->GetAskedBeamId();
2038
2039 Ptr<SatTopology> satTopology = Singleton<SatTopology>::Get();
2040
2041 satTopology->UpdateUtSatAndBeam(m_node, m_satId, m_beamId);
2042 Ptr<Node> gwNode = satTopology->GetGwFromBeam(m_beamId);
2043 satTopology->UpdateGwConnectedToUt(m_node, gwNode);
2044
2045 Address satAddress =
2046 m_beamSchedulerCallback(m_satId, m_beamId)->GetSatAddress();
2047 Mac48Address satAddress48 = Mac48Address::ConvertFrom(satAddress);
2048 if (satAddress48 != m_satelliteAddress)
2049 {
2050 SetSatelliteAddress(satAddress48);
2051 }
2052
2053 Mac48Address gwAddress =
2054 Singleton<SatTopology>::Get()->GetGwAddressInUt(m_nodeInfo->GetNodeId());
2055 if (gwAddress != m_gwAddress)
2056 {
2057 SetGwAddress(gwAddress);
2058 m_updateGwAddressCallback(gwAddress);
2059 m_routingUpdateCallback(m_nodeInfo->GetMacAddress(), gwAddress);
2060 }
2062
2063 Ptr<SatBeamScheduler> dstScheduler = m_beamSchedulerCallback(m_satId, m_beamId);
2064 srcScheduler->DisconnectUt(m_nodeInfo->GetMacAddress());
2065 dstScheduler->ConnectUt(m_nodeInfo->GetMacAddress());
2066
2067 Ptr<SatIdMapper> satIdMapper = Singleton<SatIdMapper>::Get();
2068 satIdMapper->UpdateMacToSatId(m_nodeInfo->GetMacAddress(), m_satId);
2069 satIdMapper->UpdateMacToBeamId(m_nodeInfo->GetMacAddress(), m_beamId);
2070 satTopology->UpdateUtSatAndBeam(m_node, m_satId, m_beamId);
2072
2074 {
2076 }
2077
2078 m_tbtpContainer->Clear();
2080 m_nextLogonTransmissionPossible = Simulator::Now();
2081 }
2082 }
2083 }
2084
2085 if (m_randomAccess != nullptr)
2086 {
2087 if (m_loggedOn)
2088 {
2089 // reset packet ID counter for this frame
2091
2092 // execute CRDSA trigger
2094 }
2095 else if (m_useLogon)
2096 {
2097 m_rcstState.SwitchToReadyForLogon();
2098 if (Simulator::Now() > m_nextLogonTransmissionPossible)
2099 {
2100 // Do Logon
2102 }
2103 }
2104 }
2105 }
2106 else
2107 {
2108 NS_LOG_INFO("Tx is disabled");
2109 m_rcstState.SwitchToHoldStandby();
2110 }
2111
2113 NS_ASSERT_MSG(Now() < nextSuperFrameTxTime,
2114 "Scheduling next superframe start time to the past!");
2115
2116 Time schedulingDelay = nextSuperFrameTxTime - Now();
2117 Time realDelay = GetRealSendingTime(schedulingDelay);
2118 if (realDelay == Seconds(0))
2119 {
2120 schedulingDelay += m_superframeSeq->GetDuration(SatConstVariables::SUPERFRAME_SEQUENCE);
2121 }
2122 Simulator::Schedule(GetRealSendingTime(schedulingDelay), &SatUtMac::DoFrameStart, this);
2123}
2124
2125Time
2127{
2128 if (m_deltaNcr == 0) // For some reason returning t-0 is different than returning t...
2129 {
2130 return t;
2131 }
2132
2133 uint32_t driftTicks = (t + Simulator::Now()).GetMicroSeconds() * m_clockDrift / 1000000;
2134 int32_t deltaTicks = m_deltaNcr - driftTicks;
2135 Time deltaTime = NanoSeconds(deltaTicks * 1000 / 27.0);
2136
2137 return t - deltaTime;
2138}
2139
2141 uint32_t satId,
2142 Address satAddress,
2143 Address gwAddress)
2144 : m_beamId(beamId),
2145 m_satId(satId),
2146 m_satAddress(satAddress),
2147 m_gwAddress(gwAddress)
2148{
2149 NS_LOG_FUNCTION(this << beamId << satAddress << gwAddress);
2150}
2151
2152uint32_t
2154{
2155 NS_LOG_FUNCTION(this);
2156 return m_beamId;
2157}
2158
2159uint32_t
2161{
2162 NS_LOG_FUNCTION(this);
2163 return m_satId;
2164}
2165
2166Address
2168{
2169 NS_LOG_FUNCTION(this);
2170 return m_satAddress;
2171}
2172
2173Address
2175{
2176 NS_LOG_FUNCTION(this);
2177 return m_gwAddress;
2178}
2179
2182{
2183 NS_LOG_FUNCTION(this);
2184 return m_rcstState.GetState();
2185}
2186
2187void
2189 uint32_t payloadBytes,
2191 uint8_t rcIndex,
2193 bool randomAccessChannel)
2194{
2195 NS_LOG_INFO(this << payloadBytes << type << rcIndex << policy << randomAccessChannel);
2196
2198 if ((m_handoverState == NO_HANDOVER &&
2199 (randomAccessChannel || m_firstTransmittableSuperframeId <= superFrameId)) ||
2200 (randomAccessChannel && m_handoverState != HANDOVER_RECOMMENDATION_SENT))
2201 {
2202 NS_LOG_INFO("Regular scheduling");
2203 m_utScheduler->DoScheduling(packets, payloadBytes, type, rcIndex, policy);
2204 }
2205 else
2206 {
2207 NS_LOG_INFO("Handover recommendation sent, force control packets only");
2208 m_utScheduler->DoScheduling(packets,
2209 payloadBytes,
2213
2214 // Remove every control packets except handover requests
2215 SatPhy::PacketContainer_t::iterator it = packets.begin();
2216 while (it != packets.end())
2217 {
2218 SatControlMsgTag ctrlTag;
2219 bool success = (*it)->PeekPacketTag(ctrlTag);
2220
2221 if (success && ctrlTag.GetMsgType() == SatControlMsgTag::SAT_HR_CTRL_MSG)
2222 {
2223 ++it;
2224 }
2225 else
2226 {
2227 it = packets.erase(it);
2228 }
2229 }
2230 }
2231}
2232
2233} // namespace ns3
This class implements a tag that carries the satellite MAC of GW and UT.
void SetE2ESourceAddress(Mac48Address e2eSourceAddress)
Set E2E source MAC address.
Mac48Address GetE2ESourceAddress(void) const
Get E2E source MAC address.
void SetE2EDestAddress(Mac48Address e2eDestAddress)
Set E2E destination MAC address.
Mac48Address GetE2EDestAddress(void) const
Get E2E destination MAC address.
This class implements a tag that is used to identify control messages (packages).
SatControlMsgType_t
Definition for different types of control messages.
@ SAT_LOGON_RESPONSE_CTRL_MSG
SAT_LOGON_RESPONSE_CTRL_MSG.
@ SAT_SLICE_CTRL_MSG
SAT_SLICE_CTRL_MSG.
@ SAT_TIMU_CTRL_MSG
SAT_TIMU_CTRL_MSG.
@ SAT_LOGOFF_CTRL_MSG
SAT_LOGOFF CTRL_MSG.
@ SAT_NON_CTRL_MSG
SAT_NON_CTRL_MSG.
@ SAT_CMT_CTRL_MSG
SAT_CMT_CTRL_MSG.
@ SAT_TBTP_CTRL_MSG
SAT_TBTP_CTRL_MSG.
@ SAT_NCR_CTRL_MSG
SAT_NCR_CTRL_MSG.
virtual uint32_t GetMsgId() const
Get message type specific identifier.
SatControlMsgType_t GetMsgType(void) const
Get type of the control message.
This class implements a tag that carries information about the slot IDs of CRDSA packet replicas.
SatEncapPduStatusTag is used temporarily to tag packets with the fragmentation status in the encapsul...
void SetStatus(uint8_t status)
Set PDU status.
RandomAccessTriggerType_t
The defined random access trigger types.
@ LOG_WARNING
LOG_WARNING.
void RxTraces(SatPhy::PacketContainer_t packets)
Invoke the Rx trace source for each received packet.
void SetBeamId(uint32_t beamId)
Set beam ID of the object.
SatMac::BeamSchedulerCallback m_beamSchedulerCallback
Callback to get the SatBeamScheduler linked to a beam ID.
SatMac::RoutingUpdateCallback m_routingUpdateCallback
Callback to update routing and ARP tables after a beam handover.
TracedCallback< Time, SatEnums::SatPacketEvent_t, SatEnums::SatNodeType_t, uint32_t, Mac48Address, SatEnums::SatLogLevel_t, SatEnums::SatLinkDir_t, std::string > m_packetTrace
Trace callback used for packet tracing.
Address m_satelliteAddress
MAC address of satellite on other side of the link.
virtual void SetNodeInfo(Ptr< SatNodeInfo > nodeInfo)
Set the node info.
void DoDispose(void)
Dispose of SatMac.
SatMac::ReceiveCallback m_rxCallback
The upper layer package receive callback.
bool m_ncrV2
Use of version 2 of NCR dates.
bool m_isRegenerative
Indicate if satellite is regeneration (at least LINK level) for TX.
void SetSatId(uint32_t satId)
Set sat ID of the object.
Ptr< SatHandoverModule > m_handoverModule
Module used to perform handovers.
SatMac::ReadCtrlMsgCallback m_readCtrlCallback
The read control message callback.
SatMac()
Construct a SatMac.
Ptr< SatNodeInfo > m_nodeInfo
Node info containing node related information, such as node type, node id and MAC address (of the Sat...
SatEnums::RegenerationMode_t m_returnLinkRegenerationMode
Regeneration mode on return link.
virtual void SendPacket(SatPhy::PacketContainer_t packets, uint32_t carrierId, Time duration, SatSignalParameters::txInfo_s txInfo)
Send packets to lower layer by using a callback.
SatMac::UpdateIslCallback m_updateIslCallback
The update ISL routes callback.
This class implements a tag that carries the satellite MAC specific information, such as source and d...
void SetDestAddress(Mac48Address dest)
Set destination MAC address.
Mac48Address GetSourceAddress(void) const
Get source MAC address.
Mac48Address GetDestAddress(void) const
Get destination MAC address.
void SetSourceAddress(Mac48Address source)
Set source MAC address.
SatSignalParameters::PacketsInBurst_t PacketContainer_t
Define PacketContainer in SatPhy.
@ CONFIG_TYPE_4
Configuration type 4 (ESSA).
bool HasScheduledTimeSlots()
Method of checking whether the UT has been scheduled time slots into the future.
std::pair< uint8_t, DaTimeSlotConfContainer_t > DaTimeSlotInfoItem_t
Item for DA time slot information.
SatTimeSlotType_t
Types for time slot.
@ SLOT_TYPE_TRC
Control or traffic slot.
SatTimuInfo(uint32_t beamId, uint32_t satId, Address satAddress, Address gwAddress)
UT specific Mac class for Sat Net Devices.
void SetRandomAccess(Ptr< SatRandomAccess > randomAccess)
Set the random access module.
Ptr< SatSuperframeSeq > m_superframeSeq
Used superframe sequence for the return link.
Callback< bool > TxCheckCallback
Callback to check if TX is operational.
virtual void ReceiveQueueEventEssa(SatQueue::QueueEvent_t event, uint8_t rcIndex)
Receive a queue event:
Ptr< SatTbtpContainer > m_tbtpContainer
Container for storing all the TBTP information related to this UT.
virtual void Receive(SatPhy::PacketContainer_t packets, Ptr< SatSignalParameters >)
Receive packet from lower layer.
Time m_guardTime
Guard time for time slots.
void DoEssaTransmit(Time duration, Ptr< SatWaveform > waveform, uint32_t carrierId, uint8_t rcIndex, SatUtScheduler::SatCompliancePolicy_t policy=SatUtScheduler::LOOSE)
Notify the upper layer about the ESSA Tx opportunity.
static TypeId GetTypeId(void)
Derived from Object.
int64_t m_deltaNcr
Correction to apply to NCR dates.
void PrintUsedRandomAccessSlots()
uint32_t m_beamId
ID of beam for UT.
uint32_t m_handoverMessagesCount
Time m_maxWaitingTimeLogonResponse
Timeout for waiting for a response for a logon message.
std::pair< bool, uint32_t > SearchFrameForAvailableSlot(Time superframeStartTime, Ptr< SatFrameConf > frameConf, uint32_t timeSlotCount, uint32_t superFrameId, uint32_t allocationChannel)
Callback< void, uint32_t, uint32_t > HandoverCallback
Callback to reconfigure physical layer during handover.
void SetAssignedDaResourcesCallback(SatUtMac::AssignedDaResourcesCallback cb)
Set the assigned DA resources callback.
Mac48Address m_gwAddress
SatUtMac::HandoverCallback m_handoverCallback
The physical layer handover callback.
SatUtMacState::RcstState_t GetRcstState() const
uint64_t m_ncr
NCR value of last NCR control message.
void SendLogon(Ptr< Packet > packet)
Receive a logon message to transmit /param packet The logon packet to send.
virtual void SetSatelliteAddress(Address satelliteAddress)
Set the satellite MAC address on the other side of this link (if regenerative satellite).
void ScheduleTimeSlots(Ptr< SatTbtpMessage > tbtp)
Schedules time slots according to received TBTP message.
void SetHandoverCallback(SatUtMac::HandoverCallback cb)
Method to set handover callback.
virtual void ReceiveQueueEvent(SatQueue::QueueEvent_t event, uint8_t rcIndex)
Receive a queue event:
Callback< void, Mac48Address > UpdateGwAddressCallback
Callback to update GW address to SatRequestManager.
Callback< void > SendLogonCallback
Callback to send a logon message to the gateway.
SatUtMac::SliceSubscriptionCallback m_sliceSubscriptionCallback
Tx checking callback.
Time GetRealSendingTime(Time t)
Compute real sending time of UT based on last NCR reception date and clock drift.
void ScheduleEssaTransmission(uint32_t allocationChannel)
Function for scheduling the ESSA transmissions.
SatUtMac::UpdateAddressAndIdentifierCallback m_updateAddressAndIdentifierCallback
Callback to update addresses in statistics helpers.
void SetTxCheckCallback(SatUtMac::TxCheckCallback cb)
Set the TX check callback.
Ptr< SatTimuInfo > m_timuInfo
void RemovePastRandomAccessSlots(uint32_t superFrameId)
Function for removing the past used RA slots.
void ScheduleCrdsaTransmission(uint32_t allocationChannel, SatRandomAccess::RandomAccessTxOpportunities_s txOpportunities)
Function for scheduling the CRDSA transmissions.
Callback< Time > TimingAdvanceCallback
uint32_t m_maxHandoverMessagesSent
void SetUpdateGwAddressCallback(SatUtMac::UpdateGwAddressCallback cb)
Set the gw update callback.
SatUtMac::UpdateGwAddressCallback m_updateGwAddressCallback
Callback for sending a logon message.
uint32_t m_firstTransmittableSuperframeId
std::map< std::pair< uint32_t, uint32_t >, std::set< uint32_t > > m_usedRandomAccessSlots
A container for storing the used RA slots in each frame and allocation channel.
void SetSliceSubscriptionCallback(SatUtMac::SliceSubscriptionCallback cb)
Get sliec subscription info from MAC layer.
void DoSlottedAlohaTransmit(Time duration, Ptr< SatWaveform > waveform, uint32_t carrierId, uint8_t rcIndex, SatUtScheduler::SatCompliancePolicy_t policy=SatUtScheduler::LOOSE)
Notify the upper layer about the Slotted ALOHA Tx opportunity.
uint32_t m_crdsaUniquePacketId
CRDSA packet ID (per frame).
Time m_lastNcrDateReceived
Reception date of last NCR control message.
void SetSendLogonCallback(SatUtMac::SendLogonCallback cb)
Set the logon callback.
~SatUtMac()
Destroy a SatUtMac.
Time m_windowInitLogon
The initial max time to wait when sending a logon message.
Time GetNextSuperFrameTxTime(uint8_t superFrameSeqId) const
Get Tx time for the next possible superframe.
SatUtMac::GatewayUpdateCallback m_gatewayUpdateCallback
Gateway address update callback.
void ScheduleSlottedAlohaTransmission(uint32_t allocationChannel)
Function for scheduling the Slotted ALOHA transmissions.
HandoverState_t m_handoverState
uint32_t GetCurrentSuperFrameId(uint8_t superFrameSeqId) const
void SetRaChannel(uint32_t raChannel)
Set RA channel assigned for this UT.
Mac48Address GetGwAddress()
Get address of the GW (or its MAC) serving this UT.
std::queue< Time > m_receptionDates
Store last 3 packets reception date, to be associated to NCR dates.
void ExtractPacketsToSchedule(SatPhy::PacketContainer_t &packets, uint32_t payloadBytes, SatTimeSlotConf::SatTimeSlotType_t type, uint8_t rcIndex, SatUtScheduler::SatCompliancePolicy_t policy, bool randomAccessChannel)
Extract packets from the underlying queue and put them in the provided container.
SatUtMacState m_rcstState
Time m_nextPacketTime
Next time when a next ESSA packet can be safely sent.
uint32_t m_logonChannel
RA channel dedicated to logon messages.
void ReceiveSignalingPacket(Ptr< Packet > packet)
Signaling packet receiver, which handles all the signaling packet receptions.
void SetTimingAdvanceCallback(SatUtMac::TimingAdvanceCallback cb)
Set the timing advance callback.
SatPhy::PacketContainer_t FetchPackets(uint32_t payloadBytes, SatTimeSlotConf::SatTimeSlotType_t type, uint8_t rcIndex, SatUtScheduler::SatCompliancePolicy_t policy)
Callback< void, uint8_t, uint32_t > AssignedDaResourcesCallback
Callback for informing the amount of dedicated access bytes received from TBTP.
TracedCallback< uint32_t > m_tbtpResourcesTrace
Assigned TBTP resources in superframe for this UT (in bytes).
std::pair< bool, uint32_t > FindNextAvailableRandomAccessSlot(Time opportunityOffset, Ptr< SatFrameConf > frameConf, uint32_t timeSlotCount, uint32_t superFrameId, uint32_t allocationChannel)
bool m_crdsaOnlyForControl
Planned CRDSA usage:
void DoDispose(void)
Dispose of SatUtMac.
uint32_t GetNextRandomAccessAllocationChannel()
Function for selecting the allocation channel for the current RA evaluation.
void SetLogonChannel(uint32_t channelId)
void ScheduleDaTxOpportunity(Time transmitDelay, Time duration, Ptr< SatWaveform > wf, Ptr< SatTimeSlotConf > tsConf, uint32_t carrierId)
Schdules one Tx opportunity, i.e.
SatUtMac()
Default constructor, which is not used.
Ptr< Node > m_node
Node containing this MAC.
Ptr< SatUtScheduler > m_utScheduler
UT scheduler.
bool UpdateUsedRandomAccessSlots(uint32_t superFrameId, uint32_t allocationChannel, uint32_t slot)
Function for updating the used RA slots.
void TransmitPackets(SatPhy::PacketContainer_t packets, Time duration, uint32_t carrierId, SatSignalParameters::txInfo_s txInfo)
void CreateCrdsaPacketInstances(uint32_t allocationChannel, std::set< uint32_t > slots)
Ptr< SatRandomAccess > m_randomAccess
RA main module.
bool m_isRandomAccessScheduled
Flag that indicates if a method DoRandomAccess is scheduled for asynchronous access.
TimingAdvanceCallback m_timingAdvanceCb
Callback for getting the timing advance information.
uint32_t m_satId
ID of sat for UT.
bool ControlMsgTransmissionPossible() const
Method to check whether a transmission of a control msg is somewhat possible.
int32_t m_clockDrift
Clock drift (number of ticks per second).
void DoTransmit(Time duration, uint32_t carrierId, Ptr< SatWaveform > wf, Ptr< SatTimeSlotConf > tsConf, SatUtScheduler::SatCompliancePolicy_t policy=SatUtScheduler::LOOSE)
Notify the upper layer about the Tx opportunity.
void DoFrameStart()
Function which is executed at every frame start.
Callback< void, Mac48Address > GatewayUpdateCallback
Callback to update gateway address after handover.
Time m_nextLogonTransmissionPossible
Instant when a logon message can be transmitted.
Ptr< UniformRandomVariable > m_waitingTimeLogonRng
The random generator for waiting transmission time.
void SetGwAddress(Mac48Address gwAddress)
Set address of the GW (or its MAC) serving this UT.
bool LogonMsgTransmissionPossible() const
Method to check whether a transmission of a logon msg is somewhat possible.
Time GetCurrentSuperFrameStartTime(uint8_t superFrameSeqId) const
Get start time for the current superframe.
void SetGatewayUpdateCallback(SatUtMac::GatewayUpdateCallback cb)
Method to set the gateway address update callback.
bool m_useLogon
Should logon be simulated?
virtual void SetNodeInfo(Ptr< SatNodeInfo > nodeInfo)
Set the node info.
uint32_t m_sendLogonTries
Number of times a logon message has been sent without response.
uint32_t m_raChannel
RA channel assigned to the UT.
uint32_t GetRaChannel() const
Get RA channel assigned for this UT.
void SetUpdateAddressAndIdentifierCallback(SatUtMac::UpdateAddressAndIdentifierCallback cb)
Set the callback to update addresses in statistics helpers.
void DoRandomAccess(SatEnums::RandomAccessTriggerType_t randomAccessTriggerType)
Do random access evaluation for Tx opportunities.
Callback< void, uint8_t > SliceSubscriptionCallback
Callback to check if TX is operational.
Callback< void, Ptr< Node > > UpdateAddressAndIdentifierCallback
Callback to update addresses in statistics helpers.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Uniform random variable distribution generator.
AssignedDaResourcesCallback m_assignedDaResourcesCallback
Callback for informing the assigned TBTP resources.
SatUtMac::SendLogonCallback m_sendLogonCallback
Callback for sending a logon message.
bool m_loggedOn
UT is logged on.
SatUtMac::TxCheckCallback m_txCheckCallback
Tx checking callback.
Class handling UT Mac states and transitions.
SatCompliancePolicy_t
Enum describing the wanted scheduler policy.
static std::string GetPacketInfo(const Ptr< const Packet > p)
Get packet information in std::string for printing purposes.
constexpr uint8_t SUPERFRAME_SEQUENCE
Used superframe sequence in the RTN link.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
std::map< uint32_t, std::set< uint32_t > > crdsaTxOpportunities
Struct for storing the packet specific Tx information.