satellite-gw-llc.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: Jani Puttonen <jani.puttonen@magister.fi>
19  */
20 
21 #include "satellite-gw-llc.h"
22 
23 #include "satellite-enums.h"
27 #include "satellite-node-info.h"
31 #include "satellite-time-tag.h"
32 #include "satellite-utils.h"
33 
34 #include <ns3/log.h>
35 #include <ns3/simulator.h>
36 
37 NS_LOG_COMPONENT_DEFINE("SatGwLlc");
38 
39 namespace ns3
40 {
41 
42 NS_OBJECT_ENSURE_REGISTERED(SatGwLlc);
43 
44 TypeId
46 {
47  static TypeId tid = TypeId("ns3::SatGwLlc").SetParent<SatLlc>().AddConstructor<SatGwLlc>();
48  return tid;
49 }
50 
52 {
53  NS_LOG_FUNCTION(this);
54  NS_ASSERT(false); // this version of the constructor should not been used
55 }
56 
58  SatEnums::RegenerationMode_t returnLinkRegenerationMode)
59  : SatLlc(forwardLinkRegenerationMode, returnLinkRegenerationMode)
60 {
61  NS_LOG_FUNCTION(this);
62 }
63 
65 {
66  NS_LOG_FUNCTION(this);
67 }
68 
69 void
71 {
72  NS_LOG_FUNCTION(this);
73 
75 }
76 
77 bool
78 SatGwLlc::Enque(Ptr<Packet> packet, Address dest, uint8_t flowId)
79 {
80  NS_LOG_FUNCTION(this << packet << dest << (uint32_t)flowId);
81  NS_LOG_INFO("p=" << packet);
82  NS_LOG_INFO("dest=" << dest);
83  NS_LOG_INFO("UID is " << packet->GetUid());
84 
86  {
87  SatGroundStationAddressTag groundStationAddressTag =
88  SatGroundStationAddressTag(Mac48Address::ConvertFrom(dest));
89  packet->AddPacketTag(groundStationAddressTag);
90  }
91 
92  Ptr<EncapKey> key;
94  {
95  key = Create<EncapKey>(m_nodeInfo->GetMacAddress(),
97  flowId,
98  m_nodeInfo->GetMacAddress(),
99  Mac48Address::ConvertFrom(dest));
100  }
101  else
102  {
103  key = Create<EncapKey>(m_nodeInfo->GetMacAddress(),
104  Mac48Address::ConvertFrom(dest),
105  flowId,
106  m_nodeInfo->GetMacAddress(),
107  Mac48Address::ConvertFrom(dest));
108  }
109 
110  EncapContainer_t::iterator it = m_encaps.find(key);
111 
112  if (it == m_encaps.end())
113  {
119  CreateEncap(key);
120  it = m_encaps.find(key);
121  }
122 
123  // Store packet arrival time
124  SatTimeTag timeTag(Simulator::Now());
125  packet->AddPacketTag(timeTag);
126 
127  // Add E2E address tag to identify the packet in lower layers
128  SatAddressE2ETag addressE2ETag;
129  addressE2ETag.SetE2EDestAddress(Mac48Address::ConvertFrom(dest));
130  addressE2ETag.SetE2ESourceAddress(m_nodeInfo->GetMacAddress());
131  packet->AddPacketTag(addressE2ETag);
132 
133  it->second->EnquePdu(packet, Mac48Address::ConvertFrom(dest));
134 
136 
137  // Add packet trace entry:
138  m_packetTrace(Simulator::Now(),
140  m_nodeInfo->GetNodeType(),
141  m_nodeInfo->GetNodeId(),
142  m_nodeInfo->GetMacAddress(),
144  ld,
145  SatUtils::GetPacketInfo(packet));
146 
147  return true;
148 }
149 
150 Ptr<Packet>
152  Mac48Address utAddr,
153  uint8_t flowId,
154  uint32_t& bytesLeft,
155  uint32_t& nextMinTxO)
156 {
157  NS_LOG_FUNCTION(this << utAddr << bytes << (uint32_t)flowId);
158 
159  Ptr<Packet> packet;
160  Ptr<EncapKey> key = Create<EncapKey>(m_nodeInfo->GetMacAddress(), utAddr, flowId);
161  EncapContainer_t::iterator it = m_encaps.find(key);
162 
163  if (it != m_encaps.end())
164  {
165  packet = it->second->NotifyTxOpportunity(bytes, bytesLeft, nextMinTxO);
166 
167  if (packet)
168  {
170 
171  // Add packet trace entry:
172  m_packetTrace(Simulator::Now(),
174  m_nodeInfo->GetNodeType(),
175  m_nodeInfo->GetNodeId(),
176  m_nodeInfo->GetMacAddress(),
178  ld,
179  SatUtils::GetPacketInfo(packet));
180  }
181  }
182  else
183  {
184  NS_FATAL_ERROR("Encapsulator not found for key (" << m_nodeInfo->GetMacAddress() << ", "
185  << utAddr << ", " << (uint32_t)flowId
186  << ")");
187  }
188 
189  return packet;
190 }
191 
192 void
193 SatGwLlc::CreateEncap(Ptr<EncapKey> key)
194 {
195  NS_LOG_FUNCTION(this << key->m_encapAddress << key->m_decapAddress
196  << (uint32_t)(key->m_flowId));
197 
198  Ptr<SatBaseEncapsulator> gwEncap;
199 
201  {
202  // Control packet
203  gwEncap = CreateObject<SatBaseEncapsulator>(key->m_encapAddress,
204  key->m_decapAddress,
205  key->m_sourceE2EAddress,
206  key->m_destE2EAddress,
207  key->m_flowId);
208  }
209  else if (m_fwdLinkArqEnabled)
210  {
211  gwEncap = CreateObject<SatGenericStreamEncapsulatorArq>(key->m_encapAddress,
212  key->m_decapAddress,
213  key->m_sourceE2EAddress,
214  key->m_destE2EAddress,
215  key->m_flowId,
217  }
218  else
219  {
220  gwEncap = CreateObject<SatGenericStreamEncapsulator>(key->m_encapAddress,
221  key->m_decapAddress,
222  key->m_sourceE2EAddress,
223  key->m_destE2EAddress,
224  key->m_flowId,
226  }
227 
228  Ptr<SatQueue> queue = CreateObject<SatQueue>(key->m_flowId);
229  gwEncap->SetQueue(queue);
230 
231  NS_LOG_INFO("Create encapsulator with key (" << key->m_encapAddress << ", "
232  << key->m_decapAddress << ", "
233  << (uint32_t)key->m_flowId << ")");
234 
235  // Store the encapsulator
236  std::pair<EncapContainer_t::iterator, bool> result =
237  m_encaps.insert(std::make_pair(key, gwEncap));
238  if (result.second == false)
239  {
240  NS_FATAL_ERROR("Insert to map with key (" << key->m_encapAddress << ", "
241  << key->m_decapAddress << ", "
242  << (uint32_t)key->m_flowId << ") failed!");
243  }
244 }
245 
246 void
247 SatGwLlc::CreateDecap(Ptr<EncapKey> key)
248 {
249  NS_LOG_FUNCTION(this << key->m_encapAddress << key->m_decapAddress
250  << (uint32_t)(key->m_flowId));
251 
252  Ptr<SatBaseEncapsulator> gwDecap;
253 
255  {
256  gwDecap = CreateObject<SatReturnLinkEncapsulatorArq>(key->m_encapAddress,
257  key->m_decapAddress,
258  key->m_sourceE2EAddress,
259  key->m_destE2EAddress,
260  key->m_flowId,
262  }
263  else
264  {
265  gwDecap = CreateObject<SatReturnLinkEncapsulator>(key->m_encapAddress,
266  key->m_decapAddress,
267  key->m_sourceE2EAddress,
268  key->m_destE2EAddress,
269  key->m_flowId,
271  }
272 
273  gwDecap->SetReceiveCallback(MakeCallback(&SatLlc::ReceiveHigherLayerPdu, this));
274  gwDecap->SetCtrlMsgCallback(m_sendCtrlCallback);
275 
276  NS_LOG_INFO("Create decapsulator with key (" << key->m_encapAddress << ", "
277  << key->m_decapAddress << ", "
278  << (uint32_t)key->m_flowId << ")");
279 
280  // Store the decapsulator
281  std::pair<EncapContainer_t::iterator, bool> result =
282  m_decaps.insert(std::make_pair(key, gwDecap));
283  if (result.second == false)
284  {
285  NS_FATAL_ERROR("Insert to map with key (" << key->m_encapAddress << ", "
286  << key->m_decapAddress << ", "
287  << (uint32_t)key->m_flowId << ") failed!");
288  }
289 }
290 
293 {
294  return SatEnums::LD_FORWARD;
295 }
296 
299 {
300  return SatEnums::LD_RETURN;
301 }
302 
303 void
304 SatGwLlc::GetSchedulingContexts(std::vector<Ptr<SatSchedulingObject>>& output) const
305 {
306  NS_LOG_FUNCTION(this);
307 
308  // Head of link queuing delay
309  Time holDelay;
310 
311  // Then the user data
312  for (EncapContainer_t::const_iterator cit = m_encaps.begin(); cit != m_encaps.end(); ++cit)
313  {
314  uint32_t buf = cit->second->GetTxBufferSizeInBytes();
315 
316  if (buf > 0)
317  {
318  holDelay = cit->second->GetHolDelay();
319  uint32_t minTxOpportunityInBytes = cit->second->GetMinTxOpportunityInBytes();
320  Ptr<SatSchedulingObject> so = Create<SatSchedulingObject>(cit->first->m_decapAddress,
321  buf,
322  minTxOpportunityInBytes,
323  holDelay,
324  cit->first->m_flowId);
325  output.push_back(so);
326  }
327  }
328 }
329 
330 uint32_t
331 SatGwLlc::GetNBytesInQueue(Mac48Address utAddress) const
332 {
333  NS_LOG_FUNCTION(this << utAddress);
334 
335  uint32_t sum = 0;
336 
337  for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
338  {
339  if (it->first->m_decapAddress == utAddress)
340  {
341  NS_ASSERT(it->second != nullptr);
342  Ptr<SatQueue> queue = it->second->GetQueue();
343  NS_ASSERT(queue != nullptr);
344  sum += queue->GetNBytes();
345  }
346  }
347 
348  return sum;
349 }
350 
351 uint32_t
352 SatGwLlc::GetNPacketsInQueue(Mac48Address utAddress) const
353 {
354  NS_LOG_FUNCTION(this << utAddress);
355 
356  uint32_t sum = 0;
357 
358  for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
359  {
360  if (it->first->m_decapAddress == utAddress)
361  {
362  NS_ASSERT(it->second != nullptr);
363  Ptr<SatQueue> queue = it->second->GetQueue();
364  NS_ASSERT(queue != nullptr);
365  sum += queue->GetNPackets();
366  }
367  }
368 
369  return sum;
370 }
371 
372 } // 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.
void SetE2EDestAddress(Mac48Address e2eDestAddress)
Set E2E destination MAC address.
SatLinkDir_t
Link direction used for packet tracing.
RegenerationMode_t
The regeneration mode used in satellites.
Tag to store ground station destination address.
virtual void CreateDecap(Ptr< EncapKey > key)
Virtual method to create a new decapsulator 'on-a-need-basis' dynamically.
SatGwLlc()
Construct a SatGwLlc, should not be used.
virtual Ptr< Packet > NotifyTxOpportunity(uint32_t bytes, Mac48Address utAddr, uint8_t flowId, uint32_t &bytesLeft, uint32_t &nextMinTxO)
Called from lower layer (MAC) to inform a tx opportunity of certain amount of bytes.
virtual SatEnums::SatLinkDir_t GetSatLinkRxDir()
Get the link RX direction.
virtual ~SatGwLlc()
Destroy a SatGwLlc.
virtual bool Enque(Ptr< Packet > packet, Address dest, uint8_t flowId)
Called from higher layer (SatNetDevice) to enque packet to LLC.
virtual void GetSchedulingContexts(std::vector< Ptr< SatSchedulingObject >> &output) const
Create and fill the scheduling objects based on LLC layer information.
static TypeId GetTypeId(void)
Get the type ID.
virtual SatEnums::SatLinkDir_t GetSatLinkTxDir()
Get the link TX direction.
virtual void CreateEncap(Ptr< EncapKey > key)
Virtual method to create a new encapsulator 'on-a-need-basis' dynamically.
void DoDispose()
Dispose of this class instance.
SatLlc base class holds the UT specific SatBaseEncapsulator instances, which are responsible of fragm...
Ptr< SatNodeInfo > m_nodeInfo
Node info containing node related information, such as node type, node id and MAC address (of the Sat...
virtual uint32_t GetNBytesInQueue() const
Get the total number of (new) bytes in all encapsulators.
uint32_t m_additionalHeaderSize
Additional header size to add to encapsulation/decapsulation.
bool m_fwdLinkArqEnabled
Is FWD link ARQ enabled.
SatBaseEncapsulator::SendCtrlCallback m_sendCtrlCallback
Callback to send control messages.
EncapContainer_t m_decaps
Map of decapsulator base pointers.
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:
virtual void DoDispose()
Dispose of this class instance.
EncapContainer_t m_encaps
Map of encapsulator base pointers.
SatEnums::RegenerationMode_t m_forwardLinkRegenerationMode
Regeneration mode on forward link.
virtual uint32_t GetNPacketsInQueue() const
Get the total number of (new) packets in all encapsulators.
virtual void ReceiveHigherLayerPdu(Ptr< Packet > packet, Mac48Address source, Mac48Address dest)
Receive HL PDU from encapsulator/decapsulator entity.
Mac48Address m_satelliteAddress
SAT address, used in case of network regeneration.
bool m_rtnLinkArqEnabled
Is RTN link ARQ enabled.
Time tag used to identify the time when packet is enqueued at LLC level.
static std::string GetPacketInfo(const Ptr< const Packet > p)
Get packet information in std::string for printing purposes.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.