Loading...
Searching...
No Matches
satellite-ut-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-ut-llc.h"
22
24#include "satellite-enums.h"
28#include "satellite-node-info.h"
33#include "satellite-utils.h"
34
35#include "ns3/address.h"
36#include "ns3/log.h"
37#include "ns3/mac48-address.h"
38#include "ns3/packet.h"
39#include "ns3/pointer.h"
40#include "ns3/simulator.h"
41
42#include <utility>
43#include <vector>
44
45NS_LOG_COMPONENT_DEFINE("SatUtLlc");
46
47namespace ns3
48{
49
50NS_OBJECT_ENSURE_REGISTERED(SatLlc);
51
52TypeId
54{
55 static TypeId tid = TypeId("ns3::SatUtLlc")
56 .SetParent<SatLlc>()
57 .AddConstructor<SatUtLlc>()
58 .AddAttribute("SatRequestManager",
59 "The request manager of this UT.",
60 PointerValue(),
61 MakePointerAccessor(&SatUtLlc::GetRequestManager,
63 MakePointerChecker<SatRequestManager>());
64 return tid;
65}
66
68 : SatLlc(),
70{
71 NS_LOG_FUNCTION(this);
72}
73
75{
76 NS_LOG_FUNCTION(this);
77}
78
79void
81{
82 NS_LOG_FUNCTION(this);
83
85 {
86 m_requestManager->DoDispose();
88 }
89
90 m_macQueueEventCb.Nullify();
91
93}
94
95bool
96SatUtLlc::Enque(Ptr<Packet> packet, Address dest, uint8_t flowId)
97{
98 NS_LOG_FUNCTION(this << packet << dest << (uint32_t)flowId);
99 NS_LOG_INFO("p=" << packet);
100 NS_LOG_INFO("dest=" << dest);
101 NS_LOG_INFO("UID is " << packet->GetUid());
102
103 Mac48Address destMacAddress;
104 if (dest != m_satelliteAddress)
105 {
106 destMacAddress = Mac48Address::ConvertFrom(m_gwAddress);
107 }
108 else
109 {
110 destMacAddress = Mac48Address::ConvertFrom(dest);
111 }
112
114 {
115 SatGroundStationAddressTag groundStationAddressTag =
116 SatGroundStationAddressTag(destMacAddress);
117 packet->AddPacketTag(groundStationAddressTag);
118 }
119
120 // all multicast traffic is delivered with GW address
121 // in order to avoid supporting several encaps in UT
122 // in return link there is only one receiver (GW) for the multicast traffic for the UT
123 if (destMacAddress.IsGroup())
124 {
125 destMacAddress = m_gwAddress;
126 }
127
128 Ptr<EncapKey> key;
130 {
131 key = Create<EncapKey>(m_nodeInfo->GetMacAddress(),
133 flowId,
134 m_nodeInfo->GetMacAddress(),
135 destMacAddress);
136 }
137 else
138 {
139 key = Create<EncapKey>(m_nodeInfo->GetMacAddress(),
140 destMacAddress,
141 flowId,
142 m_nodeInfo->GetMacAddress(),
143 destMacAddress);
144 }
145
146 EncapContainer_t::iterator it = m_encaps.find(key);
147
148 if (it == m_encaps.end())
149 {
155 CreateEncap(key);
156 it = m_encaps.find(key);
157 }
158
159 // Add E2E address tag to identify the packet in lower layers
160 SatAddressE2ETag addressE2ETag;
161 addressE2ETag.SetE2EDestAddress(destMacAddress);
162 addressE2ETag.SetE2ESourceAddress(m_nodeInfo->GetMacAddress());
163 packet->AddPacketTag(addressE2ETag);
164
165 it->second->EnquePdu(packet, destMacAddress);
166
167 // Add packet trace entry:
168 m_packetTrace(Simulator::Now(),
170 m_nodeInfo->GetNodeType(),
171 m_nodeInfo->GetNodeId(),
172 m_nodeInfo->GetMacAddress(),
176
177 return true;
178}
179
180Ptr<Packet>
182 Mac48Address utAddr,
183 uint8_t rcIndex,
184 uint32_t& bytesLeft,
185 uint32_t& nextMinTxO)
186{
187 NS_LOG_FUNCTION(this << utAddr << bytes << (uint32_t)rcIndex);
188
189 Ptr<Packet> packet;
190 Ptr<EncapKey> key;
192 {
193 key = Create<EncapKey>(utAddr, m_satelliteAddress, rcIndex);
194 }
195 else
196 {
197 key = Create<EncapKey>(utAddr, m_gwAddress, rcIndex);
198 }
199
200 EncapContainer_t::iterator it = m_encaps.find(key);
201
202 if (it != m_encaps.end())
203 {
204 packet = it->second->NotifyTxOpportunity(bytes, bytesLeft, nextMinTxO);
205
206 if (packet)
207 {
209
210 // Add packet trace entry:
211 m_packetTrace(Simulator::Now(),
213 m_nodeInfo->GetNodeType(),
214 m_nodeInfo->GetNodeId(),
215 m_nodeInfo->GetMacAddress(),
217 ld,
219 }
220 }
221 /*
222 * At the UT the UT scheduler may give a Tx opportunity to a encapsulator which
223 * does not exist, since it does not exact knowledge that which encapsulators
224 * have been dynamically created. Thus, it is not an error case, where the
225 * encapsulator is not found!
226 */
227
228 return packet;
229}
230
231void
232SatUtLlc::SetRequestManager(Ptr<SatRequestManager> rm)
233{
234 NS_LOG_FUNCTION(this);
235 m_requestManager = rm;
236}
237
238Ptr<SatRequestManager>
240{
241 NS_LOG_FUNCTION(this);
242
243 return m_requestManager;
244}
245
246void
248{
249 NS_LOG_FUNCTION(this);
250
251 // Control queue = rcIndex 0
253 for (EncapContainer_t::iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
254 {
255 // Set the callback for each RLE queue
256 queueCb = MakeCallback(&SatQueue::GetQueueStatistics, it->second->GetQueue());
257 m_requestManager->AddQueueCallback(it->first->m_flowId, queueCb);
258 }
259}
260
261uint32_t
262SatUtLlc::GetNumSmallerPackets(uint32_t maxPacketSizeBytes) const
263{
264 NS_LOG_FUNCTION(this << maxPacketSizeBytes);
265
266 uint32_t packets(0);
267 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
268 {
269 packets += it->second->GetQueue()->GetNumSmallerPackets(maxPacketSizeBytes);
270 }
271 return packets;
272}
273
274void
275SatUtLlc::SetNodeInfo(Ptr<SatNodeInfo> nodeInfo)
276{
277 NS_LOG_FUNCTION(this);
278
279 m_requestManager->SetNodeInfo(nodeInfo);
280 SatLlc::SetNodeInfo(nodeInfo);
281}
282
283void
284SatUtLlc::CreateEncap(Ptr<EncapKey> key)
285{
286 CreateEncap(key, nullptr);
287}
288
289void
290SatUtLlc::CreateEncap(Ptr<EncapKey> key, Ptr<SatQueue> providedQueue)
291{
292 NS_LOG_FUNCTION(this << key->m_encapAddress << key->m_decapAddress
293 << (uint32_t)(key->m_flowId));
294
295 Ptr<SatBaseEncapsulator> utEncap;
296
298 {
299 // Control packet
300 utEncap = CreateObject<SatBaseEncapsulator>(key->m_encapAddress,
301 key->m_decapAddress,
302 key->m_sourceE2EAddress,
303 key->m_destE2EAddress,
304 key->m_flowId);
305 }
306 else if (m_rtnLinkArqEnabled)
307 {
308 utEncap = CreateObject<SatReturnLinkEncapsulatorArq>(key->m_encapAddress,
309 key->m_decapAddress,
310 key->m_sourceE2EAddress,
311 key->m_destE2EAddress,
312 key->m_flowId,
314 }
315 else
316 {
317 utEncap = CreateObject<SatReturnLinkEncapsulator>(key->m_encapAddress,
318 key->m_decapAddress,
319 key->m_sourceE2EAddress,
320 key->m_destE2EAddress,
321 key->m_flowId,
323 }
324
325 Ptr<SatQueue> queue = providedQueue;
326 if (!queue)
327 {
328 queue = CreateObject<SatQueue>(key->m_flowId);
329 queue->AddQueueEventCallback(m_macQueueEventCb);
330 queue->AddQueueEventCallback(
332
333 // Set the callback for each RLE queue
335 MakeCallback(&SatQueue::GetQueueStatistics, queue);
336 m_requestManager->AddQueueCallback(key->m_flowId, queueCb);
337 }
338
339 utEncap->SetQueue(queue);
340
341 NS_LOG_INFO("Create encapsulator with key (" << key->m_encapAddress << ", "
342 << key->m_decapAddress << ", "
343 << (uint32_t)key->m_flowId << ")");
344
345 // Store the encapsulator
346 std::pair<EncapContainer_t::iterator, bool> result =
347 m_encaps.insert(std::make_pair(key, utEncap));
348 if (result.second == false)
349 {
350 NS_FATAL_ERROR("Insert to map with key (" << key->m_encapAddress << ", "
351 << key->m_decapAddress << ", "
352 << (uint32_t)key->m_flowId << ") failed!");
353 }
354}
355
356void
357SatUtLlc::CreateDecap(Ptr<EncapKey> key)
358{
359 NS_LOG_FUNCTION(this << key->m_encapAddress << key->m_decapAddress
360 << (uint32_t)(key->m_flowId));
361
362 Ptr<SatBaseEncapsulator> utDecap;
363
365 {
366 utDecap = CreateObject<SatGenericStreamEncapsulatorArq>(key->m_encapAddress,
367 key->m_decapAddress,
368 key->m_sourceE2EAddress,
369 key->m_destE2EAddress,
370 key->m_flowId,
372 }
373 else
374 {
375 utDecap = CreateObject<SatGenericStreamEncapsulator>(key->m_encapAddress,
376 key->m_decapAddress,
377 key->m_sourceE2EAddress,
378 key->m_destE2EAddress,
379 key->m_flowId,
381 }
382
383 utDecap->SetReceiveCallback(MakeCallback(&SatLlc::ReceiveHigherLayerPdu, this));
384 utDecap->SetCtrlMsgCallback(m_sendCtrlCallback);
385
386 NS_LOG_INFO("Create decapsulator with key (" << key->m_encapAddress << ", "
387 << key->m_decapAddress << ", "
388 << (uint32_t)key->m_flowId << ")");
389
390 // Store the decapsulator
391 std::pair<EncapContainer_t::iterator, bool> result =
392 m_decaps.insert(std::make_pair(key, utDecap));
393 if (result.second == false)
394 {
395 NS_FATAL_ERROR("Insert to map with key (" << key->m_encapAddress << ", "
396 << key->m_decapAddress << ", "
397 << (uint32_t)key->m_flowId << ") failed!");
398 }
399}
400
401uint32_t
402SatUtLlc::GetNBytesInQueue(Mac48Address utAddress) const
403{
404 NS_LOG_FUNCTION(this << utAddress);
405
406 uint32_t sum = 0;
407
408 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
409 {
410 if (it->first->m_encapAddress == utAddress)
411 {
412 NS_ASSERT(it->second != nullptr);
413 Ptr<SatQueue> queue = it->second->GetQueue();
414 NS_ASSERT(queue != nullptr);
415 sum += queue->GetNBytes();
416 }
417 }
418
419 return sum;
420}
421
422uint32_t
423SatUtLlc::GetNPacketsInQueue(Mac48Address utAddress) const
424{
425 NS_LOG_FUNCTION(this << utAddress);
426
427 uint32_t sum = 0;
428
429 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
430 {
431 if (it->first->m_encapAddress == utAddress)
432 {
433 NS_ASSERT(it->second != nullptr);
434 Ptr<SatQueue> queue = it->second->GetQueue();
435 NS_ASSERT(queue != nullptr);
436 sum += queue->GetNPackets();
437 }
438 }
439
440 return sum;
441}
442
443void
444SatUtLlc::GetSchedulingContexts(std::vector<Ptr<SatSchedulingObject>>& output) const
445{
446 NS_LOG_FUNCTION(this);
447 NS_ASSERT(false);
448
452}
453
459
465
466void
468{
469 NS_LOG_FUNCTION(this << &cb);
470
472}
473
474void
475SatUtLlc::SetGwAddress(Mac48Address address)
476{
477 NS_LOG_FUNCTION(this << address);
478
479 if (m_nodeInfo && m_nodeInfo->GetMacAddress() != address)
480 {
481 // Move queue from the old gateway to the new one
482 for (uint8_t rcIndex = 0;; ++rcIndex)
483 {
484 Ptr<EncapKey> peek =
485 Create<EncapKey>(m_nodeInfo->GetMacAddress(), m_gwAddress, rcIndex);
486 EncapContainer_t::iterator it = m_encaps.find(peek);
487
488 if (it != m_encaps.end())
489 {
490 Ptr<EncapKey> key = Create<EncapKey>(m_nodeInfo->GetMacAddress(), address, rcIndex);
491 CreateEncap(key, it->second->GetQueue());
492 m_encaps.erase(it);
493 NS_LOG_INFO("Queue from key "
494 << peek->m_encapAddress << ", " << peek->m_decapAddress << ", "
495 << (uint32_t)(peek->m_flowId) << " moved to key " << key->m_encapAddress
496 << ", " << key->m_decapAddress << ", " << (uint32_t)(key->m_flowId));
497 }
498
499 if (rcIndex == 255)
500 {
501 break;
502 }
503 }
504 }
505
506 SatLlc::SetGwAddress(address);
507
508 m_requestManager->SetGwAddress(address);
509}
510
511} // 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.
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 void SetGwAddress(Mac48Address address)
Set the GW address.
virtual uint32_t GetNBytesInQueue() const
Get the total number of (new) bytes in all encapsulators.
virtual void SetNodeInfo(Ptr< SatNodeInfo > nodeInfo)
Set the node info.
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.
SatEnums::RegenerationMode_t m_returnLinkRegenerationMode
Regeneration mode on return link.
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:
Mac48Address m_gwAddress
GW address.
virtual void DoDispose()
Dispose of this class instance.
EncapContainer_t m_encaps
Map of encapsulator base pointers.
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.
Callback< void, SatQueue::QueueEvent_t, uint8_t > QueueEventCallback
Callback to indicate queue related event.
QueueStats_t GetQueueStatistics(bool reset)
GetQueueStatistics returns a struct of KPIs.
void ReceiveQueueEvent(SatQueue::QueueEvent_t event, uint8_t rcIndex)
Receive a queue event.
Callback< SatQueue::QueueStats_t, bool > QueueCallback
Callback to fetch queue statistics.
void SetQueueStatisticsCallbacks()
Set queue statistics callbacks for each UT packet queue.
virtual void GetSchedulingContexts(std::vector< Ptr< SatSchedulingObject > > &output) const
Create and fill the scheduling objects based on LLC layer information.
virtual SatEnums::SatLinkDir_t GetSatLinkRxDir()
Get the link RX direction.
void SetMacQueueEventCallback(SatQueue::QueueEventCallback cb)
SatQueue::QueueEventCallback m_macQueueEventCb
Callback to send queue events to e.g.
Ptr< SatRequestManager > m_requestManager
Request manager handling the capacity requests.
void SetRequestManager(Ptr< SatRequestManager > rm)
Set a request manager for UT's LLC instance.
virtual void CreateDecap(Ptr< EncapKey > key)
Virtual method to create a new decapsulator 'on-a-need-basis' dynamically.
virtual ~SatUtLlc()
Destroy a SatUtLlc.
virtual uint32_t GetNumSmallerPackets(uint32_t maxPacketSizeBytes) const
Method checks how many packets are smaller or equal in size than the maximum packets size threshold s...
SatUtLlc()
Construct a SatUtLlc.
void SetGwAddress(Mac48Address address)
Set the GW address.
virtual void SetNodeInfo(Ptr< SatNodeInfo > nodeInfo)
Set the node info.
virtual void CreateEncap(Ptr< EncapKey > key)
Virtual method to create a new encapsulator 'on-a-need-basis' dynamically.
Ptr< SatRequestManager > GetRequestManager() const
Getter for the request manager.
void DoDispose()
Dispose of SatUtLLc.
static TypeId GetTypeId(void)
Derived form Object.
virtual bool Enque(Ptr< Packet > packet, Address dest, uint8_t flowId)
Called from higher layer (SatNetDevice) to enque packet to LLC.
virtual SatEnums::SatLinkDir_t GetSatLinkTxDir()
Get the link TX direction.
virtual Ptr< Packet > NotifyTxOpportunity(uint32_t bytes, Mac48Address utAddr, uint8_t rcIndex, uint32_t &bytesLeft, uint32_t &nextMinTxO)
Called from lower layer (MAC) to inform a Tx opportunity of certain amount of bytes.
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.