A Discrete-Event Network Simulator
API
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
65{
66 uint16_t m_dlBandwidth;
67 uint16_t m_ulBandwidth;
70};
71
72NS_LOG_COMPONENT_DEFINE("TestCarrierAggregationConfig");
73
81{
82 public:
92 uint16_t numberOfComponentCarriers,
93 std::vector<ConfigToCheck> configToCheck,
94 Time simulationDuration)
95 : TestCase(BuildNameString(numberOfNodes,
96 numberOfComponentCarriers,
97 configToCheck,
98 simulationDuration)),
99 m_numberOfNodes(numberOfNodes),
100 m_numberOfComponentCarriers(numberOfComponentCarriers),
101 m_configToCheck(configToCheck),
102 m_simulationDuration(simulationDuration)
103 {
105 }
106
107 private:
108 void DoRun() override;
109
119 std::string BuildNameString(uint32_t numberOfNodes,
120 uint16_t numberOfComponentCarriers,
121 std::vector<ConfigToCheck> configToCheck,
122 Time simulationDuration);
130 void Evaluate(std::string context,
131 Ptr<LteUeRrc> ueRrc,
132 std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
138 std::vector<std::map<uint16_t, ConfigToCheck>> EquallySpacedCcs();
139
142 std::vector<ConfigToCheck>
146 std::vector<std::map<uint16_t, ConfigToCheck>>
149};
150
151std::string
153 uint16_t numberOfComponentCarriers,
154 std::vector<ConfigToCheck> configToCheck,
155 Time simulationDuration)
156{
157 std::ostringstream oss;
158 oss << " nodes " << numberOfNodes << " carriers " << numberOfComponentCarriers
159 << " configurations " << configToCheck.size() << " duration " << simulationDuration;
160 return oss.str();
161}
162
163std::vector<std::map<uint16_t, ConfigToCheck>>
165{
166 std::vector<std::map<uint16_t, ConfigToCheck>> configToCheckContainer;
167
168 for (auto& it : m_configToCheck)
169 {
170 std::map<uint16_t, ConfigToCheck> ccmap;
171 uint32_t ulEarfcn = it.m_ulEarfcn;
172 uint32_t dlEarfcn = it.m_dlEarfcn;
173 uint32_t maxBandwidthRb = std::max<uint32_t>(it.m_ulBandwidth, it.m_dlBandwidth);
174
175 // Convert bandwidth from RBs to kHz
176 uint32_t maxBandwidthKhz =
177 LteSpectrumValueHelper::GetChannelBandwidth(maxBandwidthRb) / 1e3;
178
179 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
180 {
181 // Make sure we stay within the same band.
182 if (LteSpectrumValueHelper::GetUplinkCarrierBand(ulEarfcn) !=
183 LteSpectrumValueHelper::GetUplinkCarrierBand(it.m_ulEarfcn) ||
184 LteSpectrumValueHelper::GetDownlinkCarrierBand(dlEarfcn) !=
185 LteSpectrumValueHelper::GetDownlinkCarrierBand(it.m_dlEarfcn))
186 {
187 NS_FATAL_ERROR("Band is not wide enough to allocate " << m_numberOfComponentCarriers
188 << " CCs");
189 }
190
191 ConfigToCheck cc;
192 cc.m_dlBandwidth = it.m_dlBandwidth;
193 cc.m_dlEarfcn = dlEarfcn;
194 cc.m_ulBandwidth = it.m_ulBandwidth;
195 cc.m_ulEarfcn = ulEarfcn;
196
197 ccmap.insert(std::pair<uint16_t, ConfigToCheck>(i, cc));
198
199 NS_LOG_INFO("UL BW: " << it.m_ulBandwidth << ", DL BW: " << it.m_dlBandwidth
200 << ", UL Earfcn: " << ulEarfcn << ", DL Earfcn: " << dlEarfcn);
201
202 // The spacing between the center frequencies of two contiguous CCs should be multiple
203 // of 300 kHz. Round spacing up to 300 kHz.
204 uint32_t frequencyShift = 300 * (1 + (maxBandwidthKhz - 1) / 300);
205
206 // Unit of EARFCN corresponds to 100kHz.
207 uint32_t earfcnShift = frequencyShift / 100;
208 ulEarfcn += earfcnShift;
209 dlEarfcn += earfcnShift;
210 }
211
212 configToCheckContainer.push_back(ccmap);
213 }
214
215 return configToCheckContainer;
216}
217
218void
220 Ptr<LteUeRrc> ueRrc,
221 std::list<LteRrcSap::SCellToAddMod> sCellToAddModList)
222{
223 NS_LOG_INFO("Secondary carriers configured");
224
225 uint16_t cellId = ueRrc->GetCellId();
226 NS_LOG_INFO("cellId " << cellId);
227 NS_LOG_INFO("m_configToCheckContainer size " << m_configToCheckContainer.size());
228
230
231 std::map<uint16_t, ConfigToCheck> configToCheckMap;
232
233 if (cellId == 1)
234 {
235 configToCheckMap = m_configToCheckContainer[cellId - 1];
236 }
237 else
238 {
239 uint16_t n1 = std::max(cellId, m_numberOfComponentCarriers);
240 uint16_t n2 = std::min(cellId, m_numberOfComponentCarriers);
241 configToCheckMap = m_configToCheckContainer[n1 - n2];
242 }
243
244 NS_LOG_INFO("PCarrier - UL BW: "
245 << static_cast<uint16_t>(ueRrc->GetUlBandwidth())
246 << ", DL BW: " << static_cast<uint16_t>(ueRrc->GetDlBandwidth()) << ", UL Earfcn: "
247 << ueRrc->GetUlEarfcn() << ", DL Earfcn: " << ueRrc->GetDlEarfcn());
248
249 for (auto scell : sCellToAddModList)
250 {
251 NS_LOG_INFO("SCarrier - UL BW: "
252 << static_cast<uint16_t>(scell.radioResourceConfigCommonSCell.ulConfiguration
253 .ulFreqInfo.ulBandwidth)
254 << ", DL BW: "
255 << static_cast<uint16_t>(
256 scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth)
257 << ", UL Earfcn: "
258 << scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq
259 << ", DL Earfcn: " << scell.cellIdentification.dlCarrierFreq);
260 }
261
262 ConfigToCheck pCConfig = configToCheckMap[0]; // Primary Carrier
263 ConfigToCheck sCConfig; // Secondary Carriers
264
266 static_cast<uint16_t>(ueRrc->GetDlBandwidth()),
267 "Primary Carrier DL bandwidth configuration failed");
269 static_cast<uint16_t>(ueRrc->GetUlBandwidth()),
270 "Primary Carrier UL bandwidth configuration failed");
272 ueRrc->GetDlEarfcn(),
273 "Primary Carrier DL EARFCN configuration failed");
275 ueRrc->GetUlEarfcn(),
276 "Primary Carrier UL EARFCN configuration failed");
277
278 uint32_t ConfigToCheckMapIndex = 1;
279
280 for (auto scell : sCellToAddModList)
281 {
282 sCConfig = configToCheckMap[ConfigToCheckMapIndex];
283
285 sCConfig.m_dlBandwidth,
286 static_cast<uint16_t>(
287 scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth),
288 "Secondary Carrier DL bandwidth configuration failed");
290 sCConfig.m_ulBandwidth,
291 static_cast<uint16_t>(
292 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth),
293 "Secondary Carrier UL bandwidth configuration failed");
295 scell.cellIdentification.dlCarrierFreq,
296 "Secondary Carrier DL EARFCN configuration failed");
298 sCConfig.m_ulEarfcn,
299 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq,
300 "Secondary Carrier UL EARFCN configuration failed");
301 ConfigToCheckMapIndex++;
302 }
303}
304
305void
307{
308 Config::SetDefault("ns3::LteHelper::UseCa", BooleanValue(true));
309 Config::SetDefault("ns3::LteHelper::NumberOfComponentCarriers",
311 Config::SetDefault("ns3::LteHelper::EnbComponentCarrierManager",
312 StringValue("ns3::RrComponentCarrierManager"));
313
314 int64_t stream = 1;
315
316 Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
317
318 // Create Nodes: eNodeB and UE
319 NodeContainer enbNodes;
320 NodeContainer ueNodes;
321 enbNodes.Create(m_numberOfNodes);
322 ueNodes.Create(m_numberOfNodes);
323
324 uint32_t totalNumberOfNodes = enbNodes.GetN() + ueNodes.GetN();
325
326 // Install Mobility Model
327 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
328 for (uint32_t i = 0; i < totalNumberOfNodes; i++)
329 {
330 positionAlloc->Add(Vector(2 * i, 0, 0));
331 }
332
334 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
335 mobility.SetPositionAllocator(positionAlloc);
336
337 for (uint32_t n = 0; n < m_numberOfNodes; ++n)
338 {
339 mobility.Install(enbNodes.Get(n));
340 mobility.Install(ueNodes.Get(n));
341 }
342
343 ConfigToCheck configuration;
344 NetDeviceContainer enbDevs;
345 NetDeviceContainer ueDevs;
346
347 // Set bandwidth, EARFCN and install nodes (eNB and UE)
348 for (uint32_t i = 0; i < m_configToCheck.size(); ++i)
349 {
350 configuration = m_configToCheck[i];
351
352 lteHelper->SetEnbDeviceAttribute("DlBandwidth", UintegerValue(configuration.m_dlBandwidth));
353 lteHelper->SetEnbDeviceAttribute("UlBandwidth", UintegerValue(configuration.m_ulBandwidth));
354 lteHelper->SetEnbDeviceAttribute("DlEarfcn", UintegerValue(configuration.m_dlEarfcn));
355 lteHelper->SetEnbDeviceAttribute("UlEarfcn", UintegerValue(configuration.m_ulEarfcn));
356 lteHelper->SetUeDeviceAttribute("DlEarfcn", UintegerValue(configuration.m_dlEarfcn));
357 enbDevs.Add(lteHelper->InstallEnbDevice(enbNodes.Get(i)));
358 lteHelper->AssignStreams(enbDevs, stream);
359 ueDevs.Add(lteHelper->InstallUeDevice(ueNodes.Get(i)));
360 lteHelper->AssignStreams(ueDevs, stream);
361 }
362
363 // Calculate the DlBandwidth, UlBandwidth, DlEarfcn and UlEarfcn to which the values from UE RRC
364 // would be compared
366
367 // Attach a UE to an eNB
368 for (uint32_t k = 0; k < m_numberOfNodes; ++k)
369 {
370 lteHelper->Attach(ueDevs.Get(k), enbDevs.Get(k));
371 }
372
373 // Activate a data radio bearer
374 enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
375 EpsBearer bearer(q);
376 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
377
378 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/SCarrierConfigured",
380
381 Simulator::Stop(m_simulationDuration);
382 Simulator::Run();
383
384 NS_TEST_ASSERT_MSG_EQ(m_connectionCounter, ueNodes.GetN(), "Not all the UEs were connected");
385
386 Simulator::Destroy();
387}
388
396{
397 public:
399};
400
402 : TestSuite("lte-carrier-aggregation-configuration", SYSTEM)
403{
404 std::vector<ConfigToCheck> configToCheck;
405
406 // Test1 with 1 eNB and 1 UE.
407 // We put a configuration different than the default configuration done in LteHelper for the
408 // sake of creating PHY and MAC instances equal to the number of component carriers.
409
410 ConfigToCheck configToCheckTest1;
411 configToCheckTest1.m_dlBandwidth = 50;
412 configToCheckTest1.m_ulBandwidth = 50;
413 configToCheckTest1.m_dlEarfcn = 300;
414 configToCheckTest1.m_ulEarfcn = 300 + 18000;
415 configToCheck.push_back(configToCheckTest1);
416 uint32_t numberOfNodes = 1;
417 uint16_t numberOfComponentCarriers = 2;
418 Time simulationDuration = Seconds(1);
419
421 numberOfComponentCarriers,
422 configToCheck,
423 simulationDuration),
424 TestCase::QUICK);
425
426 // configToCheck.erase(configToCheck.begin(), configToCheck.end());
427 configToCheck.clear();
428
429 // Test2 with 2 eNBs and 2 UEs.
430 // We decrease the bandwidth so not to exceed maximum band bandwidth of 20 MHz
431
432 configToCheckTest1.m_dlBandwidth = 25;
433 configToCheckTest1.m_ulBandwidth = 25;
434 configToCheckTest1.m_dlEarfcn = 300;
435 configToCheckTest1.m_ulEarfcn = 300 + 18000;
436 configToCheck.push_back(configToCheckTest1);
437
438 ConfigToCheck configToCheckTest2;
439 configToCheckTest2.m_dlBandwidth = 25;
440 configToCheckTest2.m_ulBandwidth = 25;
441 configToCheckTest2.m_dlEarfcn = 502;
442 configToCheckTest2.m_ulEarfcn = 502 + 18000;
443 configToCheck.push_back(configToCheckTest2);
444 numberOfNodes = 2;
445 simulationDuration = Seconds(2);
446
448 numberOfComponentCarriers,
449 configToCheck,
450 simulationDuration),
451 TestCase::QUICK);
452}
453
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
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
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:482
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:1044
void SetEnbDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the eNodeB devices (LteEnbNetDevice) to be created.
Definition: lte-helper.cc:409
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1441
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:497
void SetUeDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the UE devices (LteUeNetDevice) to be created.
Definition: lte-helper.cc:430
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1572
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:78
Hold variables of type string.
Definition: string.h:42
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
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:891
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#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
#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:144
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
static CarrierAggregationConfigTestSuite g_carrierAggregationConfigTestSuite
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:691
mobility
Definition: third.py:96
This test suite verifies following two things:
uint16_t m_ulBandwidth
Uplink bandwidth.
uint16_t m_dlBandwidth
Downlink bandwidth.