A Discrete-Event Network Simulator
API
lte-test-ue-measurements.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Manuel Requena <manuel.requena@cttc.es>
19  * Nicola Baldo <nbaldo@cttc.es>
20  * Marco Miozzo <mmiozzo@cttc.es>
21  * Budiarto Herman <budiarto.herman@magister.fi>
22  */
23 
24 #include <ns3/simulator.h>
25 #include <ns3/log.h>
26 #include <ns3/callback.h>
27 #include <ns3/config.h>
28 #include <ns3/string.h>
29 #include <ns3/double.h>
30 #include <ns3/enum.h>
31 #include <ns3/boolean.h>
32 
33 #include <ns3/mobility-helper.h>
34 #include <ns3/lte-helper.h>
35 #include <ns3/point-to-point-epc-helper.h>
36 #include <ns3/internet-stack-helper.h>
37 #include <ns3/point-to-point-helper.h>
38 #include <ns3/ipv4-address-helper.h>
39 #include <ns3/ipv4-static-routing-helper.h>
40 
41 #include <ns3/node-container.h>
42 #include <ns3/net-device-container.h>
43 #include <ns3/ipv4-interface-container.h>
44 
45 #include <ns3/ff-mac-scheduler.h>
46 #include <ns3/lte-enb-net-device.h>
47 #include <ns3/lte-enb-phy.h>
48 #include <ns3/lte-enb-rrc.h>
49 #include <ns3/lte-ue-net-device.h>
50 #include <ns3/lte-ue-phy.h>
51 #include <ns3/lte-ue-rrc.h>
52 
54 #include <ns3/lte-common.h>
55 
56 using namespace ns3;
57 
58 NS_LOG_COMPONENT_DEFINE ("LteUeMeasurementsTest");
59 
60 // ===== LTE-UE-MEASUREMENTS TEST SUITE ==================================== //
61 
62 void
64  std::string path, uint16_t rnti, uint16_t cellId,
65  double rsrp, double rsrq, bool servingCell, uint8_t componentCarrierId)
66 {
67  testcase->ReportUeMeasurements (rnti, cellId, rsrp, rsrq, servingCell);
68 }
69 
70 void
72  std::string path, uint64_t imsi, uint16_t cellId,
73  uint16_t rnti, LteRrcSap::MeasurementReport meas)
74 {
75  testcase->RecvMeasurementReport (imsi, cellId, rnti, meas);
76 }
77 
78 
79 /*
80  * Test Suite
81  */
82 
84  : TestSuite ("lte-ue-measurements", SYSTEM)
85 {
86 
87  AddTestCase (new LteUeMeasurementsTestCase ("d1=10, d2=10000", 10.000000, 10000.000000, -53.739702, -113.739702, -3.010305, -63.010305), TestCase::EXTENSIVE);
88  AddTestCase (new LteUeMeasurementsTestCase ("d1=20, d2=10000", 20.000000, 10000.000000, -59.760302, -113.739702, -3.010319, -56.989719), TestCase::EXTENSIVE);
89  AddTestCase (new LteUeMeasurementsTestCase ("d1=50, d2=10000", 50.000000, 10000.000000, -67.719102, -113.739702, -3.010421, -49.031021), TestCase::EXTENSIVE);
90  AddTestCase (new LteUeMeasurementsTestCase ("d1=100, d2=10000", 100.000000, 10000.000000, -73.739702, -113.739702, -3.010783, -43.010783), TestCase::EXTENSIVE);
91  AddTestCase (new LteUeMeasurementsTestCase ("d1=200, d2=10000", 200.000000, 10000.000000, -79.760302, -113.739702, -3.012232, -36.991632), TestCase::EXTENSIVE);
92  AddTestCase (new LteUeMeasurementsTestCase ("d1=100, d2=10000", 100.000000, 10000.000000, -73.739702, -113.739702, -3.010783, -43.010783), TestCase::EXTENSIVE);
93  AddTestCase (new LteUeMeasurementsTestCase ("d1=200, d2=10000", 200.000000, 10000.000000, -79.760302, -113.739702, -3.012232, -36.991632), TestCase::EXTENSIVE);
94  AddTestCase (new LteUeMeasurementsTestCase ("d1=500, d2=10000", 500.000000, 10000.000000, -87.719102, -113.739702, -3.022359, -29.042959), TestCase::EXTENSIVE);
95  AddTestCase (new LteUeMeasurementsTestCase ("d1=1000, d2=10000", 1000.000000, 10000.000000, -93.739702, -113.739702, -3.058336, -23.058336), TestCase::EXTENSIVE);
96  AddTestCase (new LteUeMeasurementsTestCase ("d1=2000, d2=10000", 2000.000000, 10000.000000, -99.760302, -113.739702, -3.199337, -17.178738), TestCase::EXTENSIVE);
97  AddTestCase (new LteUeMeasurementsTestCase ("d1=5000, d2=10000", 5000.000000, 10000.000000, -107.719102, -113.739702, -4.075793, -10.096393), TestCase::QUICK);
98  AddTestCase (new LteUeMeasurementsTestCase ("d1=10000, d2=10000", 10000.000000, 10000.000000, -113.739702, -113.739702, -6.257687, -6.257687), TestCase::EXTENSIVE);
99  AddTestCase (new LteUeMeasurementsTestCase ("d1=20000, d2=10000", 20000.000000, 10000.000000, -119.760302, -113.739702, -10.373365, -4.352765), TestCase::EXTENSIVE);
100  AddTestCase (new LteUeMeasurementsTestCase ("d1=50000, d2=10000", 50000.000000, 10000.000000, -127.719102, -113.739702, -17.605046, -3.625645), TestCase::EXTENSIVE);
101  AddTestCase (new LteUeMeasurementsTestCase ("d1=100000, d2=10000", 100000.000000, 10000.000000, -133.739702, -113.739702, -23.511071, -3.511071), TestCase::EXTENSIVE);
102  AddTestCase (new LteUeMeasurementsTestCase ("d1=200000, d2=10000", 200000.000000, 10000.000000, -139.760302, -113.739702, -29.502549, -3.481949), TestCase::EXTENSIVE);
103  AddTestCase (new LteUeMeasurementsTestCase ("d1=500000, d2=10000", 500000.000000, 10000.000000, -147.719102, -113.739702, -37.453160, -3.473760), TestCase::EXTENSIVE);
104  AddTestCase (new LteUeMeasurementsTestCase ("d1=1000000, d2=10000", 1000000.000000, 10000.000000, -153.739702, -113.739702, -43.472589, -3.472589), TestCase::EXTENSIVE);
105 }
106 
108 
109 
110 /*
111  * Test Case
112  */
113 
115  double d1, double d2,
116  double rsrpDbmUe1,
117  double rsrpDbmUe2,
118  double rsrqDbUe1,
119  double rsrqDbUe2)
120  : TestCase (name),
121  m_d1 (d1),
122  m_d2 (d2),
123  m_rsrpDbmUeServingCell (rsrpDbmUe1),
124  m_rsrpDbmUeNeighborCell (rsrpDbmUe2),
125  m_rsrqDbUeServingCell (rsrqDbUe1),
126  m_rsrqDbUeNeighborCell (rsrqDbUe2)
127 {
128  NS_LOG_INFO ("Test UE Measurements d1 = " << d1 << " m. and d2 = " << d2 << " m.");
129 }
130 
132 {}
133 
134 void
136 {
137  NS_LOG_INFO (this << " " << GetName ());
138 
139  Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
140  Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
141  Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
142  Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
143  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
144  lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
145  lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (false));
146 
147  //Disable Uplink Power Control
148  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
149 
150  // LogComponentEnable ("LteUeMeasurementsTest", LOG_LEVEL_ALL);
151 
152  // Create Nodes: eNodeB and UE
153  NodeContainer enbNodes;
154  NodeContainer ueNodes1;
155  NodeContainer ueNodes2;
156  enbNodes.Create (2);
157  ueNodes1.Create (1);
158  ueNodes2.Create (1);
159  NodeContainer allNodes = NodeContainer (enbNodes, ueNodes1, ueNodes2);
160 
161  // the topology is the following:
162  // d2
163  // UE1-----------eNB2
164  // | |
165  // d1| |d1
166  // | d2 |
167  // eNB1----------UE2
168  //
169  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
170  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNB1
171  positionAlloc->Add (Vector (m_d2, m_d1, 0.0)); // eNB2
172  positionAlloc->Add (Vector (0.0, m_d1, 0.0)); // UE1
173  positionAlloc->Add (Vector (m_d2, 0.0, 0.0)); // UE2
175  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
176  mobility.SetPositionAllocator (positionAlloc);
177  mobility.Install (allNodes);
178 
179  // Create Devices and install them in the Nodes (eNB and UE)
180  NetDeviceContainer enbDevs;
181  NetDeviceContainer ueDevs1;
182  NetDeviceContainer ueDevs2;
183  lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
184  lteHelper->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
185  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
186  ueDevs1 = lteHelper->InstallUeDevice (ueNodes1);
187  ueDevs2 = lteHelper->InstallUeDevice (ueNodes2);
188 
189  // Attach UEs to eNodeBs
190  lteHelper->Attach (ueDevs1, enbDevs.Get (0));
191  lteHelper->Attach (ueDevs2, enbDevs.Get (1));
192 
193  // Activate an EPS bearer
194  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
195  EpsBearer bearer (q);
196  lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
197  lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
198 
199 
200  Config::Connect ("/NodeList/2/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
202  Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
204 
205  Config::Connect ("/NodeList/3/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
207  Config::Connect ("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
209 
210  // need to allow for RRC connection establishment + SRS
211  Simulator::Stop (Seconds (0.800));
212  Simulator::Run ();
213 
214  Simulator::Destroy ();
215 
216 }
217 
218 void
219 LteUeMeasurementsTestCase::ReportUeMeasurements (uint16_t rnti, uint16_t cellId,
220  double rsrp, double rsrq,
221  bool servingCell)
222 {
223  // need to allow for RRC connection establishment + CQI feedback reception + UE measurements filtering (200 ms)
224  if (Simulator::Now () > MilliSeconds (400))
225  {
226  if (servingCell)
227  {
228  NS_LOG_DEBUG ("UE serving cellId " << cellId << " Rxed RSRP " << rsrp << " thr " << m_rsrpDbmUeServingCell << " RSRQ " << rsrq << " thr " << m_rsrqDbUeServingCell);
229  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrpDbmUeServingCell, rsrp, 0.2, "Wrong RSRP UE 1");
230  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrqDbUeServingCell, rsrq, 0.2, "Wrong RSRQ UE 1");
231  }
232  else
233  {
234  NS_LOG_DEBUG ("UE neighbor cellId " << cellId << " Rxed RSRP " << rsrp << " thr " << m_rsrpDbmUeNeighborCell << " RSRQ " << rsrq << " thr " << m_rsrqDbUeNeighborCell);
235  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrpDbmUeNeighborCell, rsrp, 0.2, "Wrong RSRP UE 2");
236  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrqDbUeNeighborCell, rsrq, 0.2, "Wrong RSRQ UE ");
237  }
238  }
239 }
240 
241 void
242 LteUeMeasurementsTestCase::RecvMeasurementReport (uint64_t imsi, uint16_t cellId, uint16_t rnti,
244 {
245  // need to allow for RRC connection establishment + CQI feedback reception + UE measurements filtering (200 ms)
246  if (Simulator::Now () > MilliSeconds (400))
247  {
248  if (cellId == imsi)
249  {
250  NS_LOG_DEBUG (this << "Serving Cell: received IMSI " << imsi << " CellId " << cellId << " RNTI " << rnti
251  << " thr " << (uint16_t) EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeServingCell)
252  << " RSRP " << (uint16_t) meas.measResults.measResultPCell.rsrpResult
253  << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult
254  << " thr " << (uint16_t) EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeServingCell));
256  EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeServingCell),
257  "Wrong RSRP ");
259  EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeServingCell),
260  "Wrong RSRQ ");
261  }
262  else
263  {
264  NS_LOG_DEBUG (this << "Neighbor cell: received IMSI " << imsi << " CellId " << cellId << " RNTI " << rnti
265  << " thr " << (uint16_t) EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeNeighborCell)
266  << " RSRP " << (uint16_t) meas.measResults.measResultPCell.rsrpResult
267  << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult
268  << " thr " << (uint16_t) EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeNeighborCell));
270  EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeNeighborCell),
271  "Wrong RSRP ");
273  EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeNeighborCell),
274  "Wrong RSRQ ");
275  }
276  }
277 }
278 
279 
280 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-1 TEST SUITE ======================== //
281 
282 /*
283  * Overloaded operators, for the convenience of defining test cases
284  */
285 
286 std::vector<Time>&
287 operator<< (std::vector<Time>& v, const uint64_t& ms)
288 {
289  /*
290  * Prior attempt to use seconds as unit of choice resulted in precision lost.
291  * Therefore milliseconds are used now instead.
292  */
293  v.push_back (MilliSeconds (ms) + UE_MEASUREMENT_REPORT_DELAY);
294  return v;
295 }
296 
297 std::vector<uint8_t>&
298 operator<< (std::vector<uint8_t>& v, const uint8_t& range)
299 {
300  v.push_back (range);
301  return v;
302 }
303 
304 
305 /*
306  * Test Suite
307  */
308 
310  : TestSuite ("lte-ue-measurements-piecewise-1", SYSTEM)
311 {
312  std::vector<Time> expectedTime;
313  std::vector<uint8_t> expectedRsrp;
314 
315  // === Event A1 (serving cell becomes better than threshold) ===
316 
317  // With very low threshold
319  config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
320  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
321  config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
322  config.threshold1.range = 0;
323  config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
324  config.reportInterval = LteRrcSap::ReportConfigEutra::MS120;
325  expectedTime.clear ();
326  expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280
327  << 1400 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
328  expectedRsrp.clear ();
329  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57
330  << 51 << 51 << 47 << 47 << 51 << 57 << 57;
331  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with very low threshold",
332  config, expectedTime, expectedRsrp),
333  TestCase::EXTENSIVE);
334 
335  // With normal threshold
336  config.threshold1.range = 54;
337  expectedTime.clear ();
338  expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 2000
339  << 2120;
340  expectedRsrp.clear ();
341  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 57
342  << 57;
343  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with normal threshold",
344  config, expectedTime, expectedRsrp),
345  TestCase::EXTENSIVE);
346 
347  // With short time-to-trigger
348  config.timeToTrigger = 64;
349  expectedTime.clear ();
350  expectedTime << 264 << 384 << 504 << 624 << 744 << 1064 << 1184 << 1304 << 1424 << 2064
351  << 2184;
352  expectedRsrp.clear ();
353  expectedRsrp << 67 << 67 << 57 << 66 << 66 << 66 << 66 << 57 << 51 << 57
354  << 57;
355  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with short time-to-trigger",
356  config, expectedTime, expectedRsrp),
357  TestCase::QUICK);
358 
359  // With long time-to-trigger
360  config.timeToTrigger = 128;
361  expectedTime.clear ();
362  expectedTime << 328 << 448 << 568 << 688 << 808 << 1128 << 1248 << 1368 << 1488 << 2128;
363  expectedRsrp.clear ();
364  expectedRsrp << 67 << 57 << 57 << 66 << 47 << 66 << 57 << 57 << 51 << 57;
365  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with long time-to-trigger",
366  config, expectedTime, expectedRsrp),
367  TestCase::EXTENSIVE);
368 
369  // With super time-to-trigger
370  config.timeToTrigger = 256;
371  expectedTime.clear ();
372  expectedTime << 456 << 576 << 696 << 816 << 936 << 1056 << 1176 << 1296 << 1416 << 1536;
373  expectedRsrp.clear ();
374  expectedRsrp << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51;
375  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with super time-to-trigger",
376  config, expectedTime, expectedRsrp),
377  TestCase::EXTENSIVE);
378 
379  // With hysteresis
380  config.hysteresis = 8;
381  config.timeToTrigger = 0;
382  expectedTime.clear ();
383  expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 1480
384  << 2200;
385  expectedRsrp.clear ();
386  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 51
387  << 67;
388  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with hysteresis",
389  config, expectedTime, expectedRsrp),
390  TestCase::QUICK);
391 
392  // With very high threshold
393  config.threshold1.range = 97;
394  config.hysteresis = 0;
395  expectedTime.clear ();
396  expectedRsrp.clear ();
397  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with very high threshold",
398  config, expectedTime, expectedRsrp),
399  TestCase::TAKES_FOREVER);
400 
401  // === Event A2 (serving cell becomes worse than threshold) ===
402 
403  // With very low threshold
404  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
405  config.threshold1.range = 0;
406  expectedTime.clear ();
407  expectedRsrp.clear ();
408  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with very low threshold",
409  config, expectedTime, expectedRsrp),
410  TestCase::TAKES_FOREVER);
411 
412  // With normal threshold
413  config.threshold1.range = 54;
414  expectedTime.clear ();
415  expectedTime << 800 << 920 << 1400 << 1520 << 1640 << 1760 << 1880;
416  expectedRsrp.clear ();
417  expectedRsrp << 47 << 47 << 51 << 51 << 47 << 47 << 51;
418  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with normal threshold",
419  config, expectedTime, expectedRsrp),
420  TestCase::QUICK);
421 
422  // With short time-to-trigger
423  config.timeToTrigger = 64;
424  expectedTime.clear ();
425  expectedTime << 864 << 984 << 1464 << 1584 << 1704 << 1824 << 1944;
426  expectedRsrp.clear ();
427  expectedRsrp << 47 << 47 << 51 << 51 << 47 << 51 << 51;
428  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with short time-to-trigger",
429  config, expectedTime, expectedRsrp),
430  TestCase::EXTENSIVE);
431 
432  // With long time-to-trigger
433  config.timeToTrigger = 128;
434  expectedTime.clear ();
435  expectedTime << 928 << 1048 << 1528 << 1648 << 1768 << 1888 << 2008;
436  expectedRsrp.clear ();
437  expectedRsrp << 47 << 66 << 51 << 47 << 47 << 51 << 57;
438  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with long time-to-trigger",
439  config, expectedTime, expectedRsrp),
440  TestCase::TAKES_FOREVER);
441 
442  // With super time-to-trigger
443  config.timeToTrigger = 256;
444  expectedTime.clear ();
445  expectedTime << 1656 << 1776 << 1896 << 2016 << 2136;
446  expectedRsrp.clear ();
447  expectedRsrp << 47 << 47 << 51 << 57 << 57;
448  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with super time-to-trigger",
449  config, expectedTime, expectedRsrp),
450  TestCase::QUICK);
451 
452  // With hysteresis
453  config.hysteresis = 8;
454  config.timeToTrigger = 0;
455  expectedTime.clear ();
456  expectedTime << 800 << 920 << 1600 << 1720 << 1840 << 1960 << 2080;
457  expectedRsrp.clear ();
458  expectedRsrp << 47 << 47 << 47 << 47 << 51 << 51 << 57;
459  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with hysteresis",
460  config, expectedTime, expectedRsrp),
461  TestCase::EXTENSIVE);
462 
463  // With very high threshold
464  config.threshold1.range = 97;
465  config.hysteresis = 0;
466  expectedTime.clear ();
467  expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280
468  << 1400 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
469  expectedRsrp.clear ();
470  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57
471  << 51 << 51 << 47 << 47 << 51 << 57 << 57;
472  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with very high threshold",
473  config, expectedTime, expectedRsrp),
474  TestCase::EXTENSIVE);
475 
476  /*
477  * Event A3, A4, and A5 are not tested intensively here because they depend on
478  * the existence of at least one neighbouring cell, which is not available in
479  * this configuration. Piecewise configuration #2 includes a neighbouring
480  * cell, hence more thorough tests on these events are performed there.
481  */
482 
483  expectedTime.clear ();
484  expectedRsrp.clear ();
485 
486  // === Event A3 (neighbour becomes offset better than PCell) ===
487 
488  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
489  config.a3Offset = 0;
490  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A3",
491  config, expectedTime, expectedRsrp),
492  TestCase::EXTENSIVE);
493 
494  // === Event A4 (neighbour becomes better than threshold) ===
495 
496  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
497  config.threshold1.range = 54;
498  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4",
499  config, expectedTime, expectedRsrp),
500  TestCase::EXTENSIVE);
501 
502  // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) ===
503 
504  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
505  config.threshold2.range = 58;
506  AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5",
507  config, expectedTime, expectedRsrp),
508  TestCase::EXTENSIVE);
509 
510 } // end of LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1
511 
513 
514 
515 /*
516  * Test Case
517  */
518 
520  std::string name, LteRrcSap::ReportConfigEutra config,
521  std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp)
522  : TestCase (name),
523  m_config (config),
524  m_expectedTime (expectedTime),
525  m_expectedRsrp (expectedRsrp)
526 {
527  // input sanity check
528  uint16_t size = m_expectedTime.size ();
529 
530  if (size != m_expectedRsrp.size ())
531  {
532  NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
533  }
534 
535  m_itExpectedTime = m_expectedTime.begin ();
536  m_itExpectedRsrp = m_expectedRsrp.begin ();
537 
538  NS_LOG_INFO (this << " name=" << name);
539 }
540 
542 {
543  NS_LOG_FUNCTION (this);
544 }
545 
546 void
548 {
549  NS_LOG_INFO (this << " " << GetName ());
550 
551  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
552  lteHelper->SetAttribute ("PathlossModel",
553  StringValue ("ns3::FriisSpectrumPropagationLossModel"));
554  lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
555 
556  //Disable Uplink Power Control
557  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
558 
559  // Create Nodes: eNodeB and UE
560  NodeContainer enbNodes;
561  NodeContainer ueNodes;
562  enbNodes.Create (1);
563  ueNodes.Create (1);
564 
565  /*
566  * The topology is the following:
567  *
568  * eNodeB UE
569  * | |
570  * x ----- x --------- x --------------- x ------------------- x
571  * 100 m | 200 m | 300 m | 400 m |
572  * | | | |
573  * VeryNear Near Far VeryFar
574  */
575 
576  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
577  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNodeB
578  positionAlloc->Add (Vector (100.0, 0.0, 0.0)); // UE
580  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
581  mobility.SetPositionAllocator (positionAlloc);
582  mobility.Install (enbNodes);
583  mobility.Install (ueNodes);
584  m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
585 
586  // Disable layer-3 filtering
587  Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
588  UintegerValue (0));
589 
590  // Create Devices and install them in the Nodes (eNB and UE)
591  NetDeviceContainer enbDevs;
592  NetDeviceContainer ueDevs;
593  lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
594  lteHelper->SetSchedulerAttribute ("UlCqiFilter",
595  EnumValue (FfMacScheduler::PUSCH_UL_CQI));
596  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
597  ueDevs = lteHelper->InstallUeDevice (ueNodes);
598 
599  // Setup UE measurement configuration
600  Ptr<LteEnbRrc> enbRrc = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
601  m_expectedMeasId = enbRrc->AddUeMeasReportConfig (m_config).at (0);
602 
603  // Attach UE to eNodeB
604  lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
605 
606  // Activate an EPS bearer
607  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
608  EpsBearer bearer (q);
609  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
610 
611  // Connect to trace sources
612  Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
614  this));
615 
616  /*
617  * Schedule "teleports"
618  * 0 1 2
619  * +-------------------+-------------------+---------> time
620  * VeryNear |------ ---- ---- --------
621  * Near | ---- ----
622  * Far | ---- ----
623  * VeryFar | -- ---- ----
624  */
625  Simulator::Schedule (MilliSeconds (301),
627  Simulator::Schedule (MilliSeconds (401),
629  Simulator::Schedule (MilliSeconds (601),
631  Simulator::Schedule (MilliSeconds (801),
633  Simulator::Schedule (MilliSeconds (1001),
635  Simulator::Schedule (MilliSeconds (1201),
637  Simulator::Schedule (MilliSeconds (1401),
639  Simulator::Schedule (MilliSeconds (1601),
641  Simulator::Schedule (MilliSeconds (1801),
643  Simulator::Schedule (MilliSeconds (2001),
645 
646  // Run simulation
647  Simulator::Stop (Seconds (2.201));
648  Simulator::Run ();
649  Simulator::Destroy ();
650 
651 } // end of void LteUeMeasurementsPiecewiseTestCase1::DoRun ()
652 
653 void
655 {
656  NS_LOG_FUNCTION (this);
657  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
658  NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
659  "Reporting should have occurred at " << m_itExpectedTime->As (Time::S));
660  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
661  NS_ASSERT (hasEnded);
662 }
663 
664 void
666  std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
668 {
669  NS_LOG_FUNCTION (this << context);
670  NS_ASSERT (rnti == 1);
671  NS_ASSERT (cellId == 1);
672 
673  if (report.measResults.measId == m_expectedMeasId)
674  {
675  // verifying the report completeness
676  LteRrcSap::MeasResults measResults = report.measResults;
677  NS_LOG_DEBUG (this << " rsrp=" << (uint16_t) measResults.measResultPCell.rsrpResult
678  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.measResultPCell.rsrpResult) << " dBm)"
679  << " rsrq=" << (uint16_t) measResults.measResultPCell.rsrqResult
680  << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.measResultPCell.rsrqResult) << " dB)");
682  "Report should not have neighboring cells information");
683  NS_TEST_ASSERT_MSG_EQ (measResults.measResultListEutra.size (), 0,
684  "Unexpected report size");
685 
686  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
687  NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
688  "Reporting should not have occurred at "
689  << Simulator::Now ().As (Time::S));
690  if (!hasEnded)
691  {
692  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
693  NS_ASSERT (!hasEnded);
694 
695  // using milliseconds to avoid floating-point comparison
696  uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
697  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
699 
700  uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
701  uint16_t referenceRsrp = *m_itExpectedRsrp;
703 
704  NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
705  "Reporting should not have occurred at this time");
706  NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
707  "The RSRP observed differs with the reference RSRP");
708  } // end of if (!hasEnded)
709 
710  } // end of if (measResults.measId == m_expectedMeasId)
711 
712 } // end of LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback
713 
714 void
716 {
717  NS_LOG_FUNCTION (this);
718  m_ueMobility->SetPosition (Vector (100.0, 0.0, 0.0));
719 }
720 
721 void
723 {
724  NS_LOG_FUNCTION (this);
725  m_ueMobility->SetPosition (Vector (300.0, 0.0, 0.0));
726 }
727 
728 void
730 {
731  NS_LOG_FUNCTION (this);
732  m_ueMobility->SetPosition (Vector (600.0, 0.0, 0.0));
733 }
734 
735 void
737 {
738  NS_LOG_FUNCTION (this);
739  m_ueMobility->SetPosition (Vector (1000.0, 0.0, 0.0));
740 }
741 
742 
743 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-2 TEST SUITE ======================== //
744 
745 /*
746  * Test Suite
747  */
748 
750  : TestSuite ("lte-ue-measurements-piecewise-2", SYSTEM)
751 {
752  std::vector<Time> expectedTime;
753  std::vector<uint8_t> expectedRsrp;
754 
755  /*
756  * Higher level of fullness/duration are given to Event A1 and A2 because they
757  * are supposed to be more intensively tested in Piecewise configuration #1.
758  */
759 
760  // === Event A1 (serving cell becomes better than threshold) ===
761 
762  // With very low threshold
764  config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
765  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
766  config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
767  config.threshold1.range = 0;
768  config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
769  config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
770  expectedTime.clear ();
771  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
772  expectedRsrp.clear ();
773  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
774  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with very low threshold",
775  config, expectedTime, expectedRsrp),
776  TestCase::EXTENSIVE);
777 
778  // With normal threshold
779  config.threshold1.range = 58;
780  expectedTime.clear ();
781  expectedTime << 200 << 440 << 680 << 1000 << 1240 << 2000;
782  expectedRsrp.clear ();
783  expectedRsrp << 73 << 63 << 72 << 72 << 59 << 59;
784  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with normal threshold",
785  config, expectedTime, expectedRsrp),
786  TestCase::TAKES_FOREVER);
787 
788  // With hysteresis
789  config.hysteresis = 6;
790  expectedTime.clear ();
791  expectedTime << 200 << 440 << 680 << 1000 << 1240 << 1480 << 2200;
792  expectedRsrp.clear ();
793  expectedRsrp << 73 << 63 << 72 << 72 << 59 << 56 << 72;
794  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with hysteresis",
795  config, expectedTime, expectedRsrp),
796  TestCase::EXTENSIVE);
797 
798  // With very high threshold
799  config.threshold1.range = 97;
800  config.hysteresis = 0;
801  expectedTime.clear ();
802  expectedRsrp.clear ();
803  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with very high threshold",
804  config, expectedTime, expectedRsrp),
805  TestCase::TAKES_FOREVER);
806 
807  // === Event A2 (serving cell becomes worse than threshold) ===
808 
809  // With very low threshold
810  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
811  config.threshold1.range = 0;
812  expectedTime.clear ();
813  expectedRsrp.clear ();
814  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with very low threshold",
815  config, expectedTime, expectedRsrp),
816  TestCase::TAKES_FOREVER);
817 
818  // With normal threshold
819  config.threshold1.range = 58;
820  expectedTime.clear ();
821  expectedTime << 800 << 1400 << 1640 << 1880;
822  expectedRsrp.clear ();
823  expectedRsrp << 52 << 56 << 52 << 56;
824  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with normal threshold",
825  config, expectedTime, expectedRsrp),
826  TestCase::TAKES_FOREVER);
827 
828  // With hysteresis
829  config.hysteresis = 6;
830  expectedTime.clear ();
831  expectedTime << 800 << 1600 << 1840 << 2080;
832  expectedRsrp.clear ();
833  expectedRsrp << 52 << 52 << 56 << 59;
834  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with hysteresis",
835  config, expectedTime, expectedRsrp),
836  TestCase::EXTENSIVE);
837 
838  // With very high threshold
839  config.threshold1.range = 97;
840  config.hysteresis = 0;
841  expectedTime.clear ();
842  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
843  expectedRsrp.clear ();
844  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
845  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with very high threshold",
846  config, expectedTime, expectedRsrp),
847  TestCase::TAKES_FOREVER);
848 
849  // === Event A3 (neighbour becomes offset better than PCell) ===
850 
851  // With positive offset
852  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
853  config.threshold1.range = 0;
854  config.a3Offset = 7;
855  expectedTime.clear ();
856  expectedTime << 800 << 1600;
857  expectedRsrp.clear ();
858  expectedRsrp << 52 << 52;
859  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with positive offset",
860  config, expectedTime, expectedRsrp),
861  TestCase::QUICK);
862 
863  // With zero offset
864  config.a3Offset = 0;
865  expectedTime.clear ();
866  expectedTime << 800 << 1400 << 1640 << 1880;
867  expectedRsrp.clear ();
868  expectedRsrp << 52 << 56 << 52 << 56;
869  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with zero offset",
870  config, expectedTime, expectedRsrp),
871  TestCase::EXTENSIVE);
872 
873  // With short time-to-trigger
874  config.timeToTrigger = 160;
875  expectedTime.clear ();
876  expectedTime << 960 << 1560 << 1800 << 2040;
877  expectedRsrp.clear ();
878  expectedRsrp << 52 << 56 << 56 << 59;
879  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with short time-to-trigger",
880  config, expectedTime, expectedRsrp),
881  TestCase::EXTENSIVE);
882 
883  // With super time-to-trigger
884  config.timeToTrigger = 320;
885  expectedTime.clear ();
886  expectedTime << 1720 << 1960 << 2200;
887  expectedRsrp.clear ();
888  expectedRsrp << 52 << 56 << 72;
889  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with super time-to-trigger",
890  config, expectedTime, expectedRsrp),
891  TestCase::QUICK);
892 
893  // With hysteresis and reportOnLeave
894  config.hysteresis = 6;
895  config.reportOnLeave = true;
896  config.timeToTrigger = 0;
897  expectedTime.clear ();
898  expectedTime << 800 << 1000 << 1600 << 1840 << 2080 << 2200;
899  expectedRsrp.clear ();
900  expectedRsrp << 52 << 72 << 52 << 56 << 59 << 72;
901  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with hysteresis",
902  config, expectedTime, expectedRsrp),
903  TestCase::QUICK);
904 
905  // With negative offset
906  config.a3Offset = -7;
907  config.hysteresis = 0;
908  config.reportOnLeave = false;
909  expectedTime.clear ();
910  expectedTime << 400 << 800 << 1200 << 1440 << 1680 << 1920 << 2160;
911  expectedRsrp.clear ();
912  expectedRsrp << 63 << 52 << 59 << 56 << 52 << 56 << 59;
913  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with negative offset",
914  config, expectedTime, expectedRsrp),
915  TestCase::EXTENSIVE);
916 
917  // === Event A4 (neighbour becomes better than threshold) ===
918 
919  // With very low threshold
920  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
921  config.threshold1.range = 0;
922  config.a3Offset = 0;
923  expectedTime.clear ();
924  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
925  expectedRsrp.clear ();
926  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
927  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with very low threshold",
928  config, expectedTime, expectedRsrp),
929  TestCase::QUICK);
930 
931  // With normal threshold
932  config.threshold1.range = 58;
933  expectedTime.clear ();
934  expectedTime << 400 << 800 << 1400 << 1640 << 1880;
935  expectedRsrp.clear ();
936  expectedRsrp << 63 << 52 << 56 << 52 << 56;
937  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with normal threshold",
938  config, expectedTime, expectedRsrp),
939  TestCase::EXTENSIVE);
940 
941  // With short time-to-trigger
942  config.timeToTrigger = 160;
943  expectedTime.clear ();
944  expectedTime << 560 << 960 << 1560 << 1800 << 2040;
945  expectedRsrp.clear ();
946  expectedRsrp << 63 << 52 << 56 << 56 << 59;
947  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with short time-to-trigger",
948  config, expectedTime, expectedRsrp),
949  TestCase::QUICK);
950 
951  // With super time-to-trigger
952  config.timeToTrigger = 320;
953  expectedTime.clear ();
954  expectedTime << 1720 << 1960 << 2200;
955  expectedRsrp.clear ();
956  expectedRsrp << 52 << 56 << 72;
957  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with super time-to-trigger",
958  config, expectedTime, expectedRsrp),
959  TestCase::TAKES_FOREVER);
960 
961  // With hysteresis
962  config.hysteresis = 6;
963  config.timeToTrigger = 0;
964  expectedTime.clear ();
965  expectedTime << 400 << 800 << 1600 << 1840 << 2080;
966  expectedRsrp.clear ();
967  expectedRsrp << 63 << 52 << 52 << 56 << 59;
968  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with hysteresis",
969  config, expectedTime, expectedRsrp),
970  TestCase::QUICK);
971 
972  // With very high threshold
973  config.threshold1.range = 97;
974  config.hysteresis = 0;
975  expectedTime.clear ();
976  expectedRsrp.clear ();
977  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with very high threshold",
978  config, expectedTime, expectedRsrp),
979  TestCase::TAKES_FOREVER);
980 
981  // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) ===
982 
983  // With low-low threshold
984  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
985  config.threshold1.range = 0;
986  config.threshold2.range = 0;
987  expectedTime.clear ();
988  expectedRsrp.clear ();
989  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-low threshold",
990  config, expectedTime, expectedRsrp),
991  TestCase::EXTENSIVE);
992 
993  // With low-normal threshold
994  config.threshold2.range = 58;
995  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-normal threshold",
996  config, expectedTime, expectedRsrp),
997  TestCase::TAKES_FOREVER);
998 
999  // With low-high threshold
1000  config.threshold2.range = 97;
1001  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-high threshold",
1002  config, expectedTime, expectedRsrp),
1003  TestCase::TAKES_FOREVER);
1004 
1005  // With normal-low threshold
1006  config.threshold1.range = 58;
1007  config.threshold2.range = 0;
1008  expectedTime.clear ();
1009  expectedTime << 800 << 1400 << 1640 << 1880;
1010  expectedRsrp.clear ();
1011  expectedRsrp << 52 << 56 << 52 << 56;
1012  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-low threshold",
1013  config, expectedTime, expectedRsrp),
1014  TestCase::EXTENSIVE);
1015 
1016  // With normal-normal threshold
1017  config.threshold2.range = 58;
1018  expectedTime.clear ();
1019  expectedTime << 800 << 1400 << 1640 << 1880;
1020  expectedRsrp.clear ();
1021  expectedRsrp << 52 << 56 << 52 << 56;
1022  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-normal threshold",
1023  config, expectedTime, expectedRsrp),
1024  TestCase::EXTENSIVE);
1025 
1026  // With short time-to-trigger
1027  config.timeToTrigger = 160;
1028  expectedTime.clear ();
1029  expectedTime << 960 << 1560 << 1800 << 2040;
1030  expectedRsrp.clear ();
1031  expectedRsrp << 52 << 56 << 56 << 59;
1032  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with short time-to-trigger",
1033  config, expectedTime, expectedRsrp),
1034  TestCase::TAKES_FOREVER);
1035 
1036  // With super time-to-trigger
1037  config.timeToTrigger = 320;
1038  expectedTime.clear ();
1039  expectedTime << 1720 << 1960 << 2200;
1040  expectedRsrp.clear ();
1041  expectedRsrp << 52 << 56 << 72;
1042  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with super time-to-trigger",
1043  config, expectedTime, expectedRsrp),
1044  TestCase::QUICK);
1045 
1046  // With hysteresis
1047  config.hysteresis = 6;
1048  config.timeToTrigger = 0;
1049  expectedTime.clear ();
1050  expectedTime << 800 << 1600 << 1840 << 2080;
1051  expectedRsrp.clear ();
1052  expectedRsrp << 52 << 52 << 56 << 59;
1053  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with hysteresis",
1054  config, expectedTime, expectedRsrp),
1055  TestCase::QUICK);
1056 
1057  // With normal-high threshold
1058  config.threshold2.range = 97;
1059  config.hysteresis = 0;
1060  expectedTime.clear ();
1061  expectedRsrp.clear ();
1062  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-high threshold",
1063  config, expectedTime, expectedRsrp),
1064  TestCase::TAKES_FOREVER);
1065 
1066  // With high-low threshold
1067  config.threshold1.range = 97;
1068  config.threshold2.range = 0;
1069  expectedTime.clear ();
1070  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1071  expectedRsrp.clear ();
1072  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1073  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-low threshold",
1074  config, expectedTime, expectedRsrp),
1075  TestCase::EXTENSIVE);
1076 
1077  // With high-normal threshold
1078  config.threshold2.range = 58;
1079  expectedTime.clear ();
1080  expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1081  expectedRsrp.clear ();
1082  expectedRsrp << 63 << 52 << 56 << 52 << 56;
1083  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-normal threshold",
1084  config, expectedTime, expectedRsrp),
1085  TestCase::TAKES_FOREVER);
1086 
1087  // With high-high threshold
1088  config.threshold2.range = 97;
1089  expectedTime.clear ();
1090  expectedRsrp.clear ();
1091  AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-high threshold",
1092  config, expectedTime, expectedRsrp),
1093  TestCase::EXTENSIVE);
1094 
1095 } // end of LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2
1096 
1098 
1099 
1100 /*
1101  * Test Case
1102  */
1103 
1105  std::string name, LteRrcSap::ReportConfigEutra config,
1106  std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp)
1107  : TestCase (name),
1108  m_config (config),
1109  m_expectedTime (expectedTime),
1110  m_expectedRsrp (expectedRsrp)
1111 {
1112  // input sanity check
1113  uint16_t size = m_expectedTime.size ();
1114 
1115  if (size != m_expectedRsrp.size ())
1116  {
1117  NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
1118  }
1119 
1120  m_itExpectedTime = m_expectedTime.begin ();
1121  m_itExpectedRsrp = m_expectedRsrp.begin ();
1122 
1123  NS_LOG_INFO (this << " name=" << name);
1124 }
1125 
1127 {
1128  NS_LOG_FUNCTION (this);
1129 }
1130 
1131 void
1133 {
1134  NS_LOG_INFO (this << " " << GetName ());
1135 
1136  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
1137  lteHelper->SetAttribute ("PathlossModel",
1138  StringValue ("ns3::FriisSpectrumPropagationLossModel"));
1139  lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
1140 
1141  //Disable Uplink Power Control
1142  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
1143 
1144  // Create Nodes: eNodeB and UE
1145  NodeContainer enbNodes;
1146  NodeContainer ueNodes;
1147  enbNodes.Create (2);
1148  ueNodes.Create (1);
1149 
1150  /*
1151  * The topology is the following:
1152  *
1153  * eNodeB UE eNodeB
1154  * | | |
1155  * x ---- x --------------- x ------- x --------------- x ---- x
1156  * 50 m | 200 m | 100 m | 200 m | 50 m
1157  * | | | |
1158  * VeryNear Near Far VeryFar
1159  */
1160 
1161  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1162  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Serving eNodeB
1163  positionAlloc->Add (Vector (600.0, 0.0, 0.0)); // Neighbour eNodeB
1164  positionAlloc->Add (Vector (50.0, 0.0, 0.0)); // UE
1166  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1167  mobility.SetPositionAllocator (positionAlloc);
1168  mobility.Install (enbNodes);
1169  mobility.Install (ueNodes);
1170  m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
1171 
1172  // Disable layer-3 filtering
1173  Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
1174  UintegerValue (0));
1175 
1176  // Create Devices and install them in the Nodes (eNB and UE)
1177  NetDeviceContainer enbDevs;
1178  NetDeviceContainer ueDevs;
1179  lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
1180  lteHelper->SetSchedulerAttribute ("UlCqiFilter",
1181  EnumValue (FfMacScheduler::PUSCH_UL_CQI));
1182  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
1183  ueDevs = lteHelper->InstallUeDevice (ueNodes);
1184 
1185  // Setup UE measurement configuration in serving cell
1186  Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1187  m_expectedMeasId = enbRrc1->AddUeMeasReportConfig (m_config).at (0);
1188 
1189  // Disable handover in neighbour cell
1190  Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1191  enbRrc2->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
1192 
1193  // Attach UE to serving eNodeB
1194  lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
1195 
1196  // Activate an EPS bearer
1197  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
1198  EpsBearer bearer (q);
1199  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
1200 
1201  // Connect to trace sources in serving eNodeB
1202  Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1204  this));
1205 
1206  /*
1207  * Schedule "teleports"
1208  * 0 1 2
1209  * +-------------------+-------------------+---------> time
1210  * VeryNear |------ ---- ---- --------
1211  * Near | ---- ----
1212  * Far | ---- ----
1213  * VeryFar | -- ---- ----
1214  */
1215  Simulator::Schedule (MilliSeconds (301),
1217  Simulator::Schedule (MilliSeconds (401),
1219  Simulator::Schedule (MilliSeconds (601),
1221  Simulator::Schedule (MilliSeconds (801),
1223  Simulator::Schedule (MilliSeconds (1001),
1225  Simulator::Schedule (MilliSeconds (1201),
1227  Simulator::Schedule (MilliSeconds (1401),
1229  Simulator::Schedule (MilliSeconds (1601),
1231  Simulator::Schedule (MilliSeconds (1801),
1233  Simulator::Schedule (MilliSeconds (2001),
1235 
1236  // Run simulation
1237  Simulator::Stop (Seconds (2.201));
1238  Simulator::Run ();
1239  Simulator::Destroy ();
1240 
1241 } // end of void LteUeMeasurementsPiecewiseTestCase2::DoRun ()
1242 
1243 void
1245 {
1246  NS_LOG_FUNCTION (this);
1247  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1248  NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
1249  "Reporting should have occurred at " << m_itExpectedTime->As (Time::S));
1250  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
1251  NS_ASSERT (hasEnded);
1252 }
1253 
1254 void
1256  std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
1258 {
1259  NS_LOG_FUNCTION (this << context);
1260  NS_ASSERT (rnti == 1);
1261  NS_ASSERT (cellId == 1);
1262 
1263  if (report.measResults.measId == m_expectedMeasId)
1264  {
1265  // verifying the report completeness
1266  LteRrcSap::MeasResults measResults = report.measResults;
1267  NS_LOG_DEBUG (this << " Serving cellId=" << cellId
1268  << " rsrp=" << (uint16_t) measResults.measResultPCell.rsrpResult
1269  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.measResultPCell.rsrpResult) << " dBm)"
1270  << " rsrq=" << (uint16_t) measResults.measResultPCell.rsrqResult
1271  << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.measResultPCell.rsrqResult) << " dB)");
1272 
1273  // verifying reported best cells
1274  if (measResults.measResultListEutra.size () == 0)
1275  {
1276  NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
1277  "Unexpected report content");
1278  }
1279  else
1280  {
1282  "Unexpected report content");
1283  std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
1284  NS_ASSERT (it != measResults.measResultListEutra.end ());
1285  NS_ASSERT (it->physCellId == 2);
1286  NS_TEST_ASSERT_MSG_EQ (it->haveCgiInfo, false,
1287  "Report contains cgi-info, which is not supported");
1288  NS_TEST_ASSERT_MSG_EQ (it->haveRsrpResult, true,
1289  "Report does not contain measured RSRP result");
1290  NS_TEST_ASSERT_MSG_EQ (it->haveRsrqResult, true,
1291  "Report does not contain measured RSRQ result");
1292  NS_LOG_DEBUG (this << " Neighbour cellId=" << it->physCellId
1293  << " rsrp=" << (uint16_t) it->rsrpResult
1294  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (it->rsrpResult) << " dBm)"
1295  << " rsrq=" << (uint16_t) it->rsrqResult
1296  << " (" << EutranMeasurementMapping::RsrqRange2Db (it->rsrqResult) << " dB)");
1297 
1298  } // end of else of if (measResults.measResultListEutra.size () == 0)
1299 
1300  // verifying the report timing
1301  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1302  NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
1303  "Reporting should not have occurred at "
1304  << Simulator::Now ().As (Time::S));
1305  if (!hasEnded)
1306  {
1307  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
1308  NS_ASSERT (!hasEnded);
1309 
1310  // using milliseconds to avoid floating-point comparison
1311  uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
1312  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
1313  m_itExpectedTime++;
1314 
1315  uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
1316  uint16_t referenceRsrp = *m_itExpectedRsrp;
1317  m_itExpectedRsrp++;
1318 
1319  NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
1320  "Reporting should not have occurred at this time");
1321  NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
1322  "The RSRP observed differs with the reference RSRP");
1323 
1324  } // end of if (!hasEnded)
1325 
1326  } // end of if (report.measResults.measId == m_expectedMeasId)
1327 
1328 } // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
1329 
1330 void
1332 {
1333  NS_LOG_FUNCTION (this);
1334  m_ueMobility->SetPosition (Vector (50.0, 0.0, 0.0));
1335 }
1336 
1337 void
1339 {
1340  NS_LOG_FUNCTION (this);
1341  m_ueMobility->SetPosition (Vector (250.0, 0.0, 0.0));
1342 }
1343 
1344 void
1346 {
1347  NS_LOG_FUNCTION (this);
1348  m_ueMobility->SetPosition (Vector (350.0, 0.0, 0.0));
1349 }
1350 
1351 void
1353 {
1354  NS_LOG_FUNCTION (this);
1355  m_ueMobility->SetPosition (Vector (550.0, 0.0, 0.0));
1356 }
1357 
1358 
1359 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-3 TEST SUITE ======================== //
1360 
1361 /*
1362  * Test Suite
1363  */
1364 
1366  : TestSuite ("lte-ue-measurements-piecewise-3", SYSTEM)
1367 {
1368  std::vector<Time> expectedTime;
1369 
1370  // === Event A4 (neighbor becomes better than threshold) ===
1371 
1372  //The threshold value was chosen to achieve the following:
1373  //1. Neighbor 1 (eNB2) RSRP would be above the chosen threshold, hence,
1374  //the UE will include it in its reports to its eNB (eNB1) from the beginning
1375  //of the simulation.
1376  //2. When neighbor 2 (eNB3) is placed at a very far position, its RSRP would
1377  //be less than the chosen threshold, hence, UE will not include it in its
1378  //initial report(s) to its eNB.
1379  //3. When neighbor 2 (eNB3) is placed at a near position, its RSRP would
1380  //always be above the chosen threshold, hence, the UE will include it in its
1381  //reports to its eNB (eNB1).
1383  config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1384  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1385  config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1386  config.threshold1.range = 6;
1387  config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1388  config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1389  expectedTime.clear ();
1390  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1391 
1392  AddTestCase (new LteUeMeasurementsPiecewiseTestCase3 ("Piecewise test case 3 - Event A4",
1393  config, expectedTime),TestCase::QUICK);
1394 } // end of LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3
1395 
1397 
1398 
1399 /*
1400  * Test Case
1401  */
1402 
1404  std::string name, LteRrcSap::ReportConfigEutra config,
1405  std::vector<Time> expectedTime)
1406  : TestCase (name),
1407  m_config (config),
1408  m_expectedTime (expectedTime)
1409 {
1411 
1412  m_itExpectedTime = m_expectedTime.begin ();
1413 
1414  NS_LOG_INFO (this << " name=" << name);
1415 }
1416 
1418 {
1419  NS_LOG_FUNCTION (this);
1420 }
1421 
1422 void
1424 {
1425  NS_LOG_INFO (this << " " << GetName ());
1426 
1427  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
1428  lteHelper->SetAttribute ("PathlossModel",
1429  StringValue ("ns3::FriisSpectrumPropagationLossModel"));
1430  lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
1431 
1432  //Disable Uplink Power Control
1433  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
1434 
1435  // Create Nodes: eNodeB and UE
1436  NodeContainer enbNodes;
1437  NodeContainer ueNodes;
1438  enbNodes.Create (3);
1439  ueNodes.Create (1);
1440 
1441  /*
1442  * The topology is the following:
1443  *
1444  * We place the 3rd eNB initially very far so it does not fulfills
1445  * the entry condition to be reported.
1446  *
1447  * eNodeB UE eNodeB eNodeB
1448  * | | | |
1449  * x ---- x --------------- x -------------- x ---------------------x
1450  * 50 m 100 m 500 | 1000000
1451  * Near
1452  */
1453 
1454  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1455  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Serving eNodeB
1456  positionAlloc->Add (Vector (200.0, 0.0, 0.0)); // Neighbour eNodeB1
1457  positionAlloc->Add (Vector (1000700.0, 0.0, 0.0)); // Neighbour eNodeB2
1458  positionAlloc->Add (Vector (50.0, 0.0, 0.0)); // UE
1460  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1461  mobility.SetPositionAllocator (positionAlloc);
1462  mobility.Install (enbNodes);
1463  mobility.Install (ueNodes);
1464  m_enbMobility = enbNodes.Get (2)->GetObject<MobilityModel> ();
1465 
1466  // Disable layer-3 filtering
1467  Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
1468  UintegerValue (0));
1469 
1470  // Create Devices and install them in the Nodes (eNB and UE)
1471  NetDeviceContainer enbDevs;
1472  NetDeviceContainer ueDevs;
1473  lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
1474  lteHelper->SetSchedulerAttribute ("UlCqiFilter",
1475  EnumValue (FfMacScheduler::PUSCH_UL_CQI));
1476  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
1477  ueDevs = lteHelper->InstallUeDevice (ueNodes);
1478 
1479  // Setup UE measurement configuration in serving cell
1480  Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1481  m_expectedMeasId = enbRrc1->AddUeMeasReportConfig (m_config).at (0);
1482 
1483  // Disable handover in neighbour cells
1484  Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1485  enbRrc2->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
1486  Ptr<LteEnbRrc> enbRrc3 = enbDevs.Get (2)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1487  enbRrc3->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
1488 
1489  // Attach UE to serving eNodeB
1490  lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
1491 
1492  // Activate an EPS bearer
1493  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
1494  EpsBearer bearer (q);
1495  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
1496 
1497  // Connect to trace sources in serving eNodeB
1498  Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1500  this));
1501  /*
1502  * Schedule "teleport" for the 2nd neighbour
1503  *
1504  * We bring the 2nd neighbour near once the UE has already scheduled the periodic
1505  * reporting after detecting the 1st neighbour, which ideally should be at
1506  * 200 ms.
1507  */
1508  Simulator::Schedule (MilliSeconds (301),
1510 
1511  // Run simulation
1512  Simulator::Stop (Seconds (2.201));
1513  Simulator::Run ();
1514  Simulator::Destroy ();
1515 
1516 } // end of void LteUeMeasurementsPiecewiseTestCase3::DoRun ()
1517 
1518 void
1520 {
1521  NS_LOG_FUNCTION (this);
1522  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1523  NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
1524  "Reporting should have occurred at " << m_itExpectedTime->GetSeconds () << "s");
1525 }
1526 
1527 void
1529  std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
1531 {
1532  NS_LOG_FUNCTION (this << context);
1533  NS_ASSERT (rnti == 1);
1534  NS_ASSERT (cellId == 1);
1535 
1536  if (report.measResults.measId == m_expectedMeasId)
1537  {
1538  // verifying the report completeness
1539  LteRrcSap::MeasResults measResults = report.measResults;
1540  NS_LOG_DEBUG (this << " Serving cellId=" << cellId
1541  << " rsrp=" << (uint16_t) measResults.measResultPCell.rsrpResult
1542  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.measResultPCell.rsrpResult) << " dBm)"
1543  << " rsrq=" << (uint16_t) measResults.measResultPCell.rsrqResult
1544  << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.measResultPCell.rsrqResult) << " dB)");
1545 
1546  // verifying reported best cells
1547  if (measResults.measResultListEutra.size () == 0)
1548  {
1549  NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
1550  "Unexpected report content");
1551  }
1552  else
1553  {
1555  "Unexpected report content");
1556  std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
1557  NS_ASSERT (it != measResults.measResultListEutra.end ());
1558  for (const auto &it:measResults.measResultListEutra)
1559  {
1560  NS_ASSERT (it.physCellId == 2 || it.physCellId == 3);
1561  NS_TEST_ASSERT_MSG_EQ (it.haveCgiInfo, false,
1562  "Report contains cgi-info, which is not supported");
1563  NS_TEST_ASSERT_MSG_EQ (it.haveRsrpResult, true,
1564  "Report does not contain measured RSRP result");
1565  NS_TEST_ASSERT_MSG_EQ (it.haveRsrqResult, true,
1566  "Report does not contain measured RSRQ result");
1567  NS_LOG_DEBUG (this << " Neighbour cellId=" << it.physCellId
1568  << " rsrp=" << (uint16_t) it.rsrpResult
1569  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (it.rsrpResult) << " dBm)"
1570  << " rsrq=" << (uint16_t) it.rsrqResult
1571  << " (" << EutranMeasurementMapping::RsrqRange2Db (it.rsrqResult) << " dB)");
1572  }
1573 
1574  } // end of else of if (measResults.measResultListEutra.size () == 0)
1575 
1576  // verifying the report timing
1577  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1578  NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
1579  "Reporting should not have occurred at "
1580  << Simulator::Now ().GetSeconds () << "s");
1581  if (!hasEnded)
1582  {
1583  // using milliseconds to avoid floating-point comparison
1584  uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
1585  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
1586  m_itExpectedTime++;
1587 
1588 
1589  NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
1590  "Reporting should not have occurred at this time");
1591 
1592  } // end of if (!hasEnded)
1593 
1594  } // end of if (report.measResults.measId == m_expectedMeasId)
1595 
1596 } // end of void LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback
1597 
1598 void
1600 {
1601  NS_LOG_FUNCTION (this);
1602  m_enbMobility->SetPosition (Vector (700.0, 0.0, 0.0));
1603 }
1604 
1605 
1606 // ===== LTE-UE-MEASUREMENTS-HANDOVER TEST SUITE =========================== //
1607 
1608 /*
1609  * Test Suite
1610  */
1611 
1613  : TestSuite ("lte-ue-measurements-handover", SYSTEM)
1614 {
1615  std::list<LteRrcSap::ReportConfigEutra> sourceConfigList;
1616  std::list<LteRrcSap::ReportConfigEutra> targetConfigList;
1617  std::vector<Time> expectedTime;
1618  std::vector<uint8_t> expectedRsrp;
1619 
1620  LteRrcSap::ReportConfigEutra sourceConfig;
1621  sourceConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1622  sourceConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1623  sourceConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1624  sourceConfig.threshold1.range = 0;
1625  sourceConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1626  sourceConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1627  sourceConfigList.push_back (sourceConfig);
1628 
1629  LteRrcSap::ReportConfigEutra targetConfig;
1630  targetConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1631  targetConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1632  targetConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1633  targetConfig.threshold1.range = 0;
1634  targetConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1635  targetConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1636  targetConfigList.push_back (targetConfig);
1637 
1638  // === Report interval difference ===
1639 
1640  // decreasing report interval
1641  sourceConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS480;
1642  targetConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1643  expectedTime.clear ();
1644  expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
1645  expectedRsrp.clear ();
1646  expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
1647  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - decreasing report interval",
1648  sourceConfigList, targetConfigList,
1649  expectedTime, expectedRsrp,
1650  Seconds (2)),
1651  TestCase::TAKES_FOREVER);
1652 
1653  // increasing report interval
1654  sourceConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS120;
1655  targetConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS640;
1656  expectedTime.clear ();
1657  expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1200 << 1840;
1658  expectedRsrp.clear ();
1659  expectedRsrp << 55 << 55 << 55 << 55 << 55 << 55 << 55 << 53 << 53;
1660  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - increasing report interval",
1661  sourceConfigList, targetConfigList,
1662  expectedTime, expectedRsrp,
1663  Seconds (2)),
1664  TestCase::QUICK);
1665 
1666  // === Event difference ===
1667 
1668  sourceConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1669  targetConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1670  sourceConfigList.front ().threshold1.range = 54;
1671  sourceConfigList.front ().threshold2.range = 54;
1672  sourceConfigList.front ().a3Offset = 1;
1673  targetConfigList.front ().threshold1.range = 54;
1674  targetConfigList.front ().threshold2.range = 54;
1675  targetConfigList.front ().a3Offset = 1;
1676 
1677  // Event A1 to Event A2
1678  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1679  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1680  expectedTime.clear ();
1681  expectedTime << 200 << 440 << 680 << 920 << 1200 << 1440 << 1680 << 1920;
1682  expectedRsrp.clear ();
1683  expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53;
1684  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A1 to Event A2",
1685  sourceConfigList, targetConfigList,
1686  expectedTime, expectedRsrp,
1687  Seconds (2)),
1688  TestCase::EXTENSIVE);
1689 
1690  // Event A2 to Event A1
1691  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1692  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1693  expectedTime.clear ();
1694  expectedRsrp.clear ();
1695  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A2 to Event A1",
1696  sourceConfigList, targetConfigList,
1697  expectedTime, expectedRsrp,
1698  Seconds (2)),
1699  TestCase::TAKES_FOREVER);
1700 
1701  // Event A3 to Event A4
1702  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1703  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1704  expectedTime.clear ();
1705  expectedTime << 1200 << 1440 << 1680 << 1920;
1706  expectedRsrp.clear ();
1707  expectedRsrp << 53 << 53 << 53 << 53;
1708  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A3 to Event A4",
1709  sourceConfigList, targetConfigList,
1710  expectedTime, expectedRsrp,
1711  Seconds (2)),
1712  TestCase::TAKES_FOREVER);
1713 
1714  // Event A4 to Event A3
1715  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1716  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1717  expectedTime.clear ();
1718  expectedTime << 1200 << 1440 << 1680 << 1920;
1719  expectedRsrp.clear ();
1720  expectedRsrp << 53 << 53 << 53 << 53;
1721  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A4 to Event A3",
1722  sourceConfigList, targetConfigList,
1723  expectedTime, expectedRsrp,
1724  Seconds (2)),
1725  TestCase::QUICK);
1726 
1727  // Event A2 to Event A3
1728  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1729  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1730  expectedTime.clear ();
1731  expectedTime << 1200 << 1440 << 1680 << 1920;
1732  expectedRsrp.clear ();
1733  expectedRsrp << 53 << 53 << 53 << 53;
1734  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A2 to Event A3",
1735  sourceConfigList, targetConfigList,
1736  expectedTime, expectedRsrp,
1737  Seconds (2)),
1738  TestCase::EXTENSIVE);
1739 
1740  // Event A3 to Event A2
1741  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1742  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1743  expectedTime.clear ();
1744  expectedTime << 1200 << 1440 << 1680 << 1920;
1745  expectedRsrp.clear ();
1746  expectedRsrp << 53 << 53 << 53 << 53;
1747  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A3 to Event A2",
1748  sourceConfigList, targetConfigList,
1749  expectedTime, expectedRsrp,
1750  Seconds (2)),
1751  TestCase::TAKES_FOREVER);
1752 
1753  // Event A4 to Event A5
1754  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1755  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1756  expectedTime.clear ();
1757  expectedTime << 1200 << 1440 << 1680 << 1920;
1758  expectedRsrp.clear ();
1759  expectedRsrp << 53 << 53 << 53 << 53;
1760  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A4 to Event A5",
1761  sourceConfigList, targetConfigList,
1762  expectedTime, expectedRsrp,
1763  Seconds (2)),
1764  TestCase::TAKES_FOREVER);
1765 
1766  // Event A5 to Event A4
1767  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1768  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1769  expectedTime.clear ();
1770  expectedTime << 1200 << 1440 << 1680 << 1920;
1771  expectedRsrp.clear ();
1772  expectedRsrp << 53 << 53 << 53 << 53;
1773  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A5 to Event A4",
1774  sourceConfigList, targetConfigList,
1775  expectedTime, expectedRsrp,
1776  Seconds (2)),
1777  TestCase::EXTENSIVE);
1778 
1779  // === Threshold/offset difference ===
1780 
1781  sourceConfigList.front ().threshold1.range = 52;
1782  targetConfigList.front ().threshold1.range = 56;
1783 
1784  // Event A1
1785  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1786  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1787  expectedTime.clear ();
1788  expectedTime << 200 << 440 << 680 << 920;
1789  expectedRsrp.clear ();
1790  expectedRsrp << 55 << 55 << 55 << 55;
1791  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A1 threshold difference",
1792  sourceConfigList, targetConfigList,
1793  expectedTime, expectedRsrp,
1794  Seconds (2)),
1795  TestCase::EXTENSIVE);
1796 
1797  // Event A2
1798  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1799  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1800  expectedTime.clear ();
1801  expectedTime << 1200 << 1440 << 1680 << 1920;
1802  expectedRsrp.clear ();
1803  expectedRsrp << 53 << 53 << 53 << 53;
1804  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A2 threshold difference",
1805  sourceConfigList, targetConfigList,
1806  expectedTime, expectedRsrp,
1807  Seconds (2)),
1808  TestCase::QUICK);
1809 
1810  // Event A3
1811  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1812  sourceConfigList.front ().a3Offset = -30;
1813  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1814  targetConfigList.front ().a3Offset = 30;
1815  expectedTime.clear ();
1816  expectedTime << 200 << 440 << 680 << 920;
1817  expectedRsrp.clear ();
1818  expectedRsrp << 55 << 55 << 55 << 55;
1819  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A3 offset difference",
1820  sourceConfigList, targetConfigList,
1821  expectedTime, expectedRsrp,
1822  Seconds (2)),
1823  TestCase::QUICK);
1824 
1825  // Event A4
1826  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1827  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1828  expectedTime.clear ();
1829  expectedTime << 200 << 440 << 680 << 920;
1830  expectedRsrp.clear ();
1831  expectedRsrp << 55 << 55 << 55 << 55;
1832  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A4 threshold difference",
1833  sourceConfigList, targetConfigList,
1834  expectedTime, expectedRsrp,
1835  Seconds (2)),
1836  TestCase::EXTENSIVE);
1837 
1838  // Event A5
1839  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1840  sourceConfigList.front ().threshold2.range = 52;
1841  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1842  targetConfigList.front ().threshold2.range = 56;
1843  expectedTime.clear ();
1844  expectedRsrp.clear ();
1845  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A5 threshold difference",
1846  sourceConfigList, targetConfigList,
1847  expectedTime, expectedRsrp,
1848  Seconds (2)),
1849  TestCase::EXTENSIVE);
1850 
1851  // === Time-to-trigger (TTT) difference ===
1852 
1853  sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1854  sourceConfigList.front ().a3Offset = 1;
1855  sourceConfigList.front ().threshold1.range = 0;
1856  sourceConfigList.front ().threshold2.range = 0;
1857  targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1858  targetConfigList.front ().a3Offset = 1;
1859  targetConfigList.front ().threshold1.range = 0;
1860  targetConfigList.front ().threshold2.range = 0;
1861 
1862  // decreasing time-to-trigger (short duration)
1863  sourceConfigList.front ().timeToTrigger = 1024;
1864  targetConfigList.front ().timeToTrigger = 100;
1865  expectedTime.clear ();
1866  expectedTime << 1300 << 1540 << 1780;
1867  expectedRsrp.clear ();
1868  expectedRsrp << 53 << 53 << 53;
1869  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - decreasing TTT (short)",
1870  sourceConfigList, targetConfigList,
1871  expectedTime, expectedRsrp,
1872  Seconds (2)),
1873  TestCase::QUICK);
1874 
1875  // decreasing time-to-trigger (longer duration)
1876  sourceConfigList.front ().timeToTrigger = 1024;
1877  targetConfigList.front ().timeToTrigger = 640;
1878  expectedTime.clear ();
1879  expectedTime << 1224 << 1464 << 1704 << 1944 << 2840 << 3080 << 3320 << 3560 << 3800 << 4040;
1880  expectedRsrp.clear ();
1881  expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53 << 53 << 53;
1882  AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - decreasing TTT (long)",
1883  sourceConfigList, targetConfigList,
1884  expectedTime, expectedRsrp,
1885  Seconds (4.2)),
1886  TestCase::EXTENSIVE);
1887 
1888 } // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
1889 
1891 
1892 
1893 /*
1894  * Test Case
1895  */
1896 
1898  std::string name,
1899  std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,
1900  std::list<LteRrcSap::ReportConfigEutra> targetConfigList,
1901  std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp,
1902  Time duration)
1903  : TestCase (name),
1904  m_sourceConfigList (sourceConfigList),
1905  m_targetConfigList (targetConfigList),
1906  m_expectedTime (expectedTime),
1907  m_expectedRsrp (expectedRsrp),
1908  m_duration (duration)
1909 {
1910  // input sanity check
1911  uint16_t size = m_expectedTime.size ();
1912 
1913  if (size != m_expectedRsrp.size ())
1914  {
1915  NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
1916  }
1917 
1918  m_itExpectedTime = m_expectedTime.begin ();
1919  m_itExpectedRsrp = m_expectedRsrp.begin ();
1920 
1921  NS_LOG_INFO (this << " name=" << name);
1922 }
1923 
1925 {
1926  NS_LOG_FUNCTION (this);
1927 }
1928 
1929 void
1931 {
1932  NS_LOG_INFO (this << " " << GetName ());
1933 
1934  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
1935  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
1936  lteHelper->SetEpcHelper (epcHelper);
1937  lteHelper->SetAttribute ("PathlossModel",
1938  StringValue ("ns3::FriisSpectrumPropagationLossModel"));
1939  lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
1940 
1941  //Disable Uplink Power Control
1942  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
1943 
1944 
1945  // Create Nodes: eNodeB and UE
1946  NodeContainer enbNodes;
1947  NodeContainer ueNodes;
1948  enbNodes.Create (2);
1949  ueNodes.Create (1);
1950 
1951  /*
1952  * The topology is the following:
1953  *
1954  * eNodeB UE eNodeB
1955  * | | |
1956  * x ------------------- x ----------------------- x
1957  * 400 m 500 m
1958  */
1959 
1960  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1961  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Source eNodeB
1962  positionAlloc->Add (Vector (900.0, 0.0, 0.0)); // Target eNodeB
1963  positionAlloc->Add (Vector (400.0, 0.0, 0.0)); // UE
1965  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1966  mobility.SetPositionAllocator (positionAlloc);
1967  mobility.Install (enbNodes);
1968  mobility.Install (ueNodes);
1969 
1970  // Create P-GW node
1971  Ptr<Node> pgw = epcHelper->GetPgwNode ();
1972 
1973  // Create a single RemoteHost
1974  NodeContainer remoteHostContainer;
1975  remoteHostContainer.Create (1);
1976  Ptr<Node> remoteHost = remoteHostContainer.Get (0);
1977  InternetStackHelper internet;
1978  internet.Install (remoteHostContainer);
1979 
1980  // Create the Internet
1981  PointToPointHelper p2ph;
1982  p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
1983  p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
1984  p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
1985  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
1986  Ipv4AddressHelper ipv4h;
1987  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
1988  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
1989 
1990  // Routing of the Internet Host (towards the LTE network)
1991  Ipv4StaticRoutingHelper ipv4RoutingHelper;
1992  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
1993  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
1994 
1995  // Enable layer-3 filtering
1996  Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
1997  UintegerValue (4));
1998 
1999  // Disable control channel error model
2000  Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled",
2001  BooleanValue (false));
2002 
2003  // Create Devices and install them in the Nodes (eNB and UE)
2004  NetDeviceContainer enbDevs;
2005  NetDeviceContainer ueDevs;
2006  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
2007  ueDevs = lteHelper->InstallUeDevice (ueNodes);
2008 
2009  // Setup UE measurement configuration in eNodeBs
2010  uint8_t measId;
2011  std::list<LteRrcSap::ReportConfigEutra>::const_iterator itReportConfig;
2012  Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
2013  Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
2014 
2015  for (itReportConfig = m_sourceConfigList.begin ();
2016  itReportConfig != m_sourceConfigList.end (); itReportConfig++)
2017  {
2018  measId = enbRrc1->AddUeMeasReportConfig (*itReportConfig).at (0);
2019  m_expectedSourceCellMeasId.insert (measId);
2020  }
2021 
2022  for (itReportConfig = m_targetConfigList.begin ();
2023  itReportConfig != m_targetConfigList.end (); itReportConfig++)
2024  {
2025  measId = enbRrc2->AddUeMeasReportConfig (*itReportConfig).at (0);
2026  m_expectedTargetCellMeasId.insert (measId);
2027  }
2028 
2029  // Install the IP stack on the UEs
2030  internet.Install (ueNodes);
2031  Ipv4InterfaceContainer ueIpIfaces;
2032  ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
2033 
2034  // Assign IP address to UEs
2035  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
2036  {
2037  Ptr<Node> ueNode = ueNodes.Get (u);
2038  // Set the default gateway for the UE
2039  Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
2040  ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
2041  }
2042 
2043  // Attach UE to serving eNodeB
2044  lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
2045 
2046  // Add X2 interface
2047  lteHelper->AddX2Interface (enbNodes);
2048 
2049  // Connect to trace sources in source eNodeB
2050  Config::Connect ("/NodeList/3/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2052  this));
2053 
2054  // Connect to trace sources in target eNodeB
2055  Config::Connect ("/NodeList/4/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2057  this));
2058 
2059  // Schedule handover
2061  ueDevs.Get (0), enbDevs.Get (0), enbDevs.Get (1));
2062 
2063  // Run simulation
2064  Simulator::Stop (m_duration);
2065  Simulator::Run ();
2066  Simulator::Destroy ();
2067 
2068 } // end of void LteUeMeasurementsHandoverTestCase::DoRun ()
2069 
2070 void
2072 {
2073  NS_LOG_FUNCTION (this);
2074  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
2075  NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
2076  "Reporting should have occurred at " << m_itExpectedTime->As (Time::S));
2077  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
2078  NS_ASSERT (hasEnded);
2079 }
2080 
2081 void
2083  std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
2085 {
2086  uint8_t measId = report.measResults.measId;
2087  NS_LOG_FUNCTION (this << context << (uint16_t) measId);
2088 
2089  bool isCorrectMeasId;
2090  if (cellId == 1)
2091  {
2092  std::set<uint8_t>::iterator itMeasId = m_expectedSourceCellMeasId.find (measId);
2093  isCorrectMeasId = (itMeasId != m_expectedSourceCellMeasId.end ());
2094  }
2095  else if (cellId == 2)
2096  {
2097  std::set<uint8_t>::iterator itMeasId = m_expectedTargetCellMeasId.find (measId);
2098  isCorrectMeasId = (itMeasId != m_expectedTargetCellMeasId.end ());
2099  }
2100  else
2101  {
2102  NS_FATAL_ERROR ("Invalid cell ID " << cellId);
2103  }
2104 
2105  if (isCorrectMeasId)
2106  {
2107  // verifying the report completeness
2108  LteRrcSap::MeasResults measResults = report.measResults;
2109  NS_LOG_DEBUG (this << " Serving cellId=" << cellId
2110  << " rsrp=" << (uint16_t) measResults.measResultPCell.rsrpResult
2111  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.measResultPCell.rsrpResult) << " dBm)"
2112  << " rsrq=" << (uint16_t) measResults.measResultPCell.rsrqResult
2113  << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.measResultPCell.rsrqResult) << " dB)");
2114 
2115  // verifying reported best cells
2116  if (measResults.measResultListEutra.size () == 0)
2117  {
2118  NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
2119  "Unexpected report content");
2120  }
2121  else
2122  {
2124  "Unexpected report content");
2125  std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
2126  NS_ASSERT (it != measResults.measResultListEutra.end ());
2127  NS_ASSERT (it->physCellId != cellId);
2128  NS_ASSERT (it->physCellId <= 2);
2129  NS_TEST_ASSERT_MSG_EQ (it->haveCgiInfo, false,
2130  "Report contains cgi-info, which is not supported");
2131  NS_TEST_ASSERT_MSG_EQ (it->haveRsrpResult, true,
2132  "Report does not contain measured RSRP result");
2133  NS_TEST_ASSERT_MSG_EQ (it->haveRsrqResult, true,
2134  "Report does not contain measured RSRQ result");
2135  NS_LOG_DEBUG (this << " Neighbour cellId=" << it->physCellId
2136  << " rsrp=" << (uint16_t) it->rsrpResult
2137  << " (" << EutranMeasurementMapping::RsrpRange2Dbm (it->rsrpResult) << " dBm)"
2138  << " rsrq=" << (uint16_t) it->rsrqResult
2139  << " (" << EutranMeasurementMapping::RsrqRange2Db (it->rsrqResult) << " dB)");
2140 
2141  } // end of else of if (measResults.measResultListEutra.size () == 0)
2142 
2143  // verifying the report timing
2144  bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
2145  NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
2146  "Reporting should not have occurred at "
2147  << Simulator::Now ().As (Time::S));
2148  if (!hasEnded)
2149  {
2150  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
2151  NS_ASSERT (!hasEnded);
2152 
2153  // using milliseconds to avoid floating-point comparison
2154  uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
2155  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
2156  m_itExpectedTime++;
2157 
2158  uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
2159  uint16_t referenceRsrp = *m_itExpectedRsrp;
2160  m_itExpectedRsrp++;
2161 
2162  NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
2163  "Reporting should not have occurred at this time");
2164  NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
2165  "The RSRP observed differs with the reference RSRP");
2166 
2167  } // end of if (!hasEnded)
2168 
2169  } // end of if (report.measResults.measId == correctMeasId)
2170 
2171 } // 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.
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...
virtual void DoTeardown()
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.
virtual void DoRun()
Setup the simulation with the intended UE measurement reporting configuration, run it,...
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.
virtual void DoRun()
Setup the simulation with the intended UE measurement reporting configuration, run it,...
virtual void DoTeardown()
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
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.
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.
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.
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.
virtual void DoRun()
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.
virtual void DoTeardown()
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
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 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.
virtual void DoRun()
Setup the simulation with the intended UE measurement reporting configuration, run 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.
virtual void DoTeardown()
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
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
Class for representing data rates.
Definition: data-rate.h:89
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Hold variables of type enum.
Definition: enum.h:55
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:92
Qci
QoS Class Indicator.
Definition: eps-bearer.h:107
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:41
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
holds a vector of std::pair of Ptr<Ipv4> and interface index.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
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:272
void SetSchedulerAttribute(std::string n, const AttributeValue &v)
Set an attribute for the scheduler to be created.
Definition: lte-helper.cc:293
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Manually trigger an X2-based handover.
Definition: lte-helper.cc:1245
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:474
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:279
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:959
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1313
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:489
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1220
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.
virtual Ipv4Address GetUeDefaultGatewayAddress()
virtual Ptr< Node > GetPgwNode() const
Get the PGW node.
virtual Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Assign IPv4 addresses to UE devices.
keep track of a set of node pointers.
uint32_t GetN(void) 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:256
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
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:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
std::string GetName(void) const
Definition: test.cc:370
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:383
AttributeValue implementation for Time.
Definition: nstime.h:1308
std::ostream & operator<<(std::ostream &os, TypeId tid)
Output streamer.
Definition: type-id.cc:1202
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:281
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1709
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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:141
#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:323
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
static LteUeMeasurementsPiecewiseTestSuite2 lteUeMeasurementsPiecewiseTestSuite2
void ReportUeMeasurementsCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell, uint8_t componentCarrierId)
static LteUeMeasurementsHandoverTestSuite lteUeMeasurementsHandoverTestSuite
static LteUeMeasurementsTestSuite lteUeMeasurementsTestSuite
static LteUeMeasurementsPiecewiseTestSuite1 lteUeMeasurementsPiecewiseTestSuite1
static LteUeMeasurementsPiecewiseTestSuite3 lteUeMeasurementsPiecewiseTestSuite3
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.
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:67
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
mobility
Definition: third.py:108
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:639
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:638
MeasResults structure.
Definition: lte-rrc-sap.h:680
uint8_t measId
measure ID
Definition: lte-rrc-sap.h:681
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition: lte-rrc-sap.h:683
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition: lte-rrc-sap.h:684
MeasResultPCell measResultPCell
measurement result primary cell
Definition: lte-rrc-sap.h:682
MeasurementReport structure.
Definition: lte-rrc-sap.h:902
MeasResults measResults
measure results
Definition: lte-rrc-sap.h:903
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:362
bool reportOnLeave
Indicates whether or not the UE shall initiate the measurement reporting procedure when the leaving c...
Definition: lte-rrc-sap.h:385
uint8_t hysteresis
Parameter used within the entry and leave condition of an event triggered reporting condition....
Definition: lte-rrc-sap.h:391
ThresholdEutra threshold2
Threshold for event A5.
Definition: lte-rrc-sap.h:382
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition: lte-rrc-sap.h:381
enum ns3::LteRrcSap::ReportConfigEutra::@67 triggerQuantity
Trigger type enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@66 eventId
Event enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@69 reportInterval
Report interval enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@65 triggerType
Trigger enumeration.
int8_t a3Offset
Offset value for Event A3. An integer between -30 and 30. The actual value is (value * 0....
Definition: lte-rrc-sap.h:388
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:394
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:357
enum ns3::LteRrcSap::ThresholdEutra::@64 choice
Threshold enumeration.