A Discrete-Event Network Simulator
API
lte-test-carrier-aggregation-configuration.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2018 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zoraze Ali <zoraze.ali@cttc.es>
19 *
20 */
21
22#include <ns3/object.h>
23#include <ns3/log.h>
24#include <ns3/test.h>
25#include <ns3/simulator.h>
26#include <ns3/ptr.h>
27#include <ns3/constant-position-mobility-model.h>
28#include <ns3/node-container.h>
29#include <ns3/mobility-helper.h>
30#include <ns3/net-device-container.h>
31#include <ns3/lte-ue-rrc.h>
32#include <ns3/lte-helper.h>
33#include <ns3/lte-spectrum-value-helper.h>
34#include <ns3/callback.h>
35
36using namespace ns3;
37
66{
67 uint16_t m_dlBandwidth;
68 uint16_t m_ulBandwidth;
71};
72
73NS_LOG_COMPONENT_DEFINE ("TestCarrierAggregationConfig");
74
82{
83public:
92 CarrierAggregationConfigTestCase (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration)
93 : TestCase (BuildNameString (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration)),
94 m_numberOfNodes(numberOfNodes),
95 m_numberOfComponentCarriers(numberOfComponentCarriers),
96 m_configToCheck(configToCheck),
97 m_simulationDuration (simulationDuration)
98 {
100 }
101
102private:
103 virtual void DoRun (void);
104
114 std::string BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration);
122 void Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
128 std::vector<std::map<uint16_t, ConfigToCheck> > EquallySpacedCcs ();
129
132 std::vector<ConfigToCheck> m_configToCheck;
135 std::vector<std::map<uint16_t, ConfigToCheck> > m_configToCheckContainer;
136};
137
138std::string
139CarrierAggregationConfigTestCase::BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration)
140{
141 std::ostringstream oss;
142 oss << " nodes " << numberOfNodes << " carriers " << numberOfComponentCarriers
143 << " configurations " << configToCheck.size ()
144 << " duration " << simulationDuration;
145 return oss.str ();
146}
147
148std::vector<std::map<uint16_t, ConfigToCheck> >
150{
151 std::vector<std::map<uint16_t, ConfigToCheck> > configToCheckContainer;
152
153 for (auto &it: m_configToCheck)
154 {
155 std::map<uint16_t, ConfigToCheck> ccmap;
156 uint32_t ulEarfcn = it.m_ulEarfcn;
157 uint32_t dlEarfcn = it.m_dlEarfcn;
158 uint32_t maxBandwidthRb = std::max<uint32_t> (it.m_ulBandwidth, it.m_dlBandwidth);
159
160 // Convert bandwidth from RBs to kHz
161 uint32_t maxBandwidthKhz = LteSpectrumValueHelper::GetChannelBandwidth (maxBandwidthRb) / 1e3;
162
163 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
164 {
165 // Make sure we stay within the same band.
166 if (LteSpectrumValueHelper::GetUplinkCarrierBand (ulEarfcn) !=
167 LteSpectrumValueHelper::GetUplinkCarrierBand (it.m_ulEarfcn)
168 || LteSpectrumValueHelper::GetDownlinkCarrierBand (dlEarfcn) !=
169 LteSpectrumValueHelper::GetDownlinkCarrierBand (it.m_dlEarfcn))
170 {
171 NS_FATAL_ERROR ("Band is not wide enough to allocate " << m_numberOfComponentCarriers << " CCs");
172 }
173
174 ConfigToCheck cc;
175 cc.m_dlBandwidth = it.m_dlBandwidth;
176 cc.m_dlEarfcn = dlEarfcn;
177 cc.m_ulBandwidth = it.m_ulBandwidth;
178 cc.m_ulEarfcn = ulEarfcn;
179
180 ccmap.insert (std::pair<uint16_t, ConfigToCheck> (i, cc));
181
182 NS_LOG_INFO ("UL BW: " << it.m_ulBandwidth <<
183 ", DL BW: " << it.m_dlBandwidth <<
184 ", UL Earfcn: " << ulEarfcn <<
185 ", DL Earfcn: " << dlEarfcn);
186
187 // The spacing between the center frequencies of two contiguous CCs should be multiple of 300 kHz.
188 // Round spacing up to 300 kHz.
189 uint32_t frequencyShift = 300 * (1 + (maxBandwidthKhz - 1) / 300);
190
191 // Unit of EARFCN corresponds to 100kHz.
192 uint32_t earfcnShift = frequencyShift / 100;
193 ulEarfcn += earfcnShift;
194 dlEarfcn += earfcnShift;
195 }
196
197 configToCheckContainer.push_back (ccmap);
198 }
199
200 return configToCheckContainer;
201}
202
203void
204CarrierAggregationConfigTestCase::Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList)
205{
206 NS_LOG_INFO ("Secondary carriers configured");
207
208 uint16_t cellId = ueRrc->GetCellId ();
209 NS_LOG_INFO ("cellId " << cellId);
210 NS_LOG_INFO ("m_configToCheckContainer size " << m_configToCheckContainer.size ());
211
213
214 std::map<uint16_t, ConfigToCheck> configToCheckMap;
215
216 if (cellId == 1)
217 {
218 configToCheckMap = m_configToCheckContainer[cellId-1];
219 }
220 else
221 {
222 uint16_t n1 = std::max(cellId, m_numberOfComponentCarriers);
223 uint16_t n2 = std::min(cellId, m_numberOfComponentCarriers);
224 configToCheckMap = m_configToCheckContainer[n1-n2];
225 }
226
227 NS_LOG_INFO ("PCarrier - UL BW: " << static_cast<uint16_t> (ueRrc->GetUlBandwidth ()) <<
228 ", DL BW: " << static_cast<uint16_t> (ueRrc->GetDlBandwidth ()) <<
229 ", UL Earfcn: " << ueRrc->GetUlEarfcn () <<
230 ", DL Earfcn: " << ueRrc->GetDlEarfcn ());
231
232 for (auto scell: sCellToAddModList)
233 {
234 NS_LOG_INFO ("SCarrier - UL BW: " << static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth)<<
235 ", DL BW: " << static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth) <<
236 ", UL Earfcn: " << scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq <<
237 ", DL Earfcn: " << scell.cellIdentification.dlCarrierFreq);
238 }
239
240 ConfigToCheck pCConfig = configToCheckMap[0]; // Primary Carrier
241 ConfigToCheck sCConfig; // Secondary Carriers
242
243 NS_TEST_ASSERT_MSG_EQ (pCConfig.m_dlBandwidth, static_cast<uint16_t> (ueRrc->GetDlBandwidth ()),
244 "Primary Carrier DL bandwidth configuration failed");
245 NS_TEST_ASSERT_MSG_EQ (pCConfig.m_ulBandwidth, static_cast<uint16_t> (ueRrc->GetUlBandwidth ()),
246 "Primary Carrier UL bandwidth configuration failed");
247 NS_TEST_ASSERT_MSG_EQ (pCConfig.m_dlEarfcn, ueRrc->GetDlEarfcn (),
248 "Primary Carrier DL EARFCN configuration failed");
249 NS_TEST_ASSERT_MSG_EQ (pCConfig.m_ulEarfcn, ueRrc->GetUlEarfcn (),
250 "Primary Carrier UL EARFCN configuration failed");
251
252 uint32_t ConfigToCheckMapIndex = 1;
253
254 for (auto scell: sCellToAddModList)
255 {
256 sCConfig = configToCheckMap[ConfigToCheckMapIndex];
257
258 NS_TEST_ASSERT_MSG_EQ (sCConfig.m_dlBandwidth, static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth),
259 "Secondary Carrier DL bandwidth configuration failed");
260 NS_TEST_ASSERT_MSG_EQ (sCConfig.m_ulBandwidth, static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth),
261 "Secondary Carrier UL bandwidth configuration failed");
262 NS_TEST_ASSERT_MSG_EQ (sCConfig.m_dlEarfcn, scell.cellIdentification.dlCarrierFreq,
263 "Secondary Carrier DL EARFCN configuration failed");
264 NS_TEST_ASSERT_MSG_EQ (sCConfig.m_ulEarfcn, scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq,
265 "Secondary Carrier UL EARFCN configuration failed");
266 ConfigToCheckMapIndex++;
267 }
268}
269
270void
272{
273 Config::SetDefault ("ns3::LteHelper::UseCa", BooleanValue (true));
274 Config::SetDefault ("ns3::LteHelper::NumberOfComponentCarriers", UintegerValue (m_numberOfComponentCarriers));
275 Config::SetDefault ("ns3::LteHelper::EnbComponentCarrierManager", StringValue ("ns3::RrComponentCarrierManager"));
276
277 int64_t stream = 1;
278
279 Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
280
281 // Create Nodes: eNodeB and UE
282 NodeContainer enbNodes;
283 NodeContainer ueNodes;
284 enbNodes.Create (m_numberOfNodes);
285 ueNodes.Create (m_numberOfNodes);
286
287 uint32_t totalNumberOfNodes = enbNodes.GetN () + ueNodes.GetN ();
288
289 // Install Mobility Model
290 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
291 for (uint16_t i = 0; i < totalNumberOfNodes; i++)
292 {
293 positionAlloc->Add (Vector (2 * i, 0, 0));
294 }
295
297 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
298 mobility.SetPositionAllocator (positionAlloc);
299
300 for (uint32_t n = 0; n < m_numberOfNodes; ++n)
301 {
302 mobility.Install (enbNodes.Get (n));
303 mobility.Install (ueNodes.Get (n));
304 }
305
306 ConfigToCheck configuration;
307 NetDeviceContainer enbDevs;
308 NetDeviceContainer ueDevs;
309
310 // Set bandwidth, EARFCN and install nodes (eNB and UE)
311 for (uint32_t i = 0; i < m_configToCheck.size (); ++i)
312 {
313 configuration = m_configToCheck[i];
314
315 lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (configuration.m_dlBandwidth));
316 lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (configuration.m_ulBandwidth));
317 lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (configuration.m_dlEarfcn));
318 lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (configuration.m_ulEarfcn));
319 lteHelper->SetUeDeviceAttribute ("DlEarfcn", UintegerValue (configuration.m_dlEarfcn));
320 enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (i)));
321 lteHelper->AssignStreams (enbDevs, stream);
322 ueDevs.Add (lteHelper->InstallUeDevice (ueNodes.Get (i)));
323 lteHelper->AssignStreams (ueDevs, stream);
324 }
325
326 // Calculate the DlBandwidth, UlBandwidth, DlEarfcn and UlEarfcn to which the values from UE RRC would be compared
328
329 // Attach a UE to an eNB
330 for(uint32_t k = 0; k < m_numberOfNodes; ++k)
331 {
332 lteHelper->Attach (ueDevs.Get (k), enbDevs.Get (k));
333 }
334
335 // Activate a data radio bearer
336 enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
337 EpsBearer bearer (q);
338 lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
339
340 Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/SCarrierConfigured",
342
343 Simulator::Stop (m_simulationDuration);
345
346 NS_TEST_ASSERT_MSG_EQ (m_connectionCounter, ueNodes.GetN (), "Not all the UEs were connected");
347
348 Simulator::Destroy ();
349}
350
358{
359public:
361};
362
364 : TestSuite ("lte-carrier-aggregation-configuration", SYSTEM)
365{
366 std::vector<ConfigToCheck> configToCheck;
367
368 // Test1 with 1 eNB and 1 UE.
369 // We put a configuration different than the default configuration done in LteHelper for the sake of
370 // creating PHY and MAC instances equal to the number of component carriers.
371
372 ConfigToCheck configToCheckTest1;
373 configToCheckTest1.m_dlBandwidth = 50;
374 configToCheckTest1.m_ulBandwidth = 50;
375 configToCheckTest1.m_dlEarfcn = 300;
376 configToCheckTest1.m_ulEarfcn = 300+18000;
377 configToCheck.push_back (configToCheckTest1);
378 uint32_t numberOfNodes = 1;
379 uint16_t numberOfComponentCarriers = 2;
380 Time simulationDuration = Seconds (1);
381
382 AddTestCase (new CarrierAggregationConfigTestCase (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration), TestCase::QUICK);
383
384// configToCheck.erase(configToCheck.begin(), configToCheck.end());
385 configToCheck.clear ();
386
387 // Test2 with 2 eNBs and 2 UEs.
388 // We decrease the bandwidth so not to exceed maximum band bandwidth of 20 MHz
389
390 configToCheckTest1.m_dlBandwidth = 25;
391 configToCheckTest1.m_ulBandwidth = 25;
392 configToCheckTest1.m_dlEarfcn = 300;
393 configToCheckTest1.m_ulEarfcn = 300+18000;
394 configToCheck.push_back (configToCheckTest1);
395
396 ConfigToCheck configToCheckTest2;
397 configToCheckTest2.m_dlBandwidth = 25;
398 configToCheckTest2.m_ulBandwidth = 25;
399 configToCheckTest2.m_dlEarfcn = 502;
400 configToCheckTest2.m_ulEarfcn = 502+18000;
401 configToCheck.push_back (configToCheckTest2);
402 numberOfNodes = 2;
403 simulationDuration = Seconds (2);
404
405 AddTestCase (new CarrierAggregationConfigTestCase (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration), TestCase::QUICK);
406}
407
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
void Run(ObjectFactory &factory, uint32_t pop, uint32_t total, uint32_t runs, Ptr< RandomVariableStream > eventStream, bool calRev)
Perform the runs for a single scheduler type.
Carrier aggregation configuration test case.
CarrierAggregationConfigTestCase(uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector< ConfigToCheck > configToCheck, Time simulationDuration)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
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:92
Qci
QoS Class Indicator.
Definition: eps-bearer.h:107
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:474
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:959
void SetEnbDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the eNodeB devices (LteEnbNetDevice) to be created.
Definition: lte-helper.cc:400
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1313
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:489
void SetUeDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the UE devices (LteUeNetDevice) to be created.
Definition: lte-helper.cc:422
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1443
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(void) 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:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
Hold an unsigned integer type.
Definition: uinteger.h:44
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#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:141
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
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:661
mobility
Definition: third.py:98
This test suite verifies following two things:
uint16_t m_ulBandwidth
Uplink bandwidth.
uint16_t m_dlBandwidth
Downlink bandwidth.