Loading...
Searching...
No Matches
satellite-orbiter-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: Bastien TAURAN <bastien.tauran@viveris.fr>
19 */
20
22
24#include "satellite-time-tag.h"
25#include "satellite-utils.h"
26
27#include <utility>
28#include <vector>
29
30NS_LOG_COMPONENT_DEFINE("SatOrbiterLlc");
31
32namespace ns3
33{
34
35NS_OBJECT_ENSURE_REGISTERED(SatOrbiterLlc);
36
37TypeId
39{
40 static TypeId tid = TypeId("ns3::SatOrbiterLlc").SetParent<SatLlc>();
41 return tid;
42}
43
45 : SatLlc()
46{
47 NS_LOG_FUNCTION(this);
48}
49
51{
52 NS_LOG_FUNCTION(this);
53}
54
55void
57{
58 Object::DoDispose();
59}
60
61void
66
67bool
68SatOrbiterLlc::Enque(Ptr<Packet> packet, Address dest, uint8_t flowId)
69{
70 NS_LOG_FUNCTION(this << packet << dest << (uint32_t)flowId);
71 NS_LOG_INFO("p=" << packet);
72 NS_LOG_INFO("dest=" << dest);
73 NS_LOG_INFO("UID is " << packet->GetUid());
74
75 Ptr<EncapKey> key = Create<EncapKey>(m_nodeInfo->GetMacAddress(),
76 Mac48Address::ConvertFrom(dest),
77 flowId,
78 m_nodeInfo->GetMacAddress(),
79 Mac48Address::ConvertFrom(dest));
80
81 EncapContainer_t::iterator it = m_encaps.find(key);
82
83 if (it == m_encaps.end())
84 {
90 CreateEncap(key);
91 it = m_encaps.find(key);
92 }
93
94 it->second->EnquePdu(packet, Mac48Address::ConvertFrom(dest));
95
97
98 // Add packet trace entry:
99 m_packetTrace(Simulator::Now(),
101 m_nodeInfo->GetNodeType(),
102 m_nodeInfo->GetNodeId(),
103 m_nodeInfo->GetMacAddress(),
105 ld,
107
108 return true;
109}
110
111Ptr<Packet>
113 Mac48Address utAddr,
114 uint8_t flowId,
115 uint32_t& bytesLeft,
116 uint32_t& nextMinTxO)
117{
118 NS_LOG_FUNCTION(this << utAddr << bytes << (uint32_t)flowId);
119
120 Ptr<Packet> packet;
121 Ptr<EncapKey> key = Create<EncapKey>(m_nodeInfo->GetMacAddress(), utAddr, flowId);
122 EncapContainer_t::iterator it = m_encaps.find(key);
123
124 if (it != m_encaps.end())
125 {
126 packet = it->second->NotifyTxOpportunity(bytes, bytesLeft, nextMinTxO);
127
128 if (packet)
129 {
131
132 // Add packet trace entry:
133 m_packetTrace(Simulator::Now(),
135 m_nodeInfo->GetNodeType(),
136 m_nodeInfo->GetNodeId(),
137 m_nodeInfo->GetMacAddress(),
139 ld,
141 }
142 }
143 else
144 {
145 NS_FATAL_ERROR("Encapsulator not found for key (" << m_nodeInfo->GetMacAddress() << ", "
146 << utAddr << ", " << (uint32_t)flowId
147 << ")");
148 }
149
150 return packet;
151}
152
153void
154SatOrbiterLlc::ReceiveHigherLayerPdu(Ptr<Packet> packet, Mac48Address source, Mac48Address dest)
155{
156 NS_LOG_FUNCTION(this << packet << source << dest);
157
158 // Peek control msg tag
159 SatControlMsgTag ctrlTag;
160 bool cSuccess = packet->PeekPacketTag(ctrlTag);
161
162 if (cSuccess)
163 {
165 {
166 m_rxSatelliteCallback(packet, m_nodeInfo->GetMacAddress());
167 return;
168 }
169
170 // ARQ ACKs need to be forwarded to LLC/ARQ for processing
171 uint32_t ackId = ctrlTag.GetMsgId();
172
173 Ptr<SatArqAckMessage> ack = DynamicCast<SatArqAckMessage>(m_readCtrlCallback(ackId));
174
175 if (ack == nullptr)
176 {
177 NS_FATAL_ERROR(
178 "ARQ ACK not found, check that control msg storage time is set long enough!");
179 }
180
181 ReceiveAck(ack, source, dest);
182 }
183 // Higher layer packet
184 else
185 {
186 m_rxSatelliteCallback(packet, m_nodeInfo->GetMacAddress());
187 }
188}
189
190void
192{
193 NS_LOG_FUNCTION(this << key->m_encapAddress << key->m_decapAddress
194 << (uint32_t)(key->m_flowId));
195
196 Ptr<SatBaseEncapsulator> encap = CreateObject<SatBaseEncapsulator>(key->m_encapAddress,
197 key->m_decapAddress,
198 key->m_sourceE2EAddress,
199 key->m_destE2EAddress,
200 key->m_flowId);
201
202 Ptr<SatQueue> queue = CreateObject<SatQueue>(key->m_flowId);
203 encap->SetQueue(queue);
204
205 NS_LOG_INFO("Create encapsulator with key (" << key->m_encapAddress << ", "
206 << key->m_decapAddress << ", "
207 << (uint32_t)key->m_flowId << ")");
208
209 // Store the encapsulator
210 std::pair<EncapContainer_t::iterator, bool> result =
211 m_encaps.insert(std::make_pair(key, encap));
212 if (result.second == false)
213 {
214 NS_FATAL_ERROR("Insert to map with key (" << key->m_encapAddress << ", "
215 << key->m_decapAddress << ", "
216 << (uint32_t)key->m_flowId << ") failed!");
217 }
218}
219
220void
222{
223 NS_LOG_FUNCTION(this << key->m_encapAddress << key->m_decapAddress
224 << (uint32_t)(key->m_flowId));
225
226 Ptr<SatBaseEncapsulator> decap = CreateObject<SatBaseEncapsulator>(key->m_encapAddress,
227 key->m_decapAddress,
228 key->m_sourceE2EAddress,
229 key->m_destE2EAddress,
230 key->m_flowId);
231
232 decap->SetReceiveCallback(MakeCallback(&SatLlc::ReceiveHigherLayerPdu, this));
233 decap->SetCtrlMsgCallback(m_sendCtrlCallback);
234
235 NS_LOG_INFO("Create decapsulator with key (" << key->m_encapAddress << ", "
236 << key->m_decapAddress << ", "
237 << (uint32_t)key->m_flowId << ")");
238
239 // Store the decapsulator
240 std::pair<EncapContainer_t::iterator, bool> result =
241 m_decaps.insert(std::make_pair(key, decap));
242 if (result.second == false)
243 {
244 NS_FATAL_ERROR("Insert to map with key (" << key->m_encapAddress << ", "
245 << key->m_decapAddress << ", "
246 << (uint32_t)key->m_flowId << ") failed!");
247 }
248}
249
250void
251SatOrbiterLlc::GetSchedulingContexts(std::vector<Ptr<SatSchedulingObject>>& output) const
252{
253 NS_LOG_FUNCTION(this);
254
255 // Head of link queuing delay
256 Time holDelay;
257
258 // Then the user data
259 for (EncapContainer_t::const_iterator cit = m_encaps.begin(); cit != m_encaps.end(); ++cit)
260 {
261 uint32_t buf = cit->second->GetTxBufferSizeInBytes();
262
263 if (buf > 0)
264 {
265 holDelay = cit->second->GetHolDelay();
266 uint32_t minTxOpportunityInBytes = cit->second->GetMinTxOpportunityInBytes();
267 Ptr<SatSchedulingObject> so = Create<SatSchedulingObject>(cit->first->m_decapAddress,
268 buf,
269 minTxOpportunityInBytes,
270 holDelay,
271 cit->first->m_flowId);
272 output.push_back(so);
273 }
274 }
275}
276
277uint32_t
278SatOrbiterLlc::GetNBytesInQueue(Mac48Address utAddress) const
279{
280 NS_LOG_FUNCTION(this << utAddress);
281
282 uint32_t sum = 0;
283
284 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
285 {
286 if (it->first->m_encapAddress == utAddress)
287 {
288 NS_ASSERT(it->second != nullptr);
289 Ptr<SatQueue> queue = it->second->GetQueue();
290 NS_ASSERT(queue != nullptr);
291 sum += queue->GetNBytes();
292 }
293 }
294
295 return sum;
296}
297
298uint32_t
299SatOrbiterLlc::GetNPacketsInQueue(Mac48Address utAddress) const
300{
301 NS_LOG_FUNCTION(this << utAddress);
302
303 uint32_t sum = 0;
304
305 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
306 {
307 if (it->first->m_encapAddress == utAddress)
308 {
309 NS_ASSERT(it->second != nullptr);
310 Ptr<SatQueue> queue = it->second->GetQueue();
311 NS_ASSERT(queue != nullptr);
312 sum += queue->GetNPackets();
313 }
314 }
315
316 return sum;
317}
318
319void
321{
322 NS_LOG_FUNCTION(this);
323
324 for (EncapContainer_t::const_iterator it = m_encaps.begin(); it != m_encaps.end(); ++it)
325 {
326 NS_ASSERT(it->second != nullptr);
327 Ptr<SatQueue> queue = it->second->GetQueue();
328 NS_ASSERT(queue != nullptr);
329 queue->DequeueAll();
330 }
331}
332
333} // namespace ns3
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.
virtual SatEnums::SatLinkDir_t GetSatLinkTxDir()
Get the link TX direction.
Ptr< SatNodeInfo > m_nodeInfo
Node info containing node related information, such as node type, node id and MAC address (of the Sat...
SatLlc::ReadCtrlMsgCallback m_readCtrlCallback
The read control message callback.
virtual uint32_t GetNBytesInQueue() const
Get the total number of (new) bytes in all encapsulators.
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 ReceiveAck(Ptr< SatArqAckMessage > ack, Mac48Address source, Mac48Address dest)
Receive a control msg (ARQ ACK) from lower layer.
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.
SatOrbiterLlc holds the orbiter implementation of LLC layer.
virtual void GetSchedulingContexts(std::vector< Ptr< SatSchedulingObject > > &output) const
Create and fill the scheduling objects based on LLC layer information.
virtual void CreateEncap(Ptr< EncapKey > key)
Virtual method to create a new encapsulator 'on-a-need-basis' dynamically.
virtual ~SatOrbiterLlc()
Destroy a SatOrbiterLlc.
virtual void DoDispose()
Dispose of this class instance.
Callback< void, Ptr< Packet >, const Address & > ReceiveSatelliteCallback
Receive callback used for sending packet to netdevice layer.
virtual void ReceiveHigherLayerPdu(Ptr< Packet > packet, Mac48Address source, Mac48Address dest)
Receive HL PDU from encapsulator/decapsulator entity.
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)
Derived from Object.
virtual void CreateDecap(Ptr< EncapKey > key)
Virtual method to create a new decapsulator 'on-a-need-basis' dynamically.
SatOrbiterLlc()
Construct a SatOrbiterLlc.
virtual void ClearQueues()
Remove all packets from the queues.
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.
ReceiveSatelliteCallback m_rxSatelliteCallback
The upper layer package receive callback.
void SetReceiveSatelliteCallback(SatOrbiterLlc::ReceiveSatelliteCallback cb)
Set Receive callback to forward packet to upper layer on satellite.
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.