A Discrete-Event Network Simulator
API
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();
212 RngSeedManager::SetSeed(1);
213 RngSeedManager::SetRun(2);
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.
296 Simulator::Stop(m_simulationDuration);
297 Simulator::Run();
298 Simulator::Destroy();
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_hasHandoverFailureOccured, 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),
394 TestCase::QUICK);
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),
407 TestCase::QUICK);
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),
420 TestCase::QUICK);
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),
433 TestCase::QUICK);
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),
446 TestCase::QUICK);
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),
459 TestCase::QUICK);
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),
472 TestCase::QUICK);
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),
485 TestCase::QUICK);
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),
499 TestCase::QUICK);
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),
512 TestCase::QUICK);
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),
525 TestCase::QUICK);
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),
538 TestCase::QUICK);
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),
551 TestCase::QUICK);
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),
564 TestCase::QUICK);
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),
577 TestCase::QUICK);
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),
590 TestCase::QUICK);
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.
bool m_hasHandoverFailureOccured
has handover failure occurred in simulation
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.
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.
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
std::string GetName() const
Definition: test.cc:377
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
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:707