satellite-orbiter-net-device-dvb.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: Sami Rantanen <sami.rantanen@magister.fi>
19  */
20 
22 
23 #include "satellite-address-tag.h"
24 #include "satellite-channel.h"
26 #include "satellite-id-mapper.h"
27 #include "satellite-mac.h"
32 #include "satellite-phy-rx.h"
33 #include "satellite-phy-tx.h"
34 #include "satellite-phy.h"
35 #include "satellite-time-tag.h"
37 
38 #include <ns3/channel.h>
39 #include <ns3/error-model.h>
40 #include <ns3/ipv4-header.h>
41 #include <ns3/ipv4-l3-protocol.h>
42 #include <ns3/log.h>
43 #include <ns3/node.h>
44 #include <ns3/object-map.h>
45 #include <ns3/packet.h>
46 #include <ns3/pointer.h>
47 #include <ns3/singleton.h>
48 #include <ns3/trace-source-accessor.h>
49 #include <ns3/uinteger.h>
50 
51 #include <limits>
52 #include <map>
53 #include <set>
54 #include <utility>
55 #include <vector>
56 
57 NS_LOG_COMPONENT_DEFINE("SatOrbiterNetDeviceDvb");
58 
59 namespace ns3
60 {
61 
62 NS_OBJECT_ENSURE_REGISTERED(SatOrbiterNetDeviceDvb);
63 
64 TypeId
66 {
67  static TypeId tid = TypeId("ns3::SatOrbiterNetDeviceDvb")
68  .SetParent<SatOrbiterNetDevice>()
69  .AddConstructor<SatOrbiterNetDeviceDvb>();
70  return tid;
71 }
72 
75 {
76  NS_LOG_FUNCTION(this);
77 }
78 
79 void
80 SatOrbiterNetDeviceDvb::ReceivePacketUser(Ptr<Packet> packet, const Address& userAddress)
81 {
82  NS_LOG_FUNCTION(this << packet);
83  NS_LOG_INFO("Receiving a packet: " << packet->GetUid());
84 
85  Mac48Address macUserAddress = Mac48Address::ConvertFrom(userAddress);
86 
87  m_packetTrace(Simulator::Now(),
90  m_nodeId,
91  macUserAddress,
94  SatUtils::GetPacketInfo(packet));
95 
96  /*
97  * Invoke the `Rx` and `RxDelay` trace sources. We look at the packet's tags
98  * for information, but cannot remove the tags because the packet is a const.
99  */
101  {
102  Address addr = GetRxUtAddress(packet, SatEnums::LD_RETURN);
103 
104  m_rxUserTrace(packet, addr);
105 
106  SatDevLinkTimeTag linkTimeTag;
107  if (packet->RemovePacketTag(linkTimeTag))
108  {
109  NS_LOG_DEBUG(this << " contains a SatDevLinkTimeTag tag");
110  Time delay = Simulator::Now() - linkTimeTag.GetSenderTimestamp();
111  m_rxUserLinkDelayTrace(delay, addr);
112  if (m_lastDelays[macUserAddress].IsZero() == false)
113  {
114  Time jitter = Abs(delay - m_lastDelays[macUserAddress]);
115  m_rxUserLinkJitterTrace(jitter, addr);
116  }
117  m_lastDelays[macUserAddress] = delay;
118  }
119  }
120 
121  SatGroundStationAddressTag groundStationAddressTag;
122  if (!packet->PeekPacketTag(groundStationAddressTag))
123  {
124  NS_FATAL_ERROR("SatGroundStationAddressTag not found");
125  }
126  Mac48Address destination = groundStationAddressTag.GetGroundStationAddress();
127 
128  SatUplinkInfoTag satUplinkInfoTag;
129  if (!packet->PeekPacketTag(satUplinkInfoTag))
130  {
131  NS_FATAL_ERROR("SatUplinkInfoTag not found");
132  }
133 
134  if (m_gwConnected.count(destination))
135  {
137  {
138  // Add a SatDevLinkTimeTag tag for packet link delay computation at the receiver end.
139  packet->AddPacketTag(SatDevLinkTimeTag(Simulator::Now()));
140  }
141 
142  DynamicCast<SatOrbiterFeederMac>(m_feederMac[satUplinkInfoTag.GetBeamId()])
143  ->EnquePacket(packet);
144  }
145  else
146  {
147  if (m_islNetDevices.size() > 0)
148  {
149  SendToIsl(packet, destination);
150  }
151  }
152 }
153 
154 void
155 SatOrbiterNetDeviceDvb::ReceivePacketFeeder(Ptr<Packet> packet, const Address& feederAddress)
156 {
157  NS_LOG_FUNCTION(this << packet);
158  NS_LOG_INFO("Receiving a packet: " << packet->GetUid());
159 
160  Mac48Address macFeederAddress = Mac48Address::ConvertFrom(feederAddress);
161 
162  m_packetTrace(Simulator::Now(),
165  m_nodeId,
166  macFeederAddress,
169  SatUtils::GetPacketInfo(packet));
170 
171  /*
172  * Invoke the `Rx` and `RxDelay` trace sources. We look at the packet's tags
173  * for information, but cannot remove the tags because the packet is a const.
174  */
176  {
177  Address addr = GetRxUtAddress(packet, SatEnums::LD_FORWARD);
178 
179  m_rxFeederTrace(packet, addr);
180 
181  SatDevLinkTimeTag linkTimeTag;
182  if (packet->RemovePacketTag(linkTimeTag))
183  {
184  NS_LOG_DEBUG(this << " contains a SatDevLinkTimeTag tag");
185  Time delay = Simulator::Now() - linkTimeTag.GetSenderTimestamp();
186  m_rxFeederLinkDelayTrace(delay, addr);
187  if (m_lastDelays[macFeederAddress].IsZero() == false)
188  {
189  Time jitter = Abs(delay - m_lastDelays[macFeederAddress]);
190  m_rxFeederLinkJitterTrace(jitter, addr);
191  }
192  m_lastDelays[macFeederAddress] = delay;
193  }
194  }
195 
196  SatGroundStationAddressTag groundStationAddressTag;
197  if (!packet->PeekPacketTag(groundStationAddressTag))
198  {
199  NS_FATAL_ERROR("SatGroundStationAddressTag not found");
200  }
201  Mac48Address destination = groundStationAddressTag.GetGroundStationAddress();
202 
203  if (destination.IsBroadcast())
204  {
205  m_broadcastReceived.insert(packet->GetUid());
206  }
207 
208  SatUplinkInfoTag satUplinkInfoTag;
209  if (!packet->PeekPacketTag(satUplinkInfoTag))
210  {
211  NS_FATAL_ERROR("SatUplinkInfoTag not found");
212  }
213 
214  if (m_utConnected.count(destination) > 0 || destination.IsBroadcast())
215  {
217  {
218  // Add a SatDevLinkTimeTag tag for packet link delay computation at the receiver end.
219  packet->AddPacketTag(SatDevLinkTimeTag(Simulator::Now()));
220  }
221 
222  DynamicCast<SatOrbiterUserMac>(m_userMac[satUplinkInfoTag.GetBeamId()])
223  ->EnquePacket(packet);
224  }
225  if ((m_utConnected.count(destination) == 0 || destination.IsBroadcast()) &&
226  m_islNetDevices.size() > 0)
227  {
228  SendToIsl(packet, destination);
229  }
230 }
231 
232 void
233 SatOrbiterNetDeviceDvb::ReceiveFromIsl(Ptr<Packet> packet, Mac48Address destination)
234 {
235  NS_LOG_FUNCTION(this << packet << destination);
236 
237  if (destination.IsBroadcast())
238  {
239  if (m_broadcastReceived.count(packet->GetUid()) > 0)
240  {
241  // Packet already received, drop it
242  return;
243  }
244  else
245  {
246  // Insert in list of receuived broadcast
247  m_broadcastReceived.insert(packet->GetUid());
248  }
249  }
250 
251  if (m_gwConnected.count(destination) > 0)
252  {
253  SatUplinkInfoTag satUplinkInfoTag;
254  if (!packet->PeekPacketTag(satUplinkInfoTag))
255  {
256  NS_FATAL_ERROR("SatUplinkInfoTag not found");
257  }
258 
260  {
261  // Add a SatDevLinkTimeTag tag for packet link delay computation at the receiver end.
262  packet->AddPacketTag(SatDevLinkTimeTag(Simulator::Now()));
263  }
264 
265  DynamicCast<SatOrbiterFeederMac>(m_feederMac[satUplinkInfoTag.GetBeamId()])
266  ->EnquePacket(packet);
267  }
268  else
269  {
270  if (m_utConnected.count(destination) > 0 || destination.IsBroadcast())
271  {
272  SatUplinkInfoTag satUplinkInfoTag;
273  if (!packet->PeekPacketTag(satUplinkInfoTag))
274  {
275  NS_FATAL_ERROR("SatUplinkInfoTag not found");
276  }
277 
278  if (m_isStatisticsTagsEnabled && !destination.IsBroadcast())
279  {
280  // Add a SatDevLinkTimeTag tag for packet link delay computation at the receiver
281  // end.
282  packet->AddPacketTag(SatDevLinkTimeTag(Simulator::Now()));
283  }
284 
285  DynamicCast<SatOrbiterUserMac>(m_userMac[satUplinkInfoTag.GetBeamId()])
286  ->EnquePacket(packet);
287  }
288  if ((m_utConnected.count(destination) == 0 || destination.IsBroadcast()) &&
289  m_islNetDevices.size() > 0)
290  {
291  SendToIsl(packet, destination);
292  }
293  }
294 }
295 
296 bool
298  const Address& dest,
299  Ptr<SatSignalParameters> rxParams)
300 {
301  NS_LOG_FUNCTION(this << msg << dest);
302 
303  Ptr<Packet> packet = Create<Packet>(msg->GetSizeInBytes());
304 
306  {
307  // Add a SatAddressTag tag with this device's address as the source address.
308  packet->AddByteTag(SatAddressTag(m_address));
309 
310  // Add a SatDevLinkTimeTag tag for packet link delay computation at the receiver end.
311  packet->AddPacketTag(SatDevLinkTimeTag(Simulator::Now()));
312  }
313 
314  SatAddressE2ETag addressE2ETag;
315  addressE2ETag.SetE2ESourceAddress(m_address);
316  addressE2ETag.SetE2EDestAddress(Mac48Address::ConvertFrom(dest));
317  packet->AddPacketTag(addressE2ETag);
318 
319  SatMacTag macTag;
320  macTag.SetSourceAddress(m_address);
321  macTag.SetDestAddress(Mac48Address::ConvertFrom(dest));
322  packet->AddPacketTag(macTag);
323 
324  // Add control tag to message and write msg to container in MAC
325  SatControlMsgTag tag;
326  tag.SetMsgId(0);
327  tag.SetMsgType(msg->GetMsgType());
328  packet->AddPacketTag(tag);
329 
331  {
332  SatUplinkInfoTag satUplinkInfoTag;
333  satUplinkInfoTag.SetSinr(std::numeric_limits<double>::infinity(), 0);
334  satUplinkInfoTag.SetBeamId(rxParams->m_beamId);
335  satUplinkInfoTag.SetSatId(rxParams->m_satId);
336  packet->AddPacketTag(satUplinkInfoTag);
337  }
338 
339  rxParams->m_packetsInBurst.clear();
340  rxParams->m_packetsInBurst.push_back(packet);
341 
343  {
346  DynamicCast<SatOrbiterFeederPhy>(m_feederPhy[rxParams->m_beamId])
347  ->SendPduWithParams(rxParams);
348  break;
349  }
352  for (SatPhy::PacketContainer_t::const_iterator it = rxParams->m_packetsInBurst.begin();
353  it != rxParams->m_packetsInBurst.end();
354  ++it)
355  {
356  DynamicCast<SatOrbiterFeederMac>(m_feederMac[rxParams->m_beamId])->EnquePacket(*it);
357  }
358  break;
359  }
360  default: {
361  NS_FATAL_ERROR("Not implemented yet");
362  }
363  }
364 
365  return true;
366 }
367 
368 void
369 SatOrbiterNetDeviceDvb::ConnectUt(Mac48Address utAddress, uint32_t beamId)
370 {
371  NS_LOG_FUNCTION(this << utAddress << beamId);
372 
373  NS_ASSERT_MSG(m_utConnected.find(utAddress) == m_utConnected.end(),
374  "Cannot add same UT twice to map");
375 
376  m_utConnected.insert({utAddress, beamId});
377  Singleton<SatIdMapper>::Get()->AttachMacToSatIdIsl(utAddress, m_nodeId);
378 
379  if (m_userMac.find(beamId) != m_userMac.end())
380  {
381  Ptr<SatOrbiterUserMac> orbiterUserMac = DynamicCast<SatOrbiterUserMac>(GetUserMac(beamId));
382  NS_ASSERT(orbiterUserMac != nullptr);
383  {
384  orbiterUserMac->AddPeer(utAddress);
385  }
386  }
387 }
388 
389 void
390 SatOrbiterNetDeviceDvb::DisconnectUt(Mac48Address utAddress, uint32_t beamId)
391 {
392  NS_LOG_FUNCTION(this << utAddress << beamId);
393 
394  NS_ASSERT_MSG(m_utConnected.find(utAddress) != m_utConnected.end(), "UT not in map");
395 
396  m_utConnected.erase(utAddress);
397  Singleton<SatIdMapper>::Get()->RemoveMacToSatIdIsl(utAddress);
398 
399  if (m_userMac.find(beamId) != m_userMac.end())
400  {
401  Ptr<SatOrbiterUserMac> orbiterUserMac = DynamicCast<SatOrbiterUserMac>(GetUserMac(beamId));
402  NS_ASSERT(orbiterUserMac != nullptr);
403  {
404  orbiterUserMac->RemovePeer(utAddress);
405  }
406  }
407 }
408 
409 } // 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.
This class implements a tag that carries the MAC address of the sender of the packet.
This class implements a tag that is used to identify control messages (packages).
void SetMsgType(SatControlMsgType_t type)
Set type of the control message.
virtual void SetMsgId(uint32_t msgId)
Set message type specific identifier.
Tag to store ground station destination address.
Mac48Address GetGroundStationAddress(void) const
Get the ground station MAC address.
This class implements a tag that carries the satellite MAC specific information, such as source and d...
void SetDestAddress(Mac48Address dest)
Set destination MAC address.
void SetSourceAddress(Mac48Address source)
Set source MAC address.
void ReceivePacketUser(Ptr< Packet > packet, const Address &userAddress)
Receive the packet from the lower layers, in network regeneration on return link.
void ReceivePacketFeeder(Ptr< Packet > packet, const Address &feederAddress)
Receive the packet from the lower layers, in network regeneration on forward link.
static TypeId GetTypeId(void)
Get the type ID.
virtual void ConnectUt(Mac48Address utAddress, uint32_t beamId)
Connect a UT to this satellite.
virtual void DisconnectUt(Mac48Address utAddress, uint32_t beamId)
Disconnect a UT to this satellite.
void ReceiveFromIsl(Ptr< Packet > packet, Mac48Address destination)
Receive a packet from ISL.
virtual bool SendControlMsgToFeeder(Ptr< SatControlMessage > msg, const Address &dest, Ptr< SatSignalParameters > rxParams)
Send a control packet on the feeder link.
SatOrbiterNetDevice to be utilized in geostationary satellite.
std::map< Mac48Address, uint32_t > m_gwConnected
Set containing all connected GWs.
std::set< uint32_t > m_broadcastReceived
Keep a count of all incoming broadcast data to avoid handling them several times.
Address GetRxUtAddress(Ptr< Packet > packet, SatEnums::SatLinkDir_t ld)
Get UT MAC address associated to this packet.
std::vector< Ptr< PointToPointIslNetDevice > > m_islNetDevices
List of ISLs starting from this node.
TracedCallback< const Time &, const Address & > m_rxUserLinkJitterTrace
Traced callback for all received packets, including user link jitter information and the address of t...
TracedCallback< Ptr< const Packet >, const Address & > m_rxUserTrace
Traced callback for all received packets on user, including the address of the senders.
TracedCallback< Ptr< const Packet >, const Address & > m_rxFeederTrace
Traced callback for all received packets on feeder, including the address of the senders.
TracedCallback< const Time &, const Address & > m_rxFeederLinkDelayTrace
Traced callback for all received packets, including feeder link delay information and the address of ...
std::map< uint32_t, Ptr< SatMac > > m_feederMac
std::map< Mac48Address, Time > m_lastDelays
std::map< uint32_t, Ptr< SatMac > > m_userMac
SatEnums::RegenerationMode_t m_returnLinkRegenerationMode
std::map< uint32_t, Ptr< SatMac > > GetUserMac()
Get all User MAC objects attached to this satellite.
void SendToIsl(Ptr< Packet > packet, Mac48Address destination)
Send a packet to ISL.
TracedCallback< Time, SatEnums::SatPacketEvent_t, SatEnums::SatNodeType_t, uint32_t, Mac48Address, SatEnums::SatLogLevel_t, SatEnums::SatLinkDir_t, std::string > m_packetTrace
TracedCallback< const Time &, const Address & > m_rxUserLinkDelayTrace
Traced callback for all received packets, including user link delay information and the address of th...
TracedCallback< const Time &, const Address & > m_rxFeederLinkJitterTrace
Traced callback for all received packets, including feeder link jitter information and the address of...
std::map< uint32_t, Ptr< SatPhy > > m_feederPhy
std::map< Mac48Address, uint32_t > m_utConnected
Set containing all connected UTs.
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.