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 
35 using namespace ns3;
36 
65 {
66  uint16_t m_dlBandwidth;
67  uint16_t m_ulBandwidth;
68  uint32_t m_dlEarfcn;
69  uint32_t m_ulEarfcn;
70 };
71 
72 NS_LOG_COMPONENT_DEFINE("TestCarrierAggregationConfig");
73 
80 {
81  public:
90  CarrierAggregationConfigTestCase(uint32_t numberOfNodes,
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  {
103  m_connectionCounter = 0.0;
104  }
105 
106  private:
107  void DoRun() override;
108 
118  std::string BuildNameString(uint32_t numberOfNodes,
119  uint16_t numberOfComponentCarriers,
120  std::vector<ConfigToCheck> configToCheck,
121  Time simulationDuration);
129  void Evaluate(std::string context,
130  Ptr<LteUeRrc> ueRrc,
131  std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
137  std::vector<std::map<uint16_t, ConfigToCheck>> EquallySpacedCcs();
138 
139  uint32_t m_numberOfNodes;
141  std::vector<ConfigToCheck>
145  std::vector<std::map<uint16_t, ConfigToCheck>>
148 };
149 
150 std::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 
162 std::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 =
176  LteSpectrumValueHelper::GetChannelBandwidth(maxBandwidthRb) / 1e3;
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 
217 void
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 
228  ++m_connectionCounter;
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 
304 void
306 {
307  Config::SetDefault("ns3::LteHelper::UseCa", BooleanValue(true));
308  Config::SetDefault("ns3::LteHelper::NumberOfComponentCarriers",
309  UintegerValue(m_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 
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
364  m_configToCheckContainer = EquallySpacedCcs();
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 
380  Simulator::Stop(m_simulationDuration);
381  Simulator::Run();
382 
383  NS_TEST_ASSERT_MSG_EQ(m_connectionCounter, ueNodes.GetN(), "Not all the UEs were connected");
384 
386 }
387 
394 {
395  public:
397 };
398 
400  : TestSuite("lte-carrier-aggregation-configuration", 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::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::QUICK);
450 }
451 
#define min(a, b)
Definition: 80211b.c:41
#define max(a, b)
Definition: 80211b.c:42
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.
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
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:485
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:1039
void SetEnbDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the eNodeB devices (LteEnbNetDevice) to be created.
Definition: lte-helper.cc:412
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1436
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:500
void SetUeDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the UE devices (LteUeNetDevice) to be created.
Definition: lte-helper.cc:433
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1567
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:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
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:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#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:144
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
mobility
Definition: third.py:105
This test suite verifies following two things:
uint16_t m_ulBandwidth
Uplink bandwidth.
uint16_t m_dlBandwidth
Downlink bandwidth.