A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
test-lte-handover-failure.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013 Magister Solutions (original test-lte-handover-delay.cc)
3 * Copyright (c) 2021 University of Washington (handover failure cases)
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: Sachin Nayak <sachinnn@uw.edu>
19 */
20
21#include <ns3/boolean.h>
22#include <ns3/callback.h>
23#include <ns3/config.h>
24#include <ns3/data-rate.h>
25#include <ns3/internet-stack-helper.h>
26#include <ns3/ipv4-address-helper.h>
27#include <ns3/ipv4-interface-container.h>
28#include <ns3/ipv4-static-routing-helper.h>
29#include <ns3/ipv4-static-routing.h>
30#include <ns3/log.h>
31#include <ns3/lte-helper.h>
32#include <ns3/mobility-helper.h>
33#include <ns3/net-device-container.h>
34#include <ns3/node-container.h>
35#include <ns3/nstime.h>
36#include <ns3/point-to-point-epc-helper.h>
37#include <ns3/point-to-point-helper.h>
38#include <ns3/position-allocator.h>
39#include <ns3/rng-seed-manager.h>
40#include <ns3/simulator.h>
41#include <ns3/test.h>
42
43using namespace ns3;
44
45NS_LOG_COMPONENT_DEFINE("LteHandoverFailureTest");
46
62{
63 public:
94 bool useIdealRrc,
95 Time handoverTime,
96 Time simulationDuration,
97 uint8_t numberOfRaPreambles,
98 uint8_t preambleTransMax,
99 uint8_t raResponseWindowSize,
100 Time handoverJoiningTimeout,
101 Time handoverLeavingTimeout,
102 uint16_t targeteNodeBPosition)
103 : TestCase(name),
104 m_useIdealRrc(useIdealRrc),
105 m_handoverTime(handoverTime),
106 m_simulationDuration(simulationDuration),
107 m_numberOfRaPreambles(numberOfRaPreambles),
108 m_preambleTransMax(preambleTransMax),
109 m_raResponseWindowSize(raResponseWindowSize),
110 m_handoverJoiningTimeout(handoverJoiningTimeout),
111 m_handoverLeavingTimeout(handoverLeavingTimeout),
112 m_targeteNodeBPosition(targeteNodeBPosition),
114 {
115 }
116
117 private:
122 void DoRun() override;
123
128 void DoTeardown() override;
129
138 void UeHandoverStartCallback(std::string context,
139 uint64_t imsi,
140 uint16_t sourceCellId,
141 uint16_t rnti,
142 uint16_t targetCellId);
143
151 void HandoverFailureMaxRach(std::string context,
152 uint64_t imsi,
153 uint16_t rnti,
154 uint16_t targetCellId);
155
163 void HandoverFailureNoPreamble(std::string context,
164 uint64_t imsi,
165 uint16_t rnti,
166 uint16_t targetCellId);
167
175 void HandoverFailureJoining(std::string context,
176 uint64_t imsi,
177 uint16_t rnti,
178 uint16_t targetCellId);
179
187 void HandoverFailureLeaving(std::string context,
188 uint64_t imsi,
189 uint16_t rnti,
190 uint16_t targetCellId);
191
203
204}; // end of class LteHandoverFailureTestCase
205
206void
208{
209 NS_LOG_INFO(this << " " << GetName());
210 uint32_t previousSeed = RngSeedManager::GetSeed();
211 uint64_t previousRun = RngSeedManager::GetRun();
214
215 /*
216 * Helpers.
217 */
218 auto epcHelper = CreateObject<PointToPointEpcHelper>();
219
220 auto lteHelper = CreateObject<LteHelper>();
221 lteHelper->SetEpcHelper(epcHelper);
222
223 // Set parameters for helpers based on the test case parameters.
224 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(m_useIdealRrc));
225 Config::SetDefault("ns3::LteEnbMac::NumberOfRaPreambles", UintegerValue(m_numberOfRaPreambles));
226 Config::SetDefault("ns3::LteEnbMac::PreambleTransMax", UintegerValue(m_preambleTransMax));
227 Config::SetDefault("ns3::LteEnbMac::RaResponseWindowSize",
229 Config::SetDefault("ns3::LteEnbRrc::HandoverJoiningTimeoutDuration",
231 Config::SetDefault("ns3::LteEnbRrc::HandoverLeavingTimeoutDuration",
233
234 // Set PHY model to drastically decrease with distance.
235 lteHelper->SetPathlossModelType(TypeId::LookupByName("ns3::LogDistancePropagationLossModel"));
236 lteHelper->SetPathlossModelAttribute("Exponent", DoubleValue(3.5));
237 lteHelper->SetPathlossModelAttribute("ReferenceLoss", DoubleValue(35));
238 /*
239 * Physical layer.
240 *
241 * eNodeB 0 UE eNodeB 1
242 *
243 * x ----------------------- x -------------------------- x
244 * 200 m m_targeteNodeBPosition
245 * source target
246 */
247 // Create nodes.
248 NodeContainer enbNodes;
249 enbNodes.Create(2);
250 auto ueNode = CreateObject<Node>();
251
252 // Setup mobility
253 auto posAlloc = CreateObject<ListPositionAllocator>();
254 posAlloc->Add(Vector(0, 0, 0));
255 posAlloc->Add(Vector(m_targeteNodeBPosition, 0, 0));
256 posAlloc->Add(Vector(200, 0, 0));
257
258 MobilityHelper mobilityHelper;
259 mobilityHelper.SetMobilityModel("ns3::ConstantPositionMobilityModel");
260 mobilityHelper.SetPositionAllocator(posAlloc);
261 mobilityHelper.Install(enbNodes);
262 mobilityHelper.Install(ueNode);
263
264 /*
265 * Link layer.
266 */
267 auto enbDevs = lteHelper->InstallEnbDevice(enbNodes);
268 auto ueDev = lteHelper->InstallUeDevice(ueNode).Get(0);
269
270 /*
271 * Network layer.
272 */
273 InternetStackHelper inetStackHelper;
274 inetStackHelper.Install(ueNode);
276 ueIfs = epcHelper->AssignUeIpv4Address(ueDev);
277
278 // Setup traces.
279 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
281 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureMaxRach",
283 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureNoPreamble",
285 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureJoining",
287 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureLeaving",
289
290 // Prepare handover.
291 lteHelper->AddX2Interface(enbNodes);
292 lteHelper->Attach(ueDev, enbDevs.Get(0));
293 lteHelper->HandoverRequest(m_handoverTime, ueDev, enbDevs.Get(0), enbDevs.Get(1));
294
295 // Run simulation.
299
300 RngSeedManager::SetSeed(previousSeed);
301 RngSeedManager::SetRun(previousRun);
302} // end of void LteHandoverFailureTestCase::DoRun ()
303
304void
306 uint64_t imsi,
307 uint16_t sourceCellId,
308 uint16_t rnti,
309 uint16_t targetCellId)
310{
311 NS_LOG_FUNCTION(this << " " << context << " IMSI-" << imsi << " sourceCellID-" << sourceCellId
312 << " RNTI-" << rnti << " targetCellID-" << targetCellId);
313 NS_LOG_INFO("HANDOVER COMMAND received through at UE "
314 << imsi << " to handover from " << sourceCellId << " to " << targetCellId);
315}
316
317void
319 uint64_t imsi,
320 uint16_t rnti,
321 uint16_t targetCellId)
322{
323 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
325}
326
327void
329 uint64_t imsi,
330 uint16_t rnti,
331 uint16_t targetCellId)
332{
333 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
335}
336
337void
339 uint64_t imsi,
340 uint16_t rnti,
341 uint16_t targetCellId)
342{
343 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
345}
346
347void
349 uint64_t imsi,
350 uint16_t rnti,
351 uint16_t targetCellId)
352{
353 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
355}
356
357void
359{
360 NS_LOG_FUNCTION(this);
361 NS_TEST_ASSERT_MSG_EQ(m_hasHandoverFailureOccurred, true, "Handover failure did not occur");
362}
363
373{
374 public:
376 : TestSuite("lte-handover-failure", TestSuite::SYSTEM)
377 {
378 // Argument sequence for all test cases: useIdealRrc, handoverTime, simulationDuration,
379 // numberOfRaPreambles, preambleTransMax, raResponseWindowSize,
380 // handoverJoiningTimeout, handoverLeavingTimeout
381
382 // Test cases for REAL RRC protocol
383 AddTestCase(new LteHandoverFailureTestCase("REAL Handover failure due to maximum RACH "
384 "transmissions reached from UE to target eNodeB",
385 false,
386 Seconds(0.200),
387 Seconds(0.300),
388 52,
389 3,
390 3,
391 MilliSeconds(200),
392 MilliSeconds(500),
393 2500),
396 "REAL Handover failure due to non-allocation of non-contention preamble at "
397 "target eNodeB due to max number reached",
398 false,
399 Seconds(0.100),
400 Seconds(0.200),
401 64,
402 50,
403 3,
404 MilliSeconds(200),
405 MilliSeconds(500),
406 1500),
409 "REAL Handover failure due to HANDOVER JOINING timeout before reception of "
410 "RRC CONNECTION RECONFIGURATION at source eNodeB",
411 false,
412 Seconds(0.100),
413 Seconds(0.200),
414 52,
415 50,
416 3,
417 MilliSeconds(0),
418 MilliSeconds(500),
419 1500),
422 "REAL Handover failure due to HANDOVER JOINING timeout before completion "
423 "of non-contention RACH process to target eNodeB",
424 false,
425 Seconds(0.100),
426 Seconds(0.200),
427 52,
428 50,
429 3,
430 MilliSeconds(15),
431 MilliSeconds(500),
432 1500),
435 "REAL Handover failure due to HANDOVER JOINING timeout before reception of "
436 "RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
437 false,
438 Seconds(0.100),
439 Seconds(0.200),
440 52,
441 50,
442 3,
443 MilliSeconds(18),
444 MilliSeconds(500),
445 500),
448 "REAL Handover failure due to HANDOVER LEAVING timeout before reception of "
449 "RRC CONNECTION RECONFIGURATION at source eNodeB",
450 false,
451 Seconds(0.100),
452 Seconds(0.200),
453 52,
454 50,
455 3,
456 MilliSeconds(200),
457 MilliSeconds(0),
458 1500),
461 "REAL Handover failure due to HANDOVER LEAVING timeout before completion "
462 "of non-contention RACH process to target eNodeB",
463 false,
464 Seconds(0.100),
465 Seconds(0.200),
466 52,
467 50,
468 3,
469 MilliSeconds(200),
470 MilliSeconds(15),
471 1500),
474 "REAL Handover failure due to HANDOVER LEAVING timeout before reception of "
475 "RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
476 false,
477 Seconds(0.100),
478 Seconds(0.200),
479 52,
480 50,
481 3,
482 MilliSeconds(200),
483 MilliSeconds(18),
484 500),
486
487 // Test cases for IDEAL RRC protocol
488 AddTestCase(new LteHandoverFailureTestCase("IDEAL Handover failure due to maximum RACH "
489 "transmissions reached from UE to target eNodeB",
490 true,
491 Seconds(0.100),
492 Seconds(0.200),
493 52,
494 3,
495 3,
496 MilliSeconds(200),
497 MilliSeconds(500),
498 1500),
501 "IDEAL Handover failure due to non-allocation of non-contention preamble "
502 "at target eNodeB due to max number reached",
503 true,
504 Seconds(0.100),
505 Seconds(0.200),
506 64,
507 50,
508 3,
509 MilliSeconds(200),
510 MilliSeconds(500),
511 1500),
514 "IDEAL Handover failure due to HANDOVER JOINING timeout before reception "
515 "of RRC CONNECTION RECONFIGURATION at source eNodeB",
516 true,
517 Seconds(0.100),
518 Seconds(0.200),
519 52,
520 50,
521 3,
522 MilliSeconds(0),
523 MilliSeconds(500),
524 1500),
527 "IDEAL Handover failure due to HANDOVER JOINING timeout before completion "
528 "of non-contention RACH process to target eNodeB",
529 true,
530 Seconds(0.100),
531 Seconds(0.200),
532 52,
533 50,
534 3,
535 MilliSeconds(10),
536 MilliSeconds(500),
537 1500),
540 "IDEAL Handover failure due to HANDOVER JOINING timeout before reception "
541 "of RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
542 true,
543 Seconds(0.100),
544 Seconds(0.200),
545 52,
546 50,
547 3,
548 MilliSeconds(4),
549 MilliSeconds(500),
550 500),
553 "IDEAL Handover failure due to HANDOVER LEAVING timeout before reception "
554 "of RRC CONNECTION RECONFIGURATION at source eNodeB",
555 true,
556 Seconds(0.100),
557 Seconds(0.200),
558 52,
559 50,
560 3,
561 MilliSeconds(500),
562 MilliSeconds(0),
563 1500),
566 "IDEAL Handover failure due to HANDOVER LEAVING timeout before completion "
567 "of non-contention RACH process to target eNodeB",
568 true,
569 Seconds(0.100),
570 Seconds(0.200),
571 52,
572 50,
573 3,
574 MilliSeconds(500),
575 MilliSeconds(10),
576 1500),
579 "IDEAL Handover failure due to HANDOVER LEAVING timeout before reception "
580 "of RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
581 true,
582 Seconds(0.100),
583 Seconds(0.200),
584 52,
585 50,
586 3,
587 MilliSeconds(500),
588 MilliSeconds(4),
589 500),
591 }
Verifying that a handover failure occurs due to various causes.
LteHandoverFailureTestCase(std::string name, bool useIdealRrc, Time handoverTime, Time simulationDuration, uint8_t numberOfRaPreambles, uint8_t preambleTransMax, uint8_t raResponseWindowSize, Time handoverJoiningTimeout, Time handoverLeavingTimeout, uint16_t targeteNodeBPosition)
Constructor.
Time m_handoverJoiningTimeout
handover joining timeout duration at target eNodeB
Time m_handoverLeavingTimeout
handover leaving timeout duration at source eNodeB
uint8_t m_preambleTransMax
max number of RACH preambles possible from UE to eNodeB
uint8_t m_numberOfRaPreambles
number of random access preambles for contention based RACH process
void HandoverFailureMaxRach(std::string context, uint64_t imsi, uint16_t rnti, uint16_t targetCellId)
Handover failure callback due to maximum RACH transmissions reached from UE to target eNodeB.
void DoRun() override
Run a simulation of a two eNodeB network using the parameters provided to the constructor function.
uint16_t m_targeteNodeBPosition
position of the target eNodeB
void HandoverFailureJoining(std::string context, uint64_t imsi, uint16_t rnti, uint16_t targetCellId)
Handover failure callback due to handover joining timeout at target eNodeB.
void HandoverFailureNoPreamble(std::string context, uint64_t imsi, uint16_t rnti, uint16_t targetCellId)
Handover failure callback due to non-allocation of non-contention preamble at target eNodeB.
void HandoverFailureLeaving(std::string context, uint64_t imsi, uint16_t rnti, uint16_t targetCellId)
Handover failure callback due to handover leaving timeout at source eNodeB.
bool m_hasHandoverFailureOccurred
has handover failure occurred in simulation
void UeHandoverStartCallback(std::string context, uint64_t imsi, uint16_t sourceCellId, uint16_t rnti, uint16_t targetCellId)
UE handover start callback function to indicate start of handover.
void DoTeardown() override
Called at the end of simulation and verifies that a handover and a handover failure has occurred in t...
uint8_t m_raResponseWindowSize
window length for reception of RAR
Time m_simulationDuration
the simulation duration
The following log components can be used to debug this test's behavior: LteHandoverFailureTest:LteEnb...
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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...
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Helper class used to assign positions and mobility models to nodes.
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void SetMobilityModel(std::string type, Ts &&... args)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
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.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static uint64_t GetRun()
Get the current run number.
static uint32_t GetSeed()
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1256
@ SYSTEM
This test suite implements a System Test.
Definition: test.h:1266
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:840
Hold an unsigned integer type.
Definition: uinteger.h:45
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_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
LteHandoverFailureTestSuite g_lteHandoverFailureTestSuite
end of LteHandoverFailureTestSuite ()
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
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:702