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-typedefs.h>
39 #include <ns3/singleton.h>
40 
41 NS_LOG_COMPONENT_DEFINE("SatUserHelper");
42 
43 namespace ns3
44 {
45 
46 NS_OBJECT_ENSURE_REGISTERED(SatUserHelper);
47 
48 TypeId
50 {
51  static TypeId tid =
52  TypeId("ns3::SatUserHelper")
53  .SetParent<Object>()
54  .AddConstructor<SatUserHelper>()
55  .AddAttribute("BackboneNetworkType",
56  "Network used between GW and Router, and between Router and Users in "
57  "operator network",
59  MakeEnumAccessor(&SatUserHelper::m_backboneNetworkType),
61  "SatSimple",
63  "Csma"))
64  .AddAttribute("SubscriberNetworkType",
65  "Network used between UTs and Users in subscriber network",
67  MakeEnumAccessor(&SatUserHelper::m_subscriberNetworkType),
69  "SatSimple",
71  "Csma"))
72  .AddAttribute("PropagationDelayGetter",
73  "Callback to retrieve propagation delay models from beam IDs",
74  CallbackValue(),
75  MakeCallbackAccessor(&SatUserHelper::m_propagationDelayCallback),
76  MakeCallbackChecker())
77  .AddTraceSource("Creation",
78  "Creation traces",
79  MakeTraceSourceAccessor(&SatUserHelper::m_creationTrace),
80  "ns3::SatTypedefs::CreationCallback");
81  return tid;
82 }
83 
84 TypeId
86 {
87  return GetTypeId();
88 }
89 
91  : m_backboneNetworkType(SatUserHelper::NETWORK_TYPE_SAT_SIMPLE),
92  m_subscriberNetworkType(SatUserHelper::NETWORK_TYPE_CSMA),
93  m_router(0)
94 {
95  NS_LOG_FUNCTION(this);
96 }
97 
99 {
100  NS_LOG_FUNCTION(this);
101 }
102 
103 void
105  std::string name1,
106  const AttributeValue& value1,
107  std::string name2,
108  const AttributeValue& value2,
109  std::string name3,
110  const AttributeValue& value3,
111  std::string name4,
112  const AttributeValue& value4)
113 {
114  NS_LOG_FUNCTION(this << type);
115 
116  m_csma.SetQueue(type, name1, value1, name2, value2, name3, value3, name4, value4);
117 }
118 
119 void
120 SatUserHelper::SetCsmaDeviceAttribute(std::string name, const AttributeValue& value)
121 {
122  NS_LOG_FUNCTION(this);
123  m_csma.SetDeviceAttribute(name, value);
124 }
125 
126 void
127 SatUserHelper::SetCsmaChannelAttribute(std::string name, const AttributeValue& value)
128 {
129  NS_LOG_FUNCTION(this);
130  m_csma.SetChannelAttribute(name, value);
131 }
132 
133 void
134 SatUserHelper::SetUtBaseAddress(const Ipv4Address& network,
135  const Ipv4Mask& mask,
136  const Ipv4Address address)
137 {
138  NS_LOG_FUNCTION(this);
139 
140  m_ipv4Ut.SetBase(network, mask, address);
141 }
142 
143 void
144 SatUserHelper::SetGwBaseAddress(const Ipv4Address& network,
145  const Ipv4Mask& mask,
146  const Ipv4Address address)
147 {
148  NS_LOG_FUNCTION(this);
149 
150  m_ipv4Gw.SetBase(network, mask, address);
151 }
152 
153 void
154 SatUserHelper::SetBeamBaseAddress(const Ipv4Address& network,
155  const Ipv4Mask& mask,
156  const Ipv4Address address)
157 {
158  NS_LOG_FUNCTION(this);
159 
160  m_ipv4Beam.SetBase(network, mask, address);
161 }
162 
163 NodeContainer
164 SatUserHelper::InstallUt(NodeContainer ut, uint32_t userCount)
165 {
166  NS_LOG_FUNCTION(this << userCount);
167 
168  NodeContainer createdUsers;
169 
170  // create users and csma links between UTs and users and add IP routes
171  for (NodeContainer::Iterator i = ut.Begin(); i != ut.End(); i++)
172  {
173  createdUsers.Add(InstallUt(*i, userCount));
174  }
175 
176  return createdUsers;
177 }
178 
179 NodeContainer
180 SatUserHelper::InstallUt(Ptr<Node> ut, uint32_t userCount)
181 {
182  NS_LOG_FUNCTION(this << userCount);
183 
184  if (userCount == 0)
185  {
186  NS_FATAL_ERROR("User count is zero!!!");
187  }
188 
189  InternetStackHelper internet;
190 
191  NodeContainer users;
192  users.Create(userCount);
193  NodeContainer utUsers = NodeContainer(ut, users);
194 
195  internet.Install(users);
196 
197  NetDeviceContainer nd = InstallSubscriberNetwork(utUsers);
198  Ipv4InterfaceContainer addresses = m_ipv4Ut.Assign(nd);
199  Ipv4StaticRoutingHelper ipv4RoutingHelper;
200 
201  for (NodeContainer::Iterator i = users.Begin(); i != users.End(); i++)
202  {
203  // Add the user and the UT as a new entry to the UT map
204  std::pair<std::map<Ptr<Node>, Ptr<Node>>::iterator, bool> ret =
205  m_utMap.insert(std::make_pair(*i, ut));
206  NS_ASSERT(ret.second);
207 
208  // Add the user's MAC address to the global mapper
209  NS_ASSERT_MSG((*i)->GetNDevices() == 2,
210  "Failed to get the device to subscriber network in UT user node "
211  << (*i)->GetId());
212  // assuming that #0 is for loopback device and #1 is for subscriber network device
213  Ptr<NetDevice> dev = (*i)->GetDevice(1);
214  Singleton<SatIdMapper>::Get()->AttachMacToUtUserId(dev->GetAddress());
215 
216  // Get IPv4 protocol implementations
217  Ptr<Ipv4> ipv4 = (*i)->GetObject<Ipv4>();
218 
219  // Set default route for users toward satellite (UTs address)
220  Ptr<Ipv4StaticRouting> routing = ipv4RoutingHelper.GetStaticRouting(ipv4);
221  routing->SetDefaultRoute(addresses.GetAddress(0), 1);
222  NS_LOG_INFO("User default route: " << addresses.GetAddress(0));
223  }
224 
225  m_ipv4Ut.NewNetwork();
226 
227  std::pair<UtUsersContainer_t::const_iterator, bool> result =
228  m_utUsers.insert(std::make_pair(ut, users));
229 
230  if (result.second == false)
231  {
232  NS_FATAL_ERROR("UT is already installed.");
233  }
234 
235  m_allUtUsers.Add(users);
236 
237  return users;
238 }
239 
240 NodeContainer
241 SatUserHelper::InstallGw(NodeContainer gw, uint32_t userCount)
242 {
243  NS_LOG_FUNCTION(this << userCount);
244 
245  InternetStackHelper internet;
246 
247  if (m_router == NULL)
248  {
249  m_router = CreateObject<Node>();
250  internet.Install(m_router);
251  InstallRouter(gw, m_router);
252  }
253 
254  // create users and csma links between Router and users and add IP routes
255  NodeContainer users;
256  users.Create(userCount);
257  NodeContainer routerUsers = NodeContainer(m_router, users);
258 
259  internet.Install(users);
260 
261  NetDeviceContainer nd = InstallBackboneNetwork(routerUsers);
262  Ipv4InterfaceContainer addresses = m_ipv4Gw.Assign(nd);
263  Ipv4StaticRoutingHelper ipv4RoutingHelper;
264 
265  Ptr<Ipv4> ipv4Router = m_router->GetObject<Ipv4>();
266  uint32_t lastRouterIf = ipv4Router->GetNInterfaces() - 1;
267  Ptr<Ipv4StaticRouting> routingRouter = ipv4RoutingHelper.GetStaticRouting(ipv4Router);
268  routingRouter->SetDefaultRoute(addresses.GetAddress(1), lastRouterIf);
269  NS_LOG_INFO("Router default route: " << addresses.GetAddress(1));
270 
271  for (NodeContainer::Iterator i = users.Begin(); i != users.End(); i++)
272  {
273  // Add the user's MAC address to the global mapper
274  NS_ASSERT_MSG((*i)->GetNDevices() == 2,
275  "Failed to get the device to backbone network in GW user node "
276  << (*i)->GetId());
277  // assuming that #0 is for loopback device and #1 is for backbone network device
278  Ptr<NetDevice> dev = (*i)->GetDevice(1);
279  Singleton<SatIdMapper>::Get()->AttachMacToGwUserId(dev->GetAddress());
280 
281  // Get IPv4 protocol implementations
282  Ptr<Ipv4> ipv4 = (*i)->GetObject<Ipv4>();
283 
284  // Set default route toward router (GW) for users
285  Ptr<Ipv4StaticRouting> routing = ipv4RoutingHelper.GetStaticRouting(ipv4);
286  routing->SetDefaultRoute(addresses.GetAddress(0), 1);
287  NS_LOG_INFO("User default route: " << addresses.GetAddress(0));
288  }
289 
290  m_gwUsers.Add(users);
291  m_ipv4Gw.NewNetwork();
292 
293  return m_gwUsers;
294 }
295 
296 NodeContainer
298 {
299  NS_LOG_FUNCTION(this);
300 
301  return m_gwUsers;
302 }
303 
304 bool
305 SatUserHelper::IsGwUser(Ptr<Node> node) const
306 {
307  NS_LOG_FUNCTION(this);
308 
309  bool isGwUser = false;
310 
311  for (NodeContainer::Iterator it = m_gwUsers.Begin(); ((it != m_gwUsers.End()) && !isGwUser);
312  it++)
313  {
314  if (*it == node)
315  {
316  isGwUser = true;
317  }
318  }
319 
320  return isGwUser;
321 }
322 
323 NodeContainer
325 {
326  NS_LOG_FUNCTION(this);
327 
328  return m_allUtUsers;
329 }
330 
331 NodeContainer
332 SatUserHelper::GetUtUsers(Ptr<Node> ut) const
333 {
334  NS_LOG_FUNCTION(this);
335 
336  UtUsersContainer_t::const_iterator it = m_utUsers.find(ut);
337 
338  if (it == m_utUsers.end())
339  {
340  NS_FATAL_ERROR("UT which users are requested in not installed!!!");
341  }
342 
343  return it->second;
344 }
345 
346 uint32_t
348 {
349  NS_LOG_FUNCTION(this);
350 
351  return m_gwUsers.GetN();
352 }
353 
354 uint32_t
356 {
357  NS_LOG_FUNCTION(this);
358 
359  return m_allUtUsers.GetN();
360 }
361 
362 uint32_t
363 SatUserHelper::GetUtUserCount(Ptr<Node> ut) const
364 {
365  NS_LOG_FUNCTION(this);
366 
367  UtUsersContainer_t::const_iterator it = m_utUsers.find(ut);
368 
369  if (it == m_utUsers.end())
370  {
371  NS_FATAL_ERROR("UT which user count is requested in not installed!!!");
372  }
373 
374  return it->second.GetN();
375 }
376 
377 Ptr<Node>
378 SatUserHelper::GetUtNode(Ptr<Node> utUserNode) const
379 {
380  std::map<Ptr<Node>, Ptr<Node>>::const_iterator it = m_utMap.find(utUserNode);
381 
382  if (it == m_utMap.end())
383  {
384  return 0;
385  }
386  else
387  {
388  return it->second;
389  }
390 }
391 
392 NodeContainer
394 {
395  NodeContainer nodes;
396  for (auto& nodeInfo : m_utUsers)
397  {
398  nodes.Add(nodeInfo.first);
399  }
400 
401  return nodes;
402 }
403 
404 void
405 SatUserHelper::EnableCreationTraces(Ptr<OutputStreamWrapper> stream, CallbackBase& cb)
406 {
407  NS_LOG_FUNCTION(this);
408 
409  TraceConnect("Creation", "SatUserHelper", cb);
410 }
411 
412 void
413 SatUserHelper::InstallRouter(NodeContainer gw, Ptr<Node> router)
414 {
415  NS_LOG_FUNCTION(this);
416 
417  for (NodeContainer::Iterator i = gw.Begin(); i != gw.End(); i++)
418  {
419  NodeContainer gwRouter = NodeContainer((*i), router);
420 
421  NetDeviceContainer nd = InstallBackboneNetwork(gwRouter);
422  Ipv4InterfaceContainer addresses = m_ipv4Gw.Assign(nd);
423  Ipv4StaticRoutingHelper ipv4RoutingHelper;
424 
425  // Get IPv4 protocol implementations
426  Ptr<Ipv4> ipv4Gw = (*i)->GetObject<Ipv4>();
427  uint32_t lastGwIf = ipv4Gw->GetNInterfaces() - 1;
428  Ptr<Ipv4StaticRouting> routingGw = ipv4RoutingHelper.GetStaticRouting(ipv4Gw);
429  routingGw->SetDefaultRoute(addresses.GetAddress(1), lastGwIf);
430  NS_LOG_INFO("GW default route: " << addresses.GetAddress(1));
431 
432  for (uint32_t routeIndex = 0; routeIndex < routingGw->GetNRoutes(); routeIndex++)
433  {
434  // Get IPv4 protocol implementations
435  Ptr<Ipv4> ipv4Router = router->GetObject<Ipv4>();
436  uint32_t lastRouterIf = ipv4Router->GetNInterfaces() - 1;
437  Ptr<Ipv4StaticRouting> routingRouter = ipv4RoutingHelper.GetStaticRouting(ipv4Router);
438 
439  Ipv4RoutingTableEntry route = routingGw->GetRoute(routeIndex);
440  uint32_t interface = route.GetInterface();
441 
442  // set only routes for interfaces created earlier (and not for local delivery index 0)
443  if ((interface != 0) && (interface != lastGwIf))
444  {
445  routingRouter->AddNetworkRouteTo(route.GetDest(),
446  route.GetDestNetworkMask(),
447  addresses.GetAddress(0),
448  lastRouterIf);
449  NS_LOG_INFO("Router network route:" << route.GetDest() << ", "
450  << route.GetDestNetworkMask() << ", "
451  << addresses.GetAddress(0));
452  }
453  }
454 
455  m_ipv4Gw.NewNetwork();
456  }
457 }
458 
459 NetDeviceContainer
460 SatUserHelper::InstallSubscriberNetwork(const NodeContainer& c) const
461 {
462  NS_LOG_FUNCTION(this);
463 
464  NetDeviceContainer devs;
465 
466  switch (m_subscriberNetworkType)
467  {
469  devs = InstallSatSimpleNetwork(c);
470  break;
471 
472  case NETWORK_TYPE_CSMA:
473  devs = m_csma.Install(c);
474  break;
475 
476  default:
477  NS_ASSERT(false);
478  break;
479  }
480 
481  return devs;
482 }
483 
484 NetDeviceContainer
485 SatUserHelper::InstallBackboneNetwork(const NodeContainer& c) const
486 {
487  NS_LOG_FUNCTION(this);
488 
489  NetDeviceContainer devs;
490 
491  switch (m_backboneNetworkType)
492  {
494  devs = InstallSatSimpleNetwork(c);
495  break;
496 
497  case NETWORK_TYPE_CSMA:
498  devs = m_csma.Install(c);
499  break;
500 
501  default:
502  NS_ASSERT(false);
503  break;
504  }
505 
506  return devs;
507 }
508 
509 NetDeviceContainer
510 SatUserHelper::InstallSatSimpleNetwork(const NodeContainer& c) const
511 {
512  NS_LOG_FUNCTION(this);
513 
514  NetDeviceContainer devs;
515  Ptr<SatSimpleChannel> channel = CreateObject<SatSimpleChannel>();
516 
517  for (NodeContainer::Iterator i = c.Begin(); i != c.End(); i++)
518  {
519  Ptr<SatSimpleNetDevice> device = CreateObject<SatSimpleNetDevice>();
520  device->SetAddress(Mac48Address::Allocate());
521  (*i)->AddDevice(device);
522  device->SetChannel(channel);
523  devs.Add(device);
524  }
525 
526  return devs;
527 }
528 
529 std::string
531 {
532  NS_LOG_FUNCTION(this);
533 
534  std::ostringstream oss;
535 
536  Address devAddress;
537  Ptr<Ipv4> ipv4 = m_router->GetObject<Ipv4>(); // Get Ipv4 instance of the node
538 
539  std::vector<Ipv4Address> IPAddressVector;
540  std::vector<std::string> devNameVector;
541  std::vector<Address> devAddressVector;
542 
543  oss << "--- Router info ---" << std::endl << std::endl;
544 
545  for (uint32_t j = 0; j < m_router->GetNDevices(); j++)
546  {
547  Ptr<NetDevice> device = m_router->GetDevice(j);
548 
549  oss << device->GetInstanceTypeId().GetName() << " ";
550  oss << device->GetAddress() << " ";
551  oss << ipv4->GetAddress(j, 0).GetLocal() << " ";
552  }
553 
554  return oss.str();
555 }
556 
557 Ptr<Node>
559 {
560  NS_LOG_FUNCTION(this);
561 
562  return m_router;
563 }
564 
565 void
567  NetDeviceContainer utNd,
568  Ptr<Node> gw,
569  Ptr<NetDevice> gwNd)
570 {
571  Ipv4InterfaceContainer gwAddress = m_ipv4Beam.Assign(gwNd);
572  Ipv4Address gwAddr = gwAddress.GetAddress(0);
573  NS_LOG_FUNCTION(this << gw << gwNd << gwAddr);
574 
575  Ipv4InterfaceContainer utIfs = m_ipv4Beam.Assign(utNd);
576 
577  Ipv4StaticRoutingHelper ipv4RoutingHelper;
578  Ptr<Ipv4L3Protocol> ipv4Gw = gw->GetObject<Ipv4L3Protocol>();
579  Ptr<Ipv4StaticRouting> srGw = ipv4RoutingHelper.GetStaticRouting(ipv4Gw);
580 
581  // Store GW NetDevice for updating routing during handover
582  m_gwDevices.insert(std::make_pair(gwNd->GetAddress(), gwNd));
583 
584  // Create an ARP entry of the default GW for the UTs in this beam
585  Address macAddressGw = gwNd->GetAddress();
586  Ptr<SatArpCache> utArpCache = CreateObject<SatArpCache>();
587  utArpCache->Add(gwAddr, macAddressGw);
588  NS_LOG_INFO("UT ARP entry: " << gwAddr << " - " << macAddressGw);
589  // Store ARP cache for retrieval during handovers
590  m_arpCachesToGateway.emplace(macAddressGw, utArpCache);
591 
592  // Add the ARP entries of all the UTs in this beam
593  // - MAC address vs. IPv4 address
594  Ptr<SatArpCache> gwArpCache = CreateObject<SatArpCache>();
595  for (uint32_t i = 0; i < utIfs.GetN(); ++i)
596  {
597  NS_ASSERT(utIfs.GetN() == utNd.GetN());
598  Ptr<NetDevice> nd = utNd.Get(i);
599  Ipv4Address ipv4Addr = utIfs.GetAddress(i);
600  gwArpCache->Add(ipv4Addr, nd->GetAddress());
601  NS_LOG_INFO("GW ARP entry: " << ipv4Addr << " - " << nd->GetAddress());
602  // Store UT NetDevice for updating routing during handover
603  m_utDevices.insert(std::make_pair(nd->GetAddress(), nd));
604  }
605 
606  // Set the ARP cache to the proper GW IPv4Interface (the one for satellite
607  // link). ARP cache contains the entries for all UTs within this spot-beam.
608  ipv4Gw->GetInterface(gwNd->GetIfIndex())->SetArpCache(gwArpCache);
609  NS_LOG_INFO("Add ARP cache to GW " << gw->GetId());
610 
611  uint32_t utAddressIndex = 0;
612 
613  for (NodeContainer::Iterator i = ut.Begin(); i != ut.End(); i++)
614  {
615  Ptr<Ipv4L3Protocol> ipv4Ut = (*i)->GetObject<Ipv4L3Protocol>();
616 
617  uint32_t count = ipv4Ut->GetNInterfaces();
618 
619  for (uint32_t j = 1; j < count; j++)
620  {
621  std::string devName = ipv4Ut->GetNetDevice(j)->GetInstanceTypeId().GetName();
622 
623  // If SatNetDevice interface, add default route to towards GW of the beam on UTs
624  if (devName == "ns3::SatNetDevice" || devName == "ns3::SatLorawanNetDevice")
625  {
626  Ptr<Ipv4StaticRouting> srUt = ipv4RoutingHelper.GetStaticRouting(ipv4Ut);
627  srUt->SetDefaultRoute(gwAddr, j);
628  NS_LOG_INFO("UT default route: " << gwAddr);
629 
630  // Set the ARP cache (including the ARP entry for the default GW) to the UT
631  ipv4Ut->GetInterface(j)->SetArpCache(utArpCache);
632  NS_LOG_INFO("Add the ARP cache to UT " << (*i)->GetId());
633  }
634  else // add other interface route to GW's Satellite interface
635  {
636  Ipv4Address address = ipv4Ut->GetAddress(j, 0).GetLocal();
637  Ipv4Mask mask = ipv4Ut->GetAddress(j, 0).GetMask();
638 
639  srGw->AddNetworkRouteTo(address.CombineMask(mask),
640  mask,
641  utIfs.GetAddress(utAddressIndex),
642  gwNd->GetIfIndex());
643  NS_LOG_INFO("GW Network route: " << address.CombineMask(mask) << ", " << mask
644  << ", " << utIfs.GetAddress(utAddressIndex));
645  }
646  }
647 
648  utAddressIndex++;
649  }
650 
651  m_ipv4Beam.NewNetwork();
652 }
653 
654 void
655 SatUserHelper::UpdateUtRoutes(Address utAddress, Address gwAddress)
656 {
657  NS_LOG_FUNCTION(this << utAddress << gwAddress);
658 
659  std::map<Address, Ptr<NetDevice>>::iterator gwNdIterator = m_gwDevices.find(gwAddress);
660  NS_ASSERT_MSG(gwNdIterator != m_gwDevices.end(), "Unknown GW with MAC address " << gwAddress);
661 
662  Ptr<SatNetDevice> gwNd = DynamicCast<SatNetDevice>(gwNdIterator->second);
663  NS_ASSERT(gwNd != NULL);
664  Ipv4Address ip =
665  gwNd->GetNode()->GetObject<Ipv4L3Protocol>()->GetAddress(gwNd->GetIfIndex(), 0).GetLocal();
666 
667  std::map<Address, Ptr<NetDevice>>::iterator utNdIterator = m_utDevices.find(utAddress);
668  NS_ASSERT_MSG(utNdIterator != m_utDevices.end(), "Unknown UT with MAC address " << utAddress);
669 
670  std::map<Address, Ptr<SatArpCache>>::iterator arpCacheIterator =
671  m_arpCachesToGateway.find(gwAddress);
672  NS_ASSERT_MSG(arpCacheIterator != m_arpCachesToGateway.end(),
673  "ARP cache not found to gateway " << gwAddress);
674 
675  Ptr<SatNetDevice> utNd = DynamicCast<SatNetDevice>(utNdIterator->second);
676  NS_ASSERT(utNd != NULL);
677  Ptr<Ipv4L3Protocol> protocol = utNd->GetNode()->GetObject<Ipv4L3Protocol>();
678  uint32_t utIfIndex = utNdIterator->second->GetIfIndex();
679 
680  NS_LOG_INFO("Changing ARP cache for UT " << utAddress << " pointing to " << ip << " through "
681  << gwAddress);
682  protocol->GetInterface(utIfIndex)->SetArpCache(arpCacheIterator->second);
683 
684  Ipv4StaticRoutingHelper ipv4RoutingHelper;
685  Ptr<Ipv4StaticRouting> routing = ipv4RoutingHelper.GetStaticRouting(protocol);
686  routing->SetDefaultRoute(ip, utIfIndex);
687 
688  uint32_t satId = gwNd->GetMac()->GetSatId();
689  uint32_t beamId = gwNd->GetMac()->GetBeamId();
690  Ptr<PropagationDelayModel> flDelayModel =
692  Ptr<PropagationDelayModel> ulDelayModel =
694  Ptr<SatMobilityObserver> observer = utNd->GetNode()->GetObject<SatMobilityObserver>();
695  observer->ObserveTimingAdvance(ulDelayModel,
696  flDelayModel,
697  gwNd->GetNode()->GetObject<SatMobilityModel>());
698 }
699 
700 void
701 SatUserHelper::UpdateGwRoutes(Address ut, Address oldGateway, Address newGateway)
702 {
703  NS_LOG_FUNCTION(this << ut << oldGateway << newGateway);
704 
705  std::map<Address, Ptr<NetDevice>>::iterator utNdIterator = m_utDevices.find(ut);
706  if (utNdIterator == m_utDevices.end())
707  {
708  NS_FATAL_ERROR("Unknown UT with MAC address " << ut);
709  }
710 
711  std::map<Address, Ptr<NetDevice>>::iterator oldGwNdIterator = m_gwDevices.find(oldGateway);
712  if (oldGwNdIterator == m_gwDevices.end())
713  {
714  NS_FATAL_ERROR("Unknown GW with MAC address " << oldGateway);
715  }
716 
717  std::map<Address, Ptr<NetDevice>>::iterator newGwNdIterator = m_gwDevices.find(newGateway);
718  if (newGwNdIterator == m_gwDevices.end())
719  {
720  NS_FATAL_ERROR("Unknown GW with MAC address " << newGateway);
721  }
722 
723  uint32_t utIfIndex = utNdIterator->second->GetIfIndex();
724  Ptr<Ipv4L3Protocol> utProtocol = utNdIterator->second->GetNode()->GetObject<Ipv4L3Protocol>();
725  Ipv4Address utIpAddress = utProtocol->GetAddress(utIfIndex, 0).GetLocal();
726 
727  Ptr<Node> oldGatewayNode = oldGwNdIterator->second->GetNode();
728  uint32_t oldIfIndex = oldGwNdIterator->second->GetIfIndex();
729  Ptr<Node> newGatewayNode = newGwNdIterator->second->GetNode();
730  uint32_t newIfIndex = newGwNdIterator->second->GetIfIndex();
731 
732  Ptr<ArpCache> arpCache;
733  // Clear old ARP cache
734  arpCache = oldGatewayNode->GetObject<Ipv4L3Protocol>()->GetInterface(oldIfIndex)->GetArpCache();
735  for (ArpCache::Entry* entry : arpCache->LookupInverse(ut))
736  {
737  arpCache->Remove(entry);
738  }
739  // Add entry in new ARP cache
740  arpCache = newGatewayNode->GetObject<Ipv4L3Protocol>()->GetInterface(newIfIndex)->GetArpCache();
741  ArpCache::Entry* entry = arpCache->Add(utIpAddress);
742  entry->SetMacAddress(ut);
743  entry->MarkPermanent();
744 
745  // Change routes on GW
746  Ipv4StaticRoutingHelper ipv4RoutingHelper;
747  if (oldGatewayNode == newGatewayNode)
748  {
749  // intra-GW handover
750  Ptr<Ipv4StaticRouting> routing =
751  ipv4RoutingHelper.GetStaticRouting(oldGatewayNode->GetObject<Ipv4L3Protocol>());
752 
753  // purge old routes
754  for (uint32_t routeIndex = routing->GetNRoutes(); routeIndex > 0; --routeIndex)
755  {
756  // Note: keeping routeIndex 1-off because we are using unsigned values
757  if (routing->GetRoute(routeIndex - 1).GetGateway() == utIpAddress)
758  {
759  routing->RemoveRoute(routeIndex - 1);
760  }
761  }
762 
763  // add new ones
764  for (uint32_t ifIndex = 1; ifIndex < utProtocol->GetNInterfaces(); ++ifIndex)
765  {
766  Ipv4Address address = utProtocol->GetAddress(ifIndex, 0).GetLocal();
767  Ipv4Mask mask = utProtocol->GetAddress(ifIndex, 0).GetMask();
768 
769  if (ifIndex == utIfIndex)
770  {
771  mask = Ipv4Mask("/32");
772  }
773 
774  routing->AddNetworkRouteTo(address.CombineMask(mask), mask, utIpAddress, newIfIndex);
775  }
776  }
777  else
778  {
779  // inter-GW handover
780  Ptr<Ipv4StaticRouting> routing =
781  ipv4RoutingHelper.GetStaticRouting(oldGatewayNode->GetObject<Ipv4L3Protocol>());
782  Ptr<Ipv4StaticRouting> routingRouter =
783  ipv4RoutingHelper.GetStaticRouting(m_router->GetObject<Ipv4L3Protocol>());
784 
785  // purge old routes
786  for (uint32_t routeIndex = routing->GetNRoutes(); routeIndex > 0; --routeIndex)
787  {
788  // Note: keeping routeIndex 1-off because we are using unsigned values
789  Ipv4RoutingTableEntry gwRoute = routing->GetRoute(routeIndex - 1);
790  if (gwRoute.GetGateway() == utIpAddress)
791  {
792  routing->RemoveRoute(routeIndex - 1);
793  // search for corresponding route on terrestrial router
794  for (uint32_t routerIndex = 0; routerIndex < routingRouter->GetNRoutes();
795  ++routerIndex)
796  {
797  Ipv4RoutingTableEntry route = routingRouter->GetRoute(routerIndex);
798  if (route.GetDestNetwork() == gwRoute.GetDestNetwork() &&
799  route.GetDestNetworkMask() == gwRoute.GetDestNetworkMask())
800  {
801  routingRouter->RemoveRoute(routerIndex);
802  break;
803  }
804  }
805  }
806  }
807 
808  // add new ones
809  Ptr<Ipv4L3Protocol> gwProtocol = newGatewayNode->GetObject<Ipv4L3Protocol>();
810 
811  // start by looking up GW IP as seen by the terrestrial router
812  Ipv4Address gwAddress;
813  for (uint32_t ifIndex = 1; ifIndex < gwProtocol->GetNInterfaces(); ++ifIndex)
814  {
815  Ptr<NetDevice> gwNd = gwProtocol->GetNetDevice(ifIndex);
816  if (gwNd->GetInstanceTypeId().GetName() != "ns3::SatNetDevice" &&
817  gwNd->GetInstanceTypeId().GetName() != "ns3::SatLorawanNetDevice")
818  {
819  gwAddress = gwProtocol->GetAddress(ifIndex, 0).GetLocal();
820  break;
821  }
822  }
823 
824  // find interface on the terrestrial router to send messages to GW
825  uint32_t routingIfIndex = routingRouter->GetNRoutes();
826  for (uint32_t routeIndex = 0; routeIndex < routingRouter->GetNRoutes(); ++routeIndex)
827  {
828  Ipv4RoutingTableEntry route = routingRouter->GetRoute(routeIndex);
829  if (route.GetGateway() == gwAddress)
830  {
831  routingIfIndex = route.GetInterface();
832  break;
833  }
834  }
835 
836  NS_ASSERT_MSG(routingIfIndex != routingRouter->GetNRoutes(),
837  "Couldn't find interface on the terrestrial router to the new gateway.");
838 
839  // add routes to the new GW and the terrestrial router
840  routing = ipv4RoutingHelper.GetStaticRouting(gwProtocol);
841  for (uint32_t ifIndex = 1; ifIndex < utProtocol->GetNInterfaces(); ++ifIndex)
842  {
843  Ipv4Address address = utProtocol->GetAddress(ifIndex, 0).GetLocal();
844  Ipv4Mask mask = utProtocol->GetAddress(ifIndex, 0).GetMask();
845 
846  if (ifIndex == utIfIndex)
847  {
848  mask = Ipv4Mask("/32");
849  }
850 
851  routing->AddNetworkRouteTo(address.CombineMask(mask), mask, utIpAddress, newIfIndex);
852  routingRouter->AddNetworkRouteTo(address.CombineMask(mask),
853  mask,
854  gwAddress,
855  routingIfIndex);
856  }
857  }
858 }
859 
860 } // 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
NodeContainer GetUtNodes() const
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...
uint32_t GetGwUserCount() const
NodeContainer GetGwUsers() const
void SetBeamBaseAddress(const Ipv4Address &network, const Ipv4Mask &mask, Ipv4Address base="0.0.0.1")
NodeContainer GetUtUsers() const
NetDeviceContainer InstallSatSimpleNetwork(const NodeContainer &c) const
Install satellite simple network.
static TypeId GetTypeId(void)
Derived from Object.
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.
Ptr< Node > GetUtNode(Ptr< Node > utUserNode) const
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 InstallRouter(NodeContainer gw, Ptr< Node > router)
Install IP router to to Gateways.
void EnableCreationTraces(Ptr< OutputStreamWrapper > stream, CallbackBase &cb)
Enables creation traces to be written in given file.
NodeContainer InstallGw(NodeContainer gw, uint32_t users)
NetDeviceContainer InstallBackboneNetwork(const NodeContainer &c) const
Install network between GW and Router (or users) or Router and its users.
UtUsersContainer_t m_utUsers
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
uint32_t GetUtUserCount() 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.