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 
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 
75 {
76 public:
84  CarrierAggregationConfigTestCase (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration)
85  : TestCase (BuildNameString (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration)),
86  m_numberOfNodes(numberOfNodes),
87  m_numberOfComponentCarriers(numberOfComponentCarriers),
88  m_configToCheck(configToCheck),
89  m_simulationDuration (simulationDuration)
90  {
91  m_connectionCounter = 0.0;
92  }
93 
94 private:
95  virtual void DoRun (void);
96 
97  std::string BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration);
98  void Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
99  std::vector<std::map<uint16_t, ConfigToCheck> > EquallySpacedCcs ();
100 
101  uint32_t m_numberOfNodes;
103  std::vector<ConfigToCheck> m_configToCheck;
106  std::vector<std::map<uint16_t, ConfigToCheck> > m_configToCheckContainer;
107 };
108 
109 std::string
110 CarrierAggregationConfigTestCase::BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration)
111 {
112  std::ostringstream oss;
113  oss << " nodes " << numberOfNodes << " carriers " << numberOfComponentCarriers
114  << " configurations " << configToCheck.size ()
115  << " duration " << simulationDuration;
116  return oss.str ();
117 }
118 
119 std::vector<std::map<uint16_t, ConfigToCheck> >
121 {
122  std::vector<std::map<uint16_t, ConfigToCheck> > configToCheckContainer;
123 
124  for (auto &it: m_configToCheck)
125  {
126  std::map<uint16_t, ConfigToCheck> ccmap;
127  uint32_t ulEarfcn = it.m_ulEarfcn;
128  uint32_t dlEarfcn = it.m_dlEarfcn;
129  uint32_t maxBandwidthRb = std::max<uint32_t> (it.m_ulBandwidth, it.m_dlBandwidth);
130 
131  // Convert bandwidth from RBs to kHz
132  uint32_t maxBandwidthKhz = LteSpectrumValueHelper::GetChannelBandwidth (maxBandwidthRb) / 1e3;
133 
134  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
135  {
136  // Make sure we stay within the same band.
141  {
142  NS_FATAL_ERROR ("Band is not wide enough to allocate " << m_numberOfComponentCarriers << " CCs");
143  }
144 
145  ConfigToCheck cc;
146  cc.m_dlBandwidth = it.m_dlBandwidth;
147  cc.m_dlEarfcn = dlEarfcn;
148  cc.m_ulBandwidth = it.m_ulBandwidth;
149  cc.m_ulEarfcn = ulEarfcn;
150 
151  ccmap.insert (std::pair<uint16_t, ConfigToCheck> (i, cc));
152 
153  NS_LOG_INFO ("UL BW: " << it.m_ulBandwidth <<
154  ", DL BW: " << it.m_dlBandwidth <<
155  ", UL Earfcn: " << ulEarfcn <<
156  ", DL Earfcn: " << dlEarfcn);
157 
158  // The spacing between the center frequencies of two contiguous CCs should be multiple of 300 kHz.
159  // Round spacing up to 300 kHz.
160  uint32_t frequencyShift = 300 * (1 + (maxBandwidthKhz - 1) / 300);
161 
162  // Unit of EARFCN corresponds to 100kHz.
163  uint32_t earfcnShift = frequencyShift / 100;
164  ulEarfcn += earfcnShift;
165  dlEarfcn += earfcnShift;
166  }
167 
168  configToCheckContainer.push_back (ccmap);
169  }
170 
171  return configToCheckContainer;
172 }
173 
174 void
175 CarrierAggregationConfigTestCase::Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList)
176 {
177  NS_LOG_INFO ("Secondary carriers configured");
178 
179  uint16_t cellId = ueRrc->GetCellId ();
180  NS_LOG_INFO ("cellId " << cellId);
181  NS_LOG_INFO ("m_configToCheckContainer size " << m_configToCheckContainer.size ());
182 
183  ++m_connectionCounter;
184 
185  std::map<uint16_t, ConfigToCheck> configToCheckMap;
186 
187  if (cellId == 1)
188  {
189  configToCheckMap = m_configToCheckContainer[cellId-1];
190  }
191  else
192  {
193  uint16_t n1 = std::max(cellId, m_numberOfComponentCarriers);
194  uint16_t n2 = std::min(cellId, m_numberOfComponentCarriers);
195  configToCheckMap = m_configToCheckContainer[n1-n2];
196  }
197 
198  NS_LOG_INFO ("PCarrier - UL BW: " << static_cast<uint16_t> (ueRrc->GetUlBandwidth ()) <<
199  ", DL BW: " << static_cast<uint16_t> (ueRrc->GetDlBandwidth ()) <<
200  ", UL Earfcn: " << ueRrc->GetUlEarfcn () <<
201  ", DL Earfcn: " << ueRrc->GetDlEarfcn ());
202 
203  for (auto scell: sCellToAddModList)
204  {
205  NS_LOG_INFO ("SCarrier - UL BW: " << static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth)<<
206  ", DL BW: " << static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth) <<
207  ", UL Earfcn: " << scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq <<
208  ", DL Earfcn: " << scell.cellIdentification.dlCarrierFreq);
209  }
210 
211  ConfigToCheck pCConfig = configToCheckMap[0]; // Primary Carrier
212  ConfigToCheck sCConfig; // Secondary Carriers
213 
214  NS_TEST_ASSERT_MSG_EQ (pCConfig.m_dlBandwidth, static_cast<uint16_t> (ueRrc->GetDlBandwidth ()),
215  "Primary Carrier DL bandwidth configuration failed");
216  NS_TEST_ASSERT_MSG_EQ (pCConfig.m_ulBandwidth, static_cast<uint16_t> (ueRrc->GetUlBandwidth ()),
217  "Primary Carrier UL bandwidth configuration failed");
218  NS_TEST_ASSERT_MSG_EQ (pCConfig.m_dlEarfcn, ueRrc->GetDlEarfcn (),
219  "Primary Carrier DL EARFCN configuration failed");
220  NS_TEST_ASSERT_MSG_EQ (pCConfig.m_ulEarfcn, ueRrc->GetUlEarfcn (),
221  "Primary Carrier UL EARFCN configuration failed");
222 
223  uint32_t ConfigToCheckMapIndex = 1;
224 
225  for (auto scell: sCellToAddModList)
226  {
227  sCConfig = configToCheckMap[ConfigToCheckMapIndex];
228 
229  NS_TEST_ASSERT_MSG_EQ (sCConfig.m_dlBandwidth, static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth),
230  "Secondary Carrier DL bandwidth configuration failed");
231  NS_TEST_ASSERT_MSG_EQ (sCConfig.m_ulBandwidth, static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth),
232  "Secondary Carrier UL bandwidth configuration failed");
233  NS_TEST_ASSERT_MSG_EQ (sCConfig.m_dlEarfcn, scell.cellIdentification.dlCarrierFreq,
234  "Secondary Carrier DL EARFCN configuration failed");
235  NS_TEST_ASSERT_MSG_EQ (sCConfig.m_ulEarfcn, scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq,
236  "Secondary Carrier UL EARFCN configuration failed");
237  ConfigToCheckMapIndex++;
238  }
239 }
240 
241 void
243 {
244  Config::SetDefault ("ns3::LteHelper::UseCa", BooleanValue (true));
245  Config::SetDefault ("ns3::LteHelper::NumberOfComponentCarriers", UintegerValue (m_numberOfComponentCarriers));
246  Config::SetDefault ("ns3::LteHelper::EnbComponentCarrierManager", StringValue ("ns3::RrComponentCarrierManager"));
247 
248  int64_t stream = 1;
249 
250  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
251 
252  // Create Nodes: eNodeB and UE
253  NodeContainer enbNodes;
254  NodeContainer ueNodes;
255  enbNodes.Create (m_numberOfNodes);
256  ueNodes.Create (m_numberOfNodes);
257 
258  uint32_t totalNumberOfNodes = enbNodes.GetN () + ueNodes.GetN ();
259 
260  // Install Mobility Model
261  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
262  for (uint16_t i = 0; i < totalNumberOfNodes; i++)
263  {
264  positionAlloc->Add (Vector (2 * i, 0, 0));
265  }
266 
268  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
269  mobility.SetPositionAllocator (positionAlloc);
270 
271  for (uint32_t n = 0; n < m_numberOfNodes; ++n)
272  {
273  mobility.Install (enbNodes.Get (n));
274  mobility.Install (ueNodes.Get (n));
275  }
276 
277  ConfigToCheck configuration;
278  NetDeviceContainer enbDevs;
279  NetDeviceContainer ueDevs;
280 
281  // Set bandwidth, EARFCN and install nodes (eNB and UE)
282  for (uint32_t i = 0; i < m_configToCheck.size (); ++i)
283  {
284  configuration = m_configToCheck[i];
285 
286  lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (configuration.m_dlBandwidth));
287  lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (configuration.m_ulBandwidth));
288  lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (configuration.m_dlEarfcn));
289  lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (configuration.m_ulEarfcn));
290  lteHelper->SetUeDeviceAttribute ("DlEarfcn", UintegerValue (configuration.m_dlEarfcn));
291  enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (i)));
292  lteHelper->AssignStreams (enbDevs, stream);
293  ueDevs.Add (lteHelper->InstallUeDevice (ueNodes.Get (i)));
294  lteHelper->AssignStreams (ueDevs, stream);
295  }
296 
297  // Calculate the DlBandwidth, UlBandwidth, DlEarfcn and UlEarfcn to which the values from UE RRC would be compared
298  m_configToCheckContainer = EquallySpacedCcs ();
299 
300  // Attach a UE to an eNB
301  for(uint32_t k = 0; k < m_numberOfNodes; ++k)
302  {
303  lteHelper->Attach (ueDevs.Get (k), enbDevs.Get (k));
304  }
305 
306  // Activate a data radio bearer
308  EpsBearer bearer (q);
309  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
310 
311  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/SCarrierConfigured",
313 
314  Simulator::Stop (m_simulationDuration);
315  Simulator::Run ();
316 
317  NS_TEST_ASSERT_MSG_EQ (m_connectionCounter, ueNodes.GetN (), "Not all the UEs were connected");
318 
320 }
321 
322 
324 {
325 public:
327 };
328 
330  : TestSuite ("lte-carrier-aggregation-configuration", SYSTEM)
331 {
332  std::vector<ConfigToCheck> configToCheck;
333 
334  // Test1 with 1 eNB and 1 UE.
335  // We put a configuration different than the default configuration done in LteHelper for the sake of
336  // creating PHY and MAC instances equal to the number of component carriers.
337 
338  ConfigToCheck configToCheckTest1;
339  configToCheckTest1.m_dlBandwidth = 50;
340  configToCheckTest1.m_ulBandwidth = 50;
341  configToCheckTest1.m_dlEarfcn = 300;
342  configToCheckTest1.m_ulEarfcn = 300+18000;
343  configToCheck.push_back (configToCheckTest1);
344  uint32_t numberOfNodes = 1;
345  uint16_t numberOfComponentCarriers = 2;
346  Time simulationDuration = Seconds (1);
347 
348  AddTestCase (new CarrierAggregationConfigTestCase (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration), TestCase::QUICK);
349 
350 // configToCheck.erase(configToCheck.begin(), configToCheck.end());
351  configToCheck.clear ();
352 
353  // Test2 with 2 eNBs and 2 UEs.
354  // We decrease the bandwidth so not to exceed maximum band bandwidth of 20 MHz
355 
356  configToCheckTest1.m_dlBandwidth = 25;
357  configToCheckTest1.m_ulBandwidth = 25;
358  configToCheckTest1.m_dlEarfcn = 300;
359  configToCheckTest1.m_ulEarfcn = 300+18000;
360  configToCheck.push_back (configToCheckTest1);
361 
362  ConfigToCheck configToCheckTest2;
363  configToCheckTest2.m_dlBandwidth = 25;
364  configToCheckTest2.m_ulBandwidth = 25;
365  configToCheckTest2.m_dlEarfcn = 502;
366  configToCheckTest2.m_ulEarfcn = 502+18000;
367  configToCheck.push_back (configToCheckTest2);
368  numberOfNodes = 2;
369  simulationDuration = Seconds (2);
370 
371  AddTestCase (new CarrierAggregationConfigTestCase (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration), TestCase::QUICK);
372 }
373 
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:36
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:474
This test suite verifies following two things:
Hold variables of type string.
Definition: string.h:41
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
#define min(a, b)
Definition: 80211b.c:44
A suite of tests to run.
Definition: test.h:1342
std::vector< std::map< uint16_t, ConfigToCheck > > EquallySpacedCcs()
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
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:957
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
void SetUeDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the UE devices (LteUeNetDevice) to be created.
Definition: lte-helper.cc:422
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:277
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
encapsulates test code
Definition: test.h:1155
static CarrierAggregationConfigTestSuite g_carrierAggregationConfigTestSuite
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1439
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1310
std::vector< std::map< uint16_t, ConfigToCheck > > m_configToCheckContainer
CarrierAggregationConfigTestCase(uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector< ConfigToCheck > configToCheck, Time simulationDuration)
Constructor.
uint32_t GetN(void) const
Get the number of Ptr stored in this container.
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:71
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
tuple mobility
Definition: third.py:101
#define max(a, b)
Definition: 80211b.c:45
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Hold an unsigned integer type.
Definition: uinteger.h:44
#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:168
holds a vector of ns3::NetDevice pointers
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:421
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:843
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
static uint16_t GetUplinkCarrierBand(uint32_t nDl)
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.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
static double GetChannelBandwidth(uint8_t txBandwidthConf)
uint32_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:441
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:428
void Evaluate(std::string context, Ptr< LteUeRrc > ueRrc, std::list< LteRrcSap::SCellToAddMod > sCellToAddModList)
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:489
Helper class used to assign positions and mobility models to nodes.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:413
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
void Add(Vector v)
Add a position to the list of positions.
std::string BuildNameString(uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector< ConfigToCheck > configToCheck, Time simulationDuration)
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
uint32_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:435
Qci
QoS Class Indicator.
Definition: eps-bearer.h:77
void SetEnbDeviceAttribute(std::string n, const AttributeValue &v)
Set an attribute for the eNodeB devices (LteEnbNetDevice) to be created.
Definition: lte-helper.cc:400