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 // verifying the report completeness
1577 LteRrcSap::MeasResults measResults = report.measResults;
1579 this << " Serving cellId=" << cellId
1580 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1582 << " dBm)"
1583 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1585 << " dB)");
1586
1587 // verifying reported best cells
1588 if (measResults.measResultListEutra.empty())
1589 {
1591 false,
1592 "Unexpected report content");
1593 }
1594 else
1595 {
1597 true,
1598 "Unexpected report content");
1599 auto it = measResults.measResultListEutra.begin();
1600 NS_ASSERT(it != measResults.measResultListEutra.end());
1601 NS_ASSERT(it->physCellId == 2);
1602 NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
1603 false,
1604 "Report contains cgi-info, which is not supported");
1605 NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
1606 true,
1607 "Report does not contain measured RSRP result");
1608 NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
1609 true,
1610 "Report does not contain measured RSRQ result");
1611 NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
1612 << " rsrp=" << (uint16_t)it->rsrpResult << " ("
1613 << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
1614 << " rsrq=" << (uint16_t)it->rsrqResult << " ("
1615 << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
1616
1617 } // end of else of if (measResults.measResultListEutra.size () == 0)
1618
1619 // verifying the report timing
1620 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1621 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1622 false,
1623 "Reporting should not have occurred at "
1624 << Simulator::Now().As(Time::S));
1625 if (!hasEnded)
1626 {
1627 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1628 NS_ASSERT(!hasEnded);
1629
1630 // using milliseconds to avoid floating-point comparison
1631 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1632 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1634
1635 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
1636 uint16_t referenceRsrp = *m_itExpectedRsrp;
1638
1639 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1640 timeExpectedMs,
1641 "Reporting should not have occurred at this time");
1642 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
1643 referenceRsrp,
1644 "The RSRP observed differs with the reference RSRP");
1645
1646 } // end of if (!hasEnded)
1647
1648 } // end of if (report.measResults.measId == m_expectedMeasId)
1649
1650} // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
1651
1652void
1654{
1655 NS_LOG_FUNCTION(this);
1656 m_ueMobility->SetPosition(Vector(50.0, 0.0, 0.0));
1657}
1658
1659void
1661{
1662 NS_LOG_FUNCTION(this);
1663 m_ueMobility->SetPosition(Vector(250.0, 0.0, 0.0));
1664}
1665
1666void
1668{
1669 NS_LOG_FUNCTION(this);
1670 m_ueMobility->SetPosition(Vector(350.0, 0.0, 0.0));
1671}
1672
1673void
1675{
1676 NS_LOG_FUNCTION(this);
1677 m_ueMobility->SetPosition(Vector(550.0, 0.0, 0.0));
1678}
1679
1680// ===== LTE-UE-MEASUREMENTS-PIECEWISE-3 TEST SUITE ======================== //
1681
1682/*
1683 * Test Suite
1684 */
1685
1687 : TestSuite("lte-ue-measurements-piecewise-3", Type::SYSTEM)
1688{
1689 std::vector<Time> expectedTime;
1690
1691 // === Event A4 (neighbor becomes better than threshold) ===
1692
1693 // The threshold value was chosen to achieve the following:
1694 // 1. Neighbor 1 (eNB2) RSRP would be above the chosen threshold, hence,
1695 // the UE will include it in its reports to its eNB (eNB1) from the beginning
1696 // of the simulation.
1697 // 2. When neighbor 2 (eNB3) is placed at a very far position, its RSRP would
1698 // be less than the chosen threshold, hence, UE will not include it in its
1699 // initial report(s) to its eNB.
1700 // 3. When neighbor 2 (eNB3) is placed at a near position, its RSRP would
1701 // always be above the chosen threshold, hence, the UE will include it in its
1702 // reports to its eNB (eNB1).
1707 config.threshold1.range = 6;
1710 expectedTime.clear();
1711 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1712
1713 AddTestCase(new LteUeMeasurementsPiecewiseTestCase3("Piecewise test case 3 - Event A4",
1714 config,
1715 expectedTime),
1716 TestCase::Duration::QUICK);
1717} // end of LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3
1718
1719/**
1720 * \ingroup lte-test
1721 * Static variable for test initialization
1722 */
1724
1725/*
1726 * Test Case
1727 */
1728
1730 std::string name,
1732 std::vector<Time> expectedTime)
1733 : TestCase(name),
1734 m_config(config),
1735 m_expectedTime(expectedTime)
1736{
1737 m_expectedMeasId = std::numeric_limits<uint8_t>::max();
1738
1740
1741 NS_LOG_INFO(this << " name=" << name);
1742}
1743
1748
1749void
1751{
1752 NS_LOG_INFO(this << " " << GetName());
1753
1755 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1756 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1757
1758 // Disable Uplink Power Control
1759 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1760
1761 // Create Nodes: eNodeB and UE
1762 NodeContainer enbNodes;
1763 NodeContainer ueNodes;
1764 enbNodes.Create(3);
1765 ueNodes.Create(1);
1766
1767 /*
1768 * The topology is the following:
1769 *
1770 * We place the 3rd eNB initially very far so it does not fulfills
1771 * the entry condition to be reported.
1772 *
1773 * eNodeB UE eNodeB eNodeB
1774 * | | | |
1775 * x ---- x --------------- x -------------- x ---------------------x
1776 * 50 m 100 m 500 | 1000000
1777 * Near
1778 */
1779
1781 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1782 positionAlloc->Add(Vector(200.0, 0.0, 0.0)); // Neighbour eNodeB1
1783 positionAlloc->Add(Vector(1000700.0, 0.0, 0.0)); // Neighbour eNodeB2
1784 positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1785 MobilityHelper mobility;
1786 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1787 mobility.SetPositionAllocator(positionAlloc);
1788 mobility.Install(enbNodes);
1789 mobility.Install(ueNodes);
1790 m_enbMobility = enbNodes.Get(2)->GetObject<MobilityModel>();
1791
1792 // Disable layer-3 filtering
1793 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1794
1795 // Create Devices and install them in the Nodes (eNB and UE)
1796 NetDeviceContainer enbDevs;
1797 NetDeviceContainer ueDevs;
1798 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1799 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1800 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1801 ueDevs = lteHelper->InstallUeDevice(ueNodes);
1802
1803 // Setup UE measurement configuration in serving cell
1804 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1805 m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1806
1807 // Disable handover in neighbour cells
1808 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1809 enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1810 Ptr<LteEnbRrc> enbRrc3 = enbDevs.Get(2)->GetObject<LteEnbNetDevice>()->GetRrc();
1811 enbRrc3->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1812
1813 // Attach UE to serving eNodeB
1814 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1815
1816 // Activate an EPS bearer
1818 EpsBearer bearer(q);
1819 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1820
1821 // Connect to trace sources in serving eNodeB
1823 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1825 /*
1826 * Schedule "teleport" for the 2nd neighbour
1827 *
1828 * We bring the 2nd neighbour near once the UE has already scheduled the periodic
1829 * reporting after detecting the 1st neighbour, which ideally should be at
1830 * 200 ms.
1831 */
1834 this);
1835
1836 // Run simulation
1837 Simulator::Stop(Seconds(2.201));
1840
1841} // end of void LteUeMeasurementsPiecewiseTestCase3::DoRun ()
1842
1843void
1845{
1846 NS_LOG_FUNCTION(this);
1847 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1848 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1849 true,
1850 "Reporting should have occurred at " << m_itExpectedTime->GetSeconds()
1851 << "s");
1852}
1853
1854void
1856 std::string context,
1857 uint64_t imsi,
1858 uint16_t cellId,
1859 uint16_t rnti,
1861{
1862 NS_LOG_FUNCTION(this << context);
1863 NS_ASSERT(rnti == 1);
1864 NS_ASSERT(cellId == 1);
1865
1866 if (report.measResults.measId == m_expectedMeasId)
1867 {
1868 // verifying the report completeness
1869 LteRrcSap::MeasResults measResults = report.measResults;
1871 this << " Serving cellId=" << cellId
1872 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1874 << " dBm)"
1875 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1877 << " dB)");
1878
1879 // verifying reported best cells
1880 if (measResults.measResultListEutra.empty())
1881 {
1883 false,
1884 "Unexpected report content");
1885 }
1886 else
1887 {
1889 true,
1890 "Unexpected report content");
1891 auto it = measResults.measResultListEutra.begin();
1892 NS_ASSERT(it != measResults.measResultListEutra.end());
1893 for (const auto& it : measResults.measResultListEutra)
1894 {
1895 NS_ASSERT(it.physCellId == 2 || it.physCellId == 3);
1896 NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo,
1897 false,
1898 "Report contains cgi-info, which is not supported");
1899 NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult,
1900 true,
1901 "Report does not contain measured RSRP result");
1902 NS_TEST_ASSERT_MSG_EQ(it.haveRsrqResult,
1903 true,
1904 "Report does not contain measured RSRQ result");
1906 this << " Neighbour cellId=" << it.physCellId
1907 << " rsrp=" << (uint16_t)it.rsrpResult << " ("
1908 << EutranMeasurementMapping::RsrpRange2Dbm(it.rsrpResult) << " dBm)"
1909 << " rsrq=" << (uint16_t)it.rsrqResult << " ("
1910 << EutranMeasurementMapping::RsrqRange2Db(it.rsrqResult) << " dB)");
1911 }
1912
1913 } // end of else of if (measResults.measResultListEutra.size () == 0)
1914
1915 // verifying the report timing
1916 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1917 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1918 false,
1919 "Reporting should not have occurred at "
1920 << Simulator::Now().GetSeconds() << "s");
1921 if (!hasEnded)
1922 {
1923 // using milliseconds to avoid floating-point comparison
1924 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1925 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1927
1928 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1929 timeExpectedMs,
1930 "Reporting should not have occurred at this time");
1931
1932 } // end of if (!hasEnded)
1933
1934 } // end of if (report.measResults.measId == m_expectedMeasId)
1935
1936} // end of void LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback
1937
1938void
1940{
1941 NS_LOG_FUNCTION(this);
1942 m_enbMobility->SetPosition(Vector(700.0, 0.0, 0.0));
1943}
1944
1945// ===== LTE-UE-MEASUREMENTS-HANDOVER TEST SUITE =========================== //
1946
1947/*
1948 * Test Suite
1949 */
1950
1952 : TestSuite("lte-ue-measurements-handover", Type::SYSTEM)
1953{
1954 std::list<LteRrcSap::ReportConfigEutra> sourceConfigList;
1955 std::list<LteRrcSap::ReportConfigEutra> targetConfigList;
1956 std::vector<Time> expectedTime;
1957 std::vector<uint8_t> expectedRsrp;
1958
1959 LteRrcSap::ReportConfigEutra sourceConfig;
1963 sourceConfig.threshold1.range = 0;
1966 sourceConfigList.push_back(sourceConfig);
1967
1968 LteRrcSap::ReportConfigEutra targetConfig;
1972 targetConfig.threshold1.range = 0;
1975 targetConfigList.push_back(targetConfig);
1976
1977 // === Report interval difference ===
1978
1979 // decreasing report interval
1980 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS480;
1981 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1982 expectedTime.clear();
1983 expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
1984 expectedRsrp.clear();
1985 expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
1987 new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing report interval",
1988 sourceConfigList,
1989 targetConfigList,
1990 expectedTime,
1991 expectedRsrp,
1992 Seconds(2)),
1993 TestCase::Duration::TAKES_FOREVER);
1994
1995 // increasing report interval
1996 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS120;
1997 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS640;
1998 expectedTime.clear();
1999 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1200 << 1840;
2000 expectedRsrp.clear();
2001 expectedRsrp << 55 << 55 << 55 << 55 << 55 << 55 << 55 << 53 << 53;
2003 new LteUeMeasurementsHandoverTestCase("Handover test case - increasing report interval",
2004 sourceConfigList,
2005 targetConfigList,
2006 expectedTime,
2007 expectedRsrp,
2008 Seconds(2)),
2009 TestCase::Duration::QUICK);
2010
2011 // === Event difference ===
2012
2013 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2014 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2015 sourceConfigList.front().threshold1.range = 54;
2016 sourceConfigList.front().threshold2.range = 54;
2017 sourceConfigList.front().a3Offset = 1;
2018 targetConfigList.front().threshold1.range = 54;
2019 targetConfigList.front().threshold2.range = 54;
2020 targetConfigList.front().a3Offset = 1;
2021
2022 // Event A1 to Event A2
2023 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2024 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2025 expectedTime.clear();
2026 expectedTime << 200 << 440 << 680 << 920 << 1200 << 1440 << 1680 << 1920;
2027 expectedRsrp.clear();
2028 expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53;
2029 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 to Event A2",
2030 sourceConfigList,
2031 targetConfigList,
2032 expectedTime,
2033 expectedRsrp,
2034 Seconds(2)),
2035 TestCase::Duration::EXTENSIVE);
2036
2037 // Event A2 to Event A1
2038 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2039 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2040 expectedTime.clear();
2041 expectedRsrp.clear();
2042 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A1",
2043 sourceConfigList,
2044 targetConfigList,
2045 expectedTime,
2046 expectedRsrp,
2047 Seconds(2)),
2048 TestCase::Duration::TAKES_FOREVER);
2049
2050 // Event A3 to Event A4
2051 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2052 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2053 expectedTime.clear();
2054 expectedTime << 1200 << 1440 << 1680 << 1920;
2055 expectedRsrp.clear();
2056 expectedRsrp << 53 << 53 << 53 << 53;
2057 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A4",
2058 sourceConfigList,
2059 targetConfigList,
2060 expectedTime,
2061 expectedRsrp,
2062 Seconds(2)),
2063 TestCase::Duration::TAKES_FOREVER);
2064
2065 // Event A4 to Event A3
2066 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2067 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2068 expectedTime.clear();
2069 expectedTime << 1200 << 1440 << 1680 << 1920;
2070 expectedRsrp.clear();
2071 expectedRsrp << 53 << 53 << 53 << 53;
2072 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A3",
2073 sourceConfigList,
2074 targetConfigList,
2075 expectedTime,
2076 expectedRsrp,
2077 Seconds(2)),
2078 TestCase::Duration::QUICK);
2079
2080 // Event A2 to Event A3
2081 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2082 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2083 expectedTime.clear();
2084 expectedTime << 1200 << 1440 << 1680 << 1920;
2085 expectedRsrp.clear();
2086 expectedRsrp << 53 << 53 << 53 << 53;
2087 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A3",
2088 sourceConfigList,
2089 targetConfigList,
2090 expectedTime,
2091 expectedRsrp,
2092 Seconds(2)),
2093 TestCase::Duration::EXTENSIVE);
2094
2095 // Event A3 to Event A2
2096 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2097 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2098 expectedTime.clear();
2099 expectedTime << 1200 << 1440 << 1680 << 1920;
2100 expectedRsrp.clear();
2101 expectedRsrp << 53 << 53 << 53 << 53;
2102 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A2",
2103 sourceConfigList,
2104 targetConfigList,
2105 expectedTime,
2106 expectedRsrp,
2107 Seconds(2)),
2108 TestCase::Duration::TAKES_FOREVER);
2109
2110 // Event A4 to Event A5
2111 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2112 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2113 expectedTime.clear();
2114 expectedTime << 1200 << 1440 << 1680 << 1920;
2115 expectedRsrp.clear();
2116 expectedRsrp << 53 << 53 << 53 << 53;
2117 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A5",
2118 sourceConfigList,
2119 targetConfigList,
2120 expectedTime,
2121 expectedRsrp,
2122 Seconds(2)),
2123 TestCase::Duration::TAKES_FOREVER);
2124
2125 // Event A5 to Event A4
2126 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2127 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2128 expectedTime.clear();
2129 expectedTime << 1200 << 1440 << 1680 << 1920;
2130 expectedRsrp.clear();
2131 expectedRsrp << 53 << 53 << 53 << 53;
2132 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 to Event A4",
2133 sourceConfigList,
2134 targetConfigList,
2135 expectedTime,
2136 expectedRsrp,
2137 Seconds(2)),
2138 TestCase::Duration::EXTENSIVE);
2139
2140 // === Threshold/offset difference ===
2141
2142 sourceConfigList.front().threshold1.range = 52;
2143 targetConfigList.front().threshold1.range = 56;
2144
2145 // Event A1
2146 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2147 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2148 expectedTime.clear();
2149 expectedTime << 200 << 440 << 680 << 920;
2150 expectedRsrp.clear();
2151 expectedRsrp << 55 << 55 << 55 << 55;
2153 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 threshold difference",
2154 sourceConfigList,
2155 targetConfigList,
2156 expectedTime,
2157 expectedRsrp,
2158 Seconds(2)),
2159 TestCase::Duration::EXTENSIVE);
2160
2161 // Event A2
2162 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2163 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2164 expectedTime.clear();
2165 expectedTime << 1200 << 1440 << 1680 << 1920;
2166 expectedRsrp.clear();
2167 expectedRsrp << 53 << 53 << 53 << 53;
2169 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 threshold difference",
2170 sourceConfigList,
2171 targetConfigList,
2172 expectedTime,
2173 expectedRsrp,
2174 Seconds(2)),
2175 TestCase::Duration::QUICK);
2176
2177 // Event A3
2178 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2179 sourceConfigList.front().a3Offset = -30;
2180 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2181 targetConfigList.front().a3Offset = 30;
2182 expectedTime.clear();
2183 expectedTime << 200 << 440 << 680 << 920;
2184 expectedRsrp.clear();
2185 expectedRsrp << 55 << 55 << 55 << 55;
2187 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 offset difference",
2188 sourceConfigList,
2189 targetConfigList,
2190 expectedTime,
2191 expectedRsrp,
2192 Seconds(2)),
2193 TestCase::Duration::QUICK);
2194
2195 // Event A4
2196 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2197 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2198 expectedTime.clear();
2199 expectedTime << 200 << 440 << 680 << 920;
2200 expectedRsrp.clear();
2201 expectedRsrp << 55 << 55 << 55 << 55;
2203 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 threshold difference",
2204 sourceConfigList,
2205 targetConfigList,
2206 expectedTime,
2207 expectedRsrp,
2208 Seconds(2)),
2209 TestCase::Duration::EXTENSIVE);
2210
2211 // Event A5
2212 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2213 sourceConfigList.front().threshold2.range = 52;
2214 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2215 targetConfigList.front().threshold2.range = 56;
2216 expectedTime.clear();
2217 expectedRsrp.clear();
2219 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 threshold difference",
2220 sourceConfigList,
2221 targetConfigList,
2222 expectedTime,
2223 expectedRsrp,
2224 Seconds(2)),
2225 TestCase::Duration::EXTENSIVE);
2226
2227 // === Time-to-trigger (TTT) difference ===
2228
2229 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2230 sourceConfigList.front().a3Offset = 1;
2231 sourceConfigList.front().threshold1.range = 0;
2232 sourceConfigList.front().threshold2.range = 0;
2233 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2234 targetConfigList.front().a3Offset = 1;
2235 targetConfigList.front().threshold1.range = 0;
2236 targetConfigList.front().threshold2.range = 0;
2237
2238 // decreasing time-to-trigger (short duration)
2239 sourceConfigList.front().timeToTrigger = 1024;
2240 targetConfigList.front().timeToTrigger = 100;
2241 expectedTime.clear();
2242 expectedTime << 1300 << 1540 << 1780;
2243 expectedRsrp.clear();
2244 expectedRsrp << 53 << 53 << 53;
2245 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (short)",
2246 sourceConfigList,
2247 targetConfigList,
2248 expectedTime,
2249 expectedRsrp,
2250 Seconds(2)),
2251 TestCase::Duration::QUICK);
2252
2253 // decreasing time-to-trigger (longer duration)
2254 sourceConfigList.front().timeToTrigger = 1024;
2255 targetConfigList.front().timeToTrigger = 640;
2256 expectedTime.clear();
2257 expectedTime << 1224 << 1464 << 1704 << 1944 << 2840 << 3080 << 3320 << 3560 << 3800 << 4040;
2258 expectedRsrp.clear();
2259 expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53 << 53 << 53;
2260 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (long)",
2261 sourceConfigList,
2262 targetConfigList,
2263 expectedTime,
2264 expectedRsrp,
2265 Seconds(4.2)),
2266 TestCase::Duration::EXTENSIVE);
2267
2268} // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
2269
2270/**
2271 * \ingroup lte-test
2272 * Static variable for test initialization
2273 */
2275
2276/*
2277 * Test Case
2278 */
2279
2281 std::string name,
2282 std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,
2283 std::list<LteRrcSap::ReportConfigEutra> targetConfigList,
2284 std::vector<Time> expectedTime,
2285 std::vector<uint8_t> expectedRsrp,
2286 Time duration)
2287 : TestCase(name),
2288 m_sourceConfigList(sourceConfigList),
2289 m_targetConfigList(targetConfigList),
2290 m_expectedTime(expectedTime),
2291 m_expectedRsrp(expectedRsrp),
2292 m_duration(duration)
2293{
2294 // input sanity check
2295 uint16_t size = m_expectedTime.size();
2296
2297 if (size != m_expectedRsrp.size())
2298 {
2299 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
2300 }
2301
2304
2305 NS_LOG_INFO(this << " name=" << name);
2306}
2307
2312
2313void
2315{
2316 NS_LOG_INFO(this << " " << GetName());
2317
2320 lteHelper->SetEpcHelper(epcHelper);
2321 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
2322 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
2323
2324 // Disable Uplink Power Control
2325 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
2326
2327 // Create Nodes: eNodeB and UE
2328 NodeContainer enbNodes;
2329 NodeContainer ueNodes;
2330 enbNodes.Create(2);
2331 ueNodes.Create(1);
2332
2333 /*
2334 * The topology is the following:
2335 *
2336 * eNodeB UE eNodeB
2337 * | | |
2338 * x ------------------- x ----------------------- x
2339 * 400 m 500 m
2340 */
2341
2343 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Source eNodeB
2344 positionAlloc->Add(Vector(900.0, 0.0, 0.0)); // Target eNodeB
2345 positionAlloc->Add(Vector(400.0, 0.0, 0.0)); // UE
2346 MobilityHelper mobility;
2347 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2348 mobility.SetPositionAllocator(positionAlloc);
2349 mobility.Install(enbNodes);
2350 mobility.Install(ueNodes);
2351
2352 // Create P-GW node
2353 Ptr<Node> pgw = epcHelper->GetPgwNode();
2354
2355 // Create a single RemoteHost
2356 NodeContainer remoteHostContainer;
2357 remoteHostContainer.Create(1);
2358 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
2359 InternetStackHelper internet;
2360 internet.Install(remoteHostContainer);
2361
2362 // Create the Internet
2363 PointToPointHelper p2ph;
2364 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
2365 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
2366 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
2367 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
2368 Ipv4AddressHelper ipv4h;
2369 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
2370 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
2371
2372 // Routing of the Internet Host (towards the LTE network)
2373 Ipv4StaticRoutingHelper ipv4RoutingHelper;
2374 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
2375 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
2376 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
2377
2378 // Enable layer-3 filtering
2379 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(4));
2380
2381 // Disable control channel error model
2382 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
2383
2384 // Create Devices and install them in the Nodes (eNB and UE)
2385 NetDeviceContainer enbDevs;
2386 NetDeviceContainer ueDevs;
2387 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
2388 ueDevs = lteHelper->InstallUeDevice(ueNodes);
2389
2390 // Setup UE measurement configuration in eNodeBs
2391 uint8_t measId;
2392 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
2393 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
2394
2395 for (auto itReportConfig = m_sourceConfigList.begin();
2396 itReportConfig != m_sourceConfigList.end();
2397 itReportConfig++)
2398 {
2399 measId = enbRrc1->AddUeMeasReportConfig(*itReportConfig).at(0);
2400 m_expectedSourceCellMeasId.insert(measId);
2401 }
2402
2403 for (auto itReportConfig = m_targetConfigList.begin();
2404 itReportConfig != m_targetConfigList.end();
2405 itReportConfig++)
2406 {
2407 measId = enbRrc2->AddUeMeasReportConfig(*itReportConfig).at(0);
2408 m_expectedTargetCellMeasId.insert(measId);
2409 }
2410
2411 // Install the IP stack on the UEs
2412 internet.Install(ueNodes);
2413 Ipv4InterfaceContainer ueIpIfaces;
2414 ueIpIfaces = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevs));
2415
2416 // Assign IP address to UEs
2417 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
2418 {
2419 Ptr<Node> ueNode = ueNodes.Get(u);
2420 // Set the default gateway for the UE
2421 Ptr<Ipv4StaticRouting> ueStaticRouting =
2422 ipv4RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv4>());
2423 ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
2424 }
2425
2426 // Attach UE to serving eNodeB
2427 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
2428
2429 // Add X2 interface
2430 lteHelper->AddX2Interface(enbNodes);
2431
2432 // Connect to trace sources in source eNodeB
2434 "/NodeList/3/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2436
2437 // Connect to trace sources in target eNodeB
2439 "/NodeList/4/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2441
2442 // Schedule handover
2443 lteHelper->HandoverRequest(MilliSeconds(m_duration.GetMilliSeconds() / 2),
2444 ueDevs.Get(0),
2445 enbDevs.Get(0),
2446 enbDevs.Get(1));
2447
2448 // Run simulation
2452
2453} // end of void LteUeMeasurementsHandoverTestCase::DoRun ()
2454
2455void
2457{
2458 NS_LOG_FUNCTION(this);
2459 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2460 NS_TEST_ASSERT_MSG_EQ(hasEnded,
2461 true,
2462 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
2463 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2464 NS_ASSERT(hasEnded);
2465}
2466
2467void
2469 std::string context,
2470 uint64_t imsi,
2471 uint16_t cellId,
2472 uint16_t rnti,
2474{
2475 uint8_t measId = report.measResults.measId;
2476 NS_LOG_FUNCTION(this << context << (uint16_t)measId);
2477
2478 bool isCorrectMeasId;
2479 if (cellId == 1)
2480 {
2481 auto itMeasId = m_expectedSourceCellMeasId.find(measId);
2482 isCorrectMeasId = (itMeasId != m_expectedSourceCellMeasId.end());
2483 }
2484 else if (cellId == 2)
2485 {
2486 auto itMeasId = m_expectedTargetCellMeasId.find(measId);
2487 isCorrectMeasId = (itMeasId != m_expectedTargetCellMeasId.end());
2488 }
2489 else
2490 {
2491 NS_FATAL_ERROR("Invalid cell ID " << cellId);
2492 }
2493
2494 if (isCorrectMeasId)
2495 {
2496 // verifying the report completeness
2497 LteRrcSap::MeasResults measResults = report.measResults;
2499 this << " Serving cellId=" << cellId
2500 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
2502 << " dBm)"
2503 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
2505 << " dB)");
2506
2507 // verifying reported best cells
2508 if (measResults.measResultListEutra.empty())
2509 {
2511 false,
2512 "Unexpected report content");
2513 }
2514 else
2515 {
2517 true,
2518 "Unexpected report content");
2519 auto it = measResults.measResultListEutra.begin();
2520 NS_ASSERT(it != measResults.measResultListEutra.end());
2521 NS_ASSERT(it->physCellId != cellId);
2522 NS_ASSERT(it->physCellId <= 2);
2523 NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
2524 false,
2525 "Report contains cgi-info, which is not supported");
2526 NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
2527 true,
2528 "Report does not contain measured RSRP result");
2529 NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
2530 true,
2531 "Report does not contain measured RSRQ result");
2532 NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
2533 << " rsrp=" << (uint16_t)it->rsrpResult << " ("
2534 << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
2535 << " rsrq=" << (uint16_t)it->rsrqResult << " ("
2536 << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
2537
2538 } // end of else of if (measResults.measResultListEutra.size () == 0)
2539
2540 // verifying the report timing
2541 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2542 NS_TEST_ASSERT_MSG_EQ(hasEnded,
2543 false,
2544 "Reporting should not have occurred at "
2545 << Simulator::Now().As(Time::S));
2546 if (!hasEnded)
2547 {
2548 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2549 NS_ASSERT(!hasEnded);
2550
2551 // using milliseconds to avoid floating-point comparison
2552 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
2553 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
2555
2556 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
2557 uint16_t referenceRsrp = *m_itExpectedRsrp;
2559
2560 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
2561 timeExpectedMs,
2562 "Reporting should not have occurred at this time");
2563 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
2564 referenceRsrp,
2565 "The RSRP observed differs with the reference RSRP");
2566
2567 } // end of if (!hasEnded)
2568
2569 } // end of if (report.measResults.measId == correctMeasId)
2570
2571} // 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.
Class for representing data rates.
Definition data-rate.h:78
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
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:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
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.