A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-test-carrier-aggregation-configuration.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 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: Zoraze Ali <zoraze.ali@cttc.es>
18 *
19 */
20
21#include <ns3/callback.h>
22#include <ns3/constant-position-mobility-model.h>
23#include <ns3/log.h>
24#include <ns3/lte-helper.h>
25#include <ns3/lte-spectrum-value-helper.h>
26#include <ns3/lte-ue-rrc.h>
27#include <ns3/mobility-helper.h>
28#include <ns3/net-device-container.h>
29#include <ns3/node-container.h>
30#include <ns3/object.h>
31#include <ns3/ptr.h>
32#include <ns3/simulator.h>
33#include <ns3/test.h>
34
35using namespace ns3;
36
37/**
38 * This test suite verifies following two things:
39 *
40 * 1. When CA is enabled and UE carriers configuration is different than the default one,
41 * we check that the UE is configured properly once it receives
42 * RRC Connection Reconfiguration message from eNB.
43 *
44 * 2. A user can configure 2 or more eNBs and UEs with different configuration parameters,
45 * i.e, each eNB and UE can have different EARFCN and Bandwidths and a UE connects to
46 * an eNB with similar DL EARFCN.
47 * Here we check it with CA enabled but the end results will be the same if CA is not
48 * enabled and we have more than one eNBs and UEs with different configurations.
49 *
50 * Since we do not need EPC to test the configuration, this test only simulates
51 * the LTE radio access with RLC SM.
52 *
53 * Test 1 tests that the UE is configured properly after receiving RRC Connection
54 * Reconfiguration message from the eNB, which will overwrite UE default configuration
55 * done in LteHelper for the sake of creating PHY and MAC instances equal to the number
56 * of component carriers.
57 *
58 * Test 2 tests that in a simulation scenario every eNB or UE can be configured with
59 * different EARFCNs and Bandwidths. This will check that the eNBs and UEs configuration
60 * is not static, as reported in BUG 2840.
61 */
62
63/// ConfigToCheck structure
65{
66 uint16_t m_dlBandwidth; ///< Downlink bandwidth
67 uint16_t m_ulBandwidth; ///< Uplink bandwidth
68 uint32_t m_dlEarfcn; ///< Downlink EARFCN
69 uint32_t m_ulEarfcn; ///< Uplink EARFCN
70};
71
72NS_LOG_COMPONENT_DEFINE("TestCarrierAggregationConfig");
73
74/**
75 * \ingroup lte-test
76 *
77 * \brief Carrier aggregation configuration test case.
78 */
80{
81 public:
82 /**
83 * Constructor
84 *
85 * \param numberOfNodes Total Number of eNBs and UEs
86 * \param numberOfComponentCarriers Total number of component carriers
87 * \param configToCheck Vector containing all the configurations to check
88 * \param simulationDuration Duration of the simulation
89 */
91 uint16_t numberOfComponentCarriers,
92 std::vector<ConfigToCheck> configToCheck,
93 Time simulationDuration)
94 : TestCase(BuildNameString(numberOfNodes,
95 numberOfComponentCarriers,
96 configToCheck,
97 simulationDuration)),
98 m_numberOfNodes(numberOfNodes),
99 m_numberOfComponentCarriers(numberOfComponentCarriers),
100 m_configToCheck(configToCheck),
101 m_simulationDuration(simulationDuration)
102 {
104 }
105
106 private:
107 void DoRun() override;
108
109 /**
110 * Build name string function
111 *
112 * \param numberOfNodes Total Number of eNBs and UEs
113 * \param numberOfComponentCarriers Total number of component carriers
114 * \param configToCheck Vector containing all the configurations to check
115 * \param simulationDuration Duration of the simulation
116 * \returns the name string
117 */
118 std::string BuildNameString(uint32_t numberOfNodes,
119 uint16_t numberOfComponentCarriers,
120 std::vector<ConfigToCheck> configToCheck,
121 Time simulationDuration);
122 /**
123 * Evaluate function
124 *
125 * \param context The context
126 * \param ueRrc Pointer to the UE RRC
127 * \param sCellToAddModList List of the configuration parameters for secondary cell
128 */
129 void Evaluate(std::string context,
130 Ptr<LteUeRrc> ueRrc,
131 std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
132 /**
133 * Equally spaced component carriers function
134 *
135 * \return Vector of maps containing the per component carrier configuration
136 */
137 std::vector<std::map<uint16_t, ConfigToCheck>> EquallySpacedCcs();
138
139 uint32_t m_numberOfNodes; ///< Number of nodes
140 uint16_t m_numberOfComponentCarriers; ///< Number of component carriers
141 std::vector<ConfigToCheck>
142 m_configToCheck; ///< Vector containing all the configurations to check
143 uint32_t m_connectionCounter; ///< Connection counter
144 Time m_simulationDuration; ///< Simulation duration
145 std::vector<std::map<uint16_t, ConfigToCheck>>
146 m_configToCheckContainer; ///< Vector of maps containing the per component carrier
147 ///< configuration
148};
149
150std::string
152 uint16_t numberOfComponentCarriers,
153 std::vector<ConfigToCheck> configToCheck,
154 Time simulationDuration)
155{
156 std::ostringstream oss;
157 oss << " nodes " << numberOfNodes << " carriers " << numberOfComponentCarriers
158 << " configurations " << configToCheck.size() << " duration " << simulationDuration;
159 return oss.str();
160}
161
162std::vector<std::map<uint16_t, ConfigToCheck>>
164{
165 std::vector<std::map<uint16_t, ConfigToCheck>> configToCheckContainer;
166
167 for (auto& it : m_configToCheck)
168 {
169 std::map<uint16_t, ConfigToCheck> ccmap;
170 uint32_t ulEarfcn = it.m_ulEarfcn;
171 uint32_t dlEarfcn = it.m_dlEarfcn;
172 uint32_t maxBandwidthRb = std::max<uint32_t>(it.m_ulBandwidth, it.m_dlBandwidth);
173
174 // Convert bandwidth from RBs to kHz
175 uint32_t maxBandwidthKhz =
177
178 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
179 {
180 // Make sure we stay within the same band.
185 {
186 NS_FATAL_ERROR("Band is not wide enough to allocate " << m_numberOfComponentCarriers
187 << " CCs");
188 }
189
190 ConfigToCheck cc;
191 cc.m_dlBandwidth = it.m_dlBandwidth;
192 cc.m_dlEarfcn = dlEarfcn;
193 cc.m_ulBandwidth = it.m_ulBandwidth;
194 cc.m_ulEarfcn = ulEarfcn;
195
196 ccmap.insert(std::pair<uint16_t, ConfigToCheck>(i, cc));
197
198 NS_LOG_INFO("UL BW: " << it.m_ulBandwidth << ", DL BW: " << it.m_dlBandwidth
199 << ", UL Earfcn: " << ulEarfcn << ", DL Earfcn: " << dlEarfcn);
200
201 // The spacing between the center frequencies of two contiguous CCs should be multiple
202 // of 300 kHz. Round spacing up to 300 kHz.
203 uint32_t frequencyShift = 300 * (1 + (maxBandwidthKhz - 1) / 300);
204
205 // Unit of EARFCN corresponds to 100kHz.
206 uint32_t earfcnShift = frequencyShift / 100;
207 ulEarfcn += earfcnShift;
208 dlEarfcn += earfcnShift;
209 }
210
211 configToCheckContainer.push_back(ccmap);
212 }
213
214 return configToCheckContainer;
215}
216
217void
219 Ptr<LteUeRrc> ueRrc,
220 std::list<LteRrcSap::SCellToAddMod> sCellToAddModList)
221{
222 NS_LOG_INFO("Secondary carriers configured");
223
224 uint16_t cellId = ueRrc->GetCellId();
225 NS_LOG_INFO("cellId " << cellId);
226 NS_LOG_INFO("m_configToCheckContainer size " << m_configToCheckContainer.size());
227
229
230 std::map<uint16_t, ConfigToCheck> configToCheckMap;
231
232 if (cellId == 1)
233 {
234 configToCheckMap = m_configToCheckContainer[cellId - 1];
235 }
236 else
237 {
238 uint16_t n1 = std::max(cellId, m_numberOfComponentCarriers);
239 uint16_t n2 = std::min(cellId, m_numberOfComponentCarriers);
240 configToCheckMap = m_configToCheckContainer[n1 - n2];
241 }
242
243 NS_LOG_INFO("PCarrier - UL BW: "
244 << static_cast<uint16_t>(ueRrc->GetUlBandwidth())
245 << ", DL BW: " << static_cast<uint16_t>(ueRrc->GetDlBandwidth()) << ", UL Earfcn: "
246 << ueRrc->GetUlEarfcn() << ", DL Earfcn: " << ueRrc->GetDlEarfcn());
247
248 for (auto scell : sCellToAddModList)
249 {
250 NS_LOG_INFO("SCarrier - UL BW: "
251 << static_cast<uint16_t>(scell.radioResourceConfigCommonSCell.ulConfiguration
252 .ulFreqInfo.ulBandwidth)
253 << ", DL BW: "
254 << static_cast<uint16_t>(
255 scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth)
256 << ", UL Earfcn: "
257 << scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq
258 << ", DL Earfcn: " << scell.cellIdentification.dlCarrierFreq);
259 }
260
261 ConfigToCheck pCConfig = configToCheckMap[0]; // Primary Carrier
262 ConfigToCheck sCConfig; // Secondary Carriers
263
265 static_cast<uint16_t>(ueRrc->GetDlBandwidth()),
266 "Primary Carrier DL bandwidth configuration failed");
268 static_cast<uint16_t>(ueRrc->GetUlBandwidth()),
269 "Primary Carrier UL bandwidth configuration failed");
271 ueRrc->GetDlEarfcn(),
272 "Primary Carrier DL EARFCN configuration failed");
274 ueRrc->GetUlEarfcn(),
275 "Primary Carrier UL EARFCN configuration failed");
276
277 uint32_t ConfigToCheckMapIndex = 1;
278
279 for (auto scell : sCellToAddModList)
280 {
281 sCConfig = configToCheckMap[ConfigToCheckMapIndex];
282
284 sCConfig.m_dlBandwidth,
285 static_cast<uint16_t>(
286 scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth),
287 "Secondary Carrier DL bandwidth configuration failed");
289 sCConfig.m_ulBandwidth,
290 static_cast<uint16_t>(
291 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth),
292 "Secondary Carrier UL bandwidth configuration failed");
294 scell.cellIdentification.dlCarrierFreq,
295 "Secondary Carrier DL EARFCN configuration failed");
297 sCConfig.m_ulEarfcn,
298 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq,
299 "Secondary Carrier UL EARFCN configuration failed");
300 ConfigToCheckMapIndex++;
301 }
302}
303
304void
306{
307 Config::SetDefault("ns3::LteHelper::UseCa", BooleanValue(true));
308 Config::SetDefault("ns3::LteHelper::NumberOfComponentCarriers",
310 Config::SetDefault("ns3::LteHelper::EnbComponentCarrierManager",
311 StringValue("ns3::RrComponentCarrierManager"));
312
313 int64_t stream = 1;
314
315 Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
316
317 // Create Nodes: eNodeB and UE
318 NodeContainer enbNodes;
319 NodeContainer ueNodes;
320 enbNodes.Create(m_numberOfNodes);
321 ueNodes.Create(m_numberOfNodes);
322
323 uint32_t totalNumberOfNodes = enbNodes.GetN() + ueNodes.GetN();
324
325 // Install Mobility Model
326 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
327 for (uint32_t i = 0; i < totalNumberOfNodes; i++)
328 {
329 positionAlloc->Add(Vector(2 * i, 0, 0));
330 }
331
332 MobilityHelper mobility;
333 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
334 mobility.SetPositionAllocator(positionAlloc);
335
336 for (uint32_t n = 0; n < m_numberOfNodes; ++n)
337 {
338 mobility.Install(enbNodes.Get(n));
339 mobility.Install(ueNodes.Get(n));
340 }
341
342 ConfigToCheck configuration;
343 NetDeviceContainer enbDevs;
344 NetDeviceContainer ueDevs;
345
346 // Set bandwidth, EARFCN and install nodes (eNB and UE)
347 for (uint32_t i = 0; i < m_configToCheck.size(); ++i)
348 {
349 configuration = m_configToCheck[i];
350
351 lteHelper->SetEnbDeviceAttribute("DlBandwidth", UintegerValue(configuration.m_dlBandwidth));
352 lteHelper->SetEnbDeviceAttribute("UlBandwidth", UintegerValue(configuration.m_ulBandwidth));
353 lteHelper->SetEnbDeviceAttribute("DlEarfcn", UintegerValue(configuration.m_dlEarfcn));
354 lteHelper->SetEnbDeviceAttribute("UlEarfcn", UintegerValue(configuration.m_ulEarfcn));
355 lteHelper->SetUeDeviceAttribute("DlEarfcn", UintegerValue(configuration.m_dlEarfcn));
356 enbDevs.Add(lteHelper->InstallEnbDevice(enbNodes.Get(i)));
357 lteHelper->AssignStreams(enbDevs, stream);
358 ueDevs.Add(lteHelper->InstallUeDevice(ueNodes.Get(i)));
359 lteHelper->AssignStreams(ueDevs, stream);
360 }
361
362 // Calculate the DlBandwidth, UlBandwidth, DlEarfcn and UlEarfcn to which the values from UE RRC
363 // would be compared
365
366 // Attach a UE to an eNB
367 for (uint32_t k = 0; k < m_numberOfNodes; ++k)
368 {
369 lteHelper->Attach(ueDevs.Get(k), enbDevs.Get(k));
370 }
371
372 // Activate a data radio bearer
374 EpsBearer bearer(q);
375 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
376
377 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/SCarrierConfigured",
379
382
383 NS_TEST_ASSERT_MSG_EQ(m_connectionCounter, ueNodes.GetN(), "Not all the UEs were connected");
384
386}
387
388/**
389 * \ingroup lte-test
390 *
391 * \brief Carrier aggregation configuration test suite.
392 */
394{
395 public:
397};
398
400 : TestSuite("lte-carrier-aggregation-configuration", Type::SYSTEM)
401{
402 std::vector<ConfigToCheck> configToCheck;
403
404 // Test1 with 1 eNB and 1 UE.
405 // We put a configuration different than the default configuration done in LteHelper for the
406 // sake of creating PHY and MAC instances equal to the number of component carriers.
407
408 ConfigToCheck configToCheckTest1;
409 configToCheckTest1.m_dlBandwidth = 50;
410 configToCheckTest1.m_ulBandwidth = 50;
411 configToCheckTest1.m_dlEarfcn = 300;
412 configToCheckTest1.m_ulEarfcn = 300 + 18000;
413 configToCheck.push_back(configToCheckTest1);
414 uint32_t numberOfNodes = 1;
415 uint16_t numberOfComponentCarriers = 2;
416 Time simulationDuration = Seconds(1);
417
419 numberOfComponentCarriers,
420 configToCheck,
421 simulationDuration),
422 TestCase::Duration::QUICK);
423
424 // configToCheck.erase(configToCheck.begin(), configToCheck.end());
425 configToCheck.clear();
426
427 // Test2 with 2 eNBs and 2 UEs.
428 // We decrease the bandwidth so not to exceed maximum band bandwidth of 20 MHz
429
430 configToCheckTest1.m_dlBandwidth = 25;
431 configToCheckTest1.m_ulBandwidth = 25;
432 configToCheckTest1.m_dlEarfcn = 300;
433 configToCheckTest1.m_ulEarfcn = 300 + 18000;
434 configToCheck.push_back(configToCheckTest1);
435
436 ConfigToCheck configToCheckTest2;
437 configToCheckTest2.m_dlBandwidth = 25;
438 configToCheckTest2.m_ulBandwidth = 25;
439 configToCheckTest2.m_dlEarfcn = 502;
440 configToCheckTest2.m_ulEarfcn = 502 + 18000;
441 configToCheck.push_back(configToCheckTest2);
442 numberOfNodes = 2;
443 simulationDuration = Seconds(2);
444
446 numberOfComponentCarriers,
447 configToCheck,
448 simulationDuration),
449 TestCase::Duration::QUICK);
450}
451
452/**
453 * \ingroup lte-test
454 * Static variable for test initialization
455 */
Carrier aggregation configuration test case.
CarrierAggregationConfigTestCase(uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector< ConfigToCheck > configToCheck, Time simulationDuration)
Constructor.
uint16_t m_numberOfComponentCarriers
Number of component carriers.
void Evaluate(std::string context, Ptr< LteUeRrc > ueRrc, std::list< LteRrcSap::SCellToAddMod > sCellToAddModList)
Evaluate function.
std::vector< std::map< uint16_t, ConfigToCheck > > m_configToCheckContainer
Vector of maps containing the per component carrier configuration.
std::vector< ConfigToCheck > m_configToCheck
Vector containing all the configurations to check.
std::string BuildNameString(uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector< ConfigToCheck > configToCheck, Time simulationDuration)
Build name string function.
void DoRun() override
Implementation to actually run this TestCase.
std::vector< std::map< uint16_t, ConfigToCheck > > EquallySpacedCcs()
Equally spaced component carriers function.
Carrier aggregation configuration test suite.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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
static uint16_t GetUplinkCarrierBand(uint32_t nUl)
Converts uplink EARFCN to corresponding LTE frequency band number.
static uint16_t GetDownlinkCarrierBand(uint32_t nDl)
Converts downlink EARFCN to corresponding LTE frequency band number.
static double GetChannelBandwidth(uint16_t txBandwidthConf)
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.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
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.
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 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
Hold variables of type string.
Definition: string.h:56
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
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Hold an unsigned integer type.
Definition: uinteger.h:45
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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
static CarrierAggregationConfigTestSuite g_carrierAggregationConfigTestSuite
Static variable for test initialization.
#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
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:704
This test suite verifies following two things:
uint16_t m_ulBandwidth
Uplink bandwidth.
uint16_t m_dlBandwidth
Downlink bandwidth.