satellite-user-helper.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  * Copyright (c) 2018 CNES
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Sami Rantanen <sami.rantanen@magister.fi>
20  * Author: Mathias Ettinger <mettinger@toulouse.viveris.com>
21  */
22 
23 #include "satellite-user-helper.h"
24 
25 #include <ns3/csma-helper.h>
26 #include <ns3/enum.h>
27 #include <ns3/internet-stack-helper.h>
28 #include <ns3/ipv4-interface.h>
29 #include <ns3/ipv4-routing-table-entry.h>
30 #include <ns3/ipv4-static-routing-helper.h>
31 #include <ns3/log.h>
32 #include <ns3/satellite-arp-cache.h>
33 #include <ns3/satellite-id-mapper.h>
34 #include <ns3/satellite-mac.h>
35 #include <ns3/satellite-mobility-observer.h>
36 #include <ns3/satellite-net-device.h>
37 #include <ns3/satellite-simple-net-device.h>
38 #include <ns3/satellite-topology.h>
39 #include <ns3/satellite-typedefs.h>
40 #include <ns3/singleton.h>
41 
42 #include <iostream>
43 #include <map>
44 #include <sstream>
45 #include <string>
46 #include <utility>
47 #include <vector>
48 
49 NS_LOG_COMPONENT_DEFINE("SatUserHelper");
50 
51 namespace ns3
52 {
53 
54 NS_OBJECT_ENSURE_REGISTERED(SatUserHelper);
55 
56 TypeId
58 {
59  static TypeId tid =
60  TypeId("ns3::SatUserHelper")
61  .SetParent<Object>()
62  .AddConstructor<SatUserHelper>()
63  .AddAttribute(
64  "BackboneNetworkType",
65  "Network used between GW and Router, and between Router and Users in "
66  "operator network",
68  MakeEnumAccessor<SatUserHelper::NetworkType>(&SatUserHelper::m_backboneNetworkType),
70  "SatSimple",
72  "Csma"))
73  .AddAttribute("SubscriberNetworkType",
74  "Network used between UTs and Users in subscriber network",
76  MakeEnumAccessor<SatUserHelper::NetworkType>(
79  "SatSimple",
81  "Csma"))
82  .AddAttribute("PropagationDelayGetter",
83  "Callback to retrieve propagation delay models from beam IDs",
84  CallbackValue(),
85  MakeCallbackAccessor(&SatUserHelper::m_propagationDelayCallback),
86  MakeCallbackChecker())
87  .AddTraceSource("Creation",
88  "Creation traces",
89  MakeTraceSourceAccessor(&SatUserHelper::m_creationTrace),
90  "ns3::SatTypedefs::CreationCallback");
91  return tid;
92 }
93 
94 TypeId
96 {
97  return GetTypeId();
98 }
99 
101  : m_backboneNetworkType(SatUserHelper::NETWORK_TYPE_SAT_SIMPLE),
102  m_subscriberNetworkType(SatUserHelper::NETWORK_TYPE_CSMA),
103  m_router(0)
104 {
105  NS_LOG_FUNCTION(this);
106 }
107 
109 {
110  NS_LOG_FUNCTION(this);
111 }
112 
113 void
115  std::string name1,
116  const AttributeValue& value1,
117  std::string name2,
118  const AttributeValue& value2,
119  std::string name3,
120  const AttributeValue& value3,
121  std::string name4,
122  const AttributeValue& value4)
123 {
124  NS_LOG_FUNCTION(this << type);
125 
126  m_csma.SetQueue(type, name1, value1, name2, value2, name3, value3, name4, value4);
127 }
128 
129 void
130 SatUserHelper::SetCsmaDeviceAttribute(std::string name, const AttributeValue& value)
131 {
132  NS_LOG_FUNCTION(this);
133  m_csma.SetDeviceAttribute(name, value);
134 }
135 
136 void
137 SatUserHelper::SetCsmaChannelAttribute(std::string name, const AttributeValue& value)
138 {
139  NS_LOG_FUNCTION(this);
140  m_csma.SetChannelAttribute(name, value);
141 }
142 
143 void
144 SatUserHelper::SetUtBaseAddress(const Ipv4Address& network,
145  const Ipv4Mask& mask,
146  const Ipv4Address address)
147 {
148  NS_LOG_FUNCTION(this);
149 
150  m_ipv4Ut.SetBase(network, mask, address);
151 }
152 
153 void
154 SatUserHelper::SetGwBaseAddress(const Ipv4Address& network,
155  const Ipv4Mask& mask,
156  const Ipv4Address address)
157 {
158  NS_LOG_FUNCTION(this);
159 
160  m_ipv4Gw.SetBase(network, mask, address);
161 }
162 
163 void
164 SatUserHelper::SetBeamBaseAddress(const Ipv4Address& network,
165  const Ipv4Mask& mask,
166  const Ipv4Address address)
167 {
168  NS_LOG_FUNCTION(this);
169 
170  m_ipv4Beam.SetBase(network, mask, address);
171 }
172 
173 NodeContainer
174 SatUserHelper::InstallUt(NodeContainer ut, uint32_t userCount)
175 {
176  NS_LOG_FUNCTION(this << userCount);
177 
178  NodeContainer createdUsers;
179 
180  // create users and csma links between UTs and users and add IP routes
181  for (NodeContainer::Iterator i = ut.Begin(); i != ut.End(); i++)
182  {
183  createdUsers.Add(InstallUt(*i, userCount));
184  }
185 
186  return createdUsers;
187 }
188 
189 NodeContainer
190 SatUserHelper::InstallUt(Ptr<Node> ut, uint32_t userCount)
191 {
192  NS_LOG_FUNCTION(this << userCount);
193 
194  if (userCount == 0)
195  {
196  NS_FATAL_ERROR("User count is zero!!!");
197  }
198 
199  InternetStackHelper internet;
200 
201  NodeContainer users;
202  users.Create(userCount);
203  NodeContainer utUsers = NodeContainer(ut, users);
204 
205  internet.Install(users);
206 
207  NetDeviceContainer nd = InstallSubscriberNetwork(utUsers);
208  Ipv4InterfaceContainer addresses = m_ipv4Ut.Assign(nd);
209  Ipv4StaticRoutingHelper ipv4RoutingHelper;
210 
211  for (NodeContainer::Iterator i = users.Begin(); i != users.End(); i++)
212  {
213  // Add the user and the UT as a new entry to the UT map
214  std::pair<std::map<Ptr<Node>, Ptr<Node>>::iterator, bool> ret =
215  m_utMap.insert(std::make_pair(*i, ut));
216  NS_ASSERT(ret.second);
217 
218  // Add the user's MAC address to the global mapper
219  NS_ASSERT_MSG((*i)->GetNDevices() == 2,
220  "Failed to get the device to subscriber network in UT user node "
221  << (*i)->GetId());
222  // assuming that #0 is for loopback device and #1 is for subscriber network device
223  Ptr<NetDevice> dev = (*i)->GetDevice(1);
224  Singleton<SatIdMapper>::Get()->AttachMacToUtUserId(dev->GetAddress());
225 
226  // Get IPv4 protocol implementations
227  Ptr<Ipv4> ipv4 = (*i)->GetObject<Ipv4>();
228 
229  // Set default route for users toward satellite (UTs address)
230  Ptr<Ipv4StaticRouting> routing = ipv4RoutingHelper.GetStaticRouting(ipv4);
231  routing->SetDefaultRoute(addresses.GetAddress(0), 1);
232  NS_LOG_INFO("User default route: " << addresses.GetAddress(0));
233  }
234 
235  m_ipv4Ut.NewNetwork();
236 
237  for (NodeContainer::Iterator it = users.Begin(); it != users.End(); it++)
238  {
239  Singleton<SatTopology>::Get()->AddUtUserNode(*it, ut);
240  }
241 
242  return users;
243 }
244 
245 void
246 SatUserHelper::InstallGw(uint32_t userCount)
247 {
248  NS_LOG_FUNCTION(this << userCount);
249 
250  InternetStackHelper internet;
251 
252  if (m_router == nullptr)
253  {
254  m_router = CreateObject<Node>();
255  internet.Install(m_router);
257  }
258 
259  // create users and csma links between Router and users and add IP routes
260  NodeContainer users;
261  users.Create(userCount);
262  NodeContainer routerUsers = NodeContainer(m_router, users);
263 
264  internet.Install(users);
265 
266  NetDeviceContainer nd = InstallBackboneNetwork(routerUsers);
267  Ipv4InterfaceContainer addresses = m_ipv4Gw.Assign(nd);
268  Ipv4StaticRoutingHelper ipv4RoutingHelper;
269 
270  Ptr<Ipv4> ipv4Router = m_router->GetObject<Ipv4>();
271  uint32_t lastRouterIf = ipv4Router->GetNInterfaces() - 1;
272  Ptr<Ipv4StaticRouting> routingRouter = ipv4RoutingHelper.GetStaticRouting(ipv4Router);
273  routingRouter->SetDefaultRoute(addresses.GetAddress(1), lastRouterIf);
274  NS_LOG_INFO("Router default route: " << addresses.GetAddress(1));
275 
276  for (NodeContainer::Iterator i = users.Begin(); i != users.End(); i++)
277  {
278  // Add the user's MAC address to the global mapper
279  NS_ASSERT_MSG((*i)->GetNDevices() == 2,
280  "Failed to get the device to backbone network in GW user node "
281  << (*i)->GetId());
282  // assuming that #0 is for loopback device and #1 is for backbone network device
283  Ptr<NetDevice> dev = (*i)->GetDevice(1);
284  Singleton<SatIdMapper>::Get()->AttachMacToGwUserId(dev->GetAddress());
285 
286  // Get IPv4 protocol implementations
287  Ptr<Ipv4> ipv4 = (*i)->GetObject<Ipv4>();
288 
289  // Set default route toward router (GW) for users
290  Ptr<Ipv4StaticRouting> routing = ipv4RoutingHelper.GetStaticRouting(ipv4);
291  routing->SetDefaultRoute(addresses.GetAddress(0), 1);
292  NS_LOG_INFO("User default route: " << addresses.GetAddress(0));
293 
294  Singleton<SatTopology>::Get()->AddGwUserNode(*i);
295  }
296 
297  m_ipv4Gw.NewNetwork();
298 }
299 
300 bool
301 SatUserHelper::IsGwUser(Ptr<Node> node) const
302 {
303  NS_LOG_FUNCTION(this);
304 
305  bool isGwUser = false;
306 
307  NodeContainer gwUsers = Singleton<SatTopology>::Get()->GetGwUserNodes();
308 
309  for (NodeContainer::Iterator it = gwUsers.Begin(); ((it != gwUsers.End()) && !isGwUser); it++)
310  {
311  if (*it == node)
312  {
313  isGwUser = true;
314  }
315  }
316 
317  return isGwUser;
318 }
319 
320 void
321 SatUserHelper::EnableCreationTraces(Ptr<OutputStreamWrapper> stream, CallbackBase& cb)
322 {
323  NS_LOG_FUNCTION(this);
324 
325  TraceConnect("Creation", "SatUserHelper", cb);
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION(this);
332 
333  NodeContainer gwNodes = Singleton<SatTopology>::Get()->GetGwNodes();
334 
335  for (NodeContainer::Iterator i = gwNodes.Begin(); i != gwNodes.End(); i++)
336  {
337  NodeContainer gwRouter = NodeContainer((*i), router);
338 
339  NetDeviceContainer nd = InstallBackboneNetwork(gwRouter);
340  Ipv4InterfaceContainer addresses = m_ipv4Gw.Assign(nd);
341  Ipv4StaticRoutingHelper ipv4RoutingHelper;
342 
343  // Get IPv4 protocol implementations
344  Ptr<Ipv4> ipv4Gw = (*i)->GetObject<Ipv4>();
345  uint32_t lastGwIf = ipv4Gw->GetNInterfaces() - 1;
346  Ptr<Ipv4StaticRouting> routingGw = ipv4RoutingHelper.GetStaticRouting(ipv4Gw);
347  routingGw->SetDefaultRoute(addresses.GetAddress(1), lastGwIf);
348  NS_LOG_INFO("GW default route: " << addresses.GetAddress(1));
349 
350  for (uint32_t routeIndex = 0; routeIndex < routingGw->GetNRoutes(); routeIndex++)
351  {
352  // Get IPv4 protocol implementations
353  Ptr<Ipv4> ipv4Router = router->GetObject<Ipv4>();
354  uint32_t lastRouterIf = ipv4Router->GetNInterfaces() - 1;
355  Ptr<Ipv4StaticRouting> routingRouter = ipv4RoutingHelper.GetStaticRouting(ipv4Router);
356 
357  Ipv4RoutingTableEntry route = routingGw->GetRoute(routeIndex);
358  uint32_t interface = route.GetInterface();
359 
360  // set only routes for interfaces created earlier (and not for local delivery index 0)
361  if ((interface != 0) && (interface != lastGwIf))
362  {
363  routingRouter->AddNetworkRouteTo(route.GetDest(),
364  route.GetDestNetworkMask(),
365  addresses.GetAddress(0),
366  lastRouterIf);
367  NS_LOG_INFO("Router network route:" << route.GetDest() << ", "
368  << route.GetDestNetworkMask() << ", "
369  << addresses.GetAddress(0));
370  }
371  }
372 
373  m_ipv4Gw.NewNetwork();
374  }
375 }
376 
377 NetDeviceContainer
378 SatUserHelper::InstallSubscriberNetwork(const NodeContainer& c) const
379 {
380  NS_LOG_FUNCTION(this);
381 
382  NetDeviceContainer devs;
383 
384  switch (m_subscriberNetworkType)
385  {
387  devs = InstallSatSimpleNetwork(c);
388  break;
389 
390  case NETWORK_TYPE_CSMA:
391  devs = m_csma.Install(c);
392  break;
393 
394  default:
395  NS_ASSERT(false);
396  break;
397  }
398 
399  return devs;
400 }
401 
402 NetDeviceContainer
403 SatUserHelper::InstallBackboneNetwork(const NodeContainer& c) const
404 {
405  NS_LOG_FUNCTION(this);
406 
407  NetDeviceContainer devs;
408 
409  switch (m_backboneNetworkType)
410  {
412  devs = InstallSatSimpleNetwork(c);
413  break;
414 
415  case NETWORK_TYPE_CSMA:
416  devs = m_csma.Install(c);
417  break;
418 
419  default:
420  NS_ASSERT(false);
421  break;
422  }
423 
424  return devs;
425 }
426 
427 NetDeviceContainer
428 SatUserHelper::InstallSatSimpleNetwork(const NodeContainer& c) const
429 {
430  NS_LOG_FUNCTION(this);
431 
432  NetDeviceContainer devs;
433  Ptr<SatSimpleChannel> channel = CreateObject<SatSimpleChannel>();
434 
435  for (NodeContainer::Iterator i = c.Begin(); i != c.End(); i++)
436  {
437  Ptr<SatSimpleNetDevice> device = CreateObject<SatSimpleNetDevice>();
438  device->SetAddress(Mac48Address::Allocate());
439  (*i)->AddDevice(device);
440  device->SetChannel(channel);
441  devs.Add(device);
442  }
443 
444  return devs;
445 }
446 
447 std::string
449 {
450  NS_LOG_FUNCTION(this);
451 
452  std::ostringstream oss;
453 
454  Address devAddress;
455  Ptr<Ipv4> ipv4 = m_router->GetObject<Ipv4>(); // Get Ipv4 instance of the node
456 
457  std::vector<Ipv4Address> IPAddressVector;
458  std::vector<std::string> devNameVector;
459  std::vector<Address> devAddressVector;
460 
461  oss << "--- Router info ---" << std::endl << std::endl;
462 
463  for (uint32_t j = 0; j < m_router->GetNDevices(); j++)
464  {
465  Ptr<NetDevice> device = m_router->GetDevice(j);
466 
467  oss << device->GetInstanceTypeId().GetName() << " ";
468  oss << device->GetAddress() << " ";
469  oss << ipv4->GetAddress(j, 0).GetLocal() << " ";
470  }
471 
472  return oss.str();
473 }
474 
475 Ptr<Node>
477 {
478  NS_LOG_FUNCTION(this);
479 
480  return m_router;
481 }
482 
483 void
485  NetDeviceContainer utNd,
486  Ptr<Node> gw,
487  Ptr<NetDevice> gwNd)
488 {
489  Ipv4InterfaceContainer gwAddress = m_ipv4Beam.Assign(gwNd);
490  Ipv4Address gwAddr = gwAddress.GetAddress(0);
491  NS_LOG_FUNCTION(this << gw << gwNd << gwAddr);
492 
493  Ipv4InterfaceContainer utIfs = m_ipv4Beam.Assign(utNd);
494 
495  Ipv4StaticRoutingHelper ipv4RoutingHelper;
496  Ptr<Ipv4L3Protocol> ipv4Gw = gw->GetObject<Ipv4L3Protocol>();
497  Ptr<Ipv4StaticRouting> srGw = ipv4RoutingHelper.GetStaticRouting(ipv4Gw);
498 
499  // Store GW NetDevice for updating routing during handover
500  m_gwDevices.insert(std::make_pair(gwNd->GetAddress(), gwNd));
501 
502  // Create an ARP entry of the default GW for the UTs in this beam
503  Address macAddressGw = gwNd->GetAddress();
504  Ptr<SatArpCache> utArpCache = CreateObject<SatArpCache>();
505  utArpCache->Add(gwAddr, macAddressGw);
506  NS_LOG_INFO("UT ARP entry: " << gwAddr << " - " << macAddressGw);
507  // Store ARP cache for retrieval during handovers
508  m_arpCachesToGateway.emplace(macAddressGw, utArpCache);
509 
510  // Add the ARP entries of all the UTs in this beam
511  // - MAC address vs. IPv4 address
512  Ptr<SatArpCache> gwArpCache = CreateObject<SatArpCache>();
513  for (uint32_t i = 0; i < utIfs.GetN(); ++i)
514  {
515  NS_ASSERT(utIfs.GetN() == utNd.GetN());
516  Ptr<NetDevice> nd = utNd.Get(i);
517  Ipv4Address ipv4Addr = utIfs.GetAddress(i);
518  gwArpCache->Add(ipv4Addr, nd->GetAddress());
519  NS_LOG_INFO("GW ARP entry: " << ipv4Addr << " - " << nd->GetAddress());
520  // Store UT NetDevice for updating routing during handover
521  m_utDevices.insert(std::make_pair(nd->GetAddress(), nd));
522  }
523 
524  // Set the ARP cache to the proper GW IPv4Interface (the one for satellite
525  // link). ARP cache contains the entries for all UTs within this spot-beam.
526  ipv4Gw->GetInterface(gwNd->GetIfIndex())->SetArpCache(gwArpCache);
527  NS_LOG_INFO("Add ARP cache to GW " << gw->GetId());
528 
529  uint32_t utAddressIndex = 0;
530 
531  for (NodeContainer::Iterator i = ut.Begin(); i != ut.End(); i++)
532  {
533  Ptr<Ipv4L3Protocol> ipv4Ut = (*i)->GetObject<Ipv4L3Protocol>();
534 
535  uint32_t count = ipv4Ut->GetNInterfaces();
536 
537  for (uint32_t j = 1; j < count; j++)
538  {
539  std::string devName = ipv4Ut->GetNetDevice(j)->GetInstanceTypeId().GetName();
540 
541  // If SatNetDevice interface, add default route to towards GW of the beam on UTs
542  if (devName == "ns3::SatNetDevice" || devName == "ns3::SatLorawanNetDevice")
543  {
544  Ptr<Ipv4StaticRouting> srUt = ipv4RoutingHelper.GetStaticRouting(ipv4Ut);
545  srUt->SetDefaultRoute(gwAddr, j);
546  NS_LOG_INFO("UT default route: " << gwAddr);
547 
548  // Set the ARP cache (including the ARP entry for the default GW) to the UT
549  ipv4Ut->GetInterface(j)->SetArpCache(utArpCache);
550  NS_LOG_INFO("Add the ARP cache to UT " << (*i)->GetId());
551  }
552  else // add other interface route to GW's Satellite interface
553  {
554  Ipv4Address address = ipv4Ut->GetAddress(j, 0).GetLocal();
555  Ipv4Mask mask = ipv4Ut->GetAddress(j, 0).GetMask();
556 
557  srGw->AddNetworkRouteTo(address.CombineMask(mask),
558  mask,
559  utIfs.GetAddress(utAddressIndex),
560  gwNd->GetIfIndex());
561  NS_LOG_INFO("GW Network route: " << address.CombineMask(mask) << ", " << mask
562  << ", " << utIfs.GetAddress(utAddressIndex));
563  }
564  }
565 
566  utAddressIndex++;
567  }
568 
569  m_ipv4Beam.NewNetwork();
570 }
571 
572 void
573 SatUserHelper::UpdateUtRoutes(Address utAddress, Address gwAddress)
574 {
575  NS_LOG_FUNCTION(this << utAddress << gwAddress);
576 
577  std::map<Address, Ptr<NetDevice>>::iterator gwNdIterator = m_gwDevices.find(gwAddress);
578  NS_ASSERT_MSG(gwNdIterator != m_gwDevices.end(), "Unknown GW with MAC address " << gwAddress);
579 
580  Ptr<SatNetDevice> gwNd = DynamicCast<SatNetDevice>(gwNdIterator->second);
581  NS_ASSERT(gwNd != nullptr);
582  Ipv4Address ip =
583  gwNd->GetNode()->GetObject<Ipv4L3Protocol>()->GetAddress(gwNd->GetIfIndex(), 0).GetLocal();
584 
585  std::map<Address, Ptr<NetDevice>>::iterator utNdIterator = m_utDevices.find(utAddress);
586  NS_ASSERT_MSG(utNdIterator != m_utDevices.end(), "Unknown UT with MAC address " << utAddress);
587 
588  std::map<Address, Ptr<SatArpCache>>::iterator arpCacheIterator =
589  m_arpCachesToGateway.find(gwAddress);
590  NS_ASSERT_MSG(arpCacheIterator != m_arpCachesToGateway.end(),
591  "ARP cache not found to gateway " << gwAddress);
592 
593  Ptr<SatNetDevice> utNd = DynamicCast<SatNetDevice>(utNdIterator->second);
594  NS_ASSERT(utNd != nullptr);
595  Ptr<Ipv4L3Protocol> protocol = utNd->GetNode()->GetObject<Ipv4L3Protocol>();
596  uint32_t utIfIndex = utNdIterator->second->GetIfIndex();
597 
598  NS_LOG_INFO("Changing ARP cache for UT " << utAddress << " pointing to " << ip << " through "
599  << gwAddress);
600  protocol->GetInterface(utIfIndex)->SetArpCache(arpCacheIterator->second);
601 
602  Ipv4StaticRoutingHelper ipv4RoutingHelper;
603  Ptr<Ipv4StaticRouting> routing = ipv4RoutingHelper.GetStaticRouting(protocol);
604  routing->RemoveRoute(routing->GetNRoutes() - 1);
605  routing->SetDefaultRoute(ip, utIfIndex);
606 
607  NS_LOG_INFO("Set default route on UT to " << ip);
608 
609  uint32_t satId = gwNd->GetMac()->GetSatId();
610  uint32_t beamId = gwNd->GetMac()->GetBeamId();
611  Ptr<PropagationDelayModel> flDelayModel =
613  Ptr<PropagationDelayModel> ulDelayModel =
615  Ptr<SatMobilityObserver> observer = utNd->GetNode()->GetObject<SatMobilityObserver>();
616  observer->ObserveTimingAdvance(ulDelayModel,
617  flDelayModel,
618  gwNd->GetNode()->GetObject<SatMobilityModel>());
619 }
620 
621 void
622 SatUserHelper::UpdateGwRoutes(Address ut, Address oldGateway, Address newGateway)
623 {
624  NS_LOG_FUNCTION(this << ut << oldGateway << newGateway);
625 
626  std::map<Address, Ptr<NetDevice>>::iterator utNdIterator = m_utDevices.find(ut);
627  if (utNdIterator == m_utDevices.end())
628  {
629  NS_FATAL_ERROR("Unknown UT with MAC address " << ut);
630  }
631 
632  std::map<Address, Ptr<NetDevice>>::iterator oldGwNdIterator = m_gwDevices.find(oldGateway);
633  if (oldGwNdIterator == m_gwDevices.end())
634  {
635  NS_FATAL_ERROR("Unknown GW with MAC address " << oldGateway);
636  }
637 
638  std::map<Address, Ptr<NetDevice>>::iterator newGwNdIterator = m_gwDevices.find(newGateway);
639  if (newGwNdIterator == m_gwDevices.end())
640  {
641  NS_FATAL_ERROR("Unknown GW with MAC address " << newGateway);
642  }
643 
644  uint32_t utIfIndex = utNdIterator->second->GetIfIndex();
645  Ptr<Ipv4L3Protocol> utProtocol = utNdIterator->second->GetNode()->GetObject<Ipv4L3Protocol>();
646  Ipv4Address utIpAddress = utProtocol->GetAddress(utIfIndex, 0).GetLocal();
647 
648  Ptr<Node> oldGatewayNode = oldGwNdIterator->second->GetNode();
649  uint32_t oldIfIndex = oldGwNdIterator->second->GetIfIndex();
650  Ptr<Node> newGatewayNode = newGwNdIterator->second->GetNode();
651  uint32_t newIfIndex = newGwNdIterator->second->GetIfIndex();
652 
653  Ptr<ArpCache> arpCache;
654  // Clear old ARP cache
655  arpCache = oldGatewayNode->GetObject<Ipv4L3Protocol>()->GetInterface(oldIfIndex)->GetArpCache();
656  for (ArpCache::Entry* entry : arpCache->LookupInverse(ut))
657  {
658  arpCache->Remove(entry);
659  }
660  // Add entry in new ARP cache
661  arpCache = newGatewayNode->GetObject<Ipv4L3Protocol>()->GetInterface(newIfIndex)->GetArpCache();
662  ArpCache::Entry* entry = arpCache->Add(utIpAddress);
663  entry->SetMacAddress(ut);
664  entry->MarkPermanent();
665 
666  // Change routes on GW
667  Ipv4StaticRoutingHelper ipv4RoutingHelper;
668  if (oldGatewayNode == newGatewayNode)
669  {
670  // intra-GW handover
671  Ptr<Ipv4StaticRouting> routing =
672  ipv4RoutingHelper.GetStaticRouting(oldGatewayNode->GetObject<Ipv4L3Protocol>());
673 
674  // purge old routes
675  for (uint32_t routeIndex = routing->GetNRoutes(); routeIndex > 0; --routeIndex)
676  {
677  // Note: keeping routeIndex 1-off because we are using unsigned values
678  if (routing->GetRoute(routeIndex - 1).GetGateway() == utIpAddress)
679  {
680  routing->RemoveRoute(routeIndex - 1);
681  }
682  }
683 
684  // add new ones
685  for (uint32_t ifIndex = 1; ifIndex < utProtocol->GetNInterfaces(); ++ifIndex)
686  {
687  Ipv4Address address = utProtocol->GetAddress(ifIndex, 0).GetLocal();
688  Ipv4Mask mask = utProtocol->GetAddress(ifIndex, 0).GetMask();
689 
690  if (ifIndex == utIfIndex)
691  {
692  mask = Ipv4Mask("/32");
693  }
694 
695  routing->AddNetworkRouteTo(address.CombineMask(mask), mask, utIpAddress, newIfIndex);
696  }
697  }
698  else
699  {
700  // inter-GW handover
701  Ptr<Ipv4StaticRouting> routing =
702  ipv4RoutingHelper.GetStaticRouting(oldGatewayNode->GetObject<Ipv4L3Protocol>());
703  Ptr<Ipv4StaticRouting> routingRouter =
704  ipv4RoutingHelper.GetStaticRouting(m_router->GetObject<Ipv4L3Protocol>());
705 
706  // purge old routes
707  for (uint32_t routeIndex = routing->GetNRoutes(); routeIndex > 0; --routeIndex)
708  {
709  // Note: keeping routeIndex 1-off because we are using unsigned values
710  Ipv4RoutingTableEntry gwRoute = routing->GetRoute(routeIndex - 1);
711  if (gwRoute.GetGateway() == utIpAddress)
712  {
713  routing->RemoveRoute(routeIndex - 1);
714  // search for corresponding route on terrestrial router
715  for (uint32_t routerIndex = 0; routerIndex < routingRouter->GetNRoutes();
716  ++routerIndex)
717  {
718  Ipv4RoutingTableEntry route = routingRouter->GetRoute(routerIndex);
719  if (route.GetDestNetwork() == gwRoute.GetDestNetwork() &&
720  route.GetDestNetworkMask() == gwRoute.GetDestNetworkMask())
721  {
722  routingRouter->RemoveRoute(routerIndex);
723  break;
724  }
725  }
726  }
727  }
728 
729  // add new ones
730  Ptr<Ipv4L3Protocol> gwProtocol = newGatewayNode->GetObject<Ipv4L3Protocol>();
731 
732  // start by looking up GW IP as seen by the terrestrial router
733  Ipv4Address gwAddress;
734  for (uint32_t ifIndex = 1; ifIndex < gwProtocol->GetNInterfaces(); ++ifIndex)
735  {
736  Ptr<NetDevice> gwNd = gwProtocol->GetNetDevice(ifIndex);
737  if (gwNd->GetInstanceTypeId().GetName() != "ns3::SatNetDevice" &&
738  gwNd->GetInstanceTypeId().GetName() != "ns3::SatLorawanNetDevice")
739  {
740  gwAddress = gwProtocol->GetAddress(ifIndex, 0).GetLocal();
741  break;
742  }
743  }
744 
745  // find interface on the terrestrial router to send messages to GW
746  uint32_t routingIfIndex = routingRouter->GetNRoutes();
747  for (uint32_t routeIndex = 0; routeIndex < routingRouter->GetNRoutes(); ++routeIndex)
748  {
749  Ipv4RoutingTableEntry route = routingRouter->GetRoute(routeIndex);
750  if (route.GetGateway() == gwAddress)
751  {
752  routingIfIndex = route.GetInterface();
753  break;
754  }
755  }
756 
757  NS_ASSERT_MSG(routingIfIndex != routingRouter->GetNRoutes(),
758  "Couldn't find interface on the terrestrial router to the new gateway.");
759 
760  // add routes to the new GW and the terrestrial router
761  routing = ipv4RoutingHelper.GetStaticRouting(gwProtocol);
762  for (uint32_t ifIndex = 1; ifIndex < utProtocol->GetNInterfaces(); ++ifIndex)
763  {
764  Ipv4Address address = utProtocol->GetAddress(ifIndex, 0).GetLocal();
765  Ipv4Mask mask = utProtocol->GetAddress(ifIndex, 0).GetMask();
766 
767  if (ifIndex == utIfIndex)
768  {
769  mask = Ipv4Mask("/32");
770  }
771 
772  routing->AddNetworkRouteTo(address.CombineMask(mask), mask, utIpAddress, newIfIndex);
773  routingRouter->AddNetworkRouteTo(address.CombineMask(mask),
774  mask,
775  gwAddress,
776  routingIfIndex);
777  }
778  }
779 }
780 
781 } // namespace ns3
Keep track of the current position and velocity of an object in satellite network.
Observes given mobilities and keeps track of certain wanted properties.
void ObserveTimingAdvance(Ptr< PropagationDelayModel > ownDelayModel, Ptr< PropagationDelayModel > anotherDelayModel, Ptr< SatMobilityModel > anotherMobility)
Enable observing of the timing advance.
Build a set of user nodes and links channels between user nodes and satellite nodes.
Ipv4AddressHelper m_ipv4Gw
void InstallGw(uint32_t users)
void SetCsmaDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each CsmaNetDevice object created by the helper.
NetworkType m_subscriberNetworkType
std::map< Address, Ptr< NetDevice > > m_utDevices
Container of UT SatNetDevice accessible by MAC address.
void UpdateGwRoutes(Address ut, Address oldGateway, Address newGateway)
Update ARP cache and default route on the terrestrial network so packets are properly routed to the U...
void SetBeamBaseAddress(const Ipv4Address &network, const Ipv4Mask &mask, Ipv4Address base="0.0.0.1")
NetDeviceContainer InstallSatSimpleNetwork(const NodeContainer &c) const
Install satellite simple network.
static TypeId GetTypeId(void)
Derived from Object.
void InstallRouter(Ptr< Node > router)
Install IP router to to Gateways.
TracedCallback< std::string > m_creationTrace
Trace callback for creation traces.
std::map< Ptr< Node >, Ptr< Node > > m_utMap
Container of UT users and their corresponding UT.
void SetCsmaQueue(std::string type, std::string name1="", const AttributeValue &value1=EmptyAttributeValue(), std::string name2="", const AttributeValue &value2=EmptyAttributeValue(), std::string name3="", const AttributeValue &value3=EmptyAttributeValue(), std::string name4="", const AttributeValue &value4=EmptyAttributeValue())
Set the type and the attribute values to be associated with each Queue object in each CsmaNetDevice c...
std::map< Address, Ptr< SatArpCache > > m_arpCachesToGateway
Container of ARP tables to reach a gateway accessible by MAC address.
void SetCsmaChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each CsmaChannel object created by the helper.
std::string GetRouterInfo() const
Get router information.
void EnableCreationTraces(Ptr< OutputStreamWrapper > stream, CallbackBase &cb)
Enables creation traces to be written in given file.
NetDeviceContainer InstallBackboneNetwork(const NodeContainer &c) const
Install network between GW and Router (or users) or Router and its users.
void SetGwBaseAddress(const Ipv4Address &network, const Ipv4Mask &mask, Ipv4Address base="0.0.0.1")
Ipv4AddressHelper m_ipv4Beam
std::map< Address, Ptr< NetDevice > > m_gwDevices
Container of GW SatNetDevice accessible by MAC address.
Ptr< Node > GetRouter() const
void PopulateBeamRoutings(NodeContainer ut, NetDeviceContainer utNd, Ptr< Node > gw, Ptr< NetDevice > gwNd)
Set needed routings of satellite network and fill ARP cache for the network.
SatUserHelper::PropagationDelayCallback m_propagationDelayCallback
bool IsGwUser(Ptr< Node > node) const
Check if node is GW user or not.
TypeId GetInstanceTypeId(void) const
Derived from Object.
NodeContainer InstallUt(NodeContainer ut, uint32_t users)
void UpdateUtRoutes(Address ut, Address newGateway)
Update ARP cache and default route on an UT so packets are properly routed to the new GW as their nex...
SatUserHelper()
Create a SatUserHelper to make life easier when creating Users and their connections to satellite net...
Ipv4AddressHelper m_ipv4Ut
NetDeviceContainer InstallSubscriberNetwork(const NodeContainer &c) const
Install network between UT and its users.
void SetUtBaseAddress(const Ipv4Address &network, const Ipv4Mask &mask, Ipv4Address base="0.0.0.1")
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.