A Discrete-Event Network Simulator
API
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/config-store-module.h"
22#include "ns3/core-module.h"
23#include "ns3/internet-module.h"
24#include "ns3/lte-module.h"
25#include "ns3/mobility-module.h"
26#include "ns3/network-module.h"
27#include "ns3/point-to-point-module.h"
28
29using namespace ns3;
30
31NS_LOG_COMPONENT_DEFINE("LenaX2HandoverExample");
32
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
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
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
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
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
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
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
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);
210 InternetStackHelper internet;
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",
303 InetSocketAddress(Ipv4Address::GetAny(), dlPort));
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",
321 InetSocketAddress(Ipv4Address::GetAny(), ulPort));
322 serverApps.Add(ulPacketSinkHelper.Install(remoteHost));
323
325 ulpf.remotePortStart = ulPort;
326 ulpf.remotePortEnd = ulPort;
327 tft->Add(ulpf);
328 }
329
330 EpsBearer bearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
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));
387 Simulator::Run();
388
389 // GtkConfigStore config;
390 // config.ConfigureAttributes ();
391
392 Simulator::Destroy();
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
AttributeValue implementation for DataRate.
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
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:43
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
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:258
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...
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:282
Ptr< RadioBearerStatsCalculator > GetRlcStats()
Definition: lte-helper.cc:1708
Ptr< RadioBearerStatsCalculator > GetPdcpStats()
Definition: lte-helper.cc:1723
void EnablePhyTraces()
Enable trace sinks for PHY layer.
Definition: lte-helper.cc:1623
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Manually trigger an X2-based handover.
Definition: lte-helper.cc:1343
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:482
void SetHandoverAlgorithmType(std::string type)
Set the type of handover algorithm to be used by eNodeB devices.
Definition: lte-helper.cc:337
void EnablePdcpTraces()
Enable trace sinks for PDCP layer.
Definition: lte-helper.cc:1714
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:289
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:1044
void EnableRlcTraces()
Enable trace sinks for RLC layer.
Definition: lte-helper.cc:1563
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:497
void EnableMacTraces()
Enable trace sinks for MAC layer.
Definition: lte-helper.cc:1666
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1318
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:1159
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.
Ptr< Node > GetPgwNode() const override
Get the PGW node.
Ipv4Address GetUeDefaultGatewayAddress() override
Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices) override
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:258
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
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)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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:417
AttributeValue implementation for Time.
Definition: nstime.h:1425
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
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#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
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
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 noticication.
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 noticication.
void NotifyHandoverEndOkEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
eNB Handover end successful notification.
serverApps
Definition: first.py:48
clientApps
Definition: first.py:58
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:691
cmd
Definition: second.py:33
mobility
Definition: third.py:96
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