A Discrete-Event Network Simulator
API
lena-x2-handover.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012-2018 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  * Author: Manuel Requena <manuel.requena@cttc.es>
19  */
20 
21 #include "ns3/core-module.h"
22 #include "ns3/network-module.h"
23 #include "ns3/internet-module.h"
24 #include "ns3/mobility-module.h"
25 #include "ns3/lte-module.h"
26 #include "ns3/applications-module.h"
27 #include "ns3/point-to-point-module.h"
28 #include "ns3/config-store-module.h"
29 
30 using namespace ns3;
31 
32 NS_LOG_COMPONENT_DEFINE ("LenaX2HandoverExample");
33 
34 void
35 NotifyConnectionEstablishedUe (std::string context,
36  uint64_t imsi,
37  uint16_t cellid,
38  uint16_t rnti)
39 {
40  std::cout << Simulator::Now ().As (Time::S) << " " << context
41  << " UE IMSI " << imsi
42  << ": connected to CellId " << cellid
43  << " with RNTI " << rnti
44  << std::endl;
45 }
46 
47 void
48 NotifyHandoverStartUe (std::string context,
49  uint64_t imsi,
50  uint16_t cellid,
51  uint16_t rnti,
52  uint16_t targetCellId)
53 {
54  std::cout << Simulator::Now ().As (Time::S) << " " << context
55  << " UE IMSI " << imsi
56  << ": previously connected to CellId " << cellid
57  << " with RNTI " << rnti
58  << ", doing handover to CellId " << targetCellId
59  << std::endl;
60 }
61 
62 void
63 NotifyHandoverEndOkUe (std::string context,
64  uint64_t imsi,
65  uint16_t cellid,
66  uint16_t rnti)
67 {
68  std::cout << Simulator::Now ().As (Time::S) << " " << context
69  << " UE IMSI " << imsi
70  << ": successful handover to CellId " << cellid
71  << " with RNTI " << rnti
72  << std::endl;
73 }
74 
75 void
76 NotifyConnectionEstablishedEnb (std::string context,
77  uint64_t imsi,
78  uint16_t cellid,
79  uint16_t rnti)
80 {
81  std::cout << Simulator::Now ().As (Time::S) << " " << context
82  << " eNB CellId " << cellid
83  << ": successful connection of UE with IMSI " << imsi
84  << " RNTI " << rnti
85  << std::endl;
86 }
87 
88 void
89 NotifyHandoverStartEnb (std::string context,
90  uint64_t imsi,
91  uint16_t cellid,
92  uint16_t rnti,
93  uint16_t targetCellId)
94 {
95  std::cout << Simulator::Now ().As (Time::S) << " " << context
96  << " eNB CellId " << cellid
97  << ": start handover of UE with IMSI " << imsi
98  << " RNTI " << rnti
99  << " to CellId " << targetCellId
100  << std::endl;
101 }
102 
103 void
104 NotifyHandoverEndOkEnb (std::string context,
105  uint64_t imsi,
106  uint16_t cellid,
107  uint16_t rnti)
108 {
109  std::cout << Simulator::Now ().As (Time::S) << " " << context
110  << " eNB CellId " << cellid
111  << ": completed handover of UE with IMSI " << imsi
112  << " RNTI " << rnti
113  << std::endl;
114 }
115 
116 
122 int
123 main (int argc, char *argv[])
124 {
125  // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
126 
127  // LogComponentEnable ("LteHelper", logLevel);
128  // LogComponentEnable ("EpcHelper", logLevel);
129  // LogComponentEnable ("EpcEnbApplication", logLevel);
130  // LogComponentEnable ("EpcMmeApplication", logLevel);
131  // LogComponentEnable ("EpcPgwApplication", logLevel);
132  // LogComponentEnable ("EpcSgwApplication", logLevel);
133  // LogComponentEnable ("EpcX2", logLevel);
134 
135  // LogComponentEnable ("LteEnbRrc", logLevel);
136  // LogComponentEnable ("LteEnbNetDevice", logLevel);
137  // LogComponentEnable ("LteUeRrc", logLevel);
138  // LogComponentEnable ("LteUeNetDevice", logLevel);
139 
140  uint16_t numberOfUes = 1;
141  uint16_t numberOfEnbs = 2;
142  uint16_t numBearersPerUe = 2;
143  Time simTime = MilliSeconds (490);
144  double distance = 100.0;
145  bool disableDl = false;
146  bool disableUl = false;
147 
148  // change some default attributes so that they are reasonable for
149  // this scenario, but do this before processing command line
150  // arguments, so that the user is allowed to override these settings
151  Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (MilliSeconds (10)));
152  Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue (1000000));
153  Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (false));
154 
155  // Command line arguments
156  CommandLine cmd (__FILE__);
157  cmd.AddValue ("numberOfUes", "Number of UEs", numberOfUes);
158  cmd.AddValue ("numberOfEnbs", "Number of eNodeBs", numberOfEnbs);
159  cmd.AddValue ("simTime", "Total duration of the simulation", simTime);
160  cmd.AddValue ("disableDl", "Disable downlink data flows", disableDl);
161  cmd.AddValue ("disableUl", "Disable uplink data flows", disableUl);
162  cmd.Parse (argc, argv);
163 
164 
165  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
166  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
167  lteHelper->SetEpcHelper (epcHelper);
168  lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
169  lteHelper->SetHandoverAlgorithmType ("ns3::NoOpHandoverAlgorithm"); // disable automatic handover
170 
171  Ptr<Node> pgw = epcHelper->GetPgwNode ();
172 
173  // Create a single RemoteHost
174  NodeContainer remoteHostContainer;
175  remoteHostContainer.Create (1);
176  Ptr<Node> remoteHost = remoteHostContainer.Get (0);
177  InternetStackHelper internet;
178  internet.Install (remoteHostContainer);
179 
180  // Create the Internet
181  PointToPointHelper p2ph;
182  p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
183  p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
184  p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
185  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
186  Ipv4AddressHelper ipv4h;
187  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
188  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
189  Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
190 
191 
192  // Routing of the Internet Host (towards the LTE network)
193  Ipv4StaticRoutingHelper ipv4RoutingHelper;
194  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
195  // interface 0 is localhost, 1 is the p2p device
196  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
197 
198  NodeContainer ueNodes;
199  NodeContainer enbNodes;
200  enbNodes.Create (numberOfEnbs);
201  ueNodes.Create (numberOfUes);
202 
203  // Install Mobility Model
204  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
205  for (uint16_t i = 0; i < numberOfEnbs; i++)
206  {
207  positionAlloc->Add (Vector (distance * 2 * i - distance, 0, 0));
208  }
209  for (uint16_t i = 0; i < numberOfUes; i++)
210  {
211  positionAlloc->Add (Vector (0, 0, 0));
212  }
214  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
215  mobility.SetPositionAllocator (positionAlloc);
216  mobility.Install (enbNodes);
217  mobility.Install (ueNodes);
218 
219  // Install LTE Devices in eNB and UEs
220  NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes);
221  NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes);
222 
223  // Install the IP stack on the UEs
224  internet.Install (ueNodes);
225  Ipv4InterfaceContainer ueIpIfaces;
226  ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs));
227 
228 
229  // Attach all UEs to the first eNodeB
230  for (uint16_t i = 0; i < numberOfUes; i++)
231  {
232  lteHelper->Attach (ueLteDevs.Get (i), enbLteDevs.Get (0));
233  }
234 
235 
236  NS_LOG_LOGIC ("setting up applications");
237 
238  // Install and start applications on UEs and remote host
239  uint16_t dlPort = 10000;
240  uint16_t ulPort = 20000;
241 
242  // randomize a bit start times to avoid simulation artifacts
243  // (e.g., buffer overflows due to packet transmissions happening
244  // exactly at the same time)
245  Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable> ();
246  startTimeSeconds->SetAttribute ("Min", DoubleValue (0.05));
247  startTimeSeconds->SetAttribute ("Max", DoubleValue (0.06));
248 
249  for (uint32_t u = 0; u < numberOfUes; ++u)
250  {
251  Ptr<Node> ue = ueNodes.Get (u);
252  // Set the default gateway for the UE
253  Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject<Ipv4> ());
254  ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
255 
256  for (uint32_t b = 0; b < numBearersPerUe; ++b)
257  {
260  Ptr<EpcTft> tft = Create<EpcTft> ();
261 
262  if (!disableDl)
263  {
264  ++dlPort;
265 
266  NS_LOG_LOGIC ("installing UDP DL app for UE " << u);
267  UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort);
268  clientApps.Add (dlClientHelper.Install (remoteHost));
269  PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory",
271  serverApps.Add (dlPacketSinkHelper.Install (ue));
272 
274  dlpf.localPortStart = dlPort;
275  dlpf.localPortEnd = dlPort;
276  tft->Add (dlpf);
277  }
278 
279  if (!disableUl)
280  {
281  ++ulPort;
282 
283  NS_LOG_LOGIC ("installing UDP UL app for UE " << u);
284  UdpClientHelper ulClientHelper (remoteHostAddr, ulPort);
285  clientApps.Add (ulClientHelper.Install (ue));
286  PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory",
288  serverApps.Add (ulPacketSinkHelper.Install (remoteHost));
289 
291  ulpf.remotePortStart = ulPort;
292  ulpf.remotePortEnd = ulPort;
293  tft->Add (ulpf);
294  }
295 
297  lteHelper->ActivateDedicatedEpsBearer (ueLteDevs.Get (u), bearer, tft);
298 
299  Time startTime = Seconds (startTimeSeconds->GetValue ());
300  serverApps.Start (startTime);
301  clientApps.Start (startTime);
302  clientApps.Stop (simTime);
303 
304  } // end for b
305  }
306 
307 
308  // Add X2 interface
309  lteHelper->AddX2Interface (enbNodes);
310 
311  // X2-based Handover
312  lteHelper->HandoverRequest (MilliSeconds (300), ueLteDevs.Get (0), enbLteDevs.Get (0), enbLteDevs.Get (1));
313 
314  // Uncomment to enable PCAP tracing
315  //p2ph.EnablePcapAll("lena-x2-handover");
316 
317  lteHelper->EnablePhyTraces ();
318  lteHelper->EnableMacTraces ();
319  lteHelper->EnableRlcTraces ();
320  lteHelper->EnablePdcpTraces ();
321  Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
322  rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.05)));
323  Ptr<RadioBearerStatsCalculator> pdcpStats = lteHelper->GetPdcpStats ();
324  pdcpStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.05)));
325 
326 
327  // connect custom trace sinks for RRC connection establishment and handover notification
328  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionEstablished",
330  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionEstablished",
332  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart",
334  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
336  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk",
338  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk",
340 
341 
342  Simulator::Stop (simTime + MilliSeconds (20));
343  Simulator::Run ();
344 
345  // GtkConfigStore config;
346  // config.ConfigureAttributes ();
347 
349  return 0;
350 }
holds a vector of ns3::Application pointers.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:229
Class for representing data rates.
Definition: data-rate.h:89
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:92
@ NGBR_VIDEO_TCP_DEFAULT
Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
Definition: eps-bearer.h:120
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Ipv4Address GetAny(void)
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
Ptr< RadioBearerStatsCalculator > GetPdcpStats(void)
Definition: lte-helper.cc:1586
void SetEpcHelper(Ptr< EpcHelper > h)
Set the EpcHelper to be used to setup the EPC network in conjunction with the setup of the LTE radio ...
Definition: lte-helper.cc:272
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Manually trigger an X2-based handover.
Definition: lte-helper.cc:1245
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:474
void SetHandoverAlgorithmType(std::string type)
Set the type of handover algorithm to be used by eNodeB devices.
Definition: lte-helper.cc:327
Ptr< RadioBearerStatsCalculator > GetRlcStats(void)
Definition: lte-helper.cc:1572
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:279
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:959
void EnableRlcTraces(void)
Enable trace sinks for RLC layer.
Definition: lte-helper.cc:1435
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:489
void EnablePhyTraces(void)
Enable trace sinks for PHY layer.
Definition: lte-helper.cc:1489
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1220
void EnablePdcpTraces(void)
Enable trace sinks for PDCP layer.
Definition: lte-helper.cc:1578
uint8_t ActivateDedicatedEpsBearer(NetDeviceContainer ueDevices, EpsBearer bearer, Ptr< EpcTft > tft)
Activate a dedicated EPS bearer on a given set of UE devices.
Definition: lte-helper.cc:1068
void EnableMacTraces(void)
Enable trace sinks for MAC layer.
Definition: lte-helper.cc:1529
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
virtual Ipv4Address GetUeDefaultGatewayAddress()
virtual Ptr< Node > GetPgwNode() const
Get the PGW node.
virtual Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Assign IPv4 addresses to UE devices.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
AttributeValue implementation for Time.
Definition: nstime.h:1308
Create a client application which sends UDP packets carrying a 32bit sequence number and a 64 bit tim...
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
void NotifyHandoverEndOkUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void NotifyConnectionEstablishedUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void NotifyHandoverStartUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
void NotifyHandoverStartEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
void NotifyConnectionEstablishedEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void NotifyHandoverEndOkEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
serverApps
Definition: first.py:52
clientApps
Definition: first.py:61
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
cmd
Definition: second.py:35
mobility
Definition: third.py:108
Implement the data structure representing a TrafficFlowTemplate Packet Filter.
Definition: epc-tft.h:75
uint16_t localPortEnd
end of the port number range of the UE
Definition: epc-tft.h:140
uint16_t remotePortEnd
end of the port number range of the remote host
Definition: epc-tft.h:138
uint16_t remotePortStart
start of the port number range of the remote host
Definition: epc-tft.h:137
uint16_t localPortStart
start of the port number range of the UE
Definition: epc-tft.h:139
double startTime