Loading...
Searching...
No Matches
satellite-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-llc.h"
22
24#include "satellite-enums.h"
25#include "satellite-node-info.h"
26#include "satellite-queue.h"
28#include "satellite-time-tag.h"
29#include "satellite-topology.h"
30#include "satellite-typedefs.h"
31#include "satellite-utils.h"
32
33#include "ns3/log.h"
34#include "ns3/nstime.h"
35#include "ns3/simulator.h"
36#include "ns3/singleton.h"
37
38#include <utility>
39
40NS_LOG_COMPONENT_DEFINE("SatLlc");
41
42namespace ns3
43{
44
45NS_OBJECT_ENSURE_REGISTERED(SatLlc);
46
47TypeId
49{
50 static TypeId tid = TypeId("ns3::SatLlc")
51 .SetParent<Object>()
52 .AddAttribute("FwdLinkArqEnabled",
53 "Enable ARQ in forward link.",
54 BooleanValue(false),
55 MakeBooleanAccessor(&SatLlc::m_fwdLinkArqEnabled),
56 MakeBooleanChecker())
57 .AddAttribute("RtnLinkArqEnabled",
58 "Enable ARQ in return link.",
59 BooleanValue(false),
60 MakeBooleanAccessor(&SatLlc::m_rtnLinkArqEnabled),
61 MakeBooleanChecker())
62 .AddTraceSource("PacketTrace",
63 "Packet event trace",
64 MakeTraceSourceAccessor(&SatLlc::m_packetTrace),
65 "ns3::PacketTraceCallback");
66 return tid;
67}
68
70 : m_nodeInfo(),
71 m_encaps(),
72 m_decaps(),
79 Singleton<SatTopology>::Get()->GetForwardLinkRegenerationMode()),
80 m_returnLinkRegenerationMode(Singleton<SatTopology>::Get()->GetReturnLinkRegenerationMode())
81{
82 NS_LOG_FUNCTION(this);
83}
84
86{
87 NS_LOG_FUNCTION(this);
88}
89
90void
92{
93 NS_LOG_FUNCTION(this);
94 m_rxCallback.Nullify();
95
96 EncapContainer_t::iterator it;
97
98 for (it = m_encaps.begin(); it != m_encaps.end(); ++it)
99 {
100 it->second->DoDispose();
101 it->second = 0;
102 }
103 m_encaps.clear();
104
105 for (it = m_decaps.begin(); it != m_decaps.end(); ++it)
106 {
107 it->second->DoDispose();
108 it->second = 0;
109 }
110 m_decaps.clear();
111
112 Object::DoDispose();
113}
114
115bool
116SatLlc::Enque(Ptr<Packet> packet, Address dest, uint8_t flowId)
117{
118 NS_LOG_FUNCTION(this << packet << dest << (uint32_t)flowId);
119 NS_LOG_INFO("p=" << packet);
120 NS_LOG_INFO("dest=" << dest);
121 NS_LOG_INFO("UID is " << packet->GetUid());
122
123 Ptr<EncapKey> key = Create<EncapKey>(m_nodeInfo->GetMacAddress(),
124 Mac48Address::ConvertFrom(dest),
125 flowId,
126 m_nodeInfo->GetMacAddress(),
127 Mac48Address::ConvertFrom(dest));
128
129 EncapContainer_t::iterator it = m_encaps.find(key);
130
131 if (it == m_encaps.end())
132 {
138 CreateEncap(key);
139 it = m_encaps.find(key);
140 }
141
142 // Store packet arrival time
143 SatTimeTag timeTag(Simulator::Now());
144 packet->AddPacketTag(timeTag);
145
146 // Add E2E address tag to identify the packet in lower layers
147 SatAddressE2ETag addressE2ETag;
148 addressE2ETag.SetE2EDestAddress(Mac48Address::ConvertFrom(dest));
149 addressE2ETag.SetE2ESourceAddress(m_nodeInfo->GetMacAddress());
150 packet->AddPacketTag(addressE2ETag);
151
152 it->second->EnquePdu(packet, Mac48Address::ConvertFrom(dest));
153
155
156 // Add packet trace entry:
157 m_packetTrace(Simulator::Now(),
159 m_nodeInfo->GetNodeType(),
160 m_nodeInfo->GetNodeId(),
161 m_nodeInfo->GetMacAddress(),
163 ld,
165
166 return true;
167}
168
169void
170SatLlc::Receive(Ptr<Packet> packet, Mac48Address source, Mac48Address dest)
171{
172 NS_LOG_FUNCTION(this << source << dest << packet);
173
175
176 // Add packet trace entry:
177 m_packetTrace(Simulator::Now(),
179 m_nodeInfo->GetNodeType(),
180 m_nodeInfo->GetNodeId(),
181 m_nodeInfo->GetMacAddress(),
183 ld,
185
186 // Receive packet with a decapsulator instance which is handling the
187 // packets for this specific id
188 SatFlowIdTag flowIdTag;
189 bool mSuccess = packet->PeekPacketTag(flowIdTag);
190 if (mSuccess)
191 {
192 uint32_t flowId = flowIdTag.GetFlowId();
193 Ptr<EncapKey> key = Create<EncapKey>(source, dest, flowId);
194 EncapContainer_t::iterator it = m_decaps.find(key);
195
196 // Control messages not received by this method
197 if (flowId == SatEnums::CONTROL_FID && m_nodeInfo->GetNodeType() != SatEnums::NT_SAT)
198 {
199 NS_FATAL_ERROR("Control messages should not be received by SatLlc::Receive () method!");
200 }
201
202 if (it == m_decaps.end())
203 {
209 CreateDecap(key);
210 it = m_decaps.find(key);
211 }
212
213 it->second->ReceivePdu(packet);
214 }
215}
216
217void
218SatLlc::ReceiveAck(Ptr<SatArqAckMessage> ack, Mac48Address source, Mac48Address dest)
219{
220 NS_LOG_FUNCTION(this << source << dest);
221
228 uint32_t flowId = ack->GetFlowId();
229
230 Ptr<EncapKey> key = Create<EncapKey>(dest, source, flowId);
231 EncapContainer_t::iterator it = m_encaps.find(key);
232
233 if (it != m_encaps.end())
234 {
235 it->second->ReceiveAck(ack);
236 }
237 else
238 {
239 NS_FATAL_ERROR("Encapsulator not found for key (" << source << ", " << dest << ", "
240 << (uint32_t)flowId << ")");
241 }
242}
243
249
255
256void
257SatLlc::ReceiveHigherLayerPdu(Ptr<Packet> packet, Mac48Address source, Mac48Address dest)
258{
259 NS_LOG_FUNCTION(this << packet << source << dest);
260
261 // Remove time tag
262 SatTimeTag timeTag;
263 packet->RemovePacketTag(timeTag);
264
265 // Remove control msg tag
266 SatControlMsgTag ctrlTag;
267 bool cSuccess = packet->RemovePacketTag(ctrlTag);
268
269 if (cSuccess)
270 {
272 {
273 NS_FATAL_ERROR("A control message other than ARQ ACK received at the LLC!");
274 }
275
276 // ARQ ACKs need to be forwarded to LLC/ARQ for processing
277 uint32_t ackId = ctrlTag.GetMsgId();
278
279 Ptr<SatArqAckMessage> ack = DynamicCast<SatArqAckMessage>(m_readCtrlCallback(ackId));
280
281 if (ack == nullptr)
282 {
283 NS_FATAL_ERROR(
284 "ARQ ACK not found, check that control msg storage time is set long enough!");
285 }
286
287 ReceiveAck(ack, source, dest);
288 }
289 // Higher layer packet
290 else
291 {
292 // Call a callback to receive the packet at upper layer
293
294 // Remove SatAddressE2ETag
295 SatAddressE2ETag addressE2ETag;
296 packet->RemovePacketTag(addressE2ETag);
297
298 m_rxCallback(packet);
299 }
300}
301
302void
303SatLlc::AddEncap(Mac48Address source,
304 Mac48Address dest,
305 uint8_t flowId,
306 Ptr<SatBaseEncapsulator> enc)
307{
308 NS_LOG_FUNCTION(this << source << dest << (uint32_t)flowId);
309
310 Ptr<EncapKey> key = Create<EncapKey>(source, dest, flowId);
311 EncapContainer_t::iterator it = m_encaps.find(key);
312
313 if (it == m_encaps.end())
314 {
315 NS_LOG_INFO("Add encapsulator with key (" << source << ", " << dest << ", "
316 << (uint32_t)flowId << ")");
317
318 std::pair<EncapContainer_t::iterator, bool> result =
319 m_encaps.insert(std::make_pair(key, enc));
320 if (result.second == false)
321 {
322 NS_FATAL_ERROR("Insert to map with key (" << source << ", " << dest << ", "
323 << (uint32_t)flowId << ") failed!");
324 }
325 }
326 else
327 {
328 NS_FATAL_ERROR("Encapsulator container already holds key ("
329 << source << ", " << dest << ", " << (uint32_t)flowId << ") key!");
330 }
331}
332
333void
334SatLlc::AddDecap(Mac48Address source,
335 Mac48Address dest,
336 uint8_t flowId,
337 Ptr<SatBaseEncapsulator> dec)
338{
339 NS_LOG_FUNCTION(this << source << dest << (uint32_t)flowId);
340
341 Ptr<EncapKey> key = Create<EncapKey>(source, dest, flowId);
342 EncapContainer_t::iterator it = m_decaps.find(key);
343
344 if (it == m_decaps.end())
345 {
346 NS_LOG_INFO("Add Decapsulator with key (" << source << ", " << dest << ", "
347 << (uint32_t)flowId << ")");
348
349 std::pair<EncapContainer_t::iterator, bool> result =
350 m_decaps.insert(std::make_pair(key, dec));
351 if (result.second == false)
352 {
353 NS_FATAL_ERROR("Insert to map with key (" << source << ", " << dest << ", "
354 << (uint32_t)flowId << ") failed!");
355 }
356 }
357 else
358 {
359 NS_FATAL_ERROR("Decapsulator container already holds (" << source << ", " << dest << ", "
360 << (uint32_t)flowId << ") key!");
361 }
362}
363
364void
365SatLlc::SetNodeInfo(Ptr<SatNodeInfo> nodeInfo)
366{
367 NS_LOG_FUNCTION(this << nodeInfo);
368 m_nodeInfo = nodeInfo;
369}
370
371void
373{
374 NS_LOG_FUNCTION(this << &cb);
375 m_rxCallback = cb;
376}
377
378bool
380{
381 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
382 {
383 if (it->second->GetTxBufferSizeInBytes() > 0)
384 {
385 return false;
386 }
387 }
388 return true;
389}
390
391bool
393{
394 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
395 {
396 if (it->first->m_flowId == SatEnums::CONTROL_FID)
397 {
398 if (it->second->GetTxBufferSizeInBytes() > 0)
399 {
400 return false;
401 }
402 }
403 }
404 return true;
405}
406
407uint32_t
409{
410 NS_LOG_FUNCTION(this);
411
412 uint32_t sum = 0;
413
414 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
415 {
416 NS_ASSERT(it->second != nullptr);
417 Ptr<SatQueue> queue = it->second->GetQueue();
418 NS_ASSERT(queue != nullptr);
419 sum += queue->GetNBytes();
420 }
421
422 return sum;
423}
424
425uint32_t
427{
428 NS_LOG_FUNCTION(this);
429
430 uint32_t sum = 0;
431
432 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
433 {
434 NS_ASSERT(it->second != nullptr);
435 Ptr<SatQueue> queue = it->second->GetQueue();
436 NS_ASSERT(queue != nullptr);
437 sum += queue->GetNPackets();
438 }
439
440 return sum;
441}
442
443void
445{
446 NS_LOG_FUNCTION(this << &cb);
448}
449
450void
452{
453 NS_LOG_FUNCTION(this << &cb);
454
456}
457
458void
459SatLlc::SetGwAddress(Mac48Address address)
460{
461 NS_LOG_FUNCTION(this << address);
462 m_gwAddress = address;
463}
464
465void
466SatLlc::SetSatelliteAddress(Mac48Address address)
467{
468 NS_LOG_FUNCTION(this << address);
469 m_satelliteAddress = address;
470}
471
472void
473SatLlc::SetAdditionalHeaderSize(uint32_t additionalHeaderSize)
474{
475 NS_LOG_FUNCTION(this << additionalHeaderSize);
476 m_additionalHeaderSize = additionalHeaderSize;
477}
478
479} // 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.
Callback< bool, Ptr< SatControlMessage >, const Address & > SendCtrlCallback
Control msg sending callback.
This class implements a tag that is used to identify control messages (packages).
virtual uint32_t GetMsgId() const
Get message type specific identifier.
SatControlMsgType_t GetMsgType(void) const
Get type of the control message.
SatLinkDir_t
Link direction used for packet tracing.
SatFlowIdTag implements a tag which carries the flow identifier of a packet.
uint8_t GetFlowId() const
Get flow identifier.
SatLlc base class holds the UT specific SatBaseEncapsulator instances, which are responsible of fragm...
virtual SatEnums::SatLinkDir_t GetSatLinkTxDir()
Get the link TX direction.
virtual bool BuffersEmpty() const
Are buffers empty?
static TypeId GetTypeId(void)
Derived from Object.
virtual SatEnums::SatLinkDir_t GetSatLinkRxDir()
Get the link RX direction.
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.
SatLlc::ReadCtrlMsgCallback m_readCtrlCallback
The read control message callback.
Callback< Ptr< SatControlMessage >, uint32_t > ReadCtrlMsgCallback
Callback to read control messages from container storing control messages.
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.
void SetReadCtrlCallback(SatLlc::ReadCtrlMsgCallback cb)
Method to set read control message callback.
uint32_t m_additionalHeaderSize
Additional header size to add to encapsulation/decapsulation.
void SetReceiveCallback(SatLlc::ReceiveCallback cb)
Set Receive callback to forward packet to upper layer.
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.
virtual void CreateEncap(Ptr< EncapKey > key)=0
Virtual method to create a new encapsulator 'on-a-need-basis' dynamically.
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 CreateDecap(Ptr< EncapKey > key)=0
Virtual method to create a new decapsulator 'on-a-need-basis' dynamically.
Mac48Address m_gwAddress
GW address.
virtual void DoDispose()
Dispose of this class instance.
void AddEncap(Mac48Address source, Mac48Address dest, uint8_t flowId, Ptr< SatBaseEncapsulator > enc)
Add an encapsulator entry for the LLC.
virtual void ReceiveAck(Ptr< SatArqAckMessage > ack, Mac48Address source, Mac48Address dest)
Receive a control msg (ARQ ACK) from lower layer.
void SetCtrlMsgCallback(SatBaseEncapsulator::SendCtrlCallback cb)
EncapContainer_t m_encaps
Map of encapsulator base pointers.
virtual ~SatLlc()
Destroy a SatLlc.
void SetAdditionalHeaderSize(uint32_t additionalHeaderSize)
Set the additional header size.
SatEnums::RegenerationMode_t m_forwardLinkRegenerationMode
Regeneration mode on forward link.
virtual bool ControlBuffersEmpty() const
Are buffers empty?
SatLlc()
Construct a SatLlc.
virtual void SetSatelliteAddress(Mac48Address address)
Set the SAT address.
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.
Callback< void, Ptr< const Packet > > ReceiveCallback
Receive callback used for sending packet to netdevice layer.
virtual bool Enque(Ptr< Packet > packet, Address dest, uint8_t flowId)
Called from higher layer (SatNetDevice) to enque packet to LLC.
Mac48Address m_satelliteAddress
SAT address, used in case of network regeneration.
void AddDecap(Mac48Address source, Mac48Address dest, uint8_t flowId, Ptr< SatBaseEncapsulator > dec)
Add an decapsulator entry for the LLC.
bool m_rtnLinkArqEnabled
Is RTN link ARQ enabled.
virtual void Receive(Ptr< Packet > packet, Mac48Address source, Mac48Address dest)
Receive user data packet from lower layer.
ReceiveCallback m_rxCallback
The upper layer package receive callback.
Time tag used to identify the time when packet is enqueued at LLC level.
Class to store topology of the whole system.
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.