A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-test-cqi-generation.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Piotr Gawlowicz
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: Piotr Gawlowicz <gawlowicz.p@gmail.com>
18 *
19 */
20
22
23#include "lte-ffr-simple.h"
24
25#include "ns3/ff-mac-scheduler.h"
26#include "ns3/lte-helper.h"
27#include "ns3/lte-rrc-sap.h"
28#include "ns3/mobility-helper.h"
29#include <ns3/boolean.h>
30#include <ns3/callback.h>
31#include <ns3/config.h>
32#include <ns3/double.h>
33#include <ns3/enum.h>
34#include <ns3/log.h>
35#include <ns3/lte-ue-mac.h>
36#include <ns3/lte-ue-net-device.h>
37#include <ns3/pointer.h>
38#include <ns3/simulator.h>
39#include <ns3/string.h>
40
41using namespace ns3;
42
43NS_LOG_COMPONENT_DEFINE("LteCqiGenerationTest");
44
45void
47 std::string path,
49{
50 testcase->DlScheduling(dlInfo);
51}
52
53void
55 std::string path,
56 uint32_t frameNo,
57 uint32_t subframeNo,
58 uint16_t rnti,
59 uint8_t mcs,
60 uint16_t sizeTb,
61 uint8_t ccId)
62{
63 testcase->UlScheduling(frameNo, subframeNo, rnti, mcs, sizeTb);
64}
65
66void
68 std::string path,
70{
71 testcase->DlScheduling(dlInfo);
72}
73
74void
76 std::string path,
77 uint32_t frameNo,
78 uint32_t subframeNo,
79 uint16_t rnti,
80 uint8_t mcs,
81 uint16_t sizeTb,
82 uint8_t componentCarrierId)
83{
84 testcase->UlScheduling(frameNo, subframeNo, rnti, mcs, sizeTb);
85}
86
92 : TestSuite("lte-cqi-generation", Type::SYSTEM)
93{
94 // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_DEBUG);
95 // LogComponentEnable ("LteCqiGenerationTest", logLevel);
96 NS_LOG_INFO("Creating LteCqiGenerationTestSuite");
97
98 AddTestCase(new LteCqiGenerationTestCase("UsePdcchForCqiGeneration", false, 4, 2),
99 TestCase::Duration::QUICK);
100 AddTestCase(new LteCqiGenerationTestCase("UsePdschForCqiGeneration", true, 28, 2),
101 TestCase::Duration::QUICK);
102
103 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
106 4,
107 2),
108 TestCase::Duration::QUICK);
109 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
112 8,
113 2),
114 TestCase::Duration::QUICK);
115 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
118 10,
119 2),
120 TestCase::Duration::QUICK);
121 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
124 12,
125 2),
126 TestCase::Duration::QUICK);
127 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
130 14,
131 2),
132 TestCase::Duration::QUICK);
133 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
136 14,
137 2),
138 TestCase::Duration::QUICK);
139 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
142 8,
143 2),
144 TestCase::Duration::QUICK);
145}
146
152
154 bool usePdcchForCqiGeneration,
155 uint16_t dlMcs,
156 uint16_t ulMcs)
157 : TestCase("Downlink Power Control: " + name),
158 m_dlMcs(dlMcs),
159 m_ulMcs(ulMcs)
160{
161 m_usePdschForCqiGeneration = usePdcchForCqiGeneration;
162 NS_LOG_INFO("Creating LteCqiGenerationTestCase");
163}
164
166{
167}
168
169void
171{
172 // need to allow for RRC connection establishment + CQI feedback reception
173 if (Simulator::Now() > MilliSeconds(35))
174 {
175 // NS_LOG_UNCOND("DL MSC: " << (uint32_t)mcsTb1 << " expected DL MCS: " <<
176 // (uint32_t)m_dlMcs);
177 NS_TEST_ASSERT_MSG_EQ((uint32_t)dlInfo.mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
178 }
179}
180
181void
183 uint32_t subframeNo,
184 uint16_t rnti,
185 uint8_t mcs,
186 uint16_t sizeTb)
187{
188 // need to allow for RRC connection establishment + SRS transmission
189 if (Simulator::Now() > MilliSeconds(50))
190 {
191 // NS_LOG_UNCOND("UL MSC: " << (uint32_t)mcs << " expected UL MCS: " <<
192 // (uint32_t)m_ulMcs);
193 NS_TEST_ASSERT_MSG_EQ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
194 }
195}
196
197void
199{
200 NS_LOG_DEBUG("LteCqiGenerationTestCase");
201
203 Config::SetDefault("ns3::LteHelper::UseIdealRrc", BooleanValue(true));
204 Config::SetDefault("ns3::LteHelper::UsePdschForCqiGeneration",
206
207 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(true));
208 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(true));
209
210 Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
211
212 // Create Nodes: eNodeB and UE
213 NodeContainer enbNodes;
214 NodeContainer ueNodes1;
215 NodeContainer ueNodes2;
216 enbNodes.Create(2);
217 ueNodes1.Create(1);
218 ueNodes2.Create(1);
219 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
220
221 /*
222 * The topology is the following:
223 *
224 * eNB1 UE1 UE2 eNB2
225 * | | |
226 * x -------------------------- x -------------------------- x
227 * 500 m 500 m
228 *
229 */
230
231 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
232 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
233 positionAlloc->Add(Vector(1000, 0.0, 0.0)); // eNB2
234 positionAlloc->Add(Vector(500.0, 0.0, 0.0)); // UE1
235 positionAlloc->Add(Vector(500, 0.0, 0.0)); // UE2
236 MobilityHelper mobility;
237 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
238 mobility.SetPositionAllocator(positionAlloc);
239 mobility.Install(allNodes);
240
241 // Create Devices and install them in the Nodes (eNB and UE)
242 NetDeviceContainer enbDevs;
243 NetDeviceContainer ueDevs1;
244 NetDeviceContainer ueDevs2;
245 lteHelper->SetSchedulerType("ns3::PfFfMacScheduler");
246 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
247
248 lteHelper->SetFfrAlgorithmType("ns3::LteFrHardAlgorithm");
249
250 lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue(0));
251 lteHelper->SetFfrAlgorithmAttribute("DlSubBandwidth", UintegerValue(12));
252 lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue(0));
253 lteHelper->SetFfrAlgorithmAttribute("UlSubBandwidth", UintegerValue(25));
254 enbDevs.Add(lteHelper->InstallEnbDevice(enbNodes.Get(0)));
255
256 lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue(12));
257 lteHelper->SetFfrAlgorithmAttribute("DlSubBandwidth", UintegerValue(12));
258 lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue(0));
259 lteHelper->SetFfrAlgorithmAttribute("UlSubBandwidth", UintegerValue(25));
260 enbDevs.Add(lteHelper->InstallEnbDevice(enbNodes.Get(1)));
261
262 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
263 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
264
265 // Attach a UE to a eNB
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 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
277
278 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
280
281 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
283
284 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
286
287 Simulator::Stop(Seconds(1.100));
289
291}
292
294 uint8_t cell0Pa,
295 uint8_t cell1Pa,
296 uint16_t dlMcs,
297 uint16_t ulMcs)
298 : TestCase("Downlink Power Control: " + name),
299 m_cell0Pa(cell0Pa),
300 m_cell1Pa(cell1Pa),
301 m_dlMcs(dlMcs),
302 m_ulMcs(ulMcs)
303{
304 NS_LOG_INFO("Creating LteCqiGenerationTestCase");
305}
306
308{
309}
310
311void
313{
314 // need to allow for RRC connection establishment + CQI feedback reception
315 if (Simulator::Now() > MilliSeconds(500))
316 {
317 // NS_LOG_UNCOND("DL MSC: " << (uint32_t)mcsTb1 << " expected DL MCS: " <<
318 // (uint32_t)m_dlMcs);
319 NS_TEST_ASSERT_MSG_EQ((uint32_t)dlInfo.mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
320 }
321}
322
323void
325 uint32_t subframeNo,
326 uint16_t rnti,
327 uint8_t mcs,
328 uint16_t sizeTb)
329{
330 // need to allow for RRC connection establishment + SRS transmission
331 if (Simulator::Now() > MilliSeconds(500))
332 {
333 // NS_LOG_UNCOND("UL MSC: " << (uint32_t)mcs << " expected UL MCS: " <<
334 // (uint32_t)m_ulMcs);
335 NS_TEST_ASSERT_MSG_EQ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
336 }
337}
338
339void
341{
342 NS_LOG_DEBUG("LteCqiGenerationTestCase");
343
345 Config::SetDefault("ns3::LteHelper::UseIdealRrc", BooleanValue(true));
346 Config::SetDefault("ns3::LteHelper::UsePdschForCqiGeneration", BooleanValue(true));
347
348 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(true));
349 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(true));
350
351 Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
352 lteHelper->SetFfrAlgorithmType("ns3::LteFfrSimple");
353
354 // Create Nodes: eNodeB and UE
355 NodeContainer enbNodes;
356 NodeContainer ueNodes1;
357 NodeContainer ueNodes2;
358 enbNodes.Create(2);
359 ueNodes1.Create(1);
360 ueNodes2.Create(2);
361 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
362
363 /*
364 * The topology is the following:
365 *
366 * eNB1 UE1 UE2 eNB2 UE3
367 * | | | |
368 * x -------------------------- x -------------------------- x----x
369 * 500 m 500 m 50m
370 *
371 * see https://www.nsnam.org/bugzilla/show_bug.cgi?id=2048#c4 for why we need UE3
372 */
373
374 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
375 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
376 positionAlloc->Add(Vector(1000, 0.0, 0.0)); // eNB2
377 positionAlloc->Add(Vector(500.0, 0.0, 0.0)); // UE1
378 positionAlloc->Add(Vector(500, 0.0, 0.0)); // UE2
379 positionAlloc->Add(Vector(1050, 0.0, 0.0)); // UE3
380 MobilityHelper mobility;
381 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
382 mobility.SetPositionAllocator(positionAlloc);
383 mobility.Install(allNodes);
384
385 // Create Devices and install them in the Nodes (eNB and UE)
386 NetDeviceContainer enbDevs;
387 NetDeviceContainer ueDevs1;
388 NetDeviceContainer ueDevs2;
389 lteHelper->SetSchedulerType("ns3::PfFfMacScheduler");
390 // In this scenario, eNB2 with 2 UEs will assign 12 RBs to UE2.
391 // On the other hand eNB1 will assign 25 RBs to UE1. As per the new uplink power
392 // spectral density computation, UE with less RBs to Tx will have more power
393 // per RB. Therefore UE2 will harm UE1 more, thus, both the UEs will have
394 // different Uplink CQI, which will cause the test to fail.
395 // In this case, we can use SRS based CQIs, since, they are not dependent on
396 // the transmission bandwidth.
397 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::SRS_UL_CQI));
398 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
399 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
400 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
401 // We need to fix the stream to have control over
402 // random preamble generation by the UEs.
403 Ptr<LteUeNetDevice> lteUeDev;
404 Ptr<LteUeMac> lteUeMac;
405 lteUeDev = DynamicCast<LteUeNetDevice>(ueDevs1.Get(0));
406 lteUeMac = lteUeDev->GetMac();
407 lteUeMac->AssignStreams(1);
408 lteUeDev = DynamicCast<LteUeNetDevice>(ueDevs2.Get(0));
409 lteUeMac = lteUeDev->GetMac();
410 lteUeMac->AssignStreams(1);
411 lteUeDev = DynamicCast<LteUeNetDevice>(ueDevs2.Get(1));
412 lteUeMac = lteUeDev->GetMac();
413 lteUeMac->AssignStreams(2);
414
415 // Attach a UE to a eNB
416 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
417 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
418
419 // Activate an EPS bearer
421 EpsBearer bearer(q);
422 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
423 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
424
425 PointerValue tmp;
426 enbDevs.Get(0)->GetAttribute("LteFfrAlgorithm", tmp);
427 Ptr<LteFfrSimple> simpleFfrAlgorithmEnb0 = DynamicCast<LteFfrSimple>(tmp.GetObject());
428 simpleFfrAlgorithmEnb0->ChangePdschConfigDedicated(true);
429
430 LteRrcSap::PdschConfigDedicated pdschConfigDedicatedEnb0;
431 pdschConfigDedicatedEnb0.pa = m_cell0Pa;
432 simpleFfrAlgorithmEnb0->SetPdschConfigDedicated(pdschConfigDedicatedEnb0);
433
434 enbDevs.Get(1)->GetAttribute("LteFfrAlgorithm", tmp);
435 Ptr<LteFfrSimple> simpleFfrAlgorithmEnb1 = DynamicCast<LteFfrSimple>(tmp.GetObject());
436 simpleFfrAlgorithmEnb1->ChangePdschConfigDedicated(true);
437
438 LteRrcSap::PdschConfigDedicated pdschConfigDedicatedEnb1;
439 pdschConfigDedicatedEnb1.pa = m_cell1Pa;
440 simpleFfrAlgorithmEnb1->SetPdschConfigDedicated(pdschConfigDedicatedEnb1);
441
442 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
444
445 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
447
448 Simulator::Stop(Seconds(1.100));
450
452}
This test is very similar to LteCqiGenerationTestCase.
void DoRun() override
Implementation to actually run this TestCase.
void DlScheduling(DlSchedulingCallbackInfo dlInfo)
DL Scheduling function.
LteCqiGenerationDlPowerControlTestCase(std::string name, uint8_t cell0Pa, uint8_t cell1Pa, uint16_t dlMcs, uint16_t ulMcs)
Constructor.
void UlScheduling(uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb)
UL Scheduling function.
This is the test case for testing different configuration of CQI generation.
void UlScheduling(uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb)
UL Scheduling function.
void DoRun() override
Implementation to actually run this TestCase.
bool m_usePdschForCqiGeneration
use PDCCH for CQI generation
void DlScheduling(DlSchedulingCallbackInfo dlInfo)
DL Scheduling function.
LteCqiGenerationTestCase(std::string name, bool usePdcchForCqiGeneration, uint16_t dlMcs, uint16_t ulMcs)
Constructor.
Lte Cqi Generation Test Suite.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Hold variables of type enum.
Definition: enum.h:62
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
Qci
QoS Class Indicator.
Definition: eps-bearer.h:106
@ GBR_CONV_VOICE
GBR Conversational Voice.
Definition: eps-bearer.h:107
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
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< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Ptr< Object > GetObject() const
Get the Object referenced by the PointerValue.
Definition: pointer.cc:57
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Hold an unsigned integer type.
Definition: uinteger.h:45
void Reset()
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition: config.cc:859
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:978
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
static LteCqiGenerationTestSuite lteCqiGenerationTestSuite
Static variable for test initialization.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
#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:145
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
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 LteTestUlSchedulingCallback(LteCqiGenerationTestCase *testcase, std::string path, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb, uint8_t ccId)
void LteTestUlSchedulingCallback2(LteCqiGenerationDlPowerControlTestCase *testcase, std::string path, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb, uint8_t componentCarrierId)
void LteTestDlSchedulingCallback2(LteCqiGenerationDlPowerControlTestCase *testcase, std::string path, DlSchedulingCallbackInfo dlInfo)
void LteTestDlSchedulingCallback(LteCqiGenerationTestCase *testcase, std::string path, DlSchedulingCallbackInfo dlInfo)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
DlSchedulingCallbackInfo structure.
Definition: lte-common.h:237
PdschConfigDedicated structure.
Definition: lte-rrc-sap.h:163