A Discrete-Event Network Simulator
API
lte-test-interference.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Manuel Requena <manuel.requena@cttc.es>
18 * Nicola Baldo <nbaldo@cttc.es>
19 */
20
22
23#include "ns3/boolean.h"
24#include "ns3/double.h"
25#include "ns3/ff-mac-scheduler.h"
26#include "ns3/log.h"
27#include "ns3/lte-enb-net-device.h"
28#include "ns3/lte-enb-phy.h"
29#include "ns3/lte-helper.h"
30#include "ns3/lte-ue-net-device.h"
31#include "ns3/lte-ue-phy.h"
32#include "ns3/mobility-helper.h"
33#include "ns3/simulator.h"
34#include "ns3/string.h"
35#include <ns3/enum.h>
36#include <ns3/lte-chunk-processor.h>
37
38using namespace ns3;
39
40NS_LOG_COMPONENT_DEFINE("LteInterferenceTest");
41
42void
44 std::string path,
46{
47 testcase->DlScheduling(dlInfo);
48}
49
50void
52 std::string path,
53 uint32_t frameNo,
54 uint32_t subframeNo,
55 uint16_t rnti,
56 uint8_t mcs,
57 uint16_t sizeTb,
58 uint8_t ccId)
59{
60 testcase->UlScheduling(frameNo, subframeNo, rnti, mcs, sizeTb);
61}
62
68 : TestSuite("lte-interference", SYSTEM)
69{
70 // these two first test cases have a spectral efficiency that corresponds to CQI=0 (out of
71 // range)
72 // TODO: update the test conditions to handle out-of-range correctly
73 // AddTestCase (new LteInterferenceTestCase ("d1=50, d2=10", 50.000000, 10.000000, 0.040000,
74 // 0.040000, 0.010399, 0.010399, 0, 0), TestCase::QUICK); AddTestCase (new
75 // LteInterferenceTestCase ("d1=50, d2=20", 50.000000, 20.000000, 0.160000, 0.159998,
76 // 0.041154, 0.041153, 0, 0), TestCase::QUICK);
77
78 AddTestCase(new LteInterferenceTestCase("d1=3000, d2=6000",
79 3000.000000,
80 6000.000000,
81 3.844681,
82 1.714583,
83 0.761558,
84 0.389662,
85 6,
86 4),
87 TestCase::QUICK);
88 AddTestCase(new LteInterferenceTestCase("d1=50, d2=50",
89 50.000000,
90 50.000000,
91 0.999997,
92 0.999907,
93 0.239828,
94 0.239808,
95 2,
96 2),
97 TestCase::QUICK);
98 AddTestCase(new LteInterferenceTestCase("d1=50, d2=100",
99 50.000000,
100 100.000000,
101 3.999955,
102 3.998520,
103 0.785259,
104 0.785042,
105 6,
106 6),
107 TestCase::QUICK);
108 AddTestCase(new LteInterferenceTestCase("d1=50, d2=200",
109 50.000000,
110 200.000000,
111 15.999282,
112 15.976339,
113 1.961072,
114 1.959533,
115 14,
116 14),
117 TestCase::QUICK);
118 AddTestCase(new LteInterferenceTestCase("d1=50, d2=500",
119 50.000000,
120 500.000000,
121 99.971953,
122 99.082845,
123 4.254003,
124 4.241793,
125 22,
126 22),
127 TestCase::QUICK);
128 AddTestCase(new LteInterferenceTestCase("d1=50, d2=1000",
129 50.000000,
130 1000.000000,
131 399.551632,
132 385.718468,
133 6.194952,
134 6.144825,
135 28,
136 28),
137 TestCase::QUICK);
138 AddTestCase(new LteInterferenceTestCase("d1=50, d2=10000",
139 50.000000,
140 10000.000000,
141 35964.181431,
142 8505.970614,
143 12.667381,
144 10.588084,
145 28,
146 28),
147 TestCase::QUICK);
148 AddTestCase(new LteInterferenceTestCase("d1=50, d2=100000",
149 50.000000,
150 100000.000000,
151 327284.773828,
152 10774.181090,
153 15.853097,
154 10.928917,
155 28,
156 28),
157 TestCase::QUICK);
158 AddTestCase(new LteInterferenceTestCase("d1=50, d2=1000000",
159 50.000000,
160 1000000.000000,
161 356132.574152,
162 10802.988445,
163 15.974963,
164 10.932767,
165 28,
166 28),
167 TestCase::QUICK);
168 AddTestCase(new LteInterferenceTestCase("d1=4500, d2=12600",
169 4500.000000,
170 12600.000000,
171 6.654462,
172 1.139831,
173 1.139781,
174 0.270399,
175 8,
176 2),
177 TestCase::QUICK);
178 AddTestCase(new LteInterferenceTestCase("d1=5400, d2=12600",
179 5400.000000,
180 12600.000000,
181 4.621154,
182 0.791549,
183 0.876368,
184 0.193019,
185 6,
186 0),
187 TestCase::QUICK);
188}
189
195
201 double d1,
202 double d2,
203 double dlSinr,
204 double ulSinr,
205 double dlSe,
206 double ulSe,
207 uint16_t dlMcs,
208 uint16_t ulMcs)
209 : TestCase(name),
210 m_d1(d1),
211 m_d2(d2),
212 m_expectedDlSinrDb(10 * std::log10(dlSinr)),
213 m_expectedUlSinrDb(10 * std::log10(ulSinr)),
214 m_dlMcs(dlMcs),
215 m_ulMcs(ulMcs)
216{
217}
218
220{
221}
222
223void
225{
226 NS_LOG_INFO(this << GetName());
227
228 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
229 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false));
230 Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::PiroEW2010));
231 Config::SetDefault("ns3::LteAmc::Ber", DoubleValue(0.00005));
232 Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
233 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
234 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(false));
235 lteHelper->SetAttribute("UsePdschForCqiGeneration", BooleanValue(true));
236
237 // Disable Uplink Power Control
238 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
239
240 // Create Nodes: eNodeB and UE
241 NodeContainer enbNodes;
242 NodeContainer ueNodes1;
243 NodeContainer ueNodes2;
244 enbNodes.Create(2);
245 ueNodes1.Create(1);
246 ueNodes2.Create(1);
247 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
248
249 // the topology is the following:
250 // d2
251 // UE1-----------eNB2
252 // | |
253 // d1| |d1
254 // | d2 |
255 // eNB1----------UE2
256 //
257 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
258 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
259 positionAlloc->Add(Vector(m_d2, m_d1, 0.0)); // eNB2
260 positionAlloc->Add(Vector(0.0, m_d1, 0.0)); // UE1
261 positionAlloc->Add(Vector(m_d2, 0.0, 0.0)); // UE2
263 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
264 mobility.SetPositionAllocator(positionAlloc);
265 mobility.Install(allNodes);
266
267 // Create Devices and install them in the Nodes (eNB and UE)
268 NetDeviceContainer enbDevs;
269 NetDeviceContainer ueDevs1;
270 NetDeviceContainer ueDevs2;
271 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
272 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
273 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
274 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
275 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
276
277 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
278 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
279
280 // Activate an EPS bearer
281 enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
282 EpsBearer bearer(q);
283 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
284 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
285
286 // Use testing chunk processor in the PHY layer
287 // It will be used to test that the SNR is as intended
288 // we plug in two instances, one for DL and one for UL
289
290 Ptr<LtePhy> ue1Phy = ueDevs1.Get(0)->GetObject<LteUeNetDevice>()->GetPhy()->GetObject<LtePhy>();
291 Ptr<LteChunkProcessor> testDlSinr1 = Create<LteChunkProcessor>();
292 LteSpectrumValueCatcher dlSinr1Catcher;
293 testDlSinr1->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &dlSinr1Catcher));
294 ue1Phy->GetDownlinkSpectrumPhy()->AddDataSinrChunkProcessor(testDlSinr1);
295
296 Ptr<LtePhy> enb1phy =
297 enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetPhy()->GetObject<LtePhy>();
298 Ptr<LteChunkProcessor> testUlSinr1 = Create<LteChunkProcessor>();
299 LteSpectrumValueCatcher ulSinr1Catcher;
300 testUlSinr1->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &ulSinr1Catcher));
301 enb1phy->GetUplinkSpectrumPhy()->AddDataSinrChunkProcessor(testUlSinr1);
302
303 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
305
306 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
308
309 // same as above for eNB2 and UE2
310
311 Ptr<LtePhy> ue2Phy = ueDevs2.Get(0)->GetObject<LteUeNetDevice>()->GetPhy()->GetObject<LtePhy>();
312 Ptr<LteChunkProcessor> testDlSinr2 = Create<LteChunkProcessor>();
313 LteSpectrumValueCatcher dlSinr2Catcher;
314 testDlSinr2->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &dlSinr2Catcher));
315 ue2Phy->GetDownlinkSpectrumPhy()->AddDataSinrChunkProcessor(testDlSinr2);
316
317 Ptr<LtePhy> enb2phy =
318 enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetPhy()->GetObject<LtePhy>();
319 Ptr<LteChunkProcessor> testUlSinr2 = Create<LteChunkProcessor>();
320 LteSpectrumValueCatcher ulSinr2Catcher;
321 testUlSinr2->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &ulSinr2Catcher));
322 enb1phy->GetUplinkSpectrumPhy()->AddDataSinrChunkProcessor(testUlSinr2);
323
324 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
326
327 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
329
330 // need to allow for RRC connection establishment + SRS
331 Simulator::Stop(Seconds(0.100));
332 Simulator::Run();
333
334 if (m_dlMcs > 0)
335 {
336 double dlSinr1Db = 10.0 * std::log10(dlSinr1Catcher.GetValue()->operator[](0));
339 0.01,
340 "Wrong SINR in DL! (eNB1 --> UE1)");
341
342 double dlSinr2Db = 10.0 * std::log10(dlSinr2Catcher.GetValue()->operator[](0));
345 0.01,
346 "Wrong SINR in DL! (eNB2 --> UE2)");
347 }
348 if (m_ulMcs > 0)
349 {
350 double ulSinr1Db = 10.0 * std::log10(ulSinr1Catcher.GetValue()->operator[](0));
353 0.01,
354 "Wrong SINR in UL! (UE1 --> eNB1)");
355
356 double ulSinr2Db = 10.0 * std::log10(ulSinr2Catcher.GetValue()->operator[](0));
359 0.01,
360 "Wrong SINR in UL! (UE2 --> eNB2)");
361 }
362
363 Simulator::Destroy();
364}
365
366void
368{
369 NS_LOG_FUNCTION(dlInfo.frameNo << dlInfo.subframeNo << dlInfo.rnti << (uint32_t)dlInfo.mcsTb1
370 << dlInfo.sizeTb1 << (uint32_t)dlInfo.mcsTb2 << dlInfo.sizeTb2);
371 // need to allow for RRC connection establishment + CQI feedback reception + persistent data
372 // transmission
373 if (Simulator::Now() > MilliSeconds(65))
374 {
375 NS_TEST_ASSERT_MSG_EQ((uint32_t)dlInfo.mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
376 }
377}
378
379void
381 uint32_t subframeNo,
382 uint16_t rnti,
383 uint8_t mcs,
384 uint16_t sizeTb)
385{
386 NS_LOG_FUNCTION(frameNo << subframeNo << rnti << (uint32_t)mcs << sizeTb);
387 // need to allow for RRC connection establishment + SRS transmission
388 if (Simulator::Now() > MilliSeconds(50))
389 {
390 NS_TEST_ASSERT_MSG_EQ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
391 }
392}
Test that SINR calculation and MCS selection works fine in a multi-cell interference scenario.
LteInterferenceTestCase(std::string name, double d1, double d2, double dlSinr, double ulSinr, double dlSe, double ulSe, uint16_t dlMcs, uint16_t ulMcs)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
double m_expectedDlSinrDb
expected DL SINR in dB
void UlScheduling(uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb)
UL scheduling function.
double m_expectedUlSinrDb
expected UL SINR in dB
void DlScheduling(DlSchedulingCallbackInfo dlInfo)
DL scheduling function.
double m_d2
distance between UE and other ENB
double m_d1
distance between UE and ENB
Test suite for interference test.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:56
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
Qci
QoS Class Indicator.
Definition: eps-bearer.h:106
The eNodeB device implementation.
void SetSchedulerAttribute(std::string n, const AttributeValue &v)
Set an attribute for the scheduler to be created.
Definition: lte-helper.cc:303
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:482
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:289
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:1044
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1441
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:497
The LtePhy models the physical layer of LTE.
Definition: lte-phy.h:50
A sink to be plugged to the callback of LteChunkProcessor allowing to save and later retrieve the lat...
Ptr< SpectrumValue > GetValue()
The LteUeNetDevice class implements the UE net device.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
std::string GetName() const
Definition: test.cc:377
A suite of tests to run.
Definition: test.h:1256
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
static LteInterferenceTestSuite lteLinkAdaptationWithInterferenceTestSuite
Static variable for test initialization.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:752
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:337
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
void LteTestDlSchedulingCallback(LteInterferenceTestCase *testcase, std::string path, DlSchedulingCallbackInfo dlInfo)
void LteTestUlSchedulingCallback(LteInterferenceTestCase *testcase, std::string path, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb, uint8_t ccId)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:691
STL namespace.
mobility
Definition: third.py:96
DlSchedulingCallbackInfo structure.
Definition: lte-common.h:231
uint32_t subframeNo
subframe number
Definition: lte-common.h:233
uint16_t sizeTb2
size TB2
Definition: lte-common.h:238
uint16_t sizeTb1
size TB1
Definition: lte-common.h:236
uint32_t frameNo
frame number
Definition: lte-common.h:232