A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Manuel Requena <manuel.requena@cttc.es>
7 * Nicola Baldo <nbaldo@cttc.es>
8 */
9
11
12#include "ns3/boolean.h"
13#include "ns3/double.h"
14#include "ns3/ff-mac-scheduler.h"
15#include "ns3/log.h"
16#include "ns3/lte-enb-net-device.h"
17#include "ns3/lte-enb-phy.h"
18#include "ns3/lte-helper.h"
19#include "ns3/lte-ue-net-device.h"
20#include "ns3/lte-ue-phy.h"
21#include "ns3/mobility-helper.h"
22#include "ns3/simulator.h"
23#include "ns3/string.h"
24#include <ns3/enum.h>
25#include <ns3/lte-chunk-processor.h>
26
27using namespace ns3;
28
29NS_LOG_COMPONENT_DEFINE("LteInterferenceTest");
30
31void
33 std::string path,
35{
36 testcase->DlScheduling(dlInfo);
37}
38
39void
41 std::string path,
42 uint32_t frameNo,
43 uint32_t subframeNo,
44 uint16_t rnti,
45 uint8_t mcs,
46 uint16_t sizeTb,
47 uint8_t ccId)
48{
49 testcase->UlScheduling(frameNo, subframeNo, rnti, mcs, sizeTb);
50}
51
52/**
53 * TestSuite
54 */
55
57 : TestSuite("lte-interference", Type::SYSTEM)
58{
59 // these two first test cases have a spectral efficiency that corresponds to CQI=0 (out of
60 // range)
61 // TODO: update the test conditions to handle out-of-range correctly
62 // AddTestCase (new LteInterferenceTestCase ("d1=50, d2=10", 50.000000, 10.000000, 0.040000,
63 // 0.040000, 0.010399, 0.010399, 0, 0), TestCase::Duration::QUICK); AddTestCase (new
64 // LteInterferenceTestCase ("d1=50, d2=20", 50.000000, 20.000000, 0.160000, 0.159998,
65 // 0.041154, 0.041153, 0, 0), TestCase::Duration::QUICK);
66
67 AddTestCase(new LteInterferenceTestCase("d1=3000, d2=6000",
68 3000.000000,
69 6000.000000,
70 3.844681,
71 1.714583,
72 0.761558,
73 0.389662,
74 6,
75 4),
76 TestCase::Duration::QUICK);
77 AddTestCase(new LteInterferenceTestCase("d1=50, d2=50",
78 50.000000,
79 50.000000,
80 0.999997,
81 0.999907,
82 0.239828,
83 0.239808,
84 2,
85 2),
86 TestCase::Duration::QUICK);
87 AddTestCase(new LteInterferenceTestCase("d1=50, d2=100",
88 50.000000,
89 100.000000,
90 3.999955,
91 3.998520,
92 0.785259,
93 0.785042,
94 6,
95 6),
96 TestCase::Duration::QUICK);
97 AddTestCase(new LteInterferenceTestCase("d1=50, d2=200",
98 50.000000,
99 200.000000,
100 15.999282,
101 15.976339,
102 1.961072,
103 1.959533,
104 14,
105 14),
106 TestCase::Duration::QUICK);
107 AddTestCase(new LteInterferenceTestCase("d1=50, d2=500",
108 50.000000,
109 500.000000,
110 99.971953,
111 99.082845,
112 4.254003,
113 4.241793,
114 22,
115 22),
116 TestCase::Duration::QUICK);
117 AddTestCase(new LteInterferenceTestCase("d1=50, d2=1000",
118 50.000000,
119 1000.000000,
120 399.551632,
121 385.718468,
122 6.194952,
123 6.144825,
124 28,
125 28),
126 TestCase::Duration::QUICK);
127 AddTestCase(new LteInterferenceTestCase("d1=50, d2=10000",
128 50.000000,
129 10000.000000,
130 35964.181431,
131 8505.970614,
132 12.667381,
133 10.588084,
134 28,
135 28),
136 TestCase::Duration::QUICK);
137 AddTestCase(new LteInterferenceTestCase("d1=50, d2=100000",
138 50.000000,
139 100000.000000,
140 327284.773828,
141 10774.181090,
142 15.853097,
143 10.928917,
144 28,
145 28),
146 TestCase::Duration::QUICK);
147 AddTestCase(new LteInterferenceTestCase("d1=50, d2=1000000",
148 50.000000,
149 1000000.000000,
150 356132.574152,
151 10802.988445,
152 15.974963,
153 10.932767,
154 28,
155 28),
156 TestCase::Duration::QUICK);
157 AddTestCase(new LteInterferenceTestCase("d1=4500, d2=12600",
158 4500.000000,
159 12600.000000,
160 6.654462,
161 1.139831,
162 1.139781,
163 0.270399,
164 8,
165 2),
166 TestCase::Duration::QUICK);
167 AddTestCase(new LteInterferenceTestCase("d1=5400, d2=12600",
168 5400.000000,
169 12600.000000,
170 4.621154,
171 0.791549,
172 0.876368,
173 0.193019,
174 6,
175 0),
176 TestCase::Duration::QUICK);
177}
178
179/**
180 * \ingroup lte-test
181 * Static variable for test initialization
182 */
184
185/**
186 * TestCase
187 */
188
190 double d1,
191 double d2,
192 double dlSinr,
193 double ulSinr,
194 double dlSe,
195 double ulSe,
196 uint16_t dlMcs,
197 uint16_t ulMcs)
198 : TestCase(name),
199 m_d1(d1),
200 m_d2(d2),
201 m_expectedDlSinrDb(10 * std::log10(dlSinr)),
202 m_expectedUlSinrDb(10 * std::log10(ulSinr)),
203 m_dlMcs(dlMcs),
204 m_ulMcs(ulMcs)
205{
206}
207
211
212void
214{
215 NS_LOG_INFO(this << GetName());
216
217 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
218 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false));
219 Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::PiroEW2010));
220 Config::SetDefault("ns3::LteAmc::Ber", DoubleValue(0.00005));
222 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
223 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(false));
224 lteHelper->SetAttribute("UsePdschForCqiGeneration", BooleanValue(true));
225
226 // Disable Uplink Power Control
227 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
228
229 // Create Nodes: eNodeB and UE
230 NodeContainer enbNodes;
231 NodeContainer ueNodes1;
232 NodeContainer ueNodes2;
233 enbNodes.Create(2);
234 ueNodes1.Create(1);
235 ueNodes2.Create(1);
236 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
237
238 // the topology is the following:
239 // d2
240 // UE1-----------eNB2
241 // | |
242 // d1| |d1
243 // | d2 |
244 // eNB1----------UE2
245 //
247 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
248 positionAlloc->Add(Vector(m_d2, m_d1, 0.0)); // eNB2
249 positionAlloc->Add(Vector(0.0, m_d1, 0.0)); // UE1
250 positionAlloc->Add(Vector(m_d2, 0.0, 0.0)); // UE2
251 MobilityHelper mobility;
252 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
253 mobility.SetPositionAllocator(positionAlloc);
254 mobility.Install(allNodes);
255
256 // Create Devices and install them in the Nodes (eNB and UE)
257 NetDeviceContainer enbDevs;
258 NetDeviceContainer ueDevs1;
259 NetDeviceContainer ueDevs2;
260 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
261 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
262 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
263 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
264 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
265
266 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
267 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
268
269 // Activate an EPS bearer
271 EpsBearer bearer(q);
272 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
273 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
274
275 // Use testing chunk processor in the PHY layer
276 // It will be used to test that the SNR is as intended
277 // we plug in two instances, one for DL and one for UL
278
279 Ptr<LtePhy> ue1Phy = ueDevs1.Get(0)->GetObject<LteUeNetDevice>()->GetPhy()->GetObject<LtePhy>();
281 LteSpectrumValueCatcher dlSinr1Catcher;
282 testDlSinr1->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &dlSinr1Catcher));
283 ue1Phy->GetDownlinkSpectrumPhy()->AddDataSinrChunkProcessor(testDlSinr1);
284
285 Ptr<LtePhy> enb1phy =
286 enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetPhy()->GetObject<LtePhy>();
288 LteSpectrumValueCatcher ulSinr1Catcher;
289 testUlSinr1->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &ulSinr1Catcher));
290 enb1phy->GetUplinkSpectrumPhy()->AddDataSinrChunkProcessor(testUlSinr1);
291
292 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
294
295 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
297
298 // same as above for eNB2 and UE2
299
300 Ptr<LtePhy> ue2Phy = ueDevs2.Get(0)->GetObject<LteUeNetDevice>()->GetPhy()->GetObject<LtePhy>();
302 LteSpectrumValueCatcher dlSinr2Catcher;
303 testDlSinr2->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &dlSinr2Catcher));
304 ue2Phy->GetDownlinkSpectrumPhy()->AddDataSinrChunkProcessor(testDlSinr2);
305
306 Ptr<LtePhy> enb2phy =
307 enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetPhy()->GetObject<LtePhy>();
309 LteSpectrumValueCatcher ulSinr2Catcher;
310 testUlSinr2->AddCallback(MakeCallback(&LteSpectrumValueCatcher::ReportValue, &ulSinr2Catcher));
311 enb1phy->GetUplinkSpectrumPhy()->AddDataSinrChunkProcessor(testUlSinr2);
312
313 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
315
316 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
318
319 // need to allow for RRC connection establishment + SRS
320 Simulator::Stop(Seconds(0.100));
322
323 if (m_dlMcs > 0)
324 {
325 double dlSinr1Db = 10.0 * std::log10(dlSinr1Catcher.GetValue()->operator[](0));
328 0.01,
329 "Wrong SINR in DL! (eNB1 --> UE1)");
330
331 double dlSinr2Db = 10.0 * std::log10(dlSinr2Catcher.GetValue()->operator[](0));
334 0.01,
335 "Wrong SINR in DL! (eNB2 --> UE2)");
336 }
337 if (m_ulMcs > 0)
338 {
339 double ulSinr1Db = 10.0 * std::log10(ulSinr1Catcher.GetValue()->operator[](0));
342 0.01,
343 "Wrong SINR in UL! (UE1 --> eNB1)");
344
345 double ulSinr2Db = 10.0 * std::log10(ulSinr2Catcher.GetValue()->operator[](0));
348 0.01,
349 "Wrong SINR in UL! (UE2 --> eNB2)");
350 }
351
353}
354
355void
357{
358 NS_LOG_FUNCTION(dlInfo.frameNo << dlInfo.subframeNo << dlInfo.rnti << (uint32_t)dlInfo.mcsTb1
359 << dlInfo.sizeTb1 << (uint32_t)dlInfo.mcsTb2 << dlInfo.sizeTb2);
360 // need to allow for RRC connection establishment + CQI feedback reception + persistent data
361 // transmission
362 if (Simulator::Now() > MilliSeconds(65))
363 {
364 NS_TEST_ASSERT_MSG_EQ((uint32_t)dlInfo.mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
365 }
366}
367
368void
370 uint32_t subframeNo,
371 uint16_t rnti,
372 uint8_t mcs,
373 uint16_t sizeTb)
374{
375 NS_LOG_FUNCTION(frameNo << subframeNo << rnti << (uint32_t)mcs << sizeTb);
376 // need to allow for RRC connection establishment + SRS transmission
377 if (Simulator::Now() > MilliSeconds(50))
378 {
379 NS_TEST_ASSERT_MSG_EQ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
380 }
381}
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.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
This class contains the specification of EPS Bearers.
Definition eps-bearer.h:80
Qci
QoS Class Indicator.
Definition eps-bearer.h:95
@ GBR_CONV_VOICE
GBR Conversational Voice.
Definition eps-bearer.h:96
The eNodeB device implementation.
The LtePhy models the physical layer of LTE.
Definition lte-phy.h:40
A sink to be plugged to the callback of LteChunkProcessor allowing to save and later retrieve the lat...
Ptr< SpectrumValue > GetValue()
void ReportValue(const SpectrumValue &value)
function to be plugged to LteChunkProcessor::AddCallback ()
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
std::string GetName() const
Definition test.cc:367
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
static 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:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition test.h:327
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
void LteTestUlSchedulingCallback(CarrierAggregationTestCase *testcase, std::string path, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb, uint8_t ccId)
void LteTestDlSchedulingCallback(CarrierAggregationTestCase *testcase, std::string path, DlSchedulingCallbackInfo dlInfo)
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:684
STL namespace.
DlSchedulingCallbackInfo structure.
Definition lte-common.h:226
uint32_t subframeNo
subframe number
Definition lte-common.h:228
uint32_t frameNo
frame number
Definition lte-common.h:227