A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  */
22 
23 #include "ns3/simulator.h"
24 #include "ns3/log.h"
25 #include "ns3/string.h"
26 #include "ns3/double.h"
27 #include <ns3/enum.h>
28 #include "ns3/boolean.h"
29 #include "ns3/mobility-helper.h"
30 #include "ns3/lte-helper.h"
31 #include "ns3/ff-mac-scheduler.h"
32 
33 #include "ns3/lte-enb-phy.h"
34 #include "ns3/lte-enb-net-device.h"
35 
36 #include "ns3/lte-ue-phy.h"
37 #include "ns3/lte-ue-net-device.h"
38 #include <ns3/lte-enb-rrc.h>
39 
41 
43 #include <ns3/lte-common.h>
44 
45 NS_LOG_COMPONENT_DEFINE ("LteUeMeasurementsTest");
46 
47 namespace ns3 {
48 
49 
50 void
52  uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell)
53 {
54  testcase->ReportUeMeasurements (rnti, cellId, rsrp, rsrq, servingCell);
55 }
56 
57 void
59  uint64_t imsi, uint16_t rnti, uint16_t cellId, LteRrcSap::MeasurementReport meas)
60 {
61  testcase->RecvMeasurementReport (imsi, rnti, cellId, meas);
62 }
63 
64 
70  : TestSuite ("lte-ue-measurements", SYSTEM)
71 {
72 
73  AddTestCase (new LteUeMeasurementsTestCase ("d1=10, d2=10000", 10.000000, 10000.000000, -53.739702, -113.739702, -3.010305, -63.010305), TestCase::EXTENSIVE);
74  AddTestCase (new LteUeMeasurementsTestCase ("d1=20, d2=10000", 20.000000, 10000.000000, -59.760302, -113.739702, -3.010319, -56.989719), TestCase::EXTENSIVE);
75  AddTestCase (new LteUeMeasurementsTestCase ("d1=50, d2=10000", 50.000000, 10000.000000, -67.719102, -113.739702, -3.010421, -49.031021), TestCase::EXTENSIVE);
76  AddTestCase (new LteUeMeasurementsTestCase ("d1=100, d2=10000", 100.000000, 10000.000000, -73.739702, -113.739702, -3.010783, -43.010783), TestCase::EXTENSIVE);
77  AddTestCase (new LteUeMeasurementsTestCase ("d1=200, d2=10000", 200.000000, 10000.000000, -79.760302, -113.739702, -3.012232, -36.991632), TestCase::EXTENSIVE);
78  AddTestCase (new LteUeMeasurementsTestCase ("d1=100, d2=10000", 100.000000, 10000.000000, -73.739702, -113.739702, -3.010783, -43.010783), TestCase::EXTENSIVE);
79  AddTestCase (new LteUeMeasurementsTestCase ("d1=200, d2=10000", 200.000000, 10000.000000, -79.760302, -113.739702, -3.012232, -36.991632), TestCase::EXTENSIVE);
80  AddTestCase (new LteUeMeasurementsTestCase ("d1=500, d2=10000", 500.000000, 10000.000000, -87.719102, -113.739702, -3.022359, -29.042959), TestCase::EXTENSIVE);
81  AddTestCase (new LteUeMeasurementsTestCase ("d1=1000, d2=10000", 1000.000000, 10000.000000, -93.739702, -113.739702, -3.058336, -23.058336), TestCase::EXTENSIVE);
82  AddTestCase (new LteUeMeasurementsTestCase ("d1=2000, d2=10000", 2000.000000, 10000.000000, -99.760302, -113.739702, -3.199337, -17.178738), TestCase::EXTENSIVE);
83  AddTestCase (new LteUeMeasurementsTestCase ("d1=5000, d2=10000", 5000.000000, 10000.000000, -107.719102, -113.739702, -4.075793, -10.096393), TestCase::QUICK);
84  AddTestCase (new LteUeMeasurementsTestCase ("d1=10000, d2=10000", 10000.000000, 10000.000000, -113.739702, -113.739702, -6.257687, -6.257687), TestCase::EXTENSIVE);
85  AddTestCase (new LteUeMeasurementsTestCase ("d1=20000, d2=10000", 20000.000000, 10000.000000, -119.760302, -113.739702, -10.373365, -4.352765), TestCase::EXTENSIVE);
86  AddTestCase (new LteUeMeasurementsTestCase ("d1=50000, d2=10000", 50000.000000, 10000.000000, -127.719102, -113.739702, -17.605046, -3.625645), TestCase::EXTENSIVE);
87  AddTestCase (new LteUeMeasurementsTestCase ("d1=100000, d2=10000", 100000.000000, 10000.000000, -133.739702, -113.739702, -23.511071, -3.511071), TestCase::EXTENSIVE);
88  AddTestCase (new LteUeMeasurementsTestCase ("d1=200000, d2=10000", 200000.000000, 10000.000000, -139.760302, -113.739702, -29.502549, -3.481949), TestCase::EXTENSIVE);
89  AddTestCase (new LteUeMeasurementsTestCase ("d1=500000, d2=10000", 500000.000000, 10000.000000, -147.719102, -113.739702, -37.453160, -3.473760), TestCase::EXTENSIVE);
90  AddTestCase (new LteUeMeasurementsTestCase ("d1=1000000, d2=10000", 1000000.000000, 10000.000000, -153.739702, -113.739702, -43.472589, -3.472589), TestCase::EXTENSIVE);
91 
92 
93 }
94 
96 
97 
102 LteUeMeasurementsTestCase::LteUeMeasurementsTestCase (std::string name, double d1, double d2, double rsrpDbmUe1, double rsrpDbmUe2, double rsrqDbUe1, double rsrqDbUe2)
103  : TestCase (name),
104  m_d1 (d1),
105  m_d2 (d2),
106  m_rsrpDbmUeServingCell (rsrpDbmUe1),
107  m_rsrpDbmUeNeighborCell (rsrpDbmUe2),
108  m_rsrqDbUeServingCell (rsrqDbUe1),
109  m_rsrqDbUeNeighborCell (rsrqDbUe2)
110 {
111  NS_LOG_INFO ("Test UE Measurements d1 = " << d1 << " m. and d2 = " << d2 << " m.");
112 }
113 
115 {
116 }
117 
118 void
120 {
121  NS_LOG_INFO (this << GetName ());
122 
123  Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
124  Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
125  Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
126  Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
127  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
128  lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
129  lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (false));
130 
131  LogComponentEnable ("LteUeMeasurementsTest", LOG_LEVEL_ALL);
132 
133  // Create Nodes: eNodeB and UE
134  NodeContainer enbNodes;
135  NodeContainer ueNodes1;
136  NodeContainer ueNodes2;
137  enbNodes.Create (2);
138  ueNodes1.Create (1);
139  ueNodes2.Create (1);
140  NodeContainer allNodes = NodeContainer ( enbNodes, ueNodes1, ueNodes2);
141 
142  // the topology is the following:
143  // d2
144  // UE1-----------eNB2
145  // | |
146  // d1| |d1
147  // | d2 |
148  // eNB1----------UE2
149  //
150  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
151  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNB1
152  positionAlloc->Add (Vector (m_d2, m_d1, 0.0)); // eNB2
153  positionAlloc->Add (Vector (0.0, m_d1, 0.0)); // UE1
154  positionAlloc->Add (Vector (m_d2, 0.0, 0.0)); // UE2
155  MobilityHelper mobility;
156  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
157  mobility.SetPositionAllocator (positionAlloc);
158  mobility.Install (allNodes);
159 
160  // Create Devices and install them in the Nodes (eNB and UE)
161  NetDeviceContainer enbDevs;
162  NetDeviceContainer ueDevs1;
163  NetDeviceContainer ueDevs2;
164  lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
165  lteHelper->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
166  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
167  ueDevs1 = lteHelper->InstallUeDevice (ueNodes1);
168  ueDevs2 = lteHelper->InstallUeDevice (ueNodes2);
169 
170  lteHelper->Attach (ueDevs1, enbDevs.Get (0));
171  lteHelper->Attach (ueDevs2, enbDevs.Get (1));
172 
173  // Activate an EPS bearer
175  EpsBearer bearer (q);
176  lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
177  lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
178 
179  // Use testing chunk processor in the PHY layer
180  // It will be used to test that the SNR is as intended
181  // we plug in two instances, one for DL and one for UL
182 
183  Ptr<LtePhy> ue1Phy = ueDevs1.Get (0)->GetObject<LteUeNetDevice> ()->GetPhy ()->GetObject<LtePhy> ();
184  Ptr<LteTestSinrChunkProcessor> testDlSinr1 = Create<LteTestSinrChunkProcessor> (ue1Phy);
185  ue1Phy->GetDownlinkSpectrumPhy ()->AddDataSinrChunkProcessor (testDlSinr1);
186 
187  Ptr<LtePhy> enb1phy = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetPhy ()->GetObject<LtePhy> ();
188  Ptr<LteTestSinrChunkProcessor> testUlSinr1 = Create<LteTestSinrChunkProcessor> (enb1phy);
189  enb1phy->GetUplinkSpectrumPhy ()->AddDataSinrChunkProcessor (testUlSinr1);
190 
191  Config::Connect ("/NodeList/2/DeviceList/0/LteUePhy/ReportUeMeasurements",
193  Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
195 
196  // same as above for eNB2 and UE2
197 
198  Ptr<LtePhy> ue2Phy = ueDevs2.Get (0)->GetObject<LteUeNetDevice> ()->GetPhy ()->GetObject<LtePhy> ();
199  Ptr<LteTestSinrChunkProcessor> testDlSinr2 = Create<LteTestSinrChunkProcessor> (ue2Phy);
200  ue2Phy->GetDownlinkSpectrumPhy ()->AddDataSinrChunkProcessor (testDlSinr2);
201 
202  Ptr<LtePhy> enb2phy = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetPhy ()->GetObject<LtePhy> ();
203  Ptr<LteTestSinrChunkProcessor> testUlSinr2 = Create<LteTestSinrChunkProcessor> (enb2phy);
204  enb1phy->GetUplinkSpectrumPhy ()->AddDataSinrChunkProcessor (testUlSinr2);
205 
206  Config::Connect ("/NodeList/3/DeviceList/0/LteUePhy/ReportUeMeasurements",
208  Config::Connect ("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
210 
211 
212 // need to allow for RRC connection establishment + SRS
213  Simulator::Stop (Seconds (0.800));
214  Simulator::Run ();
215 
217 
218 }
219 
220 
221 void
222 LteUeMeasurementsTestCase::ReportUeMeasurements (uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell)
223 {
224  // need to allow for RRC connection establishment + CQI feedback reception + UE measurements filtering (200 ms)
225  if (Simulator::Now () > MilliSeconds (400))
226  {
227  if (servingCell)
228  {
229  NS_LOG_DEBUG ("UE serving cellId " << cellId << " Rxed RSRP " << rsrp << " thr " << m_rsrpDbmUeServingCell << " RSRQ " << rsrq << " thr " << m_rsrqDbUeServingCell);
230  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrpDbmUeServingCell, rsrp, 0.2, "Wrong RSRP UE 1");
231  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrqDbUeServingCell, rsrq, 0.2 , "Wrong RSRQ UE 1");
232  }
233  else
234  {
235  NS_LOG_DEBUG ("UE neighbor cellId " << cellId << " Rxed RSRP " << rsrp << " thr " << m_rsrpDbmUeNeighborCell << " RSRQ " << rsrq << " thr " << m_rsrqDbUeNeighborCell);
236  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrpDbmUeNeighborCell, rsrp, 0.2 , "Wrong RSRP UE 2");
237  NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrqDbUeNeighborCell, rsrq, 0.2 , "Wrong RSRQ UE ");
238  }
239  }
240 }
241 
242 
243 void
244 LteUeMeasurementsTestCase::RecvMeasurementReport (uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport meas)
245 {
246  // need to allow for RRC connection establishment + CQI feedback reception + UE measurements filtering (200 ms)
247  if (Simulator::Now () > MilliSeconds (400))
248  {
249  if (cellId == imsi)
250  {
251  NS_LOG_DEBUG ("Serving Cell: received IMSI " << imsi << " CellId " << cellId << " RNTI " << rnti << " thr " << (uint16_t)EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeServingCell) << " RSRP " << (uint16_t)meas.measResults.rsrpResult << " RSRQ " << (uint16_t)meas.measResults.rsrqResult << " thr " << (uint16_t)EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeServingCell));
254  }
255  else
256  {
257  NS_LOG_DEBUG ("Neighbor cell: received IMSI " << imsi << " CellId " << cellId << " RNTI " << rnti << " thr " << (uint16_t)EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeNeighborCell) << " RSRP " << (uint16_t)meas.measResults.rsrpResult << " RSRQ " << (uint16_t)meas.measResults.rsrqResult << " thr " << (uint16_t)EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeNeighborCell));
260  }
261  }
262 }
263 
264 } // namespace ns3
265 
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
Hold a bool native type.
Definition: boolean.h:38
hold variables of type string
Definition: string.h:19
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
#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:326
A suite of tests to run.
Definition: test.h:1025
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Definition: callback.h:1463
static void Run(void)
Definition: simulator.cc:157
#define NS_LOG_INFO(msg)
Definition: log.h:264
encapsulates test code
Definition: test.h:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:728
NS_LOG_COMPONENT_DEFINE("LteUeMeasurementsTest")
a 3d vector
Definition: vector.h:31
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
hold variables of type 'enum'
Definition: enum.h:37
static LteUeMeasurementsTestSuite lteUeMeasurementsTestSuite
Medium length test.
Definition: test.h:858
holds a vector of ns3::NetDevice pointers
void RecvMeasurementReportCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint64_t imsi, uint16_t rnti, uint16_t cellId, LteRrcSap::MeasurementReport meas)
void ReportUeMeasurements(uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell)
static void Destroy(void)
Definition: simulator.cc:121
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:667
keep track of a set of node pointers.
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
static Time Now(void)
Definition: simulator.cc:180
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:172
Fast test.
Definition: test.h:857
Helper class used to assign positions and mobility models to nodes.
static uint8_t Dbm2RsrpRange(double dbm)
Definition: lte-common.cc:210
LteUeMeasurementsTestCase(std::string name, double d1, double d2, double rsrpDbmUe1, double rsrpDbmUe2, double rsrqDbUe1, double rsrqDbUe2)
static void Stop(void)
Definition: simulator.cc:165
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
std::string GetName(void) const
Definition: test.cc:241
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void RecvMeasurementReport(uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport meas)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
static uint8_t Db2RsrqRange(double db)
Definition: lte-common.cc:226
Hold an floating point type.
Definition: double.h:41
Ptr< T > GetObject(void) const
Definition: object.h:360
void LogComponentEnable(char const *name, enum LogLevel level)
Definition: log.cc:311
#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:137
void ReportUeMeasurementsCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell)