A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lena-x2-handover.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2018 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Manuel Requena <manuel.requena@cttc.es>
18 */
19
20#include "ns3/applications-module.h"
21#include "ns3/core-module.h"
22#include "ns3/internet-module.h"
23#include "ns3/lte-module.h"
24#include "ns3/mobility-module.h"
25#include "ns3/network-module.h"
26#include "ns3/point-to-point-module.h"
27// #include "ns3/gtk-config-store.h"
28
29using namespace ns3;
30
31NS_LOG_COMPONENT_DEFINE("LenaX2HandoverExample");
32
33/**
34 * UE Connection established notification.
35 *
36 * \param context The context.
37 * \param imsi The IMSI of the connected terminal.
38 * \param cellid The Cell ID.
39 * \param rnti The RNTI.
40 */
41void
42NotifyConnectionEstablishedUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
43{
44 std::cout << Simulator::Now().As(Time::S) << " " << context << " UE IMSI " << imsi
45 << ": connected to CellId " << cellid << " with RNTI " << rnti << std::endl;
46}
47
48/**
49 * UE Start Handover notification.
50 *
51 * \param context The context.
52 * \param imsi The IMSI of the connected terminal.
53 * \param cellid The actual Cell ID.
54 * \param rnti The RNTI.
55 * \param targetCellId The target Cell ID.
56 */
57void
58NotifyHandoverStartUe(std::string context,
59 uint64_t imsi,
60 uint16_t cellid,
61 uint16_t rnti,
62 uint16_t targetCellId)
63{
64 std::cout << Simulator::Now().As(Time::S) << " " << context << " UE IMSI " << imsi
65 << ": previously connected to CellId " << cellid << " with RNTI " << rnti
66 << ", doing handover to CellId " << targetCellId << std::endl;
67}
68
69/**
70 * UE Handover end successful notification.
71 *
72 * \param context The context.
73 * \param imsi The IMSI of the connected terminal.
74 * \param cellid The Cell ID.
75 * \param rnti The RNTI.
76 */
77void
78NotifyHandoverEndOkUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
79{
80 std::cout << Simulator::Now().As(Time::S) << " " << context << " UE IMSI " << imsi
81 << ": successful handover to CellId " << cellid << " with RNTI " << rnti << std::endl;
82}
83
84/**
85 * eNB Connection established notification.
86 *
87 * \param context The context.
88 * \param imsi The IMSI of the connected terminal.
89 * \param cellid The Cell ID.
90 * \param rnti The RNTI.
91 */
92void
93NotifyConnectionEstablishedEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
94{
95 std::cout << Simulator::Now().As(Time::S) << " " << context << " eNB CellId " << cellid
96 << ": successful connection of UE with IMSI " << imsi << " RNTI " << rnti
97 << std::endl;
98}
99
100/**
101 * eNB Start Handover notification.
102 *
103 * \param context The context.
104 * \param imsi The IMSI of the connected terminal.
105 * \param cellid The actual Cell ID.
106 * \param rnti The RNTI.
107 * \param targetCellId The target Cell ID.
108 */
109void
110NotifyHandoverStartEnb(std::string context,
111 uint64_t imsi,
112 uint16_t cellid,
113 uint16_t rnti,
114 uint16_t targetCellId)
115{
116 std::cout << Simulator::Now().As(Time::S) << " " << context << " eNB CellId " << cellid
117 << ": start handover of UE with IMSI " << imsi << " RNTI " << rnti << " to CellId "
118 << targetCellId << std::endl;
119}
120
121/**
122 * eNB Handover end successful notification.
123 *
124 * \param context The context.
125 * \param imsi The IMSI of the connected terminal.
126 * \param cellid The Cell ID.
127 * \param rnti The RNTI.
128 */
129void
130NotifyHandoverEndOkEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
131{
132 std::cout << Simulator::Now().As(Time::S) << " " << context << " eNB CellId " << cellid
133 << ": completed handover of UE with IMSI " << imsi << " RNTI " << rnti << std::endl;
134}
135
136/**
137 * Handover failure notification
138 *
139 * \param context The context.
140 * \param imsi The IMSI of the connected terminal.
141 * \param cellid The Cell ID.
142 * \param rnti The RNTI.
143 */
144void
145NotifyHandoverFailure(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
146{
147 std::cout << Simulator::Now().As(Time::S) << " " << context << " eNB CellId " << cellid
148 << " IMSI " << imsi << " RNTI " << rnti << " handover failure" << std::endl;
149}
150
151/**
152 * Sample simulation script for a X2-based handover.
153 * It instantiates two eNodeB, attaches one UE to the 'source' eNB and
154 * triggers a handover of the UE towards the 'target' eNB.
155 */
156int
157main(int argc, char* argv[])
158{
159 // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
160
161 // LogComponentEnable ("LteHelper", logLevel);
162 // LogComponentEnable ("EpcHelper", logLevel);
163 // LogComponentEnable ("EpcEnbApplication", logLevel);
164 // LogComponentEnable ("EpcMmeApplication", logLevel);
165 // LogComponentEnable ("EpcPgwApplication", logLevel);
166 // LogComponentEnable ("EpcSgwApplication", logLevel);
167 // LogComponentEnable ("EpcX2", logLevel);
168
169 // LogComponentEnable ("LteEnbRrc", logLevel);
170 // LogComponentEnable ("LteEnbNetDevice", logLevel);
171 // LogComponentEnable ("LteUeRrc", logLevel);
172 // LogComponentEnable ("LteUeNetDevice", logLevel);
173
174 uint16_t numberOfUes = 1;
175 uint16_t numberOfEnbs = 2;
176 uint16_t numBearersPerUe = 2;
177 Time simTime = MilliSeconds(490);
178 double distance = 100.0;
179 bool disableDl = false;
180 bool disableUl = false;
181
182 // change some default attributes so that they are reasonable for
183 // this scenario, but do this before processing command line
184 // arguments, so that the user is allowed to override these settings
185 Config::SetDefault("ns3::UdpClient::Interval", TimeValue(MilliSeconds(10)));
186 Config::SetDefault("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
187 Config::SetDefault("ns3::LteHelper::UseIdealRrc", BooleanValue(false));
188
189 // Command line arguments
190 CommandLine cmd(__FILE__);
191 cmd.AddValue("numberOfUes", "Number of UEs", numberOfUes);
192 cmd.AddValue("numberOfEnbs", "Number of eNodeBs", numberOfEnbs);
193 cmd.AddValue("simTime", "Total duration of the simulation", simTime);
194 cmd.AddValue("disableDl", "Disable downlink data flows", disableDl);
195 cmd.AddValue("disableUl", "Disable uplink data flows", disableUl);
196 cmd.Parse(argc, argv);
197
198 Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
199 Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper>();
200 lteHelper->SetEpcHelper(epcHelper);
201 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
202 lteHelper->SetHandoverAlgorithmType("ns3::NoOpHandoverAlgorithm"); // disable automatic handover
203
204 Ptr<Node> pgw = epcHelper->GetPgwNode();
205
206 // Create a single RemoteHost
207 NodeContainer remoteHostContainer;
208 remoteHostContainer.Create(1);
209 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
211 internet.Install(remoteHostContainer);
212
213 // Create the Internet
215 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
216 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
217 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
218 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
219 Ipv4AddressHelper ipv4h;
220 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
221 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
222 Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress(1);
223
224 // Routing of the Internet Host (towards the LTE network)
225 Ipv4StaticRoutingHelper ipv4RoutingHelper;
226 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
227 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
228 // interface 0 is localhost, 1 is the p2p device
229 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
230
231 NodeContainer ueNodes;
232 NodeContainer enbNodes;
233 enbNodes.Create(numberOfEnbs);
234 ueNodes.Create(numberOfUes);
235
236 // Install Mobility Model
237 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
238 for (uint16_t i = 0; i < numberOfEnbs; i++)
239 {
240 positionAlloc->Add(Vector(distance * 2 * i - distance, 0, 0));
241 }
242 for (uint16_t i = 0; i < numberOfUes; i++)
243 {
244 positionAlloc->Add(Vector(0, 0, 0));
245 }
247 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
248 mobility.SetPositionAllocator(positionAlloc);
249 mobility.Install(enbNodes);
250 mobility.Install(ueNodes);
251
252 // Install LTE Devices in eNB and UEs
253 NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice(enbNodes);
254 NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice(ueNodes);
255
256 // Install the IP stack on the UEs
257 internet.Install(ueNodes);
258 Ipv4InterfaceContainer ueIpIfaces;
259 ueIpIfaces = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLteDevs));
260
261 // Attach all UEs to the first eNodeB
262 for (uint16_t i = 0; i < numberOfUes; i++)
263 {
264 lteHelper->Attach(ueLteDevs.Get(i), enbLteDevs.Get(0));
265 }
266
267 NS_LOG_LOGIC("setting up applications");
268
269 // Install and start applications on UEs and remote host
270 uint16_t dlPort = 10000;
271 uint16_t ulPort = 20000;
272
273 // randomize a bit start times to avoid simulation artifacts
274 // (e.g., buffer overflows due to packet transmissions happening
275 // exactly at the same time)
276 Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable>();
277 startTimeSeconds->SetAttribute("Min", DoubleValue(0.05));
278 startTimeSeconds->SetAttribute("Max", DoubleValue(0.06));
279
280 for (uint32_t u = 0; u < numberOfUes; ++u)
281 {
282 Ptr<Node> ue = ueNodes.Get(u);
283 // Set the default gateway for the UE
284 Ptr<Ipv4StaticRouting> ueStaticRouting =
285 ipv4RoutingHelper.GetStaticRouting(ue->GetObject<Ipv4>());
286 ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
287
288 for (uint32_t b = 0; b < numBearersPerUe; ++b)
289 {
292 Ptr<EpcTft> tft = Create<EpcTft>();
293
294 if (!disableDl)
295 {
296 ++dlPort;
297
298 NS_LOG_LOGIC("installing UDP DL app for UE " << u);
299 UdpClientHelper dlClientHelper(ueIpIfaces.GetAddress(u), dlPort);
300 clientApps.Add(dlClientHelper.Install(remoteHost));
301 PacketSinkHelper dlPacketSinkHelper(
302 "ns3::UdpSocketFactory",
304 serverApps.Add(dlPacketSinkHelper.Install(ue));
305
307 dlpf.localPortStart = dlPort;
308 dlpf.localPortEnd = dlPort;
309 tft->Add(dlpf);
310 }
311
312 if (!disableUl)
313 {
314 ++ulPort;
315
316 NS_LOG_LOGIC("installing UDP UL app for UE " << u);
317 UdpClientHelper ulClientHelper(remoteHostAddr, ulPort);
318 clientApps.Add(ulClientHelper.Install(ue));
319 PacketSinkHelper ulPacketSinkHelper(
320 "ns3::UdpSocketFactory",
322 serverApps.Add(ulPacketSinkHelper.Install(remoteHost));
323
325 ulpf.remotePortStart = ulPort;
326 ulpf.remotePortEnd = ulPort;
327 tft->Add(ulpf);
328 }
329
331 lteHelper->ActivateDedicatedEpsBearer(ueLteDevs.Get(u), bearer, tft);
332
333 Time startTime = Seconds(startTimeSeconds->GetValue());
334 serverApps.Start(startTime);
335 clientApps.Start(startTime);
336 clientApps.Stop(simTime);
337
338 } // end for b
339 }
340
341 // Add X2 interface
342 lteHelper->AddX2Interface(enbNodes);
343
344 // X2-based Handover
345 lteHelper->HandoverRequest(MilliSeconds(300),
346 ueLteDevs.Get(0),
347 enbLteDevs.Get(0),
348 enbLteDevs.Get(1));
349
350 // Uncomment to enable PCAP tracing
351 // p2ph.EnablePcapAll("lena-x2-handover");
352
353 lteHelper->EnablePhyTraces();
354 lteHelper->EnableMacTraces();
355 lteHelper->EnableRlcTraces();
356 lteHelper->EnablePdcpTraces();
357 Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats();
358 rlcStats->SetAttribute("EpochDuration", TimeValue(Seconds(0.05)));
359 Ptr<RadioBearerStatsCalculator> pdcpStats = lteHelper->GetPdcpStats();
360 pdcpStats->SetAttribute("EpochDuration", TimeValue(Seconds(0.05)));
361
362 // connect custom trace sinks for RRC connection establishment and handover notification
363 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionEstablished",
365 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionEstablished",
367 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart",
369 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
371 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk",
373 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk",
375
376 // Hook a trace sink (the same one) to the four handover failure traces
377 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureNoPreamble",
379 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureMaxRach",
381 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureLeaving",
383 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureJoining",
385
386 Simulator::Stop(simTime + MilliSeconds(20));
388
389 // GtkConfigStore config;
390 // config.ConfigureAttributes ();
391
393 return 0;
394}
holds a vector of ns3::Application pointers.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:232
Class for representing data rates.
Definition: data-rate.h:89
AttributeValue implementation for DataRate.
Definition: data-rate.h:296
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
@ NGBR_VIDEO_TCP_DEFAULT
Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
Definition: eps-bearer.h:126
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
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:42
static Ipv4Address GetAny()
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
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:257
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...
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.
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.
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)
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1406
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:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:978
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
void NotifyHandoverFailure(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Handover failure notification.
void NotifyHandoverEndOkUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
UE Handover end successful notification.
void NotifyConnectionEstablishedUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
UE Connection established notification.
void NotifyHandoverStartUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
UE Start Handover notification.
void NotifyHandoverStartEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
eNB Start Handover notification.
void NotifyConnectionEstablishedEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
eNB Connection established notification.
void NotifyHandoverEndOkEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
eNB Handover end successful notification.
ns serverApps
Definition: first.py:54
ns clientApps
Definition: first.py:64
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:706
ns cmd
Definition: second.py:40
ns mobility
Definition: third.py:105
Implement the data structure representing a TrafficFlowTemplate Packet Filter.
Definition: epc-tft.h:71
uint16_t localPortEnd
end of the port number range of the UE
Definition: epc-tft.h:132
uint16_t remotePortEnd
end of the port number range of the remote host
Definition: epc-tft.h:130
uint16_t remotePortStart
start of the port number range of the remote host
Definition: epc-tft.h:129
uint16_t localPortStart
start of the port number range of the UE
Definition: epc-tft.h:131