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