Loading...
Searching...
No Matches
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#include <utility>
38#include <vector>
39
40NS_LOG_COMPONENT_DEFINE("SatGwLlc");
41
42namespace ns3
43{
44
45NS_OBJECT_ENSURE_REGISTERED(SatGwLlc);
46
47TypeId
49{
50 static TypeId tid = TypeId("ns3::SatGwLlc").SetParent<SatLlc>().AddConstructor<SatGwLlc>();
51 return tid;
52}
53
55 : SatLlc()
56{
57 NS_LOG_FUNCTION(this);
58}
59
61{
62 NS_LOG_FUNCTION(this);
63}
64
65void
67{
68 NS_LOG_FUNCTION(this);
69
71}
72
73bool
74SatGwLlc::Enque(Ptr<Packet> packet, Address dest, uint8_t flowId)
75{
76 NS_LOG_FUNCTION(this << packet << dest << (uint32_t)flowId);
77 NS_LOG_INFO("p=" << packet);
78 NS_LOG_INFO("dest=" << dest);
79 NS_LOG_INFO("UID is " << packet->GetUid());
80
82 {
83 SatGroundStationAddressTag groundStationAddressTag;
84 // May have been already added by Lora Network Server, do not add twice
85 if (!packet->PeekPacketTag(groundStationAddressTag))
86 {
87 groundStationAddressTag = SatGroundStationAddressTag(Mac48Address::ConvertFrom(dest));
88 packet->AddPacketTag(groundStationAddressTag);
89 }
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,
146
147 return true;
148}
149
150Ptr<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,
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
192void
193SatGwLlc::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
246void
247SatGwLlc::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
296
302
303void
304SatGwLlc::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
330uint32_t
331SatGwLlc::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
351uint32_t
352SatGwLlc::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
372void
374{
375 NS_LOG_FUNCTION(this);
376
377 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
378 {
379 NS_ASSERT(it->second != nullptr);
380 Ptr<SatQueue> queue = it->second->GetQueue();
381 NS_ASSERT(queue != nullptr);
382 queue->DequeueAll();
383 }
384}
385
386} // 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.
Tag to store ground station destination address.
SatGwLlc holds the GW implementation of LLC layer.
virtual void CreateDecap(Ptr< EncapKey > key)
Virtual method to create a new decapsulator 'on-a-need-basis' dynamically.
SatGwLlc()
Construct a SatGwLlc.
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.
static TypeId GetTypeId(void)
Get the type ID.
virtual void ClearQueues()
Remove all packets from the queues.
virtual void GetSchedulingContexts(std::vector< Ptr< SatSchedulingObject > > &output) const
Create and fill the scheduling objects based on LLC layer information.
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.
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.
SatLlc()
Construct a SatLlc.
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.