satellite-gw-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  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Jani Puttonen <jani.puttonen@magister.fi>
19  */
20 
21 #include "satellite-gw-mac.h"
22 
23 #include "satellite-bbframe.h"
27 #include "satellite-log.h"
28 #include "satellite-mac-tag.h"
31 #include "satellite-time-tag.h"
32 #include "satellite-topology.h"
34 #include "satellite-utils.h"
35 
36 #include <ns3/address.h>
37 #include <ns3/boolean.h>
38 #include <ns3/log.h>
39 #include <ns3/mac48-address.h>
40 #include <ns3/packet.h>
41 #include <ns3/pointer.h>
42 #include <ns3/simulator.h>
43 #include <ns3/singleton.h>
44 #include <ns3/uinteger.h>
45 
46 #include <sstream>
47 #include <utility>
48 #include <vector>
49 
50 NS_LOG_COMPONENT_DEFINE("SatGwMac");
51 
52 namespace ns3
53 {
54 
55 NS_OBJECT_ENSURE_REGISTERED(SatGwMac);
56 
57 TypeId
59 {
60  static TypeId tid =
61  TypeId("ns3::SatGwMac")
62  .SetParent<SatMac>()
63  .AddConstructor<SatGwMac>()
64  .AddAttribute("Scheduler",
65  "Forward link scheduler used by this Sat GW MAC.",
66  PointerValue(),
67  MakePointerAccessor(&SatGwMac::m_fwdScheduler),
68  MakePointerChecker<SatFwdLinkScheduler>())
69  .AddAttribute("GuardTime",
70  "Guard time in forward link",
71  TimeValue(MicroSeconds(1)),
72  MakeTimeAccessor(&SatGwMac::m_guardTime),
73  MakeTimeChecker())
74  .AddAttribute("NcrBroadcastPeriod",
75  "Interval between two broadcast of NCR dates",
76  TimeValue(MilliSeconds(100)),
77  MakeTimeAccessor(&SatGwMac::m_ncrInterval),
78  MakeTimeChecker())
79  .AddAttribute("UseCmt",
80  "Use CMT control messages to correct time on the UTs",
81  BooleanValue(false),
82  MakeBooleanAccessor(&SatGwMac::m_useCmt),
83  MakeBooleanChecker())
84  .AddAttribute("CmtPeriodMin",
85  "Minimum interval between two CMT control messages for a same UT",
86  TimeValue(MilliSeconds(550)),
87  MakeTimeAccessor(&SatGwMac::m_cmtPeriodMin),
88  MakeTimeChecker())
89  .AddAttribute("SendNcrBroadcast",
90  "Broadcast NCR messages to all UTs",
91  BooleanValue(true),
92  MakeBooleanAccessor(&SatGwMac::m_broadcastNcr),
93  MakeBooleanChecker())
94  .AddAttribute("DisableSchedulingIfNoDeviceConnected",
95  "If true, the periodic calls of StartTransmission are not called when no "
96  "devices are connected to this MAC",
97  BooleanValue(false),
99  MakeBooleanChecker())
100  .AddTraceSource("BBFrameTxTrace",
101  "Trace for transmitted BB Frames.",
102  MakeTraceSourceAccessor(&SatGwMac::m_bbFrameTxTrace),
103  "ns3::SatBbFrame::BbFrameCallback");
104  return tid;
105 }
106 
107 TypeId
109 {
110  NS_LOG_FUNCTION(this);
111 
112  return GetTypeId();
113 }
114 
116  : SatMac(),
117  m_fwdScheduler(),
118  m_guardTime(MicroSeconds(1)),
119  m_ncrInterval(MilliSeconds(100)),
120  m_useCmt(false),
121  m_lastCmtSent(),
122  m_cmtPeriodMin(MilliSeconds(550)),
123  m_broadcastNcr(true),
124  m_disableSchedulingIfNoDeviceConnected(false),
125  m_periodicTransmissionEnabled(false)
126 {
127  NS_LOG_FUNCTION(this);
128 
129  NS_FATAL_ERROR("SatUtMac::SatGwMac - Constructor not in use");
130 }
131 
132 SatGwMac::SatGwMac(Ptr<Node> node,
133  uint32_t satId,
134  uint32_t beamId,
135  uint32_t feederSatId,
136  uint32_t feederBeamId)
137  : SatMac(satId, beamId),
138  m_node(node),
139  m_feederSatId(feederSatId),
140  m_feederBeamId(feederBeamId),
141  m_fwdScheduler(),
142  m_guardTime(MicroSeconds(1)),
143  m_ncrInterval(MilliSeconds(100)),
144  m_useCmt(false),
145  m_lastCmtSent(),
146  m_cmtPeriodMin(MilliSeconds(550)),
147  m_broadcastNcr(true),
148  m_disableSchedulingIfNoDeviceConnected(false),
149  m_periodicTransmissionEnabled(false)
150 {
151  NS_LOG_FUNCTION(this);
152 }
153 
155 {
156  NS_LOG_FUNCTION(this);
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION(this);
163 
164  m_txOpportunityCallback.Nullify();
165  m_crReceiveCallback.Nullify();
166  m_handoverCallback.Nullify();
167  m_logonCallback.Nullify();
169 
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION(this);
177 
179  {
180  NS_LOG_INFO("Do not start beam " << m_beamId << " because no device is connected");
181  return;
182  }
183 
184  if (m_periodicTransmissionEnabled == true)
185  {
186  NS_LOG_INFO("Beam " << m_beamId << " already enabled");
187  return;
188  }
189 
191 
192  if (m_fwdScheduler == nullptr)
193  {
194  NS_FATAL_ERROR("Scheduler not set for GW MAC!!!");
195  }
196 
198  m_fwdScheduler->ClearAllPackets();
199 
207  Simulator::Schedule(Seconds(0), &SatGwMac::StartTransmission, this, 0);
208 
209  if (m_broadcastNcr)
210  {
211  Simulator::Schedule(MilliSeconds(50), &SatGwMac::StartNcrTransmission, this);
212  }
213 }
214 
215 void
216 SatGwMac::Receive(SatPhy::PacketContainer_t packets, Ptr<SatSignalParameters> rxParams)
217 {
218  NS_LOG_FUNCTION(this);
219 
220  // Add packet trace entry:
221  m_packetTrace(Simulator::Now(),
223  m_nodeInfo->GetNodeType(),
224  m_nodeInfo->GetNodeId(),
225  m_nodeInfo->GetMacAddress(),
228  SatUtils::GetPacketInfo(packets));
229 
230  // Invoke the `Rx` and `RxDelay` trace sources.
231  RxTraces(packets);
232 
233  Address utId;
234 
235  for (SatPhy::PacketContainer_t::iterator i = packets.begin(); i != packets.end(); i++)
236  {
237  // Remove packet tag
238  SatMacTag macTag;
239  bool mSuccess = (*i)->PeekPacketTag(macTag);
240  if (!mSuccess)
241  {
242  NS_FATAL_ERROR("MAC tag was not found from the packet!");
243  }
244  SatAddressE2ETag addressE2ETag;
245  mSuccess = (*i)->PeekPacketTag(addressE2ETag);
246  if (!mSuccess)
247  {
248  NS_FATAL_ERROR("Address E2E tag was not found from the packet!");
249  }
250 
251  NS_LOG_INFO("Packet from " << macTag.GetSourceAddress() << " to "
252  << macTag.GetDestAddress());
253  NS_LOG_INFO("Receiver " << m_nodeInfo->GetMacAddress());
254 
255  // If the packet is intended for this receiver
256  Mac48Address destAddress = macTag.GetDestAddress();
257  utId = addressE2ETag.GetE2ESourceAddress();
258 
259  if (destAddress == m_nodeInfo->GetMacAddress() || destAddress.IsBroadcast())
260  {
261  // Peek control msg tag
262  SatControlMsgTag ctrlTag;
263  bool cSuccess = (*i)->PeekPacketTag(ctrlTag);
264 
265  if (cSuccess)
266  {
268 
270  {
271  uint32_t beamId;
272  uint32_t satId;
274  {
277  beamId = rxParams->m_beamId;
278  satId = rxParams->m_satId;
279  break;
280  }
283  SatUplinkInfoTag satUplinkInfoTag;
284  if (!(*i)->PeekPacketTag(satUplinkInfoTag))
285  {
286  NS_FATAL_ERROR("SatUplinkInfoTag not found!");
287  }
288  beamId = satUplinkInfoTag.GetBeamId();
289  satId = satUplinkInfoTag.GetSatId();
290  break;
291  }
292  default:
293  NS_FATAL_ERROR("Unknown regeneration mode");
294  }
295  ReceiveSignalingPacket(*i, satId, beamId);
296  }
297  else
298  {
299  NS_FATAL_ERROR("A control message received with not valid msg type!");
300  }
301  }
302  else
303  {
304  // Pass the source address to LLC
305  m_rxCallback(*i,
306  addressE2ETag.GetE2ESourceAddress(),
307  addressE2ETag.GetE2EDestAddress());
308  }
309  }
310  else
311  {
312  NS_LOG_INFO(
313  "Packet intended for others received by MAC: " << m_nodeInfo->GetMacAddress());
314  }
315  }
316 
317  if (m_useCmt)
318  {
320  {
321  case SatEnums::TRANSPARENT: {
322  if (rxParams->m_txInfo.waveformId == 2)
323  {
324  SendCmtMessage(utId,
325  rxParams->m_duration,
326  Seconds(0),
327  rxParams->m_satId,
328  rxParams->m_beamId);
329  m_controlMessageReceivedCallback(utId, rxParams->m_satId, rxParams->m_beamId);
330  }
331  break;
332  }
334  if (rxParams->m_txInfo.waveformId == 2)
335  {
336  for (SatPhy::PacketContainer_t::iterator i = packets.begin(); i != packets.end();
337  i++)
338  {
339  SatControlMsgTag ctrlTag;
340  if ((*i)->PeekPacketTag(ctrlTag))
341  {
342  // This is a NCR CTRL packet, do not use it
343  continue;
344  }
345  SatUplinkInfoTag satUplinkInfoTag;
346  if (!(*i)->PeekPacketTag(satUplinkInfoTag))
347  {
348  NS_FATAL_ERROR("SatUplinkInfoTag not found !");
349  }
350  Time satelliteReceptionTime = satUplinkInfoTag.GetSatelliteReceptionTime();
351  uint32_t beamId = satUplinkInfoTag.GetBeamId();
352  uint32_t satId = satUplinkInfoTag.GetSatId();
353 
354  SendCmtMessage(utId, Seconds(0), satelliteReceptionTime, satId, beamId);
355  m_controlMessageReceivedCallback(utId, satId, beamId);
356  }
357  }
358  break;
359  }
362  for (SatPhy::PacketContainer_t::iterator i = packets.begin(); i != packets.end(); i++)
363  {
364  SatUplinkInfoTag satUplinkInfoTag;
365  if (!(*i)->PeekPacketTag(satUplinkInfoTag))
366  {
367  NS_FATAL_ERROR("SatUplinkInfoTag not found !");
368  }
369  Time satelliteReceptionTime = satUplinkInfoTag.GetSatelliteReceptionTime();
370  uint32_t beamId = satUplinkInfoTag.GetBeamId();
371  uint32_t satId = satUplinkInfoTag.GetSatId();
372  bool isControl = satUplinkInfoTag.IsControl();
373 
374  if (isControl)
375  {
376  SendCmtMessage(utId, Seconds(0), satelliteReceptionTime, satId, beamId);
377  m_controlMessageReceivedCallback(utId, satId, beamId);
378  }
379  }
380  break;
381  }
382  default:
383  NS_FATAL_ERROR("Unknown regeneration mode, or received");
384  }
385  }
386 }
387 
388 void
389 SatGwMac::StartTransmission(uint32_t carrierId)
390 {
391  NS_LOG_FUNCTION(this << carrierId);
392 
393  if (m_handoverModule != nullptr)
394  {
395  if (m_handoverModule->CheckForHandoverRecommendation(m_feederSatId, m_feederBeamId))
396  {
397  NS_LOG_INFO("GW handover, old satellite is " << m_feederSatId << ", old beam is "
398  << m_feederBeamId);
399 
400  Ptr<SatBeamScheduler> srcScheduler =
402 
403  m_feederSatId = m_handoverModule->GetAskedSatId();
404  m_feederBeamId = m_handoverModule->GetAskedBeamId();
405 
406  NS_LOG_INFO("GW handover, new satellite is " << m_feederSatId << ", new beam is "
407  << m_feederBeamId);
408 
409  Ptr<SatBeamScheduler> dstScheduler =
411  srcScheduler->DisconnectGw(m_nodeInfo->GetMacAddress());
412  dstScheduler->ConnectGw(m_nodeInfo->GetMacAddress());
413 
415 
416  Ptr<SatOrbiterNetDevice> orbiterNetDevice = DynamicCast<SatOrbiterNetDevice>(
417  Singleton<SatTopology>::Get()->GetOrbiterNode(m_feederSatId)->GetDevice(0));
418  Mac48Address satFeederAddress = orbiterNetDevice->GetSatelliteFeederAddress(m_beamId);
419  SetSatelliteAddress(satFeederAddress);
420 
421  Ptr<SatGwLlc> gwLlc =
422  Singleton<SatTopology>::Get()->GetGwLlc(m_node, m_satId, m_beamId);
423  gwLlc->SetSatelliteAddress(satFeederAddress);
424 
425  Singleton<SatTopology>::Get()->UpdateGwSatAndBeam(m_node,
428 
430 
431  m_handoverModule->HandoverFinished();
432  }
433  }
434 
435  if (m_nodeInfo->GetNodeType() == SatEnums::NT_GW)
436  {
437  m_lastSOF.push(Simulator::Now());
438  uint8_t lastSOFSize = m_ncrV2 ? 3 : 1;
439  if (m_lastSOF.size() > lastSOFSize)
440  {
441  m_lastSOF.pop();
442  }
443  }
444 
445  Time txDuration;
446 
448  {
449  std::pair<Ptr<SatBbFrame>, const Time> bbFrameInfo = m_fwdScheduler->GetNextFrame();
450  Ptr<SatBbFrame> bbFrame = bbFrameInfo.first;
451  txDuration = bbFrameInfo.second;
452 
453  // trace out BB frames sent.
454  m_bbFrameTxTrace(bbFrame);
455 
456  // Handle both dummy frames and normal frames
457  if (bbFrame != nullptr)
458  {
459  // Add packet trace entry:
460  m_packetTrace(Simulator::Now(),
462  m_nodeInfo->GetNodeType(),
463  m_nodeInfo->GetNodeId(),
464  m_nodeInfo->GetMacAddress(),
467  SatUtils::GetPacketInfo(bbFrame->GetPayload()));
468 
471  txInfo.modCod = bbFrame->GetModcod();
472  txInfo.sliceId = bbFrame->GetSliceId();
473  txInfo.frameType = bbFrame->GetFrameType();
474  txInfo.waveformId = 0;
475 
479  SendPacket(bbFrame->GetPayload(), carrierId, txDuration - m_guardTime, txInfo);
480  }
481  }
482  else
483  {
489  NS_LOG_INFO("TX is disabled, thus nothing is transmitted!");
490  txDuration = m_fwdScheduler->GetDefaultFrameDuration();
491  }
492 
494  {
502  Simulator::Schedule(txDuration, &SatGwMac::StartTransmission, this, 0);
503  }
504 }
505 
506 void
507 SatGwMac::TbtpSent(Ptr<SatTbtpMessage> tbtp)
508 {
509  NS_LOG_FUNCTION(this << tbtp);
510 
511  uint32_t superframeCounter = tbtp->GetSuperframeCounter();
512 
513  if (m_tbtps.find(superframeCounter) == m_tbtps.end())
514  {
515  m_tbtps[superframeCounter] = std::vector<Ptr<SatTbtpMessage>>();
516  }
517  m_tbtps[superframeCounter].push_back(tbtp);
518 
519  Simulator::Schedule(Seconds(10), &SatGwMac::RemoveTbtp, this, superframeCounter);
520 }
521 
522 uint32_t
524 {
525  NS_LOG_FUNCTION(this);
526 
527  return m_feederSatId;
528 }
529 
530 uint32_t
532 {
533  NS_LOG_FUNCTION(this);
534 
535  return m_feederBeamId;
536 }
537 
538 void
539 SatGwMac::RemoveTbtp(uint32_t superframeCounter)
540 {
541  m_tbtps.erase(superframeCounter);
542 }
543 
544 void
546 {
547  NS_LOG_FUNCTION(this);
548 
549  SendNcrMessage();
550 
552  {
553  Simulator::Schedule(m_ncrInterval, &SatGwMac::StartNcrTransmission, this);
554  }
555 }
556 
557 void
558 SatGwMac::ReceiveSignalingPacket(Ptr<Packet> packet, uint32_t satId, uint32_t beamId)
559 {
560  NS_LOG_FUNCTION(this << packet << beamId);
561 
562  // Remove the mac tag
563  SatMacTag macTag;
564  packet->PeekPacketTag(macTag);
565 
566  SatAddressE2ETag addressE2ETag;
567  packet->PeekPacketTag(addressE2ETag);
568 
569  // Peek control msg tag
570  SatControlMsgTag ctrlTag;
571  bool cSuccess = packet->PeekPacketTag(ctrlTag);
572 
573  if (!cSuccess)
574  {
575  NS_FATAL_ERROR("SatControlMsgTag not found in the packet!");
576  }
577 
578  switch (ctrlTag.GetMsgType())
579  {
581  uint32_t msgId = ctrlTag.GetMsgId();
582  Ptr<SatCrMessage> crMsg = DynamicCast<SatCrMessage>(m_readCtrlCallback(msgId));
583 
584  if (crMsg != nullptr)
585  {
586  Mac48Address sourceAddress;
588  {
591  sourceAddress = addressE2ETag.GetE2ESourceAddress();
592  break;
593  }
595  sourceAddress = Mac48Address::ConvertFrom(m_satelliteAddress);
596  break;
597  }
598  default:
599  NS_FATAL_ERROR("Unknown regeneration mode");
600  }
601  m_fwdScheduler->CnoInfoUpdated(sourceAddress, crMsg->GetCnoEstimate());
602 
603  if (m_crReceiveCallback.IsNull() == false)
604  {
605  m_crReceiveCallback(satId, beamId, addressE2ETag.GetE2ESourceAddress(), crMsg);
606  }
607  }
608  else
609  {
615  std::stringstream msg;
616  msg << "Control message " << ctrlTag.GetMsgType()
617  << " is not found from the RTN link control msg container!";
618  msg << " at: " << Now().GetSeconds() << "s";
619  Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
620  }
621 
622  packet->RemovePacketTag(macTag);
623  packet->RemovePacketTag(addressE2ETag);
624  packet->RemovePacketTag(ctrlTag);
625 
626  break;
627  }
629  uint32_t msgId = ctrlTag.GetMsgId();
630  Ptr<SatCnoReportMessage> cnoReport =
631  DynamicCast<SatCnoReportMessage>(m_readCtrlCallback(msgId));
632 
633  if (cnoReport != nullptr)
634  {
635  m_fwdScheduler->CnoInfoUpdated(addressE2ETag.GetE2ESourceAddress(),
636  cnoReport->GetCnoEstimate());
637  }
638  else
639  {
645  std::stringstream msg;
646  msg << "Control message " << ctrlTag.GetMsgType()
647  << " is not found from the RTN link control msg container!";
648  msg << " at: " << Now().GetSeconds() << "s";
649  Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
650  }
651 
652  packet->RemovePacketTag(macTag);
653  packet->RemovePacketTag(addressE2ETag);
654  packet->RemovePacketTag(ctrlTag);
655 
656  break;
657  }
659  // ARQ ACK messages are forwarded to LLC, since they may be fragmented
660  m_rxCallback(packet, addressE2ETag.GetE2ESourceAddress(), macTag.GetDestAddress());
661  break;
662  }
664  uint32_t msgId = ctrlTag.GetMsgId();
665  Ptr<SatHandoverRecommendationMessage> handoverRecommendation =
666  DynamicCast<SatHandoverRecommendationMessage>(m_readCtrlCallback(msgId));
667 
668  if (handoverRecommendation != nullptr)
669  {
670  uint32_t newSatId = handoverRecommendation->GetRecommendedSatId();
671  uint32_t newBeamId = handoverRecommendation->GetRecommendedBeamId();
672  m_handoverCallback(addressE2ETag.GetE2ESourceAddress(),
673  satId,
674  beamId,
675  newSatId,
676  newBeamId);
677  }
678  else
679  {
685  std::stringstream msg;
686  msg << "Control message " << ctrlTag.GetMsgType()
687  << " is not found from the RTN link control msg container!";
688  msg << " at: " << Now().GetSeconds() << "s";
689  Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
690  }
691 
692  break;
693  }
695  uint32_t msgId = ctrlTag.GetMsgId();
696  Ptr<SatLogonMessage> logonMessage = DynamicCast<SatLogonMessage>(m_readCtrlCallback(msgId));
697 
698  if (logonMessage != nullptr)
699  {
700  Address utId = addressE2ETag.GetE2ESourceAddress();
701  Callback<void, uint32_t> raChannelCallback =
702  MakeBoundCallback(&SatGwMac::SendLogonResponseHelper, this, utId);
703  m_logonCallback(utId, satId, beamId, raChannelCallback);
704  }
705  else
706  {
712  std::stringstream msg;
713  msg << "Control message " << ctrlTag.GetMsgType()
714  << " is not found from the RTN link control msg container!";
715  msg << " at: " << Now().GetSeconds() << "s";
716  Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
717  }
718  break;
719  }
721  // We do nothing, from SAT to GW, these messages only add load on link
722  break;
723  }
724  default: {
725  NS_FATAL_ERROR("SatGwMac received a non-supported control packet!");
726  break;
727  }
728  }
729 }
730 
731 void
733 {
734  NS_LOG_FUNCTION(this);
735 
736  Ptr<SatNcrMessage> ncrMessage = CreateObject<SatNcrMessage>();
737  m_fwdScheduler->SendControlMsg(ncrMessage, Mac48Address::GetBroadcast());
738  m_ncrMessagesToSend.push(ncrMessage);
739 }
740 
741 void
743  Time burstDuration,
744  Time satelliteReceptionTime,
745  uint32_t satId,
746  uint32_t beamId)
747 {
748  NS_LOG_FUNCTION(this << utId);
749 
750  Time lastCmtSent = Seconds(0);
751  if (m_lastCmtSent.find(utId) != m_lastCmtSent.end())
752  {
753  lastCmtSent = m_lastCmtSent[utId];
754  }
755 
756  Time timeReceived = satelliteReceptionTime;
757  if (satelliteReceptionTime == Seconds(0))
758  {
759  timeReceived = Simulator::Now();
760  }
761 
762  if (timeReceived < lastCmtSent + m_cmtPeriodMin)
763  {
764  return;
765  }
766 
767  uint32_t indexClosest = 0;
768  uint32_t tbtpIndexClosest = 0;
769  uint32_t timeSlotIndexClosest = 0;
770  Time differenceClosest = Seconds(1000000);
771  std::vector<Ptr<SatTbtpMessage>> tbtpsForCurrentSF;
772  Ptr<SatTbtpMessage> tbtp;
773  for (uint32_t i = 0; i < m_tbtps.size(); i++)
774  {
775  tbtpsForCurrentSF = m_tbtps[i];
776  for (uint32_t tbtpIndex = 0; tbtpIndex < tbtpsForCurrentSF.size(); tbtpIndex++)
777  {
778  tbtp = tbtpsForCurrentSF[tbtpIndex];
779  std::pair<uint8_t, std::vector<Ptr<SatTimeSlotConf>>> timeslots =
780  tbtp->GetDaTimeslots(utId);
781  for (uint32_t j = 0; j < timeslots.second.size(); j++)
782  {
783  Ptr<SatTimeSlotConf> tsConf = timeslots.second[j];
784  if (tsConf->GetSlotType() == SatTimeSlotConf::SLOT_TYPE_C)
785  {
786  Time frameStartTime = Singleton<SatRtnLinkTime>::Get()->GetSuperFrameTxTime(
788  i,
789  Seconds(0));
790  Time slotStartTime = tsConf->GetStartTime();
791  Time difference = timeReceived - frameStartTime - slotStartTime - burstDuration;
792  if (Abs(difference) < differenceClosest)
793  {
794  differenceClosest = Abs(difference);
795  indexClosest = i;
796  timeSlotIndexClosest = j;
797  tbtpIndexClosest = tbtpIndex;
798  }
799  }
800  }
801  }
802  }
803 
804  if (indexClosest == 0)
805  {
806  return;
807  }
808 
809  tbtp = m_tbtps[indexClosest][tbtpIndexClosest];
810  std::pair<uint8_t, std::vector<Ptr<SatTimeSlotConf>>> timeslots = tbtp->GetDaTimeslots(utId);
811 
812  if (timeslots.second[timeSlotIndexClosest]->GetSlotType() == 0)
813  {
814  Time frameStartTime = Singleton<SatRtnLinkTime>::Get()->GetSuperFrameTxTime(
816  indexClosest,
817  Seconds(0));
818  Time slotStartTime = timeslots.second[timeSlotIndexClosest]->GetStartTime();
819 
820  Time difference = frameStartTime + slotStartTime + burstDuration - timeReceived;
821  int32_t differenceNcr = difference.GetMicroSeconds() * 27;
822 
823  if (differenceNcr > 16256 || differenceNcr < -16256)
824  {
825  NS_LOG_INFO("Burst Time Correction outside bounds, should be at least -16256 and at "
826  "most 16256, but got "
827  << differenceNcr << ". Forcing logoff of UT " << utId);
828  Ptr<SatLogoffMessage> logoffMsg = CreateObject<SatLogoffMessage>();
829  m_fwdScheduler->SendControlMsg(logoffMsg, utId);
830  m_removeUtCallback(utId, satId, beamId);
831  }
832  else
833  {
834  Ptr<SatCmtMessage> cmt = CreateObject<SatCmtMessage>();
835  cmt->SetBurstTimeCorrection(differenceNcr);
836  m_fwdScheduler->SendControlMsg(cmt, utId);
837  m_lastCmtSent[utId] = Simulator::Now();
838  }
839 
840  return;
841  }
842 }
843 
844 void
845 SatGwMac::SendLogonResponse(Address utId, uint32_t raChannel)
846 {
847  NS_LOG_FUNCTION(this << utId << raChannel);
848  Ptr<SatLogonResponseMessage> logonResponse = CreateObject<SatLogonResponseMessage>();
849  logonResponse->SetRaChannel(raChannel);
850  m_fwdScheduler->SendControlMsg(logonResponse, utId);
851 }
852 
853 void
854 SatGwMac::SendLogonResponseHelper(SatGwMac* self, Address utId, uint32_t raChannel)
855 {
856  self->SendLogonResponse(utId, raChannel);
857 }
858 
859 void
861 {
862  NS_LOG_FUNCTION(this << &cb);
863  m_crReceiveCallback = cb;
864 }
865 
866 void
868 {
869  NS_LOG_FUNCTION(this << &cb);
870  m_handoverCallback = cb;
871 }
872 
873 void
875 {
876  NS_LOG_FUNCTION(this << &cb);
877  m_logonCallback = cb;
878 }
879 
880 void
882 {
883  NS_LOG_FUNCTION(this << &cb);
885 }
886 
887 void
889 {
890  NS_LOG_FUNCTION(this << &cb);
891  m_removeUtCallback = cb;
892 }
893 
894 void
896 {
897  NS_LOG_FUNCTION(this << &cb);
899 }
900 
901 void
903 {
904  NS_LOG_FUNCTION(this << &cb);
905  m_beamCallback = cb;
906 }
907 
908 void
909 SatGwMac::SetFwdScheduler(Ptr<SatFwdLinkScheduler> fwdScheduler)
910 {
911  m_fwdScheduler = fwdScheduler;
912 
913  if (m_ncrV2)
914  {
915  m_fwdScheduler->SetDummyFrameSendingEnabled(true);
916  }
917 }
918 
919 void
920 SatGwMac::ChangeBeam(uint32_t satId, uint32_t beamId)
921 {
922  NS_LOG_FUNCTION(this << satId << beamId);
923 }
924 
925 void
926 SatGwMac::ConnectUt(Mac48Address utAddress)
927 {
928  NS_LOG_FUNCTION(this << utAddress);
929 
930  NS_ASSERT(m_peers.find(utAddress) == m_peers.end());
931 
933  {
934  NS_LOG_INFO("Start beam " << m_beamId);
935  m_peers.insert(utAddress);
937  }
938  else
939  {
940  m_peers.insert(utAddress);
941  }
942 }
943 
944 void
945 SatGwMac::DisconnectUt(Mac48Address utAddress)
946 {
947  NS_LOG_FUNCTION(this << utAddress);
948 
949  NS_ASSERT(m_peers.find(utAddress) != m_peers.end());
950 
951  m_peers.erase(utAddress);
952 
954  {
955  NS_LOG_INFO("Stop beam " << m_beamId);
957  }
958 }
959 
960 void
962 {
963  NS_LOG_FUNCTION(this);
964 
966 }
967 
968 bool
970 {
971  NS_LOG_FUNCTION(this);
972 
973  return !m_peers.empty();
974 }
975 
976 } // namespace ns3
This class implements a tag that carries the satellite MAC of GW and UT.
Mac48Address GetE2ESourceAddress(void) const
Get E2E source 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_NON_CTRL_MSG
SAT_NON_CTRL_MSG.
@ SAT_LOGON_CTRL_MSG
SAT_LOGON_CTRL_MSG.
@ SAT_CMT_CTRL_MSG
SAT_CMT_CTRL_MSG.
virtual uint32_t GetMsgId() const
Get message type specific identifier.
SatControlMsgType_t GetMsgType(void) const
Get type of the control message.
GW specific Mac class for Sat Net Devices.
void SetLogonCallback(SatGwMac::LogonCallback cb)
Method to set logon callback.
bool m_disableSchedulingIfNoDeviceConnected
If true, the periodic calls of StartTransmission are not called when no devices are connected to this...
SatGwMac::HandoverCallback m_handoverCallback
Callback to query/apply handover on the terrestrial network.
Ptr< SatFwdLinkScheduler > m_fwdScheduler
Scheduler for the forward link.
void TbtpSent(Ptr< SatTbtpMessage > tbtp)
Function called when a TBTP has been sent by the SatBeamScheduler.
Callback< void > ClearQueuesCallback
Callback to clear LLC queues.
SatGwMac::TxOpportunityCallback m_txOpportunityCallback
Callback to notify the txOpportunity to upper layer Returns a packet Attributes: payload in bytes.
void SendLogonResponse(Address utId, uint32_t raChannel)
std::map< Address, Time > m_lastCmtSent
Time of last CMT sending for each UT.
void SetRemoveUtCallback(SatGwMac::RemoveUtCallback cb)
Method to set callback for UT removing.
Time m_cmtPeriodMin
Minimum interval between two CMT control messages for a same UT.
Callback< void, Address, uint32_t, uint32_t > RemoveUtCallback
Callback to indicate NCC a UT needs to be removed.
void SetFwdScheduler(Ptr< SatFwdLinkScheduler > fwdScheduler)
Method to set forward link scheduler.
static TypeId GetTypeId(void)
Get the type ID.
SatGwMac::PhyBeamCallback m_beamCallback
Callback to change phy-layer beam ID.
SatGwMac::CrReceiveCallback m_crReceiveCallback
Capacity request receive callback.
bool m_broadcastNcr
Broadcast NCR messages to all UTs.
void ChangeBeam(uint32_t satId, uint32_t beamId)
Method handling beam handover.
static void SendLogonResponseHelper(SatGwMac *self, Address utId, uint32_t raChannel)
void SetHandoverCallback(SatGwMac::HandoverCallback cb)
Method to set handover callback.
void ConnectUt(Mac48Address utAddress)
Connect a UT to this satellite.
bool HasPeer()
Indicates if at least one device is connected in this beam.
SatGwMac::ClearQueuesCallback m_clearQueuesCallback
Callback to clear LLC queues.
void SetCrReceiveCallback(SatGwMac::CrReceiveCallback cb)
Method to set read control message callback.
uint32_t m_feederBeamId
ID of beam linked to this GW.
SatGwMac::LogonCallback m_logonCallback
Callback to log a terminal on.
Callback< void, Address, uint32_t, uint32_t, Callback< void, uint32_t > > LogonCallback
Callback to register UT logon.
void StartNcrTransmission()
Send a NCR packet to the UTs.
void ReceiveSignalingPacket(Ptr< Packet > packet, uint32_t satId, uint32_t beamId)
Signaling packet receiver, which handles all the signaling packet receptions.
~SatGwMac()
Destroy a SatGwMac.
SatGwMac()
Default constructor, which is not used.
uint32_t GetFeederBeamId()
Get ID of beam linked to this GW.
TracedCallback< Ptr< SatBbFrame > > m_bbFrameTxTrace
Trace for transmitted BB frames.
void SendCmtMessage(Address utId, Time burstDuration, Time satelliteReceptionTime, uint32_t satId, uint32_t beamId)
void StartTransmission(uint32_t carrierId)
Start sending a Packet Down the Wire.
Callback< void, uint32_t, uint32_t, Address, Ptr< SatCrMessage > > CrReceiveCallback
Callback to receive capacity request (CR) messages.
SatGwMac::RemoveUtCallback m_removeUtCallback
Callback to indicate NCC a UT needs to be removed.
void DoDispose(void)
SatGwMac::ControlMessageReceivedCallback m_controlMessageReceivedCallback
Callback to indicate NCC a control burst has been received.
std::map< uint32_t, std::vector< Ptr< SatTbtpMessage > > > m_tbtps
List of TBTPs sent to UTs.
void Receive(SatPhy::PacketContainer_t packets, Ptr< SatSignalParameters >)
Receive packet from lower layer.
void SetControlMessageReceivedCallback(SatGwMac::ControlMessageReceivedCallback cb)
Method to set callback for control burst reception.
Callback< void, Address, uint32_t, uint32_t, uint32_t, uint32_t > HandoverCallback
Callback to query/apply handover on the terrestrial network.
bool m_useCmt
Use CMT control messages to correct time on the UTs.
uint32_t GetFeederSatId()
Get ID of satellite linked to this GW.
void RemoveTbtp(uint32_t superframeCounter)
Function used to clear old TBTP.
bool m_periodicTransmissionEnabled
Indicated if periodic transmission is enabled.
Callback< void, uint32_t, uint32_t > PhyBeamCallback
Callback to change phy-layer beam ID.
void StartPeriodicTransmissions()
Starts periodical transmissions.
void SetBeamCallback(SatGwMac::PhyBeamCallback cb)
Method to set phy-layer beam handover callback.
virtual void StopPeriodicTransmissions()
Stop periodic transmission, until a pacquet in enqued.
std::set< Mac48Address > m_peers
List of UT MAC connected to this MAC.
void DisconnectUt(Mac48Address utAddress)
Disconnect a UT to this satellite.
Ptr< Node > m_node
Node containing this MAC.
Time m_ncrInterval
Interval between two broadcast of NCR dates.
Callback< void, Address, uint32_t, uint32_t > ControlMessageReceivedCallback
Callback to inform NCC a control burst has been received.
uint32_t m_feederSatId
ID of satellite linked to this GW.
TypeId GetInstanceTypeId(void) const
Derived from Object.
Time m_guardTime
Guard time for BB frames.
void SetClearQueuesCallback(SatGwMac::ClearQueuesCallback cb)
Method to set callback for LLC queues clearing.
@ LOG_WARNING
LOG_WARNING.
Definition: satellite-log.h:66
Base MAC class for SatNetDevices.
Definition: satellite-mac.h:57
void RxTraces(SatPhy::PacketContainer_t packets)
Invoke the Rx trace source for each received packet.
uint32_t m_beamId
The ID of the beam where mac belongs.
virtual void SetSatelliteAddress(Address satelliteAddress)
Set the satellite MAC address on the other side of this link (if regenerative satellite).
SatMac::BeamSchedulerCallback m_beamSchedulerCallback
Callback to get the SatBeamScheduler linked to a beam ID.
std::queue< Ptr< SatNcrMessage > > m_ncrMessagesToSend
List of NCR control messages created but not sent yet.
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.
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.
Ptr< SatHandoverModule > m_handoverModule
Module used to perform handovers.
bool m_txEnabled
Flag indicating whether the MAC is enabled, i.e.
SatMac::ReadCtrlMsgCallback m_readCtrlCallback
The read control message callback.
SatEnums::RegenerationMode_t m_forwardLinkRegenerationMode
Regeneration mode on forward link.
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.
uint32_t m_satId
The ID of the sat where mac belongs.
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.
std::queue< Time > m_lastSOF
Store last 3 SOF date for Forward messages, to insert in NCR packets.
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...
Mac48Address GetSourceAddress(void) const
Get source MAC address.
Mac48Address GetDestAddress(void) const
Get destination MAC address.
SatSignalParameters::PacketsInBurst_t PacketContainer_t
Define PacketContainer in SatPhy.
Definition: satellite-phy.h:79
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.
Struct for storing the packet specific Tx information.