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 
36 using namespace ns3;
37 
66 {
67  uint16_t m_dlBandwidth;
68  uint16_t m_ulBandwidth;
69  uint32_t m_dlEarfcn;
70  uint32_t m_ulEarfcn;
71 };
72 
73 NS_LOG_COMPONENT_DEFINE ("TestCarrierAggregationConfig");
74 
82 {
83 public:
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  {
99  m_connectionCounter = 0.0;
100  }
101 
102 private:
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 
130  uint32_t m_numberOfNodes;
132  std::vector<ConfigToCheck> m_configToCheck;
135  std::vector<std::map<uint16_t, ConfigToCheck> > m_configToCheckContainer;
136 };
137 
138 std::string
139 CarrierAggregationConfigTestCase::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 
148 std::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.
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 
203 void
204 CarrierAggregationConfigTestCase::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 
212  ++m_connectionCounter;
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 
270 void
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
327  m_configToCheckContainer = EquallySpacedCcs ();
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
337  EpsBearer bearer (q);
338  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
339 
340  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/SCarrierConfigured",
342 
343  Simulator::Stop (m_simulationDuration);
344  Simulator::Run ();
345 
346  NS_TEST_ASSERT_MSG_EQ (m_connectionCounter, ueNodes.GetN (), "Not all the UEs were connected");
347 
349 }
350 
358 {
359 public:
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
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
@ GBR_CONV_VOICE
GBR Conversational Voice.
Definition: eps-bearer.h:108
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
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(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:74
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
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:103
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:1244
static CarrierAggregationConfigTestSuite g_carrierAggregationConfigTestSuite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
mobility
Definition: third.py:108
This test suite verifies following two things:
uint16_t m_ulBandwidth
Uplink bandwidth.
uint16_t m_dlBandwidth
Downlink bandwidth.