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