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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
7 *
8 */
9
11
12#include "lte-ffr-simple.h"
13
14#include "ns3/ff-mac-scheduler.h"
15#include "ns3/lte-helper.h"
16#include "ns3/lte-rrc-sap.h"
17#include "ns3/mobility-helper.h"
18#include <ns3/boolean.h>
19#include <ns3/callback.h>
20#include <ns3/config.h>
21#include <ns3/double.h>
22#include <ns3/enum.h>
23#include <ns3/log.h>
24#include <ns3/lte-ue-mac.h>
25#include <ns3/lte-ue-net-device.h>
26#include <ns3/pointer.h>
27#include <ns3/simulator.h>
28#include <ns3/string.h>
29
30using namespace ns3;
31
32NS_LOG_COMPONENT_DEFINE("LteCqiGenerationTest");
33
34void
36 std::string path,
38{
39 testcase->DlScheduling(dlInfo);
40}
41
42void
44 std::string path,
45 uint32_t frameNo,
46 uint32_t subframeNo,
47 uint16_t rnti,
48 uint8_t mcs,
49 uint16_t sizeTb,
50 uint8_t ccId)
51{
52 testcase->UlScheduling(frameNo, subframeNo, rnti, mcs, sizeTb);
53}
54
55void
57 std::string path,
59{
60 testcase->DlScheduling(dlInfo);
61}
62
63void
65 std::string path,
66 uint32_t frameNo,
67 uint32_t subframeNo,
68 uint16_t rnti,
69 uint8_t mcs,
70 uint16_t sizeTb,
71 uint8_t componentCarrierId)
72{
73 testcase->UlScheduling(frameNo, subframeNo, rnti, mcs, sizeTb);
74}
75
76/**
77 * TestSuite
78 */
79
81 : TestSuite("lte-cqi-generation", Type::SYSTEM)
82{
83 // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_DEBUG);
84 // LogComponentEnable ("LteCqiGenerationTest", logLevel);
85 NS_LOG_INFO("Creating LteCqiGenerationTestSuite");
86
87 AddTestCase(new LteCqiGenerationTestCase("UsePdcchForCqiGeneration", false, 4, 2),
88 TestCase::Duration::QUICK);
89 AddTestCase(new LteCqiGenerationTestCase("UsePdschForCqiGeneration", true, 28, 2),
90 TestCase::Duration::QUICK);
91
92 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
95 4,
96 2),
97 TestCase::Duration::QUICK);
98 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
101 8,
102 2),
103 TestCase::Duration::QUICK);
104 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
107 10,
108 2),
109 TestCase::Duration::QUICK);
110 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
113 12,
114 2),
115 TestCase::Duration::QUICK);
116 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
119 14,
120 2),
121 TestCase::Duration::QUICK);
122 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
125 14,
126 2),
127 TestCase::Duration::QUICK);
128 AddTestCase(new LteCqiGenerationDlPowerControlTestCase("CqiGenerationWithDlPowerControl",
131 8,
132 2),
133 TestCase::Duration::QUICK);
134}
135
136/**
137 * \ingroup lte-test
138 * Static variable for test initialization
139 */
141
143 bool usePdcchForCqiGeneration,
144 uint16_t dlMcs,
145 uint16_t ulMcs)
146 : TestCase("Downlink Power Control: " + name),
147 m_dlMcs(dlMcs),
148 m_ulMcs(ulMcs)
149{
150 m_usePdschForCqiGeneration = usePdcchForCqiGeneration;
151 NS_LOG_INFO("Creating LteCqiGenerationTestCase");
152}
153
157
158void
160{
161 // need to allow for RRC connection establishment + CQI feedback reception
162 if (Simulator::Now() > MilliSeconds(35))
163 {
164 // NS_LOG_UNCOND("DL MSC: " << (uint32_t)mcsTb1 << " expected DL MCS: " <<
165 // (uint32_t)m_dlMcs);
166 NS_TEST_ASSERT_MSG_EQ((uint32_t)dlInfo.mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
167 }
168}
169
170void
172 uint32_t subframeNo,
173 uint16_t rnti,
174 uint8_t mcs,
175 uint16_t sizeTb)
176{
177 // need to allow for RRC connection establishment + SRS transmission
178 if (Simulator::Now() > MilliSeconds(50))
179 {
180 // NS_LOG_UNCOND("UL MSC: " << (uint32_t)mcs << " expected UL MCS: " <<
181 // (uint32_t)m_ulMcs);
182 NS_TEST_ASSERT_MSG_EQ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
183 }
184}
185
186void
188{
189 NS_LOG_DEBUG("LteCqiGenerationTestCase");
190
192 Config::SetDefault("ns3::LteHelper::UseIdealRrc", BooleanValue(true));
193 Config::SetDefault("ns3::LteHelper::UsePdschForCqiGeneration",
195
196 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(true));
197 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(true));
198
200
201 // Create Nodes: eNodeB and UE
202 NodeContainer enbNodes;
203 NodeContainer ueNodes1;
204 NodeContainer ueNodes2;
205 enbNodes.Create(2);
206 ueNodes1.Create(1);
207 ueNodes2.Create(1);
208 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
209
210 /*
211 * The topology is the following:
212 *
213 * eNB1 UE1 UE2 eNB2
214 * | | |
215 * x -------------------------- x -------------------------- x
216 * 500 m 500 m
217 *
218 */
219
221 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
222 positionAlloc->Add(Vector(1000, 0.0, 0.0)); // eNB2
223 positionAlloc->Add(Vector(500.0, 0.0, 0.0)); // UE1
224 positionAlloc->Add(Vector(500, 0.0, 0.0)); // UE2
225 MobilityHelper mobility;
226 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
227 mobility.SetPositionAllocator(positionAlloc);
228 mobility.Install(allNodes);
229
230 // Create Devices and install them in the Nodes (eNB and UE)
231 NetDeviceContainer enbDevs;
232 NetDeviceContainer ueDevs1;
233 NetDeviceContainer ueDevs2;
234 lteHelper->SetSchedulerType("ns3::PfFfMacScheduler");
235 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
236
237 lteHelper->SetFfrAlgorithmType("ns3::LteFrHardAlgorithm");
238
239 lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue(0));
240 lteHelper->SetFfrAlgorithmAttribute("DlSubBandwidth", UintegerValue(12));
241 lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue(0));
242 lteHelper->SetFfrAlgorithmAttribute("UlSubBandwidth", UintegerValue(25));
243 enbDevs.Add(lteHelper->InstallEnbDevice(enbNodes.Get(0)));
244
245 lteHelper->SetFfrAlgorithmAttribute("DlSubBandOffset", UintegerValue(12));
246 lteHelper->SetFfrAlgorithmAttribute("DlSubBandwidth", UintegerValue(12));
247 lteHelper->SetFfrAlgorithmAttribute("UlSubBandOffset", UintegerValue(0));
248 lteHelper->SetFfrAlgorithmAttribute("UlSubBandwidth", UintegerValue(25));
249 enbDevs.Add(lteHelper->InstallEnbDevice(enbNodes.Get(1)));
250
251 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
252 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
253
254 // Attach a UE to a eNB
255 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
256 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
257
258 // Activate an EPS bearer
260 EpsBearer bearer(q);
261 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
262 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
263
264 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
266
267 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
269
270 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
272
273 Config::Connect("/NodeList/1/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
275
276 Simulator::Stop(Seconds(1.100));
278
280}
281
283 uint8_t cell0Pa,
284 uint8_t cell1Pa,
285 uint16_t dlMcs,
286 uint16_t ulMcs)
287 : TestCase("Downlink Power Control: " + name),
288 m_cell0Pa(cell0Pa),
289 m_cell1Pa(cell1Pa),
290 m_dlMcs(dlMcs),
291 m_ulMcs(ulMcs)
292{
293 NS_LOG_INFO("Creating LteCqiGenerationTestCase");
294}
295
299
300void
302{
303 // need to allow for RRC connection establishment + CQI feedback reception
304 if (Simulator::Now() > MilliSeconds(500))
305 {
306 // NS_LOG_UNCOND("DL MSC: " << (uint32_t)mcsTb1 << " expected DL MCS: " <<
307 // (uint32_t)m_dlMcs);
308 NS_TEST_ASSERT_MSG_EQ((uint32_t)dlInfo.mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
309 }
310}
311
312void
314 uint32_t subframeNo,
315 uint16_t rnti,
316 uint8_t mcs,
317 uint16_t sizeTb)
318{
319 // need to allow for RRC connection establishment + SRS transmission
320 if (Simulator::Now() > MilliSeconds(500))
321 {
322 // NS_LOG_UNCOND("UL MSC: " << (uint32_t)mcs << " expected UL MCS: " <<
323 // (uint32_t)m_ulMcs);
324 NS_TEST_ASSERT_MSG_EQ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
325 }
326}
327
328void
330{
331 NS_LOG_DEBUG("LteCqiGenerationTestCase");
332
334 Config::SetDefault("ns3::LteHelper::UseIdealRrc", BooleanValue(true));
335 Config::SetDefault("ns3::LteHelper::UsePdschForCqiGeneration", BooleanValue(true));
336
337 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(true));
338 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(true));
339
341 lteHelper->SetFfrAlgorithmType("ns3::LteFfrSimple");
342
343 // Create Nodes: eNodeB and UE
344 NodeContainer enbNodes;
345 NodeContainer ueNodes1;
346 NodeContainer ueNodes2;
347 enbNodes.Create(2);
348 ueNodes1.Create(1);
349 ueNodes2.Create(2);
350 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
351
352 /*
353 * The topology is the following:
354 *
355 * eNB1 UE1 UE2 eNB2 UE3
356 * | | | |
357 * x -------------------------- x -------------------------- x----x
358 * 500 m 500 m 50m
359 *
360 * see https://www.nsnam.org/bugzilla/show_bug.cgi?id=2048#c4 for why we need UE3
361 */
362
364 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
365 positionAlloc->Add(Vector(1000, 0.0, 0.0)); // eNB2
366 positionAlloc->Add(Vector(500.0, 0.0, 0.0)); // UE1
367 positionAlloc->Add(Vector(500, 0.0, 0.0)); // UE2
368 positionAlloc->Add(Vector(1050, 0.0, 0.0)); // UE3
369 MobilityHelper mobility;
370 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
371 mobility.SetPositionAllocator(positionAlloc);
372 mobility.Install(allNodes);
373
374 // Create Devices and install them in the Nodes (eNB and UE)
375 NetDeviceContainer enbDevs;
376 NetDeviceContainer ueDevs1;
377 NetDeviceContainer ueDevs2;
378 lteHelper->SetSchedulerType("ns3::PfFfMacScheduler");
379 // In this scenario, eNB2 with 2 UEs will assign 12 RBs to UE2.
380 // On the other hand eNB1 will assign 25 RBs to UE1. As per the new uplink power
381 // spectral density computation, UE with less RBs to Tx will have more power
382 // per RB. Therefore UE2 will harm UE1 more, thus, both the UEs will have
383 // different Uplink CQI, which will cause the test to fail.
384 // In this case, we can use SRS based CQIs, since, they are not dependent on
385 // the transmission bandwidth.
386 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::SRS_UL_CQI));
387 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
388 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
389 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
390 // We need to fix the stream to have control over
391 // random preamble generation by the UEs.
392 Ptr<LteUeNetDevice> lteUeDev;
393 Ptr<LteUeMac> lteUeMac;
394 lteUeDev = DynamicCast<LteUeNetDevice>(ueDevs1.Get(0));
395 lteUeMac = lteUeDev->GetMac();
396 lteUeMac->AssignStreams(1);
397 lteUeDev = DynamicCast<LteUeNetDevice>(ueDevs2.Get(0));
398 lteUeMac = lteUeDev->GetMac();
399 lteUeMac->AssignStreams(1);
400 lteUeDev = DynamicCast<LteUeNetDevice>(ueDevs2.Get(1));
401 lteUeMac = lteUeDev->GetMac();
402 lteUeMac->AssignStreams(2);
403
404 // Attach a UE to a eNB
405 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
406 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
407
408 // Activate an EPS bearer
410 EpsBearer bearer(q);
411 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
412 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
413
414 PointerValue tmp;
415 enbDevs.Get(0)->GetAttribute("LteFfrAlgorithm", tmp);
416 Ptr<LteFfrSimple> simpleFfrAlgorithmEnb0 = DynamicCast<LteFfrSimple>(tmp.GetObject());
417 simpleFfrAlgorithmEnb0->ChangePdschConfigDedicated(true);
418
419 LteRrcSap::PdschConfigDedicated pdschConfigDedicatedEnb0;
420 pdschConfigDedicatedEnb0.pa = m_cell0Pa;
421 simpleFfrAlgorithmEnb0->SetPdschConfigDedicated(pdschConfigDedicatedEnb0);
422
423 enbDevs.Get(1)->GetAttribute("LteFfrAlgorithm", tmp);
424 Ptr<LteFfrSimple> simpleFfrAlgorithmEnb1 = DynamicCast<LteFfrSimple>(tmp.GetObject());
425 simpleFfrAlgorithmEnb1->ChangePdschConfigDedicated(true);
426
427 LteRrcSap::PdschConfigDedicated pdschConfigDedicatedEnb1;
428 pdschConfigDedicatedEnb1.pa = m_cell1Pa;
429 simpleFfrAlgorithmEnb1->SetPdschConfigDedicated(pdschConfigDedicatedEnb1);
430
431 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
433
434 Config::Connect("/NodeList/0/DeviceList/0/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
436
437 Simulator::Stop(Seconds(1.100));
439
441}
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.
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
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.
Ptr< Object > GetObject() const
Get the Object referenced by the PointerValue.
Definition pointer.cc:46
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
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
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Hold an unsigned integer type.
Definition uinteger.h:34
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:848
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_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
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:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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
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 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.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
DlSchedulingCallbackInfo structure.
Definition lte-common.h:226
PdschConfigDedicated structure.