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