1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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  * Authors: Manuel Requena <manuel.requena@cttc.es>
19  */
20 
21 #include "ns3/core-module.h"
22 #include "ns3/network-module.h"
23 #include "ns3/point-to-point-module.h"
24 #include "ns3/internet-module.h"
25 #include "ns3/applications-module.h"
26 #include "ns3/mobility-module.h"
27 #include "ns3/config-store-module.h"
28 #include "ns3/lte-module.h"
29 // #include "ns3/gtk-config-store.h"
30 
31 using namespace ns3;
32 
33 /**
34  * Sample simulation script for LTE+EPC with different backhauls.
35  *
36  * The purpose of this example is to compare:
37  *
38  *  (1) how the simulation user can use a pre-existing EpcHelper that builds
39  *      a predefined backhaul network (e.g. the PointToPointEpcHelper) and
40  *
41  *  (2) how the simulation user can build its custom backhaul network in
42  *      the simulation program (i.e. the point-to-point links are created
43  *      in the simulation program instead of the pre-existing PointToPointEpcHelper)
44  *
45  * The pre-existing PointToPointEpcHelper is used with option --useHelper=1 and
46  * the custom backhaul is built with option --useHelper=0
47  */
48 
49 NS_LOG_COMPONENT_DEFINE ("LenaSimpleEpcBackhaul");
50 
51 int
main(int argc,char * argv[])52 main (int argc, char *argv[])
53 {
54   uint16_t numNodePairs = 2;
55   Time simTime = MilliSeconds (1900);
56   double distance = 60.0;
57   Time interPacketInterval = MilliSeconds (100);
58   bool disableDl = false;
59   bool disableUl = false;
60   bool useHelper = false;
61 
62   // Command line arguments
63   CommandLine cmd (__FILE__);
64   cmd.AddValue ("numNodePairs", "Number of eNodeBs + UE pairs", numNodePairs);
65   cmd.AddValue ("simTime", "Total duration of the simulation", simTime);
66   cmd.AddValue ("distance", "Distance between eNBs [m]", distance);
67   cmd.AddValue ("interPacketInterval", "Inter packet interval", interPacketInterval);
68   cmd.AddValue ("disableDl", "Disable downlink data flows", disableDl);
69   cmd.AddValue ("disableUl", "Disable uplink data flows", disableUl);
70   cmd.AddValue ("useHelper", "Build the backhaul network using the helper or "
71                              "it is built in the example", useHelper);
72   cmd.Parse (argc, argv);
73 
74   ConfigStore inputConfig;
75   inputConfig.ConfigureDefaults ();
76 
77   // parse again so you can override default values from the command line
78   cmd.Parse(argc, argv);
79 
80   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
81   Ptr<EpcHelper> epcHelper;
82   if (!useHelper)
83     {
84       epcHelper = CreateObject<NoBackhaulEpcHelper> ();
85     }
86   else
87     {
88       epcHelper = CreateObject<PointToPointEpcHelper> ();
89     }
90   lteHelper->SetEpcHelper (epcHelper);
91 
92   Ptr<Node> pgw = epcHelper->GetPgwNode ();
93 
94   // Create a single RemoteHost
95   NodeContainer remoteHostContainer;
96   remoteHostContainer.Create (1);
97   Ptr<Node> remoteHost = remoteHostContainer.Get (0);
98   InternetStackHelper internet;
99   internet.Install (remoteHostContainer);
100 
101   // Create the Internet
102   PointToPointHelper p2ph;
103   p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
104   p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
105   p2ph.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
106   NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
107   Ipv4AddressHelper ipv4h;
108   ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
109   Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
110   // interface 0 is localhost, 1 is the p2p device
111   Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
112 
113   Ipv4StaticRoutingHelper ipv4RoutingHelper;
114   Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
115   remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
116 
117   NodeContainer ueNodes;
118   NodeContainer enbNodes;
119   enbNodes.Create (numNodePairs);
120   ueNodes.Create (numNodePairs);
121 
122   // Install Mobility Model for eNBs and UEs
123   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
124   for (uint16_t i = 0; i < numNodePairs; i++)
125     {
126       positionAlloc->Add (Vector (distance * i, 0, 0));
127     }
128   MobilityHelper mobility;
129   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
130   mobility.SetPositionAllocator (positionAlloc);
131   mobility.Install (enbNodes);
132   mobility.Install (ueNodes);
133 
134   // SGW node
135   Ptr<Node> sgw = epcHelper->GetSgwNode ();
136 
137   // Install Mobility Model for SGW
138   Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator> ();
139   positionAlloc2->Add (Vector (0.0,  50.0, 0.0));
140   MobilityHelper mobility2;
141   mobility2.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
142   mobility2.SetPositionAllocator (positionAlloc2);
143   mobility2.Install (sgw);
144 
145   // Install LTE Devices to the nodes
146   NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes);
147   NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes);
148 
149   if (!useHelper)
150     {
151       Ipv4AddressHelper s1uIpv4AddressHelper;
152 
153       // Create networks of the S1 interfaces
154       s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252");
155 
156       for (uint16_t i = 0; i < numNodePairs; ++i)
157         {
158           Ptr<Node> enb = enbNodes.Get (i);
159 
160           // Create a point to point link between the eNB and the SGW with
161           // the corresponding new NetDevices on each side
162           PointToPointHelper p2ph;
163           DataRate s1uLinkDataRate = DataRate ("10Gb/s");
164           uint16_t s1uLinkMtu = 2000;
165           Time s1uLinkDelay = Time (0);
166           p2ph.SetDeviceAttribute ("DataRate", DataRateValue (s1uLinkDataRate));
167           p2ph.SetDeviceAttribute ("Mtu", UintegerValue (s1uLinkMtu));
168           p2ph.SetChannelAttribute ("Delay", TimeValue (s1uLinkDelay));
169           NetDeviceContainer sgwEnbDevices = p2ph.Install (sgw, enb);
170 
171           Ipv4InterfaceContainer sgwEnbIpIfaces = s1uIpv4AddressHelper.Assign (sgwEnbDevices);
172           s1uIpv4AddressHelper.NewNetwork ();
173 
174           Ipv4Address sgwS1uAddress = sgwEnbIpIfaces.GetAddress (0);
175           Ipv4Address enbS1uAddress = sgwEnbIpIfaces.GetAddress (1);
176 
177           // Create S1 interface between the SGW and the eNB
178           epcHelper->AddS1Interface (enb, enbS1uAddress, sgwS1uAddress);
179         }
180     }
181 
182   // Install the IP stack on the UEs
183   internet.Install (ueNodes);
184   Ipv4InterfaceContainer ueIpIface;
185   ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs));
186   // Assign IP address to UEs, and install applications
187   for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
188     {
189       Ptr<Node> ueNode = ueNodes.Get (u);
190       // Set the default gateway for the UE
191       Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
192       ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
193     }
194 
195   // Attach one UE per eNodeB
196   for (uint16_t i = 0; i < numNodePairs; i++)
197     {
198       lteHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i));
199       // side effect: the default EPS bearer will be activated
200     }
201 
202 
203   // Install and start applications on UEs and remote host
204   uint16_t dlPort = 1100;
205   uint16_t ulPort = 2000;
206   ApplicationContainer clientApps;
207   ApplicationContainer serverApps;
208   for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
209     {
210       if (!disableDl)
211         {
212           PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
213           serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u)));
214 
215           UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort);
216           dlClient.SetAttribute ("Interval", TimeValue (interPacketInterval));
217           dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
218           clientApps.Add (dlClient.Install (remoteHost));
219         }
220 
221       if (!disableUl)
222         {
223           ++ulPort;
224           PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
225           serverApps.Add (ulPacketSinkHelper.Install (remoteHost));
226 
227           UdpClientHelper ulClient (remoteHostAddr, ulPort);
228           ulClient.SetAttribute ("Interval", TimeValue (interPacketInterval));
229           ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
230           clientApps.Add (ulClient.Install (ueNodes.Get(u)));
231         }
232     }
233 
234   serverApps.Start (MilliSeconds (500));
235   clientApps.Start (MilliSeconds (500));
236   lteHelper->EnableTraces ();
237   // Uncomment to enable PCAP tracing
238   //p2ph.EnablePcapAll("lena-simple-epc-backhaul");
239 
240   Simulator::Stop (simTime);
241   Simulator::Run ();
242 
243   /*GtkConfigStore config;
244   config.ConfigureAttributes();*/
245 
246   Simulator::Destroy ();
247   return 0;
248 }
249