satellite-mac.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sami Rantanen <sami.rantanen@magister.fi>
19  */
20 
21 #include "satellite-mac.h"
22 
23 #include "satellite-address-tag.h"
24 #include "satellite-mac-tag.h"
25 #include "satellite-time-tag.h"
26 #include "satellite-topology.h"
27 #include "satellite-typedefs.h"
28 
29 #include <ns3/boolean.h>
30 #include <ns3/log.h>
31 #include <ns3/nstime.h>
32 #include <ns3/packet.h>
33 #include <ns3/pointer.h>
34 #include <ns3/simulator.h>
35 #include <ns3/singleton.h>
36 #include <ns3/trace-source-accessor.h>
37 #include <ns3/uinteger.h>
38 
39 NS_LOG_COMPONENT_DEFINE("SatMac");
40 
41 namespace ns3
42 {
43 
44 NS_OBJECT_ENSURE_REGISTERED(SatMac);
45 
46 TypeId
48 {
49  static TypeId tid =
50  TypeId("ns3::SatMac")
51  .SetParent<Object>()
52  .AddConstructor<SatMac>()
53  .AddAttribute("EnableStatisticsTags",
54  "If true, some tags will be added to each transmitted packet to assist "
55  "with statistics computation",
56  BooleanValue(false),
57  MakeBooleanAccessor(&SatMac::m_isStatisticsTagsEnabled),
58  MakeBooleanChecker())
59  .AddAttribute("NcrVersion2",
60  "NCR version used (false for 1, true for 2)",
61  BooleanValue(false),
62  MakeBooleanAccessor(&SatMac::m_ncrV2),
63  MakeBooleanChecker())
64  .AddTraceSource("PacketTrace",
65  "Packet event trace",
66  MakeTraceSourceAccessor(&SatMac::m_packetTrace),
67  "ns3::SatTypedefs::PacketTraceCallback")
68  .AddTraceSource("Rx",
69  "A packet received",
70  MakeTraceSourceAccessor(&SatMac::m_rxTrace),
71  "ns3::SatTypedefs::PacketSenderAddressCallback")
72  .AddTraceSource("RxDelay",
73  "A packet is received with delay information",
74  MakeTraceSourceAccessor(&SatMac::m_rxDelayTrace),
75  "ns3::SatTypedefs::PacketDelayAddressCallback")
76  .AddTraceSource("RxLinkDelay",
77  "A packet is received with link delay information",
78  MakeTraceSourceAccessor(&SatMac::m_rxLinkDelayTrace),
79  "ns3::SatTypedefs::PacketDelayAddressCallback")
80  .AddTraceSource("RxJitter",
81  "A packet is received with jitter information",
82  MakeTraceSourceAccessor(&SatMac::m_rxJitterTrace),
83  "ns3::SatTypedefs::PacketJitterAddressCallback")
84  .AddTraceSource("RxLinkJitter",
85  "A packet is received with link jitter information",
86  MakeTraceSourceAccessor(&SatMac::m_rxLinkJitterTrace),
87  "ns3::SatTypedefs::PacketJitterAddressCallback")
88  .AddTraceSource("BeamServiceTime",
89  "A beam was disabled. Transmits length of last beam service time.",
90  MakeTraceSourceAccessor(&SatMac::m_beamServiceTrace),
91  "ns3::SatTypedefs::ServiceTimeCallback");
92  return tid;
93 }
94 
96  : m_isStatisticsTagsEnabled(false),
97  m_ncrV2(false),
98  m_routingUpdateCallback(),
99  m_nodeInfo(),
100  m_handoverModule(nullptr),
101  m_txEnabled(true),
102  m_beamEnabledTime(Seconds(0)),
103  m_lastDelay(0),
104  m_forwardLinkRegenerationMode(
105  Singleton<SatTopology>::Get()->GetForwardLinkRegenerationMode()),
106  m_returnLinkRegenerationMode(Singleton<SatTopology>::Get()->GetReturnLinkRegenerationMode()),
107  m_isRegenerative(false),
108  m_satelliteAddress(),
109  m_lastLinkDelay(0)
110 {
111  NS_LOG_FUNCTION(this);
112  NS_ASSERT(false); // this version of the constructor should not been used
113 }
114 
115 SatMac::SatMac(uint32_t satId, uint32_t beamId)
116  : m_isStatisticsTagsEnabled(false),
117  m_ncrV2(false),
118  m_routingUpdateCallback(),
119  m_nodeInfo(),
120  m_satId(satId),
121  m_beamId(beamId),
122  m_handoverModule(nullptr),
123  m_txEnabled(true),
124  m_beamEnabledTime(Seconds(0)),
125  m_lastDelay(0),
126  m_forwardLinkRegenerationMode(
127  Singleton<SatTopology>::Get()->GetForwardLinkRegenerationMode()),
128  m_returnLinkRegenerationMode(Singleton<SatTopology>::Get()->GetReturnLinkRegenerationMode()),
129  m_isRegenerative(false),
130  m_satelliteAddress(),
131  m_lastLinkDelay(0)
132 {
133  NS_LOG_FUNCTION(this);
134 }
135 
137 {
138  NS_LOG_FUNCTION(this);
139 }
140 
141 void
143 {
144  NS_LOG_FUNCTION(this);
145  if (m_txEnabled)
146  {
147  m_beamServiceTrace(Simulator::Now() - m_beamEnabledTime);
148  }
149 
150  m_txCallback.Nullify();
151  m_rxCallback.Nullify();
152  m_readCtrlCallback.Nullify();
153  m_reserveCtrlCallback.Nullify();
154  m_sendCtrlCallback.Nullify();
155  m_routingUpdateCallback.Nullify();
156  m_beamSchedulerCallback.Nullify();
157 
158  Object::DoDispose();
159 }
160 
161 void
162 SatMac::SetNodeInfo(Ptr<SatNodeInfo> nodeInfo)
163 {
164  NS_LOG_FUNCTION(this << nodeInfo);
165  NS_LOG_INFO("Node (id)= " << nodeInfo->GetNodeId()
166  << " Node (type)= " << nodeInfo->GetNodeType()
167  << " Address= " << nodeInfo->GetMacAddress());
168  m_nodeInfo = nodeInfo;
169 }
170 
171 uint32_t
173 {
174  NS_LOG_FUNCTION(this << msg);
175 
176  uint32_t id = 0;
177 
178  if (m_reserveCtrlCallback.IsNull() == false)
179  {
180  id = m_reserveCtrlCallback(msg);
181  }
182  else
183  {
184  NS_FATAL_ERROR("Reserve control message (m_reserveCtrlCallback) callback is NULL!");
185  }
186  return id;
187 }
188 
189 uint32_t
191 {
192  NS_LOG_FUNCTION(this << sendId);
193 
194  uint32_t recvId(0);
195  if (m_sendCtrlCallback.IsNull() == false)
196  {
197  recvId = m_sendCtrlCallback(sendId);
198  }
199  else
200  {
201  NS_FATAL_ERROR("Write control message (m_writeCtrlCallback) callback is NULL!");
202  }
203  return recvId;
204 }
205 
206 void
207 SatMac::ReceiveQueueEvent(SatQueue::QueueEvent_t /*event*/, uint8_t /*flowIndex*/)
208 {
209  NS_LOG_FUNCTION(this);
210 }
211 
212 void
214 {
215  NS_LOG_FUNCTION(this);
216  if (!m_txEnabled)
217  m_beamEnabledTime = Simulator::Now();
218  m_txEnabled = true;
219 }
220 
221 void
223 {
224  NS_LOG_FUNCTION(this);
225  if (m_txEnabled)
226  m_beamServiceTrace(Simulator::Now() - m_beamEnabledTime);
227  m_txEnabled = false;
228 }
229 
230 void
231 SatMac::SetSatelliteAddress(Address satelliteAddress)
232 {
233  m_satelliteAddress = satelliteAddress;
234  m_isRegenerative = true;
235 }
236 
237 void
239 {
241  {
242  for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
243  ++it)
244  {
245  SatMacTimeTag timeTag;
246  if (!(*it)->PeekPacketTag(timeTag))
247  {
248  (*it)->AddPacketTag(SatMacTimeTag(Simulator::Now()));
249  }
250 
251  SatMacLinkTimeTag linkTimeTag;
252  if (!(*it)->PeekPacketTag(linkTimeTag))
253  {
254  (*it)->AddPacketTag(SatMacLinkTimeTag(Simulator::Now()));
255  }
256  }
257  }
258 }
259 
260 void
262  uint32_t carrierId,
263  Time duration,
265 {
266  NS_LOG_FUNCTION(this);
267 
268  // Add a SatMacTimeTag tag for packet delay computation at the receiver end.
269  SetTimeTag(packets);
270 
271  // Update local destination MAC tag with satellite one if satellite is regenerative
272  if (m_isRegenerative)
273  {
274  for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
275  ++it)
276  {
277  SatMacTag mTag;
278  bool success = (*it)->RemovePacketTag(mTag);
279 
280  // MAC tag found
281  if (success)
282  {
283  mTag.SetDestAddress(Mac48Address::ConvertFrom(m_satelliteAddress));
284  (*it)->AddPacketTag(mTag);
285  }
286  }
287  }
288 
295  for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end(); ++it)
296  {
297  SatControlMsgTag cTag;
298  bool success = (*it)->RemovePacketTag(cTag);
299 
300  // Control tag found
301  if (success)
302  {
303  uint32_t sendId = cTag.GetMsgId();
304 
305  // Add the msg to container and receive the used recv id.
306  uint32_t recvId = SendCtrlMsgFromContainer(sendId);
307 
308  // Store the recv id to tag and add the tag back to the packet
309  cTag.SetMsgId(recvId);
310  (*it)->AddPacketTag(cTag);
311 
313  {
314  Ptr<SatNcrMessage> ncrMsg = m_ncrMessagesToSend.front();
315  m_ncrMessagesToSend.pop();
316  uint8_t lastSOFSize = m_ncrV2 ? 3 : 1;
317  ncrMsg->SetNcrDate(m_lastSOF.size() == lastSOFSize
318  ? m_lastSOF.front().GetNanoSeconds() * 0.027
319  : 0);
320  }
321  }
322  }
323 
324  // Use call back to send packet to lower layer
325  m_txCallback(packets, carrierId, duration, txInfo);
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION(this);
332 
334  {
335  for (SatPhy::PacketContainer_t::const_iterator it1 = packets.begin(); it1 != packets.end();
336  ++it1)
337  {
338  // Remove packet tag
339  SatMacTag macTag;
340  bool mSuccess = (*it1)->PeekPacketTag(macTag);
341  if (!mSuccess)
342  {
343  NS_FATAL_ERROR("MAC tag was not found from the packet!");
344  }
345 
346  // If the packet is intended for this receiver
347  Mac48Address destAddress = macTag.GetDestAddress();
348 
349  if (destAddress == m_nodeInfo->GetMacAddress())
350  {
351  Address addr; // invalid address.
352 
353  bool isTaggedWithAddress = false;
354  ByteTagIterator it2 = (*it1)->GetByteTagIterator();
355 
356  while (!isTaggedWithAddress && it2.HasNext())
357  {
358  ByteTagIterator::Item item = it2.Next();
359 
360  if (item.GetTypeId() == SatAddressTag::GetTypeId())
361  {
362  NS_LOG_DEBUG(this << " contains a SatAddressTag tag:"
363  << " start=" << item.GetStart()
364  << " end=" << item.GetEnd());
365  SatAddressTag addrTag;
366  item.GetTag(addrTag);
367  addr = addrTag.GetSourceAddress();
368  isTaggedWithAddress = true; // this will exit the while loop.
369  }
370  }
371 
372  m_rxTrace(*it1, addr);
373 
374  SatMacTimeTag timeTag;
375  if ((*it1)->RemovePacketTag(timeTag))
376  {
377  NS_LOG_DEBUG(this << " contains a SatMacTimeTag tag");
378  Time delay = Simulator::Now() - timeTag.GetSenderTimestamp();
379  m_rxDelayTrace(delay, addr);
380  if (m_lastDelay.IsZero() == false)
381  {
382  Time jitter = Abs(delay - m_lastDelay);
383  m_rxJitterTrace(jitter, addr);
384  }
385  m_lastDelay = delay;
386  }
387  SatMacLinkTimeTag linkTimeTag;
388  if ((*it1)->RemovePacketTag(linkTimeTag))
389  {
390  NS_LOG_DEBUG(this << " contains a SatMacLinkTimeTag tag");
391  Time delay = Simulator::Now() - linkTimeTag.GetSenderLinkTimestamp();
392  m_rxLinkDelayTrace(delay, addr);
393  if (m_lastLinkDelay.IsZero() == false)
394  {
395  Time jitter = Abs(delay - m_lastLinkDelay);
396  m_rxLinkJitterTrace(jitter, addr);
397  }
398  m_lastLinkDelay = delay;
399  }
400  } // end of `if (destAddress == m_nodeInfo->GetMacAddress () || destAddress.IsBroadcast
401  // ())`
402  } // end of `for it1 = packets.begin () -> packets.end ()`
403  } // end of `if (m_isStatisticsTagsEnabled)`
404 }
405 
406 void
407 SatMac::SetHandoverModule(Ptr<SatHandoverModule> handoverModule)
408 {
409  NS_LOG_INFO(this << handoverModule);
410 
411  m_handoverModule = handoverModule;
412 }
413 
414 void
416 {
417  NS_LOG_FUNCTION(this << &cb);
418  m_txCallback = cb;
419 }
420 
421 void
423 {
424  NS_LOG_FUNCTION(this << &cb);
425  m_rxCallback = cb;
426 }
427 
428 void
430 {
431  NS_LOG_FUNCTION(this << &cb);
432  m_rxLoraCallback = cb;
433 }
434 
435 void
437 {
438  NS_LOG_FUNCTION(this << &cb);
439  m_readCtrlCallback = cb;
440 }
441 
442 void
444 {
445  NS_LOG_FUNCTION(this << &cb);
447 }
448 
449 void
451 {
452  NS_LOG_FUNCTION(this << &cb);
453  m_sendCtrlCallback = cb;
454 }
455 
456 void
458 {
459  NS_LOG_FUNCTION(this << &cb);
461 }
462 
463 void
465 {
466  NS_LOG_FUNCTION(this << &cb);
467 
469 }
470 
471 void
473 {
474  NS_LOG_FUNCTION(this << &cb);
475  m_updateIslCallback = cb;
476 }
477 
478 } // namespace ns3
This class implements a tag that carries the MAC address of the sender of the packet.
static TypeId GetTypeId()
Inherited from ObjectBase base class.
Address GetSourceAddress() const
Get the source address.
This class implements a tag that is used to identify control messages (packages).
@ 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.
virtual void SetMsgId(uint32_t msgId)
Set message type specific identifier.
Callback< void > UpdateIslCallback
Callback to update ISL routes when handovers are performed.
TracedCallback< const Time &, const Address & > m_rxJitterTrace
Traced callback for all received packets, including jitter information and the address of the senders...
SatMac::TransmitCallback m_txCallback
The lower layer packet transmit callback.
void RxTraces(SatPhy::PacketContainer_t packets)
Invoke the Rx trace source for each received packet.
void SetBeamSchedulerCallback(SatMac::BeamSchedulerCallback cb)
Set the beam scheduler callback.
uint32_t ReserveIdAndStoreCtrlMsgToContainer(Ptr< SatControlMessage > msg)
Reserve id and store the control message.
TracedCallback< Time > m_beamServiceTrace
Traced callback for beam being disabled and including service time.
static TypeId GetTypeId(void)
Derived from Object.
void SetReserveCtrlCallback(SatMac::ReserveCtrlMsgCallback cb)
Method to set reserve control message id callback.
virtual void SetSatelliteAddress(Address satelliteAddress)
Set the satellite MAC address on the other side of this link (if regenerative satellite).
Callback< void, SatPhy::PacketContainer_t, uint32_t, Time, SatSignalParameters::txInfo_s > TransmitCallback
Callback to send packet to lower layer.
SatMac::BeamSchedulerCallback m_beamSchedulerCallback
Callback to get the SatBeamScheduler linked to a beam ID.
Callback< Ptr< SatBeamScheduler >, uint32_t, uint32_t > BeamSchedulerCallback
Callback to get the SatBeamScheduler from the beam ID for handover.
void SetTransmitCallback(SatMac::TransmitCallback cb)
Method to set transmit callback.
bool m_isStatisticsTagsEnabled
EnableStatisticsTags attribute.
Time m_beamEnabledTime
Time of the last beam enable event.
SatMac::RoutingUpdateCallback m_routingUpdateCallback
Callback to update routing and ARP tables after a beam handover.
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.
SatMac::SendCtrlMsgCallback m_sendCtrlCallback
The send control message callback.
void SetTimeTag(SatPhy::PacketContainer_t packets)
Set SatMacTimeTag of packets.
Callback< uint32_t, Ptr< SatControlMessage > > ReserveCtrlMsgCallback
Callback to reserve an id and initially store the control message.
Address m_satelliteAddress
MAC address of satellite on other side of the link.
virtual void Enable()
Enable the MAC layer, i.e.
SatMac::LoraReceiveCallback m_rxLoraCallback
The upper layer package receive callback.
void SetSendCtrlCallback(SatMac::SendCtrlMsgCallback cb)
Method to set send control message callback.
virtual void SetNodeInfo(Ptr< SatNodeInfo > nodeInfo)
Set the node info.
void DoDispose(void)
Dispose of SatMac.
virtual void ReceiveQueueEvent(SatQueue::QueueEvent_t event, uint8_t flowIndex)
Receive a queue event:
TracedCallback< const Time &, const Address & > m_rxLinkJitterTrace
Traced callback for all received packets, including link jitter information and the address of the se...
TracedCallback< const Time &, const Address & > m_rxDelayTrace
Traced callback for all received packets, including delay information and the address of the senders.
Time m_lastDelay
Last delay measurement.
Callback< void, Ptr< const Packet > > LoraReceiveCallback
Callback to receive packet by upper layer.
~SatMac()
Destroy a SatMac.
void SetRoutingUpdateCallback(SatMac::RoutingUpdateCallback cb)
Method to set the routing update callback.
SatMac::ReceiveCallback m_rxCallback
The upper layer package receive callback.
bool m_ncrV2
Use of version 2 of NCR dates.
void SetUpdateIslCallback(SatMac::UpdateIslCallback cb)
Method to set update ISL callback.
bool m_isRegenerative
Indicate if satellite is regeneration (at least LINK level) for TX.
Callback< void, Address, Address > RoutingUpdateCallback
Callback to update routing and ARP tables after handover.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced callback for all received packets, including the address of the senders.
Callback< void, Ptr< Packet >, Mac48Address, Mac48Address > ReceiveCallback
Callback to receive packet by upper layer.
Ptr< SatHandoverModule > m_handoverModule
Module used to perform handovers.
void SetReadCtrlCallback(SatMac::ReadCtrlMsgCallback cb)
Method to set read control message callback.
void SetHandoverModule(Ptr< SatHandoverModule > handoverModule)
Set the handover module.
bool m_txEnabled
Flag indicating whether the MAC is enabled, i.e.
TracedCallback< const Time &, const Address & > m_rxLinkDelayTrace
Traced callback for all received packets, including link delay information and the address of the sen...
SatMac::ReadCtrlMsgCallback m_readCtrlCallback
The read control message callback.
Callback< uint32_t, uint32_t > SendCtrlMsgCallback
Callback to send a control message and allocate a recv ID for it.
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...
void SetLoraReceiveCallback(SatMac::LoraReceiveCallback cb)
Method to set receive callback.
uint32_t SendCtrlMsgFromContainer(uint32_t sendId)
Send the control message from the container.
Time m_lastLinkDelay
Last delay measurement for link.
Callback< Ptr< SatControlMessage >, uint32_t > ReadCtrlMsgCallback
Callback to read control messages from container storing control messages.
void SetReceiveCallback(SatMac::ReceiveCallback cb)
Method to set receive callback.
SatMac::ReserveCtrlMsgCallback m_reserveCtrlCallback
The reserve control message id callback.
virtual void Disable()
Disable the MAC layer, i.e.
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...
void SetDestAddress(Mac48Address dest)
Set destination MAC address.
Mac48Address GetDestAddress(void) const
Get destination MAC address.
Time tag used to identify the time when packet is enqueued at MAC level.
Time GetSenderTimestamp(void) const
Get sender time stamp of this tag.
SatSignalParameters::PacketsInBurst_t PacketContainer_t
Define PacketContainer in SatPhy.
Definition: satellite-phy.h:79
Class to store topology of the whole system.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
Struct for storing the packet specific Tx information.