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
38 /**
39 * This test suite verifies following two things:
40 *
41 * 1. When CA is enabled and UE carriers configuration is different than the default one,
42 * we check that the UE is configured properly once it receives
43 * RRC Connection Reconfiguration message from eNB.
44 *
45 * 2. A user can configure 2 or more eNBs and UEs with different configuration parameters,
46 * i.e, each eNB and UE can have different EARFCN and Bandwidths and a UE connects to
47 * an eNB with similar DL EARFCN.
48 * Here we check it with CA enabled but the end results will be the same if CA is not
49 * enabled and we have more than one eNBs and UEs with different configurations.
50 *
51 * Since we do not need EPC to test the configuration, this test only simulates
52 * the LTE radio access with RLC SM.
53 *
54 * Test 1 tests that the UE is configured properly after receiving RRC Connection
55 * Reconfiguration message from the eNB, which will overwrite UE default configuration
56 * done in LteHelper for the sake of creating PHY and MAC instances equal to the number
57 * of component carriers.
58 *
59 * Test 2 tests that in a simulation scenario every eNB or UE can be configured with
60 * different EARFCNs and Bandwidths. This will check that the eNBs and UEs configuration
61 * is not static, as reported in BUG 2840.
62 */
63
64 /// ConfigToCheck structure
65 struct ConfigToCheck
66 {
67 uint16_t m_dlBandwidth; ///< Downlink bandwidth
68 uint16_t m_ulBandwidth; ///< Uplink bandwidth
69 uint32_t m_dlEarfcn; ///< Downlink EARFCN
70 uint32_t m_ulEarfcn; ///< Uplink EARFCN
71 };
72
73 NS_LOG_COMPONENT_DEFINE ("TestCarrierAggregationConfig");
74
75 /**
76 * \ingroup lte-test
77 * \ingroup tests
78 *
79 * \brief Carrier aggregation configuration test case.
80 */
81 class CarrierAggregationConfigTestCase : public TestCase
82 {
83 public:
84 /**
85 * Constructor
86 *
87 * \param numberOfNodes Total Number of eNBs and UEs
88 * \param numberOfComponentCarriers Total number of component carriers
89 * \param configToCheck Vector containing all the configurations to check
90 * \param simulationDuration Duration of the simulation
91 */
CarrierAggregationConfigTestCase(uint32_t numberOfNodes,uint16_t numberOfComponentCarriers,std::vector<ConfigToCheck> configToCheck,Time simulationDuration)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
105 /**
106 * Build name string function
107 *
108 * \param numberOfNodes Total Number of eNBs and UEs
109 * \param numberOfComponentCarriers Total number of component carriers
110 * \param configToCheck Vector containing all the configurations to check
111 * \param simulationDuration Duration of the simulation
112 * \returns the name string
113 */
114 std::string BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration);
115 /**
116 * Evaluate function
117 *
118 * \param context The context
119 * \param ueRrc Pointer to the UE RRC
120 * \param sCellToAddModList List of the configuration parameters for secondary cell
121 */
122 void Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
123 /**
124 * Equally spaced component carriers function
125 *
126 * \return Vector of maps containing the per component carrier configuration
127 */
128 std::vector<std::map<uint16_t, ConfigToCheck> > EquallySpacedCcs ();
129
130 uint32_t m_numberOfNodes; ///< Numer of nodes
131 uint16_t m_numberOfComponentCarriers; ///< Number of component carriers
132 std::vector<ConfigToCheck> m_configToCheck; ///< Vector containing all the configurations to check
133 uint32_t m_connectionCounter; ///< Connection counter
134 Time m_simulationDuration; ///< Simulation duration
135 std::vector<std::map<uint16_t, ConfigToCheck> > m_configToCheckContainer; ///< Vector of maps containing the per component carrier configuration
136 };
137
138 std::string
BuildNameString(uint32_t numberOfNodes,uint16_t numberOfComponentCarriers,std::vector<ConfigToCheck> configToCheck,Time simulationDuration)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> >
EquallySpacedCcs()149 CarrierAggregationConfigTestCase::EquallySpacedCcs ()
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
203 void
Evaluate(std::string context,Ptr<LteUeRrc> ueRrc,std::list<LteRrcSap::SCellToAddMod> sCellToAddModList)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
DoRun()271 CarrierAggregationConfigTestCase::DoRun ()
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
296 MobilityHelper mobility;
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
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",
341 MakeCallback (&CarrierAggregationConfigTestCase::Evaluate, this));
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
348 Simulator::Destroy ();
349 }
350
351 /**
352 * \ingroup lte-test
353 * \ingroup tests
354 *
355 * \brief Carrier aggregation configuration test suite.
356 */
357 class CarrierAggregationConfigTestSuite : public TestSuite
358 {
359 public:
360 CarrierAggregationConfigTestSuite ();
361 };
362
CarrierAggregationConfigTestSuite()363 CarrierAggregationConfigTestSuite::CarrierAggregationConfigTestSuite ()
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
408 static CarrierAggregationConfigTestSuite g_carrierAggregationConfigTestSuite;
409