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