A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-test-ue-measurements.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Manuel Requena <manuel.requena@cttc.es>
7 * Nicola Baldo <nbaldo@cttc.es>
8 * Marco Miozzo <mmiozzo@cttc.es>
9 * Budiarto Herman <budiarto.herman@magister.fi>
10 */
11
13
14#include <ns3/boolean.h>
15#include <ns3/callback.h>
16#include <ns3/config.h>
17#include <ns3/double.h>
18#include <ns3/enum.h>
19#include <ns3/ff-mac-scheduler.h>
20#include <ns3/internet-stack-helper.h>
21#include <ns3/ipv4-address-helper.h>
22#include <ns3/ipv4-interface-container.h>
23#include <ns3/ipv4-static-routing-helper.h>
24#include <ns3/log.h>
25#include <ns3/lte-common.h>
26#include <ns3/lte-enb-net-device.h>
27#include <ns3/lte-enb-phy.h>
28#include <ns3/lte-enb-rrc.h>
29#include <ns3/lte-helper.h>
30#include <ns3/lte-ue-net-device.h>
31#include <ns3/lte-ue-phy.h>
32#include <ns3/lte-ue-rrc.h>
33#include <ns3/mobility-helper.h>
34#include <ns3/net-device-container.h>
35#include <ns3/node-container.h>
36#include <ns3/point-to-point-epc-helper.h>
37#include <ns3/point-to-point-helper.h>
38#include <ns3/simulator.h>
39#include <ns3/string.h>
40
41using namespace ns3;
42
43NS_LOG_COMPONENT_DEFINE("LteUeMeasurementsTest");
44
45// ===== LTE-UE-MEASUREMENTS TEST SUITE ==================================== //
46
47void
49 std::string path,
50 uint16_t rnti,
51 uint16_t cellId,
52 double rsrp,
53 double rsrq,
54 bool servingCell,
55 uint8_t componentCarrierId)
56{
57 testcase->ReportUeMeasurements(rnti, cellId, rsrp, rsrq, servingCell);
58}
59
60void
62 std::string path,
63 uint64_t imsi,
64 uint16_t cellId,
65 uint16_t rnti,
67{
68 testcase->RecvMeasurementReport(imsi, cellId, rnti, meas);
69}
70
71/*
72 * Test Suite
73 */
74
76 : TestSuite("lte-ue-measurements", Type::SYSTEM)
77{
78 AddTestCase(new LteUeMeasurementsTestCase("d1=10, d2=10000",
79 10.000000,
80 10000.000000,
81 -53.739702,
82 -113.739702,
83 -3.010305,
84 -63.010305),
85 TestCase::Duration::EXTENSIVE);
86 AddTestCase(new LteUeMeasurementsTestCase("d1=20, d2=10000",
87 20.000000,
88 10000.000000,
89 -59.760302,
90 -113.739702,
91 -3.010319,
92 -56.989719),
93 TestCase::Duration::EXTENSIVE);
94 AddTestCase(new LteUeMeasurementsTestCase("d1=50, d2=10000",
95 50.000000,
96 10000.000000,
97 -67.719102,
98 -113.739702,
99 -3.010421,
100 -49.031021),
101 TestCase::Duration::EXTENSIVE);
102 AddTestCase(new LteUeMeasurementsTestCase("d1=100, d2=10000",
103 100.000000,
104 10000.000000,
105 -73.739702,
106 -113.739702,
107 -3.010783,
108 -43.010783),
109 TestCase::Duration::EXTENSIVE);
110 AddTestCase(new LteUeMeasurementsTestCase("d1=200, d2=10000",
111 200.000000,
112 10000.000000,
113 -79.760302,
114 -113.739702,
115 -3.012232,
116 -36.991632),
117 TestCase::Duration::EXTENSIVE);
118 AddTestCase(new LteUeMeasurementsTestCase("d1=100, d2=10000",
119 100.000000,
120 10000.000000,
121 -73.739702,
122 -113.739702,
123 -3.010783,
124 -43.010783),
125 TestCase::Duration::EXTENSIVE);
126 AddTestCase(new LteUeMeasurementsTestCase("d1=200, d2=10000",
127 200.000000,
128 10000.000000,
129 -79.760302,
130 -113.739702,
131 -3.012232,
132 -36.991632),
133 TestCase::Duration::EXTENSIVE);
134 AddTestCase(new LteUeMeasurementsTestCase("d1=500, d2=10000",
135 500.000000,
136 10000.000000,
137 -87.719102,
138 -113.739702,
139 -3.022359,
140 -29.042959),
141 TestCase::Duration::EXTENSIVE);
142 AddTestCase(new LteUeMeasurementsTestCase("d1=1000, d2=10000",
143 1000.000000,
144 10000.000000,
145 -93.739702,
146 -113.739702,
147 -3.058336,
148 -23.058336),
149 TestCase::Duration::EXTENSIVE);
150 AddTestCase(new LteUeMeasurementsTestCase("d1=2000, d2=10000",
151 2000.000000,
152 10000.000000,
153 -99.760302,
154 -113.739702,
155 -3.199337,
156 -17.178738),
157 TestCase::Duration::EXTENSIVE);
158 AddTestCase(new LteUeMeasurementsTestCase("d1=5000, d2=10000",
159 5000.000000,
160 10000.000000,
161 -107.719102,
162 -113.739702,
163 -4.075793,
164 -10.096393),
165 TestCase::Duration::QUICK);
166 AddTestCase(new LteUeMeasurementsTestCase("d1=10000, d2=10000",
167 10000.000000,
168 10000.000000,
169 -113.739702,
170 -113.739702,
171 -6.257687,
172 -6.257687),
173 TestCase::Duration::EXTENSIVE);
174 AddTestCase(new LteUeMeasurementsTestCase("d1=20000, d2=10000",
175 20000.000000,
176 10000.000000,
177 -119.760302,
178 -113.739702,
179 -10.373365,
180 -4.352765),
181 TestCase::Duration::EXTENSIVE);
182 AddTestCase(new LteUeMeasurementsTestCase("d1=50000, d2=10000",
183 50000.000000,
184 10000.000000,
185 -127.719102,
186 -113.739702,
187 -17.605046,
188 -3.625645),
189 TestCase::Duration::EXTENSIVE);
190 AddTestCase(new LteUeMeasurementsTestCase("d1=100000, d2=10000",
191 100000.000000,
192 10000.000000,
193 -133.739702,
194 -113.739702,
195 -23.511071,
196 -3.511071),
197 TestCase::Duration::EXTENSIVE);
198 AddTestCase(new LteUeMeasurementsTestCase("d1=200000, d2=10000",
199 200000.000000,
200 10000.000000,
201 -139.760302,
202 -113.739702,
203 -29.502549,
204 -3.481949),
205 TestCase::Duration::EXTENSIVE);
206 AddTestCase(new LteUeMeasurementsTestCase("d1=500000, d2=10000",
207 500000.000000,
208 10000.000000,
209 -147.719102,
210 -113.739702,
211 -37.453160,
212 -3.473760),
213 TestCase::Duration::EXTENSIVE);
214 AddTestCase(new LteUeMeasurementsTestCase("d1=1000000, d2=10000",
215 1000000.000000,
216 10000.000000,
217 -153.739702,
218 -113.739702,
219 -43.472589,
220 -3.472589),
221 TestCase::Duration::EXTENSIVE);
222}
223
224/**
225 * @ingroup lte-test
226 * Static variable for test initialization
227 */
229
230/*
231 * Test Case
232 */
233
235 double d1,
236 double d2,
237 double rsrpDbmUe1,
238 double rsrpDbmUe2,
239 double rsrqDbUe1,
240 double rsrqDbUe2)
241 : TestCase(name),
242 m_d1(d1),
243 m_d2(d2),
244 m_rsrpDbmUeServingCell(rsrpDbmUe1),
245 m_rsrpDbmUeNeighborCell(rsrpDbmUe2),
246 m_rsrqDbUeServingCell(rsrqDbUe1),
247 m_rsrqDbUeNeighborCell(rsrqDbUe2)
248{
249 NS_LOG_INFO("Test UE Measurements d1 = " << d1 << " m. and d2 = " << d2 << " m.");
250}
251
255
256void
258{
259 NS_LOG_INFO(this << " " << GetName());
260
261 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
262 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false));
263 Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::PiroEW2010));
264 Config::SetDefault("ns3::LteAmc::Ber", DoubleValue(0.00005));
266 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
267 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(false));
268
269 // Disable Uplink Power Control
270 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
271
272 // LogComponentEnable ("LteUeMeasurementsTest", LOG_LEVEL_ALL);
273
274 // Create Nodes: eNodeB and UE
275 NodeContainer enbNodes;
276 NodeContainer ueNodes1;
277 NodeContainer ueNodes2;
278 enbNodes.Create(2);
279 ueNodes1.Create(1);
280 ueNodes2.Create(1);
281 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
282
283 // the topology is the following:
284 // d2
285 // UE1-----------eNB2
286 // | |
287 // d1| |d1
288 // | d2 |
289 // eNB1----------UE2
290 //
292 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
293 positionAlloc->Add(Vector(m_d2, m_d1, 0.0)); // eNB2
294 positionAlloc->Add(Vector(0.0, m_d1, 0.0)); // UE1
295 positionAlloc->Add(Vector(m_d2, 0.0, 0.0)); // UE2
296 MobilityHelper mobility;
297 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
298 mobility.SetPositionAllocator(positionAlloc);
299 mobility.Install(allNodes);
300
301 // Create Devices and install them in the Nodes (eNB and UE)
302 NetDeviceContainer enbDevs;
303 NetDeviceContainer ueDevs1;
304 NetDeviceContainer ueDevs2;
305 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
306 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
307 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
308 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
309 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
310
311 // Attach UEs to eNodeBs
312 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
313 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
314
315 // Activate an EPS bearer
317 EpsBearer bearer(q);
318 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
319 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
320
322 "/NodeList/2/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
324 Config::Connect("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
326
328 "/NodeList/3/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
330 Config::Connect("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
332
333 // need to allow for RRC connection establishment + SRS
334 Simulator::Stop(Seconds(0.800));
336
338}
339
340void
342 uint16_t cellId,
343 double rsrp,
344 double rsrq,
345 bool servingCell)
346{
347 // need to allow for RRC connection establishment + CQI feedback reception + UE measurements
348 // filtering (200 ms)
349 if (Simulator::Now() > MilliSeconds(400))
350 {
351 if (servingCell)
352 {
353 NS_LOG_DEBUG("UE serving cellId " << cellId << " Rxed RSRP " << rsrp << " thr "
354 << m_rsrpDbmUeServingCell << " RSRQ " << rsrq
355 << " thr " << m_rsrqDbUeServingCell);
356 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrpDbmUeServingCell, rsrp, 0.2, "Wrong RSRP UE 1");
357 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrqDbUeServingCell, rsrq, 0.2, "Wrong RSRQ UE 1");
358 }
359 else
360 {
361 NS_LOG_DEBUG("UE neighbor cellId " << cellId << " Rxed RSRP " << rsrp << " thr "
362 << m_rsrpDbmUeNeighborCell << " RSRQ " << rsrq
363 << " thr " << m_rsrqDbUeNeighborCell);
364 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrpDbmUeNeighborCell, rsrp, 0.2, "Wrong RSRP UE 2");
365 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrqDbUeNeighborCell, rsrq, 0.2, "Wrong RSRQ UE ");
366 }
367 }
368}
369
370void
372 uint16_t cellId,
373 uint16_t rnti,
375{
376 // need to allow for RRC connection establishment + CQI feedback reception + UE measurements
377 // filtering (200 ms)
378 if (Simulator::Now() > MilliSeconds(400))
379 {
380 if (cellId == imsi)
381 {
383 this << "Serving Cell: received IMSI " << imsi << " CellId " << cellId << " RNTI "
384 << rnti << " thr "
386 << " RSRP " << (uint16_t)meas.measResults.measResultPCell.rsrpResult
387 << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult << " thr "
391 "Wrong RSRP ");
394 "Wrong RSRQ ");
395 }
396 else
397 {
399 this << "Neighbor cell: received IMSI " << imsi << " CellId " << cellId << " RNTI "
400 << rnti << " thr "
402 << " RSRP " << (uint16_t)meas.measResults.measResultPCell.rsrpResult
403 << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult << " thr "
407 "Wrong RSRP ");
410 "Wrong RSRQ ");
411 }
412 }
413}
414
415// ===== LTE-UE-MEASUREMENTS-PIECEWISE-1 TEST SUITE ======================== //
416
417/*
418 * Overloaded operators, for the convenience of defining test cases
419 */
420
421std::vector<Time>&
422operator<<(std::vector<Time>& v, const uint64_t& ms)
423{
424 /*
425 * Prior attempt to use seconds as unit of choice resulted in precision lost.
426 * Therefore milliseconds are used now instead.
427 */
428 v.push_back(MilliSeconds(ms) + UE_MEASUREMENT_REPORT_DELAY);
429 return v;
430}
431
432std::vector<uint8_t>&
433operator<<(std::vector<uint8_t>& v, const uint8_t& range)
434{
435 v.push_back(range);
436 return v;
437}
438
439/*
440 * Test Suite
441 */
442
444 : TestSuite("lte-ue-measurements-piecewise-1", Type::SYSTEM)
445{
446 std::vector<Time> expectedTime;
447 std::vector<uint8_t> expectedRsrp;
448
449 // === Event A1 (serving cell becomes better than threshold) ===
450
451 // With very low threshold
456 config.threshold1.range = 0;
459 expectedTime.clear();
460 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280 << 1400
461 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
462 expectedRsrp.clear();
463 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51 << 47 << 47
464 << 51 << 57 << 57;
466 "Piecewise test case 1 - Event A1 with very low threshold",
467 config,
468 expectedTime,
469 expectedRsrp),
470 TestCase::Duration::EXTENSIVE);
471
472 // With normal threshold
473 config.threshold1.range = 54;
474 expectedTime.clear();
475 expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 2000 << 2120;
476 expectedRsrp.clear();
477 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 57 << 57;
479 "Piecewise test case 1 - Event A1 with normal threshold",
480 config,
481 expectedTime,
482 expectedRsrp),
483 TestCase::Duration::EXTENSIVE);
484
485 // With short time-to-trigger
486 config.timeToTrigger = 64;
487 expectedTime.clear();
488 expectedTime << 264 << 384 << 504 << 624 << 744 << 1064 << 1184 << 1304 << 1424 << 2064 << 2184;
489 expectedRsrp.clear();
490 expectedRsrp << 67 << 67 << 57 << 66 << 66 << 66 << 66 << 57 << 51 << 57 << 57;
492 "Piecewise test case 1 - Event A1 with short time-to-trigger",
493 config,
494 expectedTime,
495 expectedRsrp),
496 TestCase::Duration::QUICK);
497
498 // With long time-to-trigger
499 config.timeToTrigger = 128;
500 expectedTime.clear();
501 expectedTime << 328 << 448 << 568 << 688 << 808 << 1128 << 1248 << 1368 << 1488 << 2128;
502 expectedRsrp.clear();
503 expectedRsrp << 67 << 57 << 57 << 66 << 47 << 66 << 57 << 57 << 51 << 57;
505 "Piecewise test case 1 - Event A1 with long time-to-trigger",
506 config,
507 expectedTime,
508 expectedRsrp),
509 TestCase::Duration::EXTENSIVE);
510
511 // With super time-to-trigger
512 config.timeToTrigger = 256;
513 expectedTime.clear();
514 expectedTime << 456 << 576 << 696 << 816 << 936 << 1056 << 1176 << 1296 << 1416 << 1536;
515 expectedRsrp.clear();
516 expectedRsrp << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51;
518 "Piecewise test case 1 - Event A1 with super time-to-trigger",
519 config,
520 expectedTime,
521 expectedRsrp),
522 TestCase::Duration::EXTENSIVE);
523
524 // With hysteresis
525 config.hysteresis = 8;
526 config.timeToTrigger = 0;
527 expectedTime.clear();
528 expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 1480 << 2200;
529 expectedRsrp.clear();
530 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 51 << 67;
532 new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A1 with hysteresis",
533 config,
534 expectedTime,
535 expectedRsrp),
536 TestCase::Duration::QUICK);
537
538 // With very high threshold
539 config.threshold1.range = 97;
540 config.hysteresis = 0;
541 expectedTime.clear();
542 expectedRsrp.clear();
544 "Piecewise test case 1 - Event A1 with very high threshold",
545 config,
546 expectedTime,
547 expectedRsrp),
548 TestCase::Duration::TAKES_FOREVER);
549
550 // === Event A2 (serving cell becomes worse than threshold) ===
551
552 // With very low threshold
554 config.threshold1.range = 0;
555 expectedTime.clear();
556 expectedRsrp.clear();
558 "Piecewise test case 1 - Event A2 with very low threshold",
559 config,
560 expectedTime,
561 expectedRsrp),
562 TestCase::Duration::TAKES_FOREVER);
563
564 // With normal threshold
565 config.threshold1.range = 54;
566 expectedTime.clear();
567 expectedTime << 800 << 920 << 1400 << 1520 << 1640 << 1760 << 1880;
568 expectedRsrp.clear();
569 expectedRsrp << 47 << 47 << 51 << 51 << 47 << 47 << 51;
571 "Piecewise test case 1 - Event A2 with normal threshold",
572 config,
573 expectedTime,
574 expectedRsrp),
575 TestCase::Duration::QUICK);
576
577 // With short time-to-trigger
578 config.timeToTrigger = 64;
579 expectedTime.clear();
580 expectedTime << 864 << 984 << 1464 << 1584 << 1704 << 1824 << 1944;
581 expectedRsrp.clear();
582 expectedRsrp << 47 << 47 << 51 << 51 << 47 << 51 << 51;
584 "Piecewise test case 1 - Event A2 with short time-to-trigger",
585 config,
586 expectedTime,
587 expectedRsrp),
588 TestCase::Duration::EXTENSIVE);
589
590 // With long time-to-trigger
591 config.timeToTrigger = 128;
592 expectedTime.clear();
593 expectedTime << 928 << 1048 << 1528 << 1648 << 1768 << 1888 << 2008;
594 expectedRsrp.clear();
595 expectedRsrp << 47 << 66 << 51 << 47 << 47 << 51 << 57;
597 "Piecewise test case 1 - Event A2 with long time-to-trigger",
598 config,
599 expectedTime,
600 expectedRsrp),
601 TestCase::Duration::TAKES_FOREVER);
602
603 // With super time-to-trigger
604 config.timeToTrigger = 256;
605 expectedTime.clear();
606 expectedTime << 1656 << 1776 << 1896 << 2016 << 2136;
607 expectedRsrp.clear();
608 expectedRsrp << 47 << 47 << 51 << 57 << 57;
610 "Piecewise test case 1 - Event A2 with super time-to-trigger",
611 config,
612 expectedTime,
613 expectedRsrp),
614 TestCase::Duration::QUICK);
615
616 // With hysteresis
617 config.hysteresis = 8;
618 config.timeToTrigger = 0;
619 expectedTime.clear();
620 expectedTime << 800 << 920 << 1600 << 1720 << 1840 << 1960 << 2080;
621 expectedRsrp.clear();
622 expectedRsrp << 47 << 47 << 47 << 47 << 51 << 51 << 57;
624 new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A2 with hysteresis",
625 config,
626 expectedTime,
627 expectedRsrp),
628 TestCase::Duration::EXTENSIVE);
629
630 // With very high threshold
631 config.threshold1.range = 97;
632 config.hysteresis = 0;
633 expectedTime.clear();
634 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280 << 1400
635 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
636 expectedRsrp.clear();
637 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51 << 47 << 47
638 << 51 << 57 << 57;
640 "Piecewise test case 1 - Event A2 with very high threshold",
641 config,
642 expectedTime,
643 expectedRsrp),
644 TestCase::Duration::EXTENSIVE);
645
646 /*
647 * Event A3, A4, and A5 are not tested intensively here because they depend on
648 * the existence of at least one neighbouring cell, which is not available in
649 * this configuration. Piecewise configuration #2 includes a neighbouring
650 * cell, hence more thorough tests on these events are performed there.
651 */
652
653 expectedTime.clear();
654 expectedRsrp.clear();
655
656 // === Event A3 (neighbour becomes offset better than PCell) ===
657
659 config.a3Offset = 0;
660 AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A3",
661 config,
662 expectedTime,
663 expectedRsrp),
664 TestCase::Duration::EXTENSIVE);
665
666 // === Event A4 (neighbour becomes better than threshold) ===
667
669 config.threshold1.range = 54;
670 AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A4",
671 config,
672 expectedTime,
673 expectedRsrp),
674 TestCase::Duration::EXTENSIVE);
675
676 // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than
677 // another absolute threshold2) ===
678
680 config.threshold2.range = 58;
681 AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A5",
682 config,
683 expectedTime,
684 expectedRsrp),
685 TestCase::Duration::EXTENSIVE);
686
687} // end of LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1
688
689/**
690 * @ingroup lte-test
691 * Static variable for test initialization
692 */
694
695/*
696 * Test Case
697 */
698
700 std::string name,
702 std::vector<Time> expectedTime,
703 std::vector<uint8_t> expectedRsrp)
704 : TestCase(name),
705 m_config(config),
706 m_expectedTime(expectedTime),
707 m_expectedRsrp(expectedRsrp)
708{
709 // input sanity check
710 uint16_t size = m_expectedTime.size();
711
712 if (size != m_expectedRsrp.size())
713 {
714 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
715 }
716
719
720 NS_LOG_INFO(this << " name=" << name);
721}
722
727
728void
730{
731 NS_LOG_INFO(this << " " << GetName());
732
734 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
735 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
736
737 // Disable Uplink Power Control
738 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
739
740 // Create Nodes: eNodeB and UE
741 NodeContainer enbNodes;
742 NodeContainer ueNodes;
743 enbNodes.Create(1);
744 ueNodes.Create(1);
745
746 /*
747 * The topology is the following:
748 *
749 * eNodeB UE
750 * | |
751 * x ----- x --------- x --------------- x ------------------- x
752 * 100 m | 200 m | 300 m | 400 m |
753 * | | | |
754 * VeryNear Near Far VeryFar
755 */
756
758 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNodeB
759 positionAlloc->Add(Vector(100.0, 0.0, 0.0)); // UE
760 MobilityHelper mobility;
761 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
762 mobility.SetPositionAllocator(positionAlloc);
763 mobility.Install(enbNodes);
764 mobility.Install(ueNodes);
765 m_ueMobility = ueNodes.Get(0)->GetObject<MobilityModel>();
766
767 // Disable layer-3 filtering
768 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
769
770 // Create Devices and install them in the Nodes (eNB and UE)
771 NetDeviceContainer enbDevs;
772 NetDeviceContainer ueDevs;
773 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
774 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
775 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
776 ueDevs = lteHelper->InstallUeDevice(ueNodes);
777
778 // Setup UE measurement configuration
779 Ptr<LteEnbRrc> enbRrc = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
780 m_expectedMeasId = enbRrc->AddUeMeasReportConfig(m_config).at(0);
781
782 // Attach UE to eNodeB
783 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
784
785 // Activate an EPS bearer
787 EpsBearer bearer(q);
788 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
789
790 // Connect to trace sources
792 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
794
795 /*
796 * Schedule "teleports"
797 * 0 1 2
798 * +-------------------+-------------------+---------> time
799 * VeryNear |------ ---- ---- --------
800 * Near | ---- ----
801 * Far | ---- ----
802 * VeryFar | -- ---- ----
803 */
806 this);
809 this);
812 this);
815 this);
818 this);
821 this);
824 this);
827 this);
830 this);
833 this);
834
835 // Run simulation
836 Simulator::Stop(Seconds(2.201));
839
840} // end of void LteUeMeasurementsPiecewiseTestCase1::DoRun ()
841
842void
844{
845 NS_LOG_FUNCTION(this);
846 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
847 NS_TEST_ASSERT_MSG_EQ(hasEnded,
848 true,
849 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
850 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
851 NS_ASSERT(hasEnded);
852}
853
854void
856 std::string context,
857 uint64_t imsi,
858 uint16_t cellId,
859 uint16_t rnti,
861{
862 NS_LOG_FUNCTION(this << context);
863 NS_ASSERT(rnti == 1);
864 NS_ASSERT(cellId == 1);
865
866 if (report.measResults.measId == m_expectedMeasId)
867 {
868 // verifying the report completeness
869 LteRrcSap::MeasResults measResults = report.measResults;
871 this << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
873 << " dBm)"
874 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
876 << " dB)");
878 false,
879 "Report should not have neighboring cells information");
880 NS_TEST_ASSERT_MSG_EQ(measResults.measResultListEutra.size(), 0, "Unexpected report size");
881
882 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
883 NS_TEST_ASSERT_MSG_EQ(hasEnded,
884 false,
885 "Reporting should not have occurred at "
886 << Simulator::Now().As(Time::S));
887 if (!hasEnded)
888 {
889 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
890 NS_ASSERT(!hasEnded);
891
892 // using milliseconds to avoid floating-point comparison
893 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
894 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
896
897 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
898 uint16_t referenceRsrp = *m_itExpectedRsrp;
900
901 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
902 timeExpectedMs,
903 "Reporting should not have occurred at this time");
904 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
905 referenceRsrp,
906 "The RSRP observed differs with the reference RSRP");
907 } // end of if (!hasEnded)
908
909 } // end of if (measResults.measId == m_expectedMeasId)
910
911} // end of LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback
912
913void
915{
916 NS_LOG_FUNCTION(this);
917 m_ueMobility->SetPosition(Vector(100.0, 0.0, 0.0));
918}
919
920void
922{
923 NS_LOG_FUNCTION(this);
924 m_ueMobility->SetPosition(Vector(300.0, 0.0, 0.0));
925}
926
927void
929{
930 NS_LOG_FUNCTION(this);
931 m_ueMobility->SetPosition(Vector(600.0, 0.0, 0.0));
932}
933
934void
936{
937 NS_LOG_FUNCTION(this);
938 m_ueMobility->SetPosition(Vector(1000.0, 0.0, 0.0));
939}
940
941// ===== LTE-UE-MEASUREMENTS-PIECEWISE-2 TEST SUITE ======================== //
942
943/*
944 * Test Suite
945 */
946
948 : TestSuite("lte-ue-measurements-piecewise-2", Type::SYSTEM)
949{
950 std::vector<Time> expectedTime;
951 std::vector<uint8_t> expectedRsrp;
952
953 /*
954 * Higher level of fullness/duration are given to Event A1 and A2 because they
955 * are supposed to be more intensively tested in Piecewise configuration #1.
956 */
957
958 // === Event A1 (serving cell becomes better than threshold) ===
959
960 // With very low threshold
965 config.threshold1.range = 0;
968 expectedTime.clear();
969 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
970 expectedRsrp.clear();
971 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
973 "Piecewise test case 2 - Event A1 with very low threshold",
974 config,
975 expectedTime,
976 expectedRsrp),
977 TestCase::Duration::EXTENSIVE);
978
979 // With normal threshold
980 config.threshold1.range = 58;
981 expectedTime.clear();
982 expectedTime << 200 << 440 << 680 << 1000 << 1240 << 2000;
983 expectedRsrp.clear();
984 expectedRsrp << 73 << 63 << 72 << 72 << 59 << 59;
986 "Piecewise test case 2 - Event A1 with normal threshold",
987 config,
988 expectedTime,
989 expectedRsrp),
990 TestCase::Duration::TAKES_FOREVER);
991
992 // With hysteresis
993 config.hysteresis = 6;
994 expectedTime.clear();
995 expectedTime << 200 << 440 << 680 << 1000 << 1240 << 1480 << 2200;
996 expectedRsrp.clear();
997 expectedRsrp << 73 << 63 << 72 << 72 << 59 << 56 << 72;
999 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A1 with hysteresis",
1000 config,
1001 expectedTime,
1002 expectedRsrp),
1003 TestCase::Duration::EXTENSIVE);
1004
1005 // With very high threshold
1006 config.threshold1.range = 97;
1007 config.hysteresis = 0;
1008 expectedTime.clear();
1009 expectedRsrp.clear();
1011 "Piecewise test case 2 - Event A1 with very high threshold",
1012 config,
1013 expectedTime,
1014 expectedRsrp),
1015 TestCase::Duration::TAKES_FOREVER);
1016
1017 // === Event A2 (serving cell becomes worse than threshold) ===
1018
1019 // With very low threshold
1021 config.threshold1.range = 0;
1022 expectedTime.clear();
1023 expectedRsrp.clear();
1025 "Piecewise test case 2 - Event A2 with very low threshold",
1026 config,
1027 expectedTime,
1028 expectedRsrp),
1029 TestCase::Duration::TAKES_FOREVER);
1030
1031 // With normal threshold
1032 config.threshold1.range = 58;
1033 expectedTime.clear();
1034 expectedTime << 800 << 1400 << 1640 << 1880;
1035 expectedRsrp.clear();
1036 expectedRsrp << 52 << 56 << 52 << 56;
1038 "Piecewise test case 2 - Event A2 with normal threshold",
1039 config,
1040 expectedTime,
1041 expectedRsrp),
1042 TestCase::Duration::TAKES_FOREVER);
1043
1044 // With hysteresis
1045 config.hysteresis = 6;
1046 expectedTime.clear();
1047 expectedTime << 800 << 1600 << 1840 << 2080;
1048 expectedRsrp.clear();
1049 expectedRsrp << 52 << 52 << 56 << 59;
1051 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A2 with hysteresis",
1052 config,
1053 expectedTime,
1054 expectedRsrp),
1055 TestCase::Duration::EXTENSIVE);
1056
1057 // With very high threshold
1058 config.threshold1.range = 97;
1059 config.hysteresis = 0;
1060 expectedTime.clear();
1061 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1062 expectedRsrp.clear();
1063 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1065 "Piecewise test case 2 - Event A2 with very high threshold",
1066 config,
1067 expectedTime,
1068 expectedRsrp),
1069 TestCase::Duration::TAKES_FOREVER);
1070
1071 // === Event A3 (neighbour becomes offset better than PCell) ===
1072
1073 // With positive offset
1075 config.threshold1.range = 0;
1076 config.a3Offset = 7;
1077 expectedTime.clear();
1078 expectedTime << 800 << 1600;
1079 expectedRsrp.clear();
1080 expectedRsrp << 52 << 52;
1082 "Piecewise test case 2 - Event A3 with positive offset",
1083 config,
1084 expectedTime,
1085 expectedRsrp),
1086 TestCase::Duration::QUICK);
1087
1088 // With zero offset
1089 config.a3Offset = 0;
1090 expectedTime.clear();
1091 expectedTime << 800 << 1400 << 1640 << 1880;
1092 expectedRsrp.clear();
1093 expectedRsrp << 52 << 56 << 52 << 56;
1095 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A3 with zero offset",
1096 config,
1097 expectedTime,
1098 expectedRsrp),
1099 TestCase::Duration::EXTENSIVE);
1100
1101 // With short time-to-trigger
1102 config.timeToTrigger = 160;
1103 expectedTime.clear();
1104 expectedTime << 960 << 1560 << 1800 << 2040;
1105 expectedRsrp.clear();
1106 expectedRsrp << 52 << 56 << 56 << 59;
1108 "Piecewise test case 2 - Event A3 with short time-to-trigger",
1109 config,
1110 expectedTime,
1111 expectedRsrp),
1112 TestCase::Duration::EXTENSIVE);
1113
1114 // With super time-to-trigger
1115 config.timeToTrigger = 320;
1116 expectedTime.clear();
1117 expectedTime << 1720 << 1960 << 2200;
1118 expectedRsrp.clear();
1119 expectedRsrp << 52 << 56 << 72;
1121 "Piecewise test case 2 - Event A3 with super time-to-trigger",
1122 config,
1123 expectedTime,
1124 expectedRsrp),
1125 TestCase::Duration::QUICK);
1126
1127 // With hysteresis and reportOnLeave
1128 config.hysteresis = 6;
1129 config.reportOnLeave = true;
1130 config.timeToTrigger = 0;
1131 expectedTime.clear();
1132 expectedTime << 800 << 1000 << 1600 << 1840 << 2080 << 2200;
1133 expectedRsrp.clear();
1134 expectedRsrp << 52 << 72 << 52 << 56 << 59 << 72;
1136 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A3 with hysteresis",
1137 config,
1138 expectedTime,
1139 expectedRsrp),
1140 TestCase::Duration::QUICK);
1141
1142 // With negative offset
1143 config.a3Offset = -7;
1144 config.hysteresis = 0;
1145 config.reportOnLeave = false;
1146 expectedTime.clear();
1147 expectedTime << 400 << 800 << 1200 << 1440 << 1680 << 1920 << 2160;
1148 expectedRsrp.clear();
1149 expectedRsrp << 63 << 52 << 59 << 56 << 52 << 56 << 59;
1151 "Piecewise test case 2 - Event A3 with negative offset",
1152 config,
1153 expectedTime,
1154 expectedRsrp),
1155 TestCase::Duration::EXTENSIVE);
1156
1157 // === Event A4 (neighbour becomes better than threshold) ===
1158
1159 // With very low threshold
1161 config.threshold1.range = 0;
1162 config.a3Offset = 0;
1163 expectedTime.clear();
1164 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1165 expectedRsrp.clear();
1166 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1168 "Piecewise test case 2 - Event A4 with very low threshold",
1169 config,
1170 expectedTime,
1171 expectedRsrp),
1172 TestCase::Duration::QUICK);
1173
1174 // With normal threshold
1175 config.threshold1.range = 58;
1176 expectedTime.clear();
1177 expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1178 expectedRsrp.clear();
1179 expectedRsrp << 63 << 52 << 56 << 52 << 56;
1181 "Piecewise test case 2 - Event A4 with normal threshold",
1182 config,
1183 expectedTime,
1184 expectedRsrp),
1185 TestCase::Duration::EXTENSIVE);
1186
1187 // With short time-to-trigger
1188 config.timeToTrigger = 160;
1189 expectedTime.clear();
1190 expectedTime << 560 << 960 << 1560 << 1800 << 2040;
1191 expectedRsrp.clear();
1192 expectedRsrp << 63 << 52 << 56 << 56 << 59;
1194 "Piecewise test case 2 - Event A4 with short time-to-trigger",
1195 config,
1196 expectedTime,
1197 expectedRsrp),
1198 TestCase::Duration::QUICK);
1199
1200 // With super time-to-trigger
1201 config.timeToTrigger = 320;
1202 expectedTime.clear();
1203 expectedTime << 1720 << 1960 << 2200;
1204 expectedRsrp.clear();
1205 expectedRsrp << 52 << 56 << 72;
1207 "Piecewise test case 2 - Event A4 with super time-to-trigger",
1208 config,
1209 expectedTime,
1210 expectedRsrp),
1211 TestCase::Duration::TAKES_FOREVER);
1212
1213 // With hysteresis
1214 config.hysteresis = 6;
1215 config.timeToTrigger = 0;
1216 expectedTime.clear();
1217 expectedTime << 400 << 800 << 1600 << 1840 << 2080;
1218 expectedRsrp.clear();
1219 expectedRsrp << 63 << 52 << 52 << 56 << 59;
1221 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A4 with hysteresis",
1222 config,
1223 expectedTime,
1224 expectedRsrp),
1225 TestCase::Duration::QUICK);
1226
1227 // With very high threshold
1228 config.threshold1.range = 97;
1229 config.hysteresis = 0;
1230 expectedTime.clear();
1231 expectedRsrp.clear();
1233 "Piecewise test case 2 - Event A4 with very high threshold",
1234 config,
1235 expectedTime,
1236 expectedRsrp),
1237 TestCase::Duration::TAKES_FOREVER);
1238
1239 // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than
1240 // another absolute threshold2) ===
1241
1242 // With low-low threshold
1244 config.threshold1.range = 0;
1245 config.threshold2.range = 0;
1246 expectedTime.clear();
1247 expectedRsrp.clear();
1249 "Piecewise test case 2 - Event A5 with low-low threshold",
1250 config,
1251 expectedTime,
1252 expectedRsrp),
1253 TestCase::Duration::EXTENSIVE);
1254
1255 // With low-normal threshold
1256 config.threshold2.range = 58;
1258 "Piecewise test case 2 - Event A5 with low-normal threshold",
1259 config,
1260 expectedTime,
1261 expectedRsrp),
1262 TestCase::Duration::TAKES_FOREVER);
1263
1264 // With low-high threshold
1265 config.threshold2.range = 97;
1267 "Piecewise test case 2 - Event A5 with low-high threshold",
1268 config,
1269 expectedTime,
1270 expectedRsrp),
1271 TestCase::Duration::TAKES_FOREVER);
1272
1273 // With normal-low threshold
1274 config.threshold1.range = 58;
1275 config.threshold2.range = 0;
1276 expectedTime.clear();
1277 expectedTime << 800 << 1400 << 1640 << 1880;
1278 expectedRsrp.clear();
1279 expectedRsrp << 52 << 56 << 52 << 56;
1281 "Piecewise test case 2 - Event A5 with normal-low threshold",
1282 config,
1283 expectedTime,
1284 expectedRsrp),
1285 TestCase::Duration::EXTENSIVE);
1286
1287 // With normal-normal threshold
1288 config.threshold2.range = 58;
1289 expectedTime.clear();
1290 expectedTime << 800 << 1400 << 1640 << 1880;
1291 expectedRsrp.clear();
1292 expectedRsrp << 52 << 56 << 52 << 56;
1294 "Piecewise test case 2 - Event A5 with normal-normal threshold",
1295 config,
1296 expectedTime,
1297 expectedRsrp),
1298 TestCase::Duration::EXTENSIVE);
1299
1300 // With short time-to-trigger
1301 config.timeToTrigger = 160;
1302 expectedTime.clear();
1303 expectedTime << 960 << 1560 << 1800 << 2040;
1304 expectedRsrp.clear();
1305 expectedRsrp << 52 << 56 << 56 << 59;
1307 "Piecewise test case 2 - Event A5 with short time-to-trigger",
1308 config,
1309 expectedTime,
1310 expectedRsrp),
1311 TestCase::Duration::TAKES_FOREVER);
1312
1313 // With super time-to-trigger
1314 config.timeToTrigger = 320;
1315 expectedTime.clear();
1316 expectedTime << 1720 << 1960 << 2200;
1317 expectedRsrp.clear();
1318 expectedRsrp << 52 << 56 << 72;
1320 "Piecewise test case 2 - Event A5 with super time-to-trigger",
1321 config,
1322 expectedTime,
1323 expectedRsrp),
1324 TestCase::Duration::QUICK);
1325
1326 // With hysteresis
1327 config.hysteresis = 6;
1328 config.timeToTrigger = 0;
1329 expectedTime.clear();
1330 expectedTime << 800 << 1600 << 1840 << 2080;
1331 expectedRsrp.clear();
1332 expectedRsrp << 52 << 52 << 56 << 59;
1334 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A5 with hysteresis",
1335 config,
1336 expectedTime,
1337 expectedRsrp),
1338 TestCase::Duration::QUICK);
1339
1340 // With normal-high threshold
1341 config.threshold2.range = 97;
1342 config.hysteresis = 0;
1343 expectedTime.clear();
1344 expectedRsrp.clear();
1346 "Piecewise test case 2 - Event A5 with normal-high threshold",
1347 config,
1348 expectedTime,
1349 expectedRsrp),
1350 TestCase::Duration::TAKES_FOREVER);
1351
1352 // With high-low threshold
1353 config.threshold1.range = 97;
1354 config.threshold2.range = 0;
1355 expectedTime.clear();
1356 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1357 expectedRsrp.clear();
1358 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1360 "Piecewise test case 2 - Event A5 with high-low threshold",
1361 config,
1362 expectedTime,
1363 expectedRsrp),
1364 TestCase::Duration::EXTENSIVE);
1365
1366 // With high-normal threshold
1367 config.threshold2.range = 58;
1368 expectedTime.clear();
1369 expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1370 expectedRsrp.clear();
1371 expectedRsrp << 63 << 52 << 56 << 52 << 56;
1373 "Piecewise test case 2 - Event A5 with high-normal threshold",
1374 config,
1375 expectedTime,
1376 expectedRsrp),
1377 TestCase::Duration::TAKES_FOREVER);
1378
1379 // With high-high threshold
1380 config.threshold2.range = 97;
1381 expectedTime.clear();
1382 expectedRsrp.clear();
1384 "Piecewise test case 2 - Event A5 with high-high threshold",
1385 config,
1386 expectedTime,
1387 expectedRsrp),
1388 TestCase::Duration::EXTENSIVE);
1389
1390} // end of LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2
1391
1392/**
1393 * @ingroup lte-test
1394 * Static variable for test initialization
1395 */
1397
1398/*
1399 * Test Case
1400 */
1401
1403 std::string name,
1405 std::vector<Time> expectedTime,
1406 std::vector<uint8_t> expectedRsrp)
1407 : TestCase(name),
1408 m_config(config),
1409 m_expectedTime(expectedTime),
1410 m_expectedRsrp(expectedRsrp)
1411{
1412 // input sanity check
1413 uint16_t size = m_expectedTime.size();
1414
1415 if (size != m_expectedRsrp.size())
1416 {
1417 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
1418 }
1419
1422
1423 NS_LOG_INFO(this << " name=" << name);
1424}
1425
1430
1431void
1433{
1434 NS_LOG_INFO(this << " " << GetName());
1435
1437 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1438 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1439
1440 // Disable Uplink Power Control
1441 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1442
1443 // Create Nodes: eNodeB and UE
1444 NodeContainer enbNodes;
1445 NodeContainer ueNodes;
1446 enbNodes.Create(2);
1447 ueNodes.Create(1);
1448
1449 /*
1450 * The topology is the following:
1451 *
1452 * eNodeB UE eNodeB
1453 * | | |
1454 * x ---- x --------------- x ------- x --------------- x ---- x
1455 * 50 m | 200 m | 100 m | 200 m | 50 m
1456 * | | | |
1457 * VeryNear Near Far VeryFar
1458 */
1459
1461 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1462 positionAlloc->Add(Vector(600.0, 0.0, 0.0)); // Neighbour eNodeB
1463 positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1464 MobilityHelper mobility;
1465 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1466 mobility.SetPositionAllocator(positionAlloc);
1467 mobility.Install(enbNodes);
1468 mobility.Install(ueNodes);
1469 m_ueMobility = ueNodes.Get(0)->GetObject<MobilityModel>();
1470
1471 // Disable layer-3 filtering
1472 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1473
1474 // Create Devices and install them in the Nodes (eNB and UE)
1475 NetDeviceContainer enbDevs;
1476 NetDeviceContainer ueDevs;
1477 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1478 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1479 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1480 ueDevs = lteHelper->InstallUeDevice(ueNodes);
1481
1482 // Setup UE measurement configuration in serving cell
1483 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1484 m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1485
1486 // Disable handover in neighbour cell
1487 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1488 enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1489
1490 // Attach UE to serving eNodeB
1491 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1492
1493 // Activate an EPS bearer
1495 EpsBearer bearer(q);
1496 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1497
1498 // Connect to trace sources in serving eNodeB
1500 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1502
1503 /*
1504 * Schedule "teleports"
1505 * 0 1 2
1506 * +-------------------+-------------------+---------> time
1507 * VeryNear |------ ---- ---- --------
1508 * Near | ---- ----
1509 * Far | ---- ----
1510 * VeryFar | -- ---- ----
1511 */
1514 this);
1517 this);
1520 this);
1523 this);
1526 this);
1529 this);
1532 this);
1535 this);
1538 this);
1541 this);
1542
1543 // Run simulation
1544 Simulator::Stop(Seconds(2.201));
1547
1548} // end of void LteUeMeasurementsPiecewiseTestCase2::DoRun ()
1549
1550void
1552{
1553 NS_LOG_FUNCTION(this);
1554 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1555 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1556 true,
1557 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
1558 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1559 NS_ASSERT(hasEnded);
1560}
1561
1562void
1564 std::string context,
1565 uint64_t imsi,
1566 uint16_t cellId,
1567 uint16_t rnti,
1569{
1570 NS_LOG_FUNCTION(this << context);
1571 NS_ASSERT(rnti == 1);
1572 NS_ASSERT(cellId == 1);
1573
1574 if (report.measResults.measId != m_expectedMeasId)
1575 {
1576 return;
1577 }
1578
1579 // verifying the report completeness
1580 LteRrcSap::MeasResults measResults = report.measResults;
1582 this << " Serving cellId=" << cellId
1583 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1585 << " dBm)"
1586 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1588 << " dB)");
1589
1590 // verifying reported best cells
1591 if (measResults.measResultListEutra.empty())
1592 {
1594 false,
1595 "Unexpected report content");
1596 }
1597 else
1598 {
1600 true,
1601 "Unexpected report content");
1602 auto it = measResults.measResultListEutra.begin();
1603 NS_ASSERT(it != measResults.measResultListEutra.end());
1604 NS_ASSERT(it->physCellId == 2);
1605 NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
1606 false,
1607 "Report contains cgi-info, which is not supported");
1608 NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
1609 true,
1610 "Report does not contain measured RSRP result");
1611 NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
1612 true,
1613 "Report does not contain measured RSRQ result");
1614 NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
1615 << " rsrp=" << (uint16_t)it->rsrpResult << " ("
1616 << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
1617 << " rsrq=" << (uint16_t)it->rsrqResult << " ("
1618 << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
1619
1620 } // end of else of if (measResults.measResultListEutra.size () == 0)
1621
1622 // verifying the report timing
1623 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1624 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1625 false,
1626 "Reporting should not have occurred at " << Simulator::Now().As(Time::S));
1627 if (hasEnded)
1628 {
1629 return;
1630 }
1631
1632 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1633 NS_ASSERT(!hasEnded);
1634
1635 // using milliseconds to avoid floating-point comparison
1636 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1637 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1639
1640 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
1641 uint16_t referenceRsrp = *m_itExpectedRsrp;
1643
1644 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1645 timeExpectedMs,
1646 "Reporting should not have occurred at this time");
1647 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
1648 referenceRsrp,
1649 "The RSRP observed differs with the reference RSRP");
1650
1651} // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
1652
1653void
1655{
1656 NS_LOG_FUNCTION(this);
1657 m_ueMobility->SetPosition(Vector(50.0, 0.0, 0.0));
1658}
1659
1660void
1662{
1663 NS_LOG_FUNCTION(this);
1664 m_ueMobility->SetPosition(Vector(250.0, 0.0, 0.0));
1665}
1666
1667void
1669{
1670 NS_LOG_FUNCTION(this);
1671 m_ueMobility->SetPosition(Vector(350.0, 0.0, 0.0));
1672}
1673
1674void
1676{
1677 NS_LOG_FUNCTION(this);
1678 m_ueMobility->SetPosition(Vector(550.0, 0.0, 0.0));
1679}
1680
1681// ===== LTE-UE-MEASUREMENTS-PIECEWISE-3 TEST SUITE ======================== //
1682
1683/*
1684 * Test Suite
1685 */
1686
1688 : TestSuite("lte-ue-measurements-piecewise-3", Type::SYSTEM)
1689{
1690 std::vector<Time> expectedTime;
1691
1692 // === Event A4 (neighbor becomes better than threshold) ===
1693
1694 // The threshold value was chosen to achieve the following:
1695 // 1. Neighbor 1 (eNB2) RSRP would be above the chosen threshold, hence,
1696 // the UE will include it in its reports to its eNB (eNB1) from the beginning
1697 // of the simulation.
1698 // 2. When neighbor 2 (eNB3) is placed at a very far position, its RSRP would
1699 // be less than the chosen threshold, hence, UE will not include it in its
1700 // initial report(s) to its eNB.
1701 // 3. When neighbor 2 (eNB3) is placed at a near position, its RSRP would
1702 // always be above the chosen threshold, hence, the UE will include it in its
1703 // reports to its eNB (eNB1).
1708 config.threshold1.range = 6;
1711 expectedTime.clear();
1712 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1713
1714 AddTestCase(new LteUeMeasurementsPiecewiseTestCase3("Piecewise test case 3 - Event A4",
1715 config,
1716 expectedTime),
1717 TestCase::Duration::QUICK);
1718} // end of LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3
1719
1720/**
1721 * @ingroup lte-test
1722 * Static variable for test initialization
1723 */
1725
1726/*
1727 * Test Case
1728 */
1729
1731 std::string name,
1733 std::vector<Time> expectedTime)
1734 : TestCase(name),
1735 m_config(config),
1736 m_expectedTime(expectedTime)
1737{
1738 m_expectedMeasId = std::numeric_limits<uint8_t>::max();
1739
1741
1742 NS_LOG_INFO(this << " name=" << name);
1743}
1744
1749
1750void
1752{
1753 NS_LOG_INFO(this << " " << GetName());
1754
1756 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1757 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1758
1759 // Disable Uplink Power Control
1760 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1761
1762 // Create Nodes: eNodeB and UE
1763 NodeContainer enbNodes;
1764 NodeContainer ueNodes;
1765 enbNodes.Create(3);
1766 ueNodes.Create(1);
1767
1768 /*
1769 * The topology is the following:
1770 *
1771 * We place the 3rd eNB initially very far so it does not fulfills
1772 * the entry condition to be reported.
1773 *
1774 * eNodeB UE eNodeB eNodeB
1775 * | | | |
1776 * x ---- x --------------- x -------------- x ---------------------x
1777 * 50 m 100 m 500 | 1000000
1778 * Near
1779 */
1780
1782 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1783 positionAlloc->Add(Vector(200.0, 0.0, 0.0)); // Neighbour eNodeB1
1784 positionAlloc->Add(Vector(1000700.0, 0.0, 0.0)); // Neighbour eNodeB2
1785 positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1786 MobilityHelper mobility;
1787 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1788 mobility.SetPositionAllocator(positionAlloc);
1789 mobility.Install(enbNodes);
1790 mobility.Install(ueNodes);
1791 m_enbMobility = enbNodes.Get(2)->GetObject<MobilityModel>();
1792
1793 // Disable layer-3 filtering
1794 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1795
1796 // Create Devices and install them in the Nodes (eNB and UE)
1797 NetDeviceContainer enbDevs;
1798 NetDeviceContainer ueDevs;
1799 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1800 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1801 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1802 ueDevs = lteHelper->InstallUeDevice(ueNodes);
1803
1804 // Setup UE measurement configuration in serving cell
1805 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1806 m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1807
1808 // Disable handover in neighbour cells
1809 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1810 enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1811 Ptr<LteEnbRrc> enbRrc3 = enbDevs.Get(2)->GetObject<LteEnbNetDevice>()->GetRrc();
1812 enbRrc3->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1813
1814 // Attach UE to serving eNodeB
1815 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1816
1817 // Activate an EPS bearer
1819 EpsBearer bearer(q);
1820 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1821
1822 // Connect to trace sources in serving eNodeB
1824 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1826 /*
1827 * Schedule "teleport" for the 2nd neighbour
1828 *
1829 * We bring the 2nd neighbour near once the UE has already scheduled the periodic
1830 * reporting after detecting the 1st neighbour, which ideally should be at
1831 * 200 ms.
1832 */
1835 this);
1836
1837 // Run simulation
1838 Simulator::Stop(Seconds(2.201));
1841
1842} // end of void LteUeMeasurementsPiecewiseTestCase3::DoRun ()
1843
1844void
1846{
1847 NS_LOG_FUNCTION(this);
1848 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1849 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1850 true,
1851 "Reporting should have occurred at " << m_itExpectedTime->GetSeconds()
1852 << "s");
1853}
1854
1855void
1857 std::string context,
1858 uint64_t imsi,
1859 uint16_t cellId,
1860 uint16_t rnti,
1862{
1863 NS_LOG_FUNCTION(this << context);
1864 NS_ASSERT(rnti == 1);
1865 NS_ASSERT(cellId == 1);
1866
1867 if (report.measResults.measId != m_expectedMeasId)
1868 {
1869 return;
1870 }
1871
1872 // verifying the report completeness
1873 LteRrcSap::MeasResults measResults = report.measResults;
1875 this << " Serving cellId=" << cellId
1876 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1878 << " dBm)"
1879 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1881 << " dB)");
1882
1883 // verifying reported best cells
1884 if (measResults.measResultListEutra.empty())
1885 {
1887 false,
1888 "Unexpected report content");
1889 }
1890 else
1891 {
1893 true,
1894 "Unexpected report content");
1895 auto it = measResults.measResultListEutra.begin();
1896 NS_ASSERT(it != measResults.measResultListEutra.end());
1897 for (const auto& it : measResults.measResultListEutra)
1898 {
1899 NS_ASSERT(it.physCellId == 2 || it.physCellId == 3);
1900 NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo,
1901 false,
1902 "Report contains cgi-info, which is not supported");
1903 NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult,
1904 true,
1905 "Report does not contain measured RSRP result");
1906 NS_TEST_ASSERT_MSG_EQ(it.haveRsrqResult,
1907 true,
1908 "Report does not contain measured RSRQ result");
1909 NS_LOG_DEBUG(this << " Neighbour cellId=" << it.physCellId
1910 << " rsrp=" << (uint16_t)it.rsrpResult << " ("
1911 << EutranMeasurementMapping::RsrpRange2Dbm(it.rsrpResult) << " dBm)"
1912 << " rsrq=" << (uint16_t)it.rsrqResult << " ("
1913 << EutranMeasurementMapping::RsrqRange2Db(it.rsrqResult) << " dB)");
1914 }
1915
1916 } // end of else of if (measResults.measResultListEutra.size () == 0)
1917
1918 // verifying the report timing
1919 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1920 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1921 false,
1922 "Reporting should not have occurred at " << Simulator::Now().GetSeconds()
1923 << "s");
1924 if (hasEnded)
1925 {
1926 return;
1927 }
1928
1929 // using milliseconds to avoid floating-point comparison
1930 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1931 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1933
1934 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1935 timeExpectedMs,
1936 "Reporting should not have occurred at this time");
1937
1938} // end of void LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback
1939
1940void
1942{
1943 NS_LOG_FUNCTION(this);
1944 m_enbMobility->SetPosition(Vector(700.0, 0.0, 0.0));
1945}
1946
1947// ===== LTE-UE-MEASUREMENTS-HANDOVER TEST SUITE =========================== //
1948
1949/*
1950 * Test Suite
1951 */
1952
1954 : TestSuite("lte-ue-measurements-handover", Type::SYSTEM)
1955{
1956 std::list<LteRrcSap::ReportConfigEutra> sourceConfigList;
1957 std::list<LteRrcSap::ReportConfigEutra> targetConfigList;
1958 std::vector<Time> expectedTime;
1959 std::vector<uint8_t> expectedRsrp;
1960
1961 LteRrcSap::ReportConfigEutra sourceConfig;
1965 sourceConfig.threshold1.range = 0;
1968 sourceConfigList.push_back(sourceConfig);
1969
1970 LteRrcSap::ReportConfigEutra targetConfig;
1974 targetConfig.threshold1.range = 0;
1977 targetConfigList.push_back(targetConfig);
1978
1979 // === Report interval difference ===
1980
1981 // decreasing report interval
1982 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS480;
1983 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1984 expectedTime.clear();
1985 expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
1986 expectedRsrp.clear();
1987 expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
1989 new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing report interval",
1990 sourceConfigList,
1991 targetConfigList,
1992 expectedTime,
1993 expectedRsrp,
1994 Seconds(2)),
1995 TestCase::Duration::TAKES_FOREVER);
1996
1997 // increasing report interval
1998 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS120;
1999 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS640;
2000 expectedTime.clear();
2001 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1200 << 1840;
2002 expectedRsrp.clear();
2003 expectedRsrp << 55 << 55 << 55 << 55 << 55 << 55 << 55 << 53 << 53;
2005 new LteUeMeasurementsHandoverTestCase("Handover test case - increasing report interval",
2006 sourceConfigList,
2007 targetConfigList,
2008 expectedTime,
2009 expectedRsrp,
2010 Seconds(2)),
2011 TestCase::Duration::QUICK);
2012
2013 // === Event difference ===
2014
2015 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2016 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2017 sourceConfigList.front().threshold1.range = 54;
2018 sourceConfigList.front().threshold2.range = 54;
2019 sourceConfigList.front().a3Offset = 1;
2020 targetConfigList.front().threshold1.range = 54;
2021 targetConfigList.front().threshold2.range = 54;
2022 targetConfigList.front().a3Offset = 1;
2023
2024 // Event A1 to Event A2
2025 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2026 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2027 expectedTime.clear();
2028 expectedTime << 200 << 440 << 680 << 920 << 1200 << 1440 << 1680 << 1920;
2029 expectedRsrp.clear();
2030 expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53;
2031 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 to Event A2",
2032 sourceConfigList,
2033 targetConfigList,
2034 expectedTime,
2035 expectedRsrp,
2036 Seconds(2)),
2037 TestCase::Duration::EXTENSIVE);
2038
2039 // Event A2 to Event A1
2040 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2041 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2042 expectedTime.clear();
2043 expectedRsrp.clear();
2044 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A1",
2045 sourceConfigList,
2046 targetConfigList,
2047 expectedTime,
2048 expectedRsrp,
2049 Seconds(2)),
2050 TestCase::Duration::TAKES_FOREVER);
2051
2052 // Event A3 to Event A4
2053 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2054 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2055 expectedTime.clear();
2056 expectedTime << 1200 << 1440 << 1680 << 1920;
2057 expectedRsrp.clear();
2058 expectedRsrp << 53 << 53 << 53 << 53;
2059 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A4",
2060 sourceConfigList,
2061 targetConfigList,
2062 expectedTime,
2063 expectedRsrp,
2064 Seconds(2)),
2065 TestCase::Duration::TAKES_FOREVER);
2066
2067 // Event A4 to Event A3
2068 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2069 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2070 expectedTime.clear();
2071 expectedTime << 1200 << 1440 << 1680 << 1920;
2072 expectedRsrp.clear();
2073 expectedRsrp << 53 << 53 << 53 << 53;
2074 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A3",
2075 sourceConfigList,
2076 targetConfigList,
2077 expectedTime,
2078 expectedRsrp,
2079 Seconds(2)),
2080 TestCase::Duration::QUICK);
2081
2082 // Event A2 to Event A3
2083 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2084 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2085 expectedTime.clear();
2086 expectedTime << 1200 << 1440 << 1680 << 1920;
2087 expectedRsrp.clear();
2088 expectedRsrp << 53 << 53 << 53 << 53;
2089 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A3",
2090 sourceConfigList,
2091 targetConfigList,
2092 expectedTime,
2093 expectedRsrp,
2094 Seconds(2)),
2095 TestCase::Duration::EXTENSIVE);
2096
2097 // Event A3 to Event A2
2098 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2099 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2100 expectedTime.clear();
2101 expectedTime << 1200 << 1440 << 1680 << 1920;
2102 expectedRsrp.clear();
2103 expectedRsrp << 53 << 53 << 53 << 53;
2104 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A2",
2105 sourceConfigList,
2106 targetConfigList,
2107 expectedTime,
2108 expectedRsrp,
2109 Seconds(2)),
2110 TestCase::Duration::TAKES_FOREVER);
2111
2112 // Event A4 to Event A5
2113 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2114 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2115 expectedTime.clear();
2116 expectedTime << 1200 << 1440 << 1680 << 1920;
2117 expectedRsrp.clear();
2118 expectedRsrp << 53 << 53 << 53 << 53;
2119 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A5",
2120 sourceConfigList,
2121 targetConfigList,
2122 expectedTime,
2123 expectedRsrp,
2124 Seconds(2)),
2125 TestCase::Duration::TAKES_FOREVER);
2126
2127 // Event A5 to Event A4
2128 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2129 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2130 expectedTime.clear();
2131 expectedTime << 1200 << 1440 << 1680 << 1920;
2132 expectedRsrp.clear();
2133 expectedRsrp << 53 << 53 << 53 << 53;
2134 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 to Event A4",
2135 sourceConfigList,
2136 targetConfigList,
2137 expectedTime,
2138 expectedRsrp,
2139 Seconds(2)),
2140 TestCase::Duration::EXTENSIVE);
2141
2142 // === Threshold/offset difference ===
2143
2144 sourceConfigList.front().threshold1.range = 52;
2145 targetConfigList.front().threshold1.range = 56;
2146
2147 // Event A1
2148 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2149 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2150 expectedTime.clear();
2151 expectedTime << 200 << 440 << 680 << 920;
2152 expectedRsrp.clear();
2153 expectedRsrp << 55 << 55 << 55 << 55;
2155 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 threshold difference",
2156 sourceConfigList,
2157 targetConfigList,
2158 expectedTime,
2159 expectedRsrp,
2160 Seconds(2)),
2161 TestCase::Duration::EXTENSIVE);
2162
2163 // Event A2
2164 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2165 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2166 expectedTime.clear();
2167 expectedTime << 1200 << 1440 << 1680 << 1920;
2168 expectedRsrp.clear();
2169 expectedRsrp << 53 << 53 << 53 << 53;
2171 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 threshold difference",
2172 sourceConfigList,
2173 targetConfigList,
2174 expectedTime,
2175 expectedRsrp,
2176 Seconds(2)),
2177 TestCase::Duration::QUICK);
2178
2179 // Event A3
2180 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2181 sourceConfigList.front().a3Offset = -30;
2182 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2183 targetConfigList.front().a3Offset = 30;
2184 expectedTime.clear();
2185 expectedTime << 200 << 440 << 680 << 920;
2186 expectedRsrp.clear();
2187 expectedRsrp << 55 << 55 << 55 << 55;
2189 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 offset difference",
2190 sourceConfigList,
2191 targetConfigList,
2192 expectedTime,
2193 expectedRsrp,
2194 Seconds(2)),
2195 TestCase::Duration::QUICK);
2196
2197 // Event A4
2198 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2199 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2200 expectedTime.clear();
2201 expectedTime << 200 << 440 << 680 << 920;
2202 expectedRsrp.clear();
2203 expectedRsrp << 55 << 55 << 55 << 55;
2205 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 threshold difference",
2206 sourceConfigList,
2207 targetConfigList,
2208 expectedTime,
2209 expectedRsrp,
2210 Seconds(2)),
2211 TestCase::Duration::EXTENSIVE);
2212
2213 // Event A5
2214 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2215 sourceConfigList.front().threshold2.range = 52;
2216 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2217 targetConfigList.front().threshold2.range = 56;
2218 expectedTime.clear();
2219 expectedRsrp.clear();
2221 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 threshold difference",
2222 sourceConfigList,
2223 targetConfigList,
2224 expectedTime,
2225 expectedRsrp,
2226 Seconds(2)),
2227 TestCase::Duration::EXTENSIVE);
2228
2229 // === Time-to-trigger (TTT) difference ===
2230
2231 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2232 sourceConfigList.front().a3Offset = 1;
2233 sourceConfigList.front().threshold1.range = 0;
2234 sourceConfigList.front().threshold2.range = 0;
2235 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2236 targetConfigList.front().a3Offset = 1;
2237 targetConfigList.front().threshold1.range = 0;
2238 targetConfigList.front().threshold2.range = 0;
2239
2240 // decreasing time-to-trigger (short duration)
2241 sourceConfigList.front().timeToTrigger = 1024;
2242 targetConfigList.front().timeToTrigger = 100;
2243 expectedTime.clear();
2244 expectedTime << 1300 << 1540 << 1780;
2245 expectedRsrp.clear();
2246 expectedRsrp << 53 << 53 << 53;
2247 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (short)",
2248 sourceConfigList,
2249 targetConfigList,
2250 expectedTime,
2251 expectedRsrp,
2252 Seconds(2)),
2253 TestCase::Duration::QUICK);
2254
2255 // decreasing time-to-trigger (longer duration)
2256 sourceConfigList.front().timeToTrigger = 1024;
2257 targetConfigList.front().timeToTrigger = 640;
2258 expectedTime.clear();
2259 expectedTime << 1224 << 1464 << 1704 << 1944 << 2840 << 3080 << 3320 << 3560 << 3800 << 4040;
2260 expectedRsrp.clear();
2261 expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53 << 53 << 53;
2262 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (long)",
2263 sourceConfigList,
2264 targetConfigList,
2265 expectedTime,
2266 expectedRsrp,
2267 Seconds(4.2)),
2268 TestCase::Duration::EXTENSIVE);
2269
2270} // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
2271
2272/**
2273 * @ingroup lte-test
2274 * Static variable for test initialization
2275 */
2277
2278/*
2279 * Test Case
2280 */
2281
2283 std::string name,
2284 std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,
2285 std::list<LteRrcSap::ReportConfigEutra> targetConfigList,
2286 std::vector<Time> expectedTime,
2287 std::vector<uint8_t> expectedRsrp,
2288 Time duration)
2289 : TestCase(name),
2290 m_sourceConfigList(sourceConfigList),
2291 m_targetConfigList(targetConfigList),
2292 m_expectedTime(expectedTime),
2293 m_expectedRsrp(expectedRsrp),
2294 m_duration(duration)
2295{
2296 // input sanity check
2297 uint16_t size = m_expectedTime.size();
2298
2299 if (size != m_expectedRsrp.size())
2300 {
2301 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
2302 }
2303
2306
2307 NS_LOG_INFO(this << " name=" << name);
2308}
2309
2314
2315void
2317{
2318 NS_LOG_INFO(this << " " << GetName());
2319
2322 lteHelper->SetEpcHelper(epcHelper);
2323 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
2324 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
2325
2326 // Disable Uplink Power Control
2327 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
2328
2329 // Create Nodes: eNodeB and UE
2330 NodeContainer enbNodes;
2331 NodeContainer ueNodes;
2332 enbNodes.Create(2);
2333 ueNodes.Create(1);
2334
2335 /*
2336 * The topology is the following:
2337 *
2338 * eNodeB UE eNodeB
2339 * | | |
2340 * x ------------------- x ----------------------- x
2341 * 400 m 500 m
2342 */
2343
2345 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Source eNodeB
2346 positionAlloc->Add(Vector(900.0, 0.0, 0.0)); // Target eNodeB
2347 positionAlloc->Add(Vector(400.0, 0.0, 0.0)); // UE
2348 MobilityHelper mobility;
2349 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2350 mobility.SetPositionAllocator(positionAlloc);
2351 mobility.Install(enbNodes);
2352 mobility.Install(ueNodes);
2353
2354 // Create P-GW node
2355 Ptr<Node> pgw = epcHelper->GetPgwNode();
2356
2357 // Create a single RemoteHost
2358 NodeContainer remoteHostContainer;
2359 remoteHostContainer.Create(1);
2360 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
2361 InternetStackHelper internet;
2362 internet.Install(remoteHostContainer);
2363
2364 // Create the Internet
2365 PointToPointHelper p2ph;
2366 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
2367 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
2368 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
2369 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
2370 Ipv4AddressHelper ipv4h;
2371 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
2372 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
2373
2374 // Routing of the Internet Host (towards the LTE network)
2375 Ipv4StaticRoutingHelper ipv4RoutingHelper;
2376 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
2377 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
2378 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
2379
2380 // Enable layer-3 filtering
2381 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(4));
2382
2383 // Disable control channel error model
2384 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
2385
2386 // Create Devices and install them in the Nodes (eNB and UE)
2387 NetDeviceContainer enbDevs;
2388 NetDeviceContainer ueDevs;
2389 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
2390 ueDevs = lteHelper->InstallUeDevice(ueNodes);
2391
2392 // Setup UE measurement configuration in eNodeBs
2393 uint8_t measId;
2394 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
2395 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
2396
2397 for (auto itReportConfig = m_sourceConfigList.begin();
2398 itReportConfig != m_sourceConfigList.end();
2399 itReportConfig++)
2400 {
2401 measId = enbRrc1->AddUeMeasReportConfig(*itReportConfig).at(0);
2402 m_expectedSourceCellMeasId.insert(measId);
2403 }
2404
2405 for (auto itReportConfig = m_targetConfigList.begin();
2406 itReportConfig != m_targetConfigList.end();
2407 itReportConfig++)
2408 {
2409 measId = enbRrc2->AddUeMeasReportConfig(*itReportConfig).at(0);
2410 m_expectedTargetCellMeasId.insert(measId);
2411 }
2412
2413 // Install the IP stack on the UEs
2414 internet.Install(ueNodes);
2415 Ipv4InterfaceContainer ueIpIfaces;
2416 ueIpIfaces = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevs));
2417
2418 // Assign IP address to UEs
2419 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
2420 {
2421 Ptr<Node> ueNode = ueNodes.Get(u);
2422 // Set the default gateway for the UE
2423 Ptr<Ipv4StaticRouting> ueStaticRouting =
2424 ipv4RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv4>());
2425 ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
2426 }
2427
2428 // Attach UE to serving eNodeB
2429 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
2430
2431 // Add X2 interface
2432 lteHelper->AddX2Interface(enbNodes);
2433
2434 // Connect to trace sources in source eNodeB
2436 "/NodeList/3/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2438
2439 // Connect to trace sources in target eNodeB
2441 "/NodeList/4/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2443
2444 // Schedule handover
2445 lteHelper->HandoverRequest(MilliSeconds(m_duration.GetMilliSeconds() / 2),
2446 ueDevs.Get(0),
2447 enbDevs.Get(0),
2448 enbDevs.Get(1));
2449
2450 // Run simulation
2454
2455} // end of void LteUeMeasurementsHandoverTestCase::DoRun ()
2456
2457void
2459{
2460 NS_LOG_FUNCTION(this);
2461 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2462 NS_TEST_ASSERT_MSG_EQ(hasEnded,
2463 true,
2464 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
2465 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2466 NS_ASSERT(hasEnded);
2467}
2468
2469void
2471 std::string context,
2472 uint64_t imsi,
2473 uint16_t cellId,
2474 uint16_t rnti,
2476{
2477 uint8_t measId = report.measResults.measId;
2478 NS_LOG_FUNCTION(this << context << (uint16_t)measId);
2479
2480 bool isCorrectMeasId;
2481 if (cellId == 1)
2482 {
2483 auto itMeasId = m_expectedSourceCellMeasId.find(measId);
2484 isCorrectMeasId = (itMeasId != m_expectedSourceCellMeasId.end());
2485 }
2486 else if (cellId == 2)
2487 {
2488 auto itMeasId = m_expectedTargetCellMeasId.find(measId);
2489 isCorrectMeasId = (itMeasId != m_expectedTargetCellMeasId.end());
2490 }
2491 else
2492 {
2493 NS_FATAL_ERROR("Invalid cell ID " << cellId);
2494 }
2495
2496 if (!isCorrectMeasId)
2497 {
2498 return;
2499 }
2500
2501 // verifying the report completeness
2502 LteRrcSap::MeasResults measResults = report.measResults;
2504 this << " Serving cellId=" << cellId
2505 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
2507 << " dBm)"
2508 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
2510 << " dB)");
2511
2512 // verifying reported best cells
2513 if (measResults.measResultListEutra.empty())
2514 {
2516 false,
2517 "Unexpected report content");
2518 }
2519 else
2520 {
2522 true,
2523 "Unexpected report content");
2524 auto it = measResults.measResultListEutra.begin();
2525 NS_ASSERT(it != measResults.measResultListEutra.end());
2526 NS_ASSERT(it->physCellId != cellId);
2527 NS_ASSERT(it->physCellId <= 2);
2528 NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
2529 false,
2530 "Report contains cgi-info, which is not supported");
2531 NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
2532 true,
2533 "Report does not contain measured RSRP result");
2534 NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
2535 true,
2536 "Report does not contain measured RSRQ result");
2537 NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
2538 << " rsrp=" << (uint16_t)it->rsrpResult << " ("
2539 << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
2540 << " rsrq=" << (uint16_t)it->rsrqResult << " ("
2541 << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
2542
2543 } // end of else of if (measResults.measResultListEutra.size () == 0)
2544
2545 // verifying the report timing
2546 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2547 NS_TEST_ASSERT_MSG_EQ(hasEnded,
2548 false,
2549 "Reporting should not have occurred at " << Simulator::Now().As(Time::S));
2550 if (hasEnded)
2551 {
2552 return;
2553 }
2554
2555 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2556 NS_ASSERT(!hasEnded);
2557
2558 // using milliseconds to avoid floating-point comparison
2559 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
2560 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
2562
2563 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
2564 uint16_t referenceRsrp = *m_itExpectedRsrp;
2566
2567 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
2568 timeExpectedMs,
2569 "Reporting should not have occurred at this time");
2570 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
2571 referenceRsrp,
2572 "The RSRP observed differs with the reference RSRP");
2573
2574} // end of void LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback
Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in a handover configuration.
std::vector< uint8_t >::iterator m_itExpectedRsrp
Pointer to the element of m_expectedRsrp which is expected to occur next in the simulation.
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
std::list< LteRrcSap::ReportConfigEutra > m_sourceConfigList
The list of active report triggering configuration for the source eNodeB.
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
std::set< uint8_t > m_expectedTargetCellMeasId
The list of measurement identities being tested in the target cell.
LteUeMeasurementsHandoverTestCase(std::string name, std::list< LteRrcSap::ReportConfigEutra > sourceConfigList, std::list< LteRrcSap::ReportConfigEutra > targetConfigList, std::vector< Time > expectedTime, std::vector< uint8_t > expectedRsrp, Time duration)
Constructor.
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when either one of the eNodeBs receives measurement report from UE, then perform verificatio...
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
std::list< LteRrcSap::ReportConfigEutra > m_targetConfigList
The list of active report triggering configuration for the target eNodeB.
std::set< uint8_t > m_expectedSourceCellMeasId
The list of measurement identities being tested in the source cell.
std::vector< uint8_t > m_expectedRsrp
The list of expected values of RSRP (in 3GPP range unit) from the measurement reports received.
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsHandoverTestCase.
Testing UE measurements in LTE with simulation of 1 eNodeB and 1 UE in piecewise configuration and 12...
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
LteRrcSap::ReportConfigEutra m_config
The active report triggering configuration.
uint8_t m_expectedMeasId
The measurement identity being tested.
LteUeMeasurementsPiecewiseTestCase1(std::string name, LteRrcSap::ReportConfigEutra config, std::vector< Time > expectedTime, std::vector< uint8_t > expectedRsrp)
Constructor.
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
Ptr< MobilityModel > m_ueMobility
the mobility model
void TeleportVeryNear()
Teleport very near function.
std::vector< uint8_t > m_expectedRsrp
The list of expected values of RSRP (in 3GPP range unit) from the measurement reports received.
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
std::vector< uint8_t >::iterator m_itExpectedRsrp
Pointer to the element of m_expectedRsrp which is expected to occur next in the simulation.
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when eNodeB receives measurement report from UE, then perform verification on it.
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in piecewise configuration and 24...
Ptr< MobilityModel > m_ueMobility
the mobility model
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
void TeleportVeryNear()
Teleport very near function.
std::vector< uint8_t > m_expectedRsrp
The list of expected values of RSRP (in 3GPP range unit) from the measurement reports received.
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
LteUeMeasurementsPiecewiseTestCase2(std::string name, LteRrcSap::ReportConfigEutra config, std::vector< Time > expectedTime, std::vector< uint8_t > expectedRsrp)
Constructor.
LteRrcSap::ReportConfigEutra m_config
The active report triggering configuration.
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when eNodeB receives measurement report from UE, then perform verification on it.
void TeleportVeryFar()
Teleport very far function.
std::vector< uint8_t >::iterator m_itExpectedRsrp
Pointer to the element of m_expectedRsrp which is expected to occur next in the simulation.
uint8_t m_expectedMeasId
The measurement identity being tested.
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
Testing UE measurements in LTE with simulation of 3 eNodeB and 1 UE in piecewise configuration and 24...
Ptr< MobilityModel > m_enbMobility
the mobility model
LteUeMeasurementsPiecewiseTestCase3(std::string name, LteRrcSap::ReportConfigEutra config, std::vector< Time > expectedTime)
Constructor.
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when eNodeB receives measurement report from UE, then perform verification on it.
LteRrcSap::ReportConfigEutra m_config
The active report triggering configuration.
uint8_t m_expectedMeasId
The measurement identity being tested.
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
void TeleportEnbNear()
Teleport the eNb near function.
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsPiecewiseTestCase1...
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsPiecewiseTestCase2...
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsPiecewiseTestCase3...
Test that UE measurements calculation works properly in a scenario with 2 eNodeBs and 2UEs.
double m_d1
distance between UE and ENB node pair
double m_rsrqDbUeServingCell
RSRQ in dBm UE 1.
double m_rsrpDbmUeServingCell
RSRP in dBm UE 1.
LteUeMeasurementsTestCase(std::string name, double d1, double d2, double rsrpDbmUe1, double rsrpDbmUe2, double rsrqDbUe1, double rsrqDbUe2)
Constructor.
void ReportUeMeasurements(uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell)
Report UE measurements function.
void DoRun() override
Implementation to actually run this TestCase.
double m_rsrqDbUeNeighborCell
RSRQ in dBm UE 2.
double m_d2
distance between UE and other ENB node
double m_rsrpDbmUeNeighborCell
RSRP in dBm UE 2.
void RecvMeasurementReport(uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport meas)
Reeive measurement report function.
Test that UE Measurements (see 36.214) calculation works fine in a multi-cell interference scenario.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Class for representing data rates.
Definition data-rate.h:78
AttributeValue implementation for DataRate.
Definition data-rate.h:285
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
This class contains the specification of EPS Bearers.
Definition eps-bearer.h:80
Qci
QoS Class Indicator.
Definition eps-bearer.h:95
@ GBR_CONV_VOICE
GBR Conversational Voice.
Definition eps-bearer.h:96
static uint8_t Dbm2RsrpRange(double dbm)
convert an RSRP value in dBm to the corresponding range as per 3GPP TS 36.133 section 9....
static double RsrpRange2Dbm(uint8_t range)
converts an RSRP range to dBm as per 3GPP TS 36.133 section 9.1.4 RSRP Measurement Report Mapping
static double RsrqRange2Db(uint8_t range)
converts an RSRQ range to dB as per 3GPP TS 36.133 section 9.1.7 RSRQ Measurement Report Mapping
static uint8_t Db2RsrqRange(double db)
convert an RSRQ value in dB to the corresponding range as per 3GPP TS 36.133 section 9....
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.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
holds a vector of std::pair of Ptr<Ipv4> and interface index.
a class to represent an Ipv4 address mask
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...
The eNodeB device implementation.
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
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.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
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.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
std::string GetName() const
Definition test.cc:367
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:397
@ S
second
Definition nstime.h:105
AttributeValue implementation for Time.
Definition nstime.h:1431
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:264
static LteUeMeasurementsPiecewiseTestSuite2 lteUeMeasurementsPiecewiseTestSuite2
Static variable for test initialization.
static LteUeMeasurementsHandoverTestSuite lteUeMeasurementsHandoverTestSuite
Static variable for test initialization.
static LteUeMeasurementsTestSuite lteUeMeasurementsTestSuite
Static variable for test initialization.
static LteUeMeasurementsPiecewiseTestSuite1 lteUeMeasurementsPiecewiseTestSuite1
Static variable for test initialization.
static LteUeMeasurementsPiecewiseTestSuite3 lteUeMeasurementsPiecewiseTestSuite3
Static variable for test initialization.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:134
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition test.h:327
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
void ReportUeMeasurementsCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell, uint8_t componentCarrierId)
void RecvMeasurementReportCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport meas)
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:684
const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition lte-ue-rrc.cc:35
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
uint8_t rsrqResult
the RSRQ result
uint8_t rsrpResult
the RSRP result
MeasResults structure.
uint8_t measId
measure ID
bool haveMeasResultNeighCells
have measure result neighbor cells
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
MeasResultPCell measResultPCell
measurement result primary cell
MeasurementReport structure.
MeasResults measResults
measure results
Specifies criteria for triggering of an E-UTRA measurement reporting event.
bool reportOnLeave
Indicates whether or not the UE shall initiate the measurement reporting procedure when the leaving c...
enum ns3::LteRrcSap::ReportConfigEutra::@62 eventId
Event enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@61 triggerType
Trigger enumeration.
uint8_t hysteresis
Parameter used within the entry and leave condition of an event triggered reporting condition.
@ RSRP
Reference Signal Received Power.
@ EVENT_A2
Event A2: Serving becomes worse than absolute threshold.
@ EVENT_A3
Event A3: Neighbour becomes amount of offset better than PCell.
@ EVENT_A4
Event A4: Neighbour becomes better than absolute threshold.
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
@ EVENT_A5
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
enum ns3::LteRrcSap::ReportConfigEutra::@65 reportInterval
Report interval enumeration.
ThresholdEutra threshold2
Threshold for event A5.
enum ns3::LteRrcSap::ReportConfigEutra::@63 triggerQuantity
Trigger type enumeration.
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
int8_t a3Offset
Offset value for Event A3.
uint16_t timeToTrigger
Time during which specific criteria for the event needs to be met in order to trigger a measurement r...
@ THRESHOLD_RSRP
RSRP is used for the threshold.
enum ns3::LteRrcSap::ThresholdEutra::@60 choice
Threshold enumeration.
uint8_t range
Value range used in RSRP/RSRQ threshold.