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
63{
64 public:
95 bool useIdealRrc,
96 Time handoverTime,
97 Time simulationDuration,
98 uint8_t numberOfRaPreambles,
99 uint8_t preambleTransMax,
100 uint8_t raResponseWindowSize,
101 Time handoverJoiningTimeout,
102 Time handoverLeavingTimeout,
103 uint16_t targeteNodeBPosition)
104 : TestCase(name),
105 m_useIdealRrc(useIdealRrc),
106 m_handoverTime(handoverTime),
107 m_simulationDuration(simulationDuration),
108 m_numberOfRaPreambles(numberOfRaPreambles),
109 m_preambleTransMax(preambleTransMax),
110 m_raResponseWindowSize(raResponseWindowSize),
111 m_handoverJoiningTimeout(handoverJoiningTimeout),
112 m_handoverLeavingTimeout(handoverLeavingTimeout),
113 m_targeteNodeBPosition(targeteNodeBPosition),
115 {
116 }
117
118 private:
123 void DoRun() override;
124
129 void DoTeardown() override;
130
139 void UeHandoverStartCallback(std::string context,
140 uint64_t imsi,
141 uint16_t sourceCellId,
142 uint16_t rnti,
143 uint16_t targetCellId);
144
152 void HandoverFailureMaxRach(std::string context,
153 uint64_t imsi,
154 uint16_t rnti,
155 uint16_t targetCellId);
156
164 void HandoverFailureNoPreamble(std::string context,
165 uint64_t imsi,
166 uint16_t rnti,
167 uint16_t targetCellId);
168
176 void HandoverFailureJoining(std::string context,
177 uint64_t imsi,
178 uint16_t rnti,
179 uint16_t targetCellId);
180
188 void HandoverFailureLeaving(std::string context,
189 uint64_t imsi,
190 uint16_t rnti,
191 uint16_t targetCellId);
192
204
205}; // end of class LteHandoverFailureTestCase
206
207void
209{
210 NS_LOG_INFO(this << " " << GetName());
211 uint32_t previousSeed = RngSeedManager::GetSeed();
212 uint64_t previousRun = RngSeedManager::GetRun();
213 RngSeedManager::SetSeed(1);
214 RngSeedManager::SetRun(2);
215
216 /*
217 * Helpers.
218 */
219 auto epcHelper = CreateObject<PointToPointEpcHelper>();
220
221 auto lteHelper = CreateObject<LteHelper>();
222 lteHelper->SetEpcHelper(epcHelper);
223
224 // Set parameters for helpers based on the test case parameters.
225 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(m_useIdealRrc));
226 Config::SetDefault("ns3::LteEnbMac::NumberOfRaPreambles", UintegerValue(m_numberOfRaPreambles));
227 Config::SetDefault("ns3::LteEnbMac::PreambleTransMax", UintegerValue(m_preambleTransMax));
228 Config::SetDefault("ns3::LteEnbMac::RaResponseWindowSize",
230 Config::SetDefault("ns3::LteEnbRrc::HandoverJoiningTimeoutDuration",
232 Config::SetDefault("ns3::LteEnbRrc::HandoverLeavingTimeoutDuration",
234
235 // Set PHY model to drastically decrease with distance.
236 lteHelper->SetPathlossModelType(TypeId::LookupByName("ns3::LogDistancePropagationLossModel"));
237 lteHelper->SetPathlossModelAttribute("Exponent", DoubleValue(3.5));
238 lteHelper->SetPathlossModelAttribute("ReferenceLoss", DoubleValue(35));
239 /*
240 * Physical layer.
241 *
242 * eNodeB 0 UE eNodeB 1
243 *
244 * x ----------------------- x -------------------------- x
245 * 200 m m_targeteNodeBPosition
246 * source target
247 */
248 // Create nodes.
249 NodeContainer enbNodes;
250 enbNodes.Create(2);
251 auto ueNode = CreateObject<Node>();
252
253 // Setup mobility
254 auto posAlloc = CreateObject<ListPositionAllocator>();
255 posAlloc->Add(Vector(0, 0, 0));
256 posAlloc->Add(Vector(m_targeteNodeBPosition, 0, 0));
257 posAlloc->Add(Vector(200, 0, 0));
258
259 MobilityHelper mobilityHelper;
260 mobilityHelper.SetMobilityModel("ns3::ConstantPositionMobilityModel");
261 mobilityHelper.SetPositionAllocator(posAlloc);
262 mobilityHelper.Install(enbNodes);
263 mobilityHelper.Install(ueNode);
264
265 /*
266 * Link layer.
267 */
268 auto enbDevs = lteHelper->InstallEnbDevice(enbNodes);
269 auto ueDev = lteHelper->InstallUeDevice(ueNode).Get(0);
270
271 /*
272 * Network layer.
273 */
274 InternetStackHelper inetStackHelper;
275 inetStackHelper.Install(ueNode);
277 ueIfs = epcHelper->AssignUeIpv4Address(ueDev);
278
279 // Setup traces.
280 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
282 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureMaxRach",
284 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureNoPreamble",
286 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureJoining",
288 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverFailureLeaving",
290
291 // Prepare handover.
292 lteHelper->AddX2Interface(enbNodes);
293 lteHelper->Attach(ueDev, enbDevs.Get(0));
294 lteHelper->HandoverRequest(m_handoverTime, ueDev, enbDevs.Get(0), enbDevs.Get(1));
295
296 // Run simulation.
297 Simulator::Stop(m_simulationDuration);
298 Simulator::Run();
299 Simulator::Destroy();
300
301 RngSeedManager::SetSeed(previousSeed);
302 RngSeedManager::SetRun(previousRun);
303} // end of void LteHandoverFailureTestCase::DoRun ()
304
305void
307 uint64_t imsi,
308 uint16_t sourceCellId,
309 uint16_t rnti,
310 uint16_t targetCellId)
311{
312 NS_LOG_FUNCTION(this << " " << context << " IMSI-" << imsi << " sourceCellID-" << sourceCellId
313 << " RNTI-" << rnti << " targetCellID-" << targetCellId);
314 NS_LOG_INFO("HANDOVER COMMAND received through at UE "
315 << imsi << " to handover from " << sourceCellId << " to " << targetCellId);
316}
317
318void
320 uint64_t imsi,
321 uint16_t rnti,
322 uint16_t targetCellId)
323{
324 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
326}
327
328void
330 uint64_t imsi,
331 uint16_t rnti,
332 uint16_t targetCellId)
333{
334 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
336}
337
338void
340 uint64_t imsi,
341 uint16_t rnti,
342 uint16_t targetCellId)
343{
344 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
346}
347
348void
350 uint64_t imsi,
351 uint16_t rnti,
352 uint16_t targetCellId)
353{
354 NS_LOG_FUNCTION(this << context << imsi << rnti << targetCellId);
356}
357
358void
360{
361 NS_LOG_FUNCTION(this);
362 NS_TEST_ASSERT_MSG_EQ(m_hasHandoverFailureOccured, true, "Handover failure did not occur");
363}
364
375{
376 public:
378 : TestSuite("lte-handover-failure", TestSuite::SYSTEM)
379 {
380 // Argument sequence for all test cases: useIdealRrc, handoverTime, simulationDuration,
381 // numberOfRaPreambles, preambleTransMax, raResponseWindowSize,
382 // handoverJoiningTimeout, handoverLeavingTimeout
383
384 // Test cases for REAL RRC protocol
385 AddTestCase(new LteHandoverFailureTestCase("REAL Handover failure due to maximum RACH "
386 "transmissions reached from UE to target eNodeB",
387 false,
388 Seconds(0.200),
389 Seconds(0.300),
390 52,
391 3,
392 3,
393 MilliSeconds(200),
394 MilliSeconds(500),
395 2500),
396 TestCase::QUICK);
398 "REAL Handover failure due to non-allocation of non-contention preamble at "
399 "target eNodeB due to max number reached",
400 false,
401 Seconds(0.100),
402 Seconds(0.200),
403 64,
404 50,
405 3,
406 MilliSeconds(200),
407 MilliSeconds(500),
408 1500),
409 TestCase::QUICK);
411 "REAL Handover failure due to HANDOVER JOINING timeout before reception of "
412 "RRC CONNECTION RECONFIGURATION at source eNodeB",
413 false,
414 Seconds(0.100),
415 Seconds(0.200),
416 52,
417 50,
418 3,
419 MilliSeconds(0),
420 MilliSeconds(500),
421 1500),
422 TestCase::QUICK);
424 "REAL Handover failure due to HANDOVER JOINING timeout before completion "
425 "of non-contention RACH process to target eNodeB",
426 false,
427 Seconds(0.100),
428 Seconds(0.200),
429 52,
430 50,
431 3,
432 MilliSeconds(15),
433 MilliSeconds(500),
434 1500),
435 TestCase::QUICK);
437 "REAL Handover failure due to HANDOVER JOINING timeout before reception of "
438 "RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
439 false,
440 Seconds(0.100),
441 Seconds(0.200),
442 52,
443 50,
444 3,
445 MilliSeconds(18),
446 MilliSeconds(500),
447 500),
448 TestCase::QUICK);
450 "REAL Handover failure due to HANDOVER LEAVING timeout before reception of "
451 "RRC CONNECTION RECONFIGURATION at source eNodeB",
452 false,
453 Seconds(0.100),
454 Seconds(0.200),
455 52,
456 50,
457 3,
458 MilliSeconds(200),
459 MilliSeconds(0),
460 1500),
461 TestCase::QUICK);
463 "REAL Handover failure due to HANDOVER LEAVING timeout before completion "
464 "of non-contention RACH process to target eNodeB",
465 false,
466 Seconds(0.100),
467 Seconds(0.200),
468 52,
469 50,
470 3,
471 MilliSeconds(200),
472 MilliSeconds(15),
473 1500),
474 TestCase::QUICK);
476 "REAL Handover failure due to HANDOVER LEAVING timeout before reception of "
477 "RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
478 false,
479 Seconds(0.100),
480 Seconds(0.200),
481 52,
482 50,
483 3,
484 MilliSeconds(200),
485 MilliSeconds(18),
486 500),
487 TestCase::QUICK);
488
489 // Test cases for IDEAL RRC protocol
490 AddTestCase(new LteHandoverFailureTestCase("IDEAL Handover failure due to maximum RACH "
491 "transmissions reached from UE to target eNodeB",
492 true,
493 Seconds(0.100),
494 Seconds(0.200),
495 52,
496 3,
497 3,
498 MilliSeconds(200),
499 MilliSeconds(500),
500 1500),
501 TestCase::QUICK);
503 "IDEAL Handover failure due to non-allocation of non-contention preamble "
504 "at target eNodeB due to max number reached",
505 true,
506 Seconds(0.100),
507 Seconds(0.200),
508 64,
509 50,
510 3,
511 MilliSeconds(200),
512 MilliSeconds(500),
513 1500),
514 TestCase::QUICK);
516 "IDEAL Handover failure due to HANDOVER JOINING timeout before reception "
517 "of RRC CONNECTION RECONFIGURATION at source eNodeB",
518 true,
519 Seconds(0.100),
520 Seconds(0.200),
521 52,
522 50,
523 3,
524 MilliSeconds(0),
525 MilliSeconds(500),
526 1500),
527 TestCase::QUICK);
529 "IDEAL Handover failure due to HANDOVER JOINING timeout before completion "
530 "of non-contention RACH process to target eNodeB",
531 true,
532 Seconds(0.100),
533 Seconds(0.200),
534 52,
535 50,
536 3,
537 MilliSeconds(10),
538 MilliSeconds(500),
539 1500),
540 TestCase::QUICK);
542 "IDEAL Handover failure due to HANDOVER JOINING timeout before reception "
543 "of RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
544 true,
545 Seconds(0.100),
546 Seconds(0.200),
547 52,
548 50,
549 3,
550 MilliSeconds(4),
551 MilliSeconds(500),
552 500),
553 TestCase::QUICK);
555 "IDEAL Handover failure due to HANDOVER LEAVING timeout before reception "
556 "of RRC CONNECTION RECONFIGURATION at source eNodeB",
557 true,
558 Seconds(0.100),
559 Seconds(0.200),
560 52,
561 50,
562 3,
563 MilliSeconds(500),
564 MilliSeconds(0),
565 1500),
566 TestCase::QUICK);
568 "IDEAL Handover failure due to HANDOVER LEAVING timeout before completion "
569 "of non-contention RACH process to target eNodeB",
570 true,
571 Seconds(0.100),
572 Seconds(0.200),
573 52,
574 50,
575 3,
576 MilliSeconds(500),
577 MilliSeconds(10),
578 1500),
579 TestCase::QUICK);
581 "IDEAL Handover failure due to HANDOVER LEAVING timeout before reception "
582 "of RRC CONNECTION RECONFIGURATION COMPLETE at target eNodeB",
583 true,
584 Seconds(0.100),
585 Seconds(0.200),
586 52,
587 50,
588 3,
589 MilliSeconds(500),
590 MilliSeconds(4),
591 500),
592 TestCase::QUICK);
593 }
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 occured 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 occured in th...
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:1425
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
#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
LteHandoverFailureTestSuite g_lteHandoverFailureTestSuite
end of LteHandoverFailureTestSuite ()
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
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