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-typedefs.h"
27 
28 #include <ns3/boolean.h>
29 #include <ns3/log.h>
30 #include <ns3/nstime.h>
31 #include <ns3/packet.h>
32 #include <ns3/pointer.h>
33 #include <ns3/simulator.h>
34 #include <ns3/trace-source-accessor.h>
35 #include <ns3/uinteger.h>
36 
37 NS_LOG_COMPONENT_DEFINE("SatMac");
38 
39 namespace ns3
40 {
41 
42 NS_OBJECT_ENSURE_REGISTERED(SatMac);
43 
44 TypeId
46 {
47  static TypeId tid =
48  TypeId("ns3::SatMac")
49  .SetParent<Object>()
50  .AddConstructor<SatMac>()
51  .AddAttribute("EnableStatisticsTags",
52  "If true, some tags will be added to each transmitted packet to assist "
53  "with statistics computation",
54  BooleanValue(false),
55  MakeBooleanAccessor(&SatMac::m_isStatisticsTagsEnabled),
56  MakeBooleanChecker())
57  .AddAttribute("NcrVersion2",
58  "NCR version used (false for 1, true for 2)",
59  BooleanValue(false),
60  MakeBooleanAccessor(&SatMac::m_ncrV2),
61  MakeBooleanChecker())
62  .AddTraceSource("PacketTrace",
63  "Packet event trace",
64  MakeTraceSourceAccessor(&SatMac::m_packetTrace),
65  "ns3::SatTypedefs::PacketTraceCallback")
66  .AddTraceSource("Rx",
67  "A packet received",
68  MakeTraceSourceAccessor(&SatMac::m_rxTrace),
69  "ns3::SatTypedefs::PacketSenderAddressCallback")
70  .AddTraceSource("RxDelay",
71  "A packet is received with delay information",
72  MakeTraceSourceAccessor(&SatMac::m_rxDelayTrace),
73  "ns3::SatTypedefs::PacketDelayAddressCallback")
74  .AddTraceSource("RxLinkDelay",
75  "A packet is received with link delay information",
76  MakeTraceSourceAccessor(&SatMac::m_rxLinkDelayTrace),
77  "ns3::SatTypedefs::PacketDelayAddressCallback")
78  .AddTraceSource("RxJitter",
79  "A packet is received with jitter information",
80  MakeTraceSourceAccessor(&SatMac::m_rxJitterTrace),
81  "ns3::SatTypedefs::PacketJitterAddressCallback")
82  .AddTraceSource("RxLinkJitter",
83  "A packet is received with link jitter information",
84  MakeTraceSourceAccessor(&SatMac::m_rxLinkJitterTrace),
85  "ns3::SatTypedefs::PacketJitterAddressCallback")
86  .AddTraceSource("BeamServiceTime",
87  "A beam was disabled. Transmits length of last beam service time.",
88  MakeTraceSourceAccessor(&SatMac::m_beamServiceTrace),
89  "ns3::SatTypedefs::ServiceTimeCallback");
90  return tid;
91 }
92 
94  : m_isStatisticsTagsEnabled(false),
95  m_ncrV2(false),
96  m_routingUpdateCallback(),
97  m_nodeInfo(),
98  m_txEnabled(true),
99  m_beamEnabledTime(Seconds(0)),
100  m_lastDelay(0),
101  m_forwardLinkRegenerationMode(SatEnums::TRANSPARENT),
102  m_returnLinkRegenerationMode(SatEnums::TRANSPARENT),
103  m_isRegenerative(false),
104  m_satelliteAddress(),
105  m_lastLinkDelay(0)
106 {
107  NS_LOG_FUNCTION(this);
108  NS_ASSERT(false); // this version of the constructor should not been used
109 }
110 
111 SatMac::SatMac(uint32_t satId,
112  uint32_t beamId,
113  SatEnums::RegenerationMode_t forwardLinkRegenerationMode,
114  SatEnums::RegenerationMode_t returnLinkRegenerationMode)
115  : m_isStatisticsTagsEnabled(false),
116  m_ncrV2(false),
117  m_routingUpdateCallback(),
118  m_nodeInfo(),
119  m_satId(satId),
120  m_beamId(beamId),
121  m_txEnabled(true),
122  m_beamEnabledTime(Seconds(0)),
123  m_lastDelay(0),
124  m_forwardLinkRegenerationMode(forwardLinkRegenerationMode),
125  m_returnLinkRegenerationMode(returnLinkRegenerationMode),
126  m_isRegenerative(false),
127  m_satelliteAddress(),
128  m_lastLinkDelay(0)
129 {
130  NS_LOG_FUNCTION(this);
131 }
132 
134 {
135  NS_LOG_FUNCTION(this);
136 }
137 
138 void
140 {
141  NS_LOG_FUNCTION(this);
142  if (m_txEnabled)
143  m_beamServiceTrace(Simulator::Now() - m_beamEnabledTime);
144 
145  m_txCallback.Nullify();
146  m_rxCallback.Nullify();
147  m_readCtrlCallback.Nullify();
148  m_reserveCtrlCallback.Nullify();
149  m_sendCtrlCallback.Nullify();
150  m_routingUpdateCallback.Nullify();
151 
152  Object::DoDispose();
153 }
154 
155 void
156 SatMac::SetNodeInfo(Ptr<SatNodeInfo> nodeInfo)
157 {
158  NS_LOG_FUNCTION(this << nodeInfo);
159  NS_LOG_INFO("Node (id)= " << nodeInfo->GetNodeId()
160  << " Node (type)= " << nodeInfo->GetNodeType()
161  << " Address= " << nodeInfo->GetMacAddress());
162  m_nodeInfo = nodeInfo;
163 }
164 
165 uint32_t
167 {
168  NS_LOG_FUNCTION(this << msg);
169 
170  uint32_t id = 0;
171 
172  if (m_reserveCtrlCallback.IsNull() == false)
173  {
174  id = m_reserveCtrlCallback(msg);
175  }
176  else
177  {
178  NS_FATAL_ERROR("Reserve control message (m_reserveCtrlCallback) callback is NULL!");
179  }
180  return id;
181 }
182 
183 uint32_t
185 {
186  NS_LOG_FUNCTION(this << sendId);
187 
188  uint32_t recvId(0);
189  if (m_sendCtrlCallback.IsNull() == false)
190  {
191  recvId = m_sendCtrlCallback(sendId);
192  }
193  else
194  {
195  NS_FATAL_ERROR("Write control message (m_writeCtrlCallback) callback is NULL!");
196  }
197  return recvId;
198 }
199 
200 void
201 SatMac::ReceiveQueueEvent(SatQueue::QueueEvent_t /*event*/, uint8_t /*flowIndex*/)
202 {
203  NS_LOG_FUNCTION(this);
204 }
205 
206 void
208 {
209  NS_LOG_FUNCTION(this);
210  if (!m_txEnabled)
211  m_beamEnabledTime = Simulator::Now();
212  m_txEnabled = true;
213 }
214 
215 void
217 {
218  NS_LOG_FUNCTION(this);
219  if (m_txEnabled)
220  m_beamServiceTrace(Simulator::Now() - m_beamEnabledTime);
221  m_txEnabled = false;
222 }
223 
224 void
225 SatMac::SetSatelliteAddress(Address satelliteAddress)
226 {
227  m_satelliteAddress = satelliteAddress;
228  m_isRegenerative = true;
229 }
230 
231 void
233 {
235  {
236  for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
237  ++it)
238  {
239  SatMacTimeTag timeTag;
240  if (!(*it)->PeekPacketTag(timeTag))
241  {
242  (*it)->AddPacketTag(SatMacTimeTag(Simulator::Now()));
243  }
244 
245  SatMacLinkTimeTag linkTimeTag;
246  if (!(*it)->PeekPacketTag(linkTimeTag))
247  {
248  (*it)->AddPacketTag(SatMacLinkTimeTag(Simulator::Now()));
249  }
250  }
251  }
252 }
253 
254 void
256  uint32_t carrierId,
257  Time duration,
259 {
260  NS_LOG_FUNCTION(this);
261 
262  // Add a SatMacTimeTag tag for packet delay computation at the receiver end.
263  SetTimeTag(packets);
264 
265  // Update local destination MAC tag with satellite one if satellite is regenerative
266  if (m_isRegenerative)
267  {
268  for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end();
269  ++it)
270  {
271  SatMacTag mTag;
272  bool success = (*it)->RemovePacketTag(mTag);
273 
274  // MAC tag found
275  if (success)
276  {
277  mTag.SetDestAddress(Mac48Address::ConvertFrom(m_satelliteAddress));
278  (*it)->AddPacketTag(mTag);
279  }
280  }
281  }
282 
289  for (SatPhy::PacketContainer_t::const_iterator it = packets.begin(); it != packets.end(); ++it)
290  {
291  SatControlMsgTag cTag;
292  bool success = (*it)->RemovePacketTag(cTag);
293 
294  // Control tag found
295  if (success)
296  {
297  uint32_t sendId = cTag.GetMsgId();
298 
299  // Add the msg to container and receive the used recv id.
300  uint32_t recvId = SendCtrlMsgFromContainer(sendId);
301 
302  // Store the recv id to tag and add the tag back to the packet
303  cTag.SetMsgId(recvId);
304  (*it)->AddPacketTag(cTag);
305 
307  {
308  Ptr<SatNcrMessage> ncrMsg = m_ncrMessagesToSend.front();
309  m_ncrMessagesToSend.pop();
310  uint8_t lastSOFSize = m_ncrV2 ? 3 : 1;
311  ncrMsg->SetNcrDate(m_lastSOF.size() == lastSOFSize
312  ? m_lastSOF.front().GetNanoSeconds() * 0.027
313  : 0);
314  }
315  }
316  }
317 
318  // Use call back to send packet to lower layer
319  m_txCallback(packets, carrierId, duration, txInfo);
320 }
321 
322 void
324 {
325  NS_LOG_FUNCTION(this);
326 
328  {
329  for (SatPhy::PacketContainer_t::const_iterator it1 = packets.begin(); it1 != packets.end();
330  ++it1)
331  {
332  // Remove packet tag
333  SatMacTag macTag;
334  bool mSuccess = (*it1)->PeekPacketTag(macTag);
335  if (!mSuccess)
336  {
337  NS_FATAL_ERROR("MAC tag was not found from the packet!");
338  }
339 
340  // If the packet is intended for this receiver
341  Mac48Address destAddress = macTag.GetDestAddress();
342 
343  if (destAddress == m_nodeInfo->GetMacAddress())
344  {
345  Address addr; // invalid address.
346 
347  bool isTaggedWithAddress = false;
348  ByteTagIterator it2 = (*it1)->GetByteTagIterator();
349 
350  while (!isTaggedWithAddress && it2.HasNext())
351  {
352  ByteTagIterator::Item item = it2.Next();
353 
354  if (item.GetTypeId() == SatAddressTag::GetTypeId())
355  {
356  NS_LOG_DEBUG(this << " contains a SatAddressTag tag:"
357  << " start=" << item.GetStart()
358  << " end=" << item.GetEnd());
359  SatAddressTag addrTag;
360  item.GetTag(addrTag);
361  addr = addrTag.GetSourceAddress();
362  isTaggedWithAddress = true; // this will exit the while loop.
363  }
364  }
365 
366  m_rxTrace(*it1, addr);
367 
368  SatMacTimeTag timeTag;
369  if ((*it1)->RemovePacketTag(timeTag))
370  {
371  NS_LOG_DEBUG(this << " contains a SatMacTimeTag tag");
372  Time delay = Simulator::Now() - timeTag.GetSenderTimestamp();
373  m_rxDelayTrace(delay, addr);
374  if (m_lastDelay.IsZero() == false)
375  {
376  Time jitter = Abs(delay - m_lastDelay);
377  m_rxJitterTrace(jitter, addr);
378  }
379  m_lastDelay = delay;
380  }
381  SatMacLinkTimeTag linkTimeTag;
382  if ((*it1)->RemovePacketTag(linkTimeTag))
383  {
384  NS_LOG_DEBUG(this << " contains a SatMacLinkTimeTag tag");
385  Time delay = Simulator::Now() - linkTimeTag.GetSenderLinkTimestamp();
386  m_rxLinkDelayTrace(delay, addr);
387  if (m_lastLinkDelay.IsZero() == false)
388  {
389  Time jitter = Abs(delay - m_lastLinkDelay);
390  m_rxLinkJitterTrace(jitter, addr);
391  }
392  m_lastLinkDelay = delay;
393  }
394  } // end of `if (destAddress == m_nodeInfo->GetMacAddress () || destAddress.IsBroadcast
395  // ())`
396  } // end of `for it1 = packets.begin () -> packets.end ()`
397  } // end of `if (m_isStatisticsTagsEnabled)`
398 }
399 
400 void
402 {
403  NS_LOG_FUNCTION(this << &cb);
404  m_txCallback = cb;
405 }
406 
407 void
409 {
410  NS_LOG_FUNCTION(this << &cb);
411  m_rxCallback = cb;
412 }
413 
414 void
416 {
417  NS_LOG_FUNCTION(this << &cb);
418  m_rxLoraCallback = cb;
419 }
420 
421 void
423 {
424  NS_LOG_FUNCTION(this << &cb);
425  m_readCtrlCallback = cb;
426 }
427 
428 void
430 {
431  NS_LOG_FUNCTION(this << &cb);
433 }
434 
435 void
437 {
438  NS_LOG_FUNCTION(this << &cb);
439  m_sendCtrlCallback = cb;
440 }
441 
442 void
444 {
445  NS_LOG_FUNCTION(this << &cb);
447 }
448 
449 } // 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.
SatEnums class is for simplifying the use of enumerators in the satellite module.
RegenerationMode_t
The regeneration mode used in satellites.
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.
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.
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.
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.
void SetReadCtrlCallback(SatMac::ReadCtrlMsgCallback cb)
Method to set read control message callback.
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.
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:78
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
Struct for storing the packet specific Tx information.