1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
19 * Budiarto Herman <budiarto.herman@magister.fi>
20 */
21
22
23 #include <ns3/core-module.h>
24 #include <ns3/network-module.h>
25 #include <ns3/mobility-module.h>
26 #include <ns3/lte-module.h>
27 #include <cmath>
28
29 using namespace ns3;
30
31 NS_LOG_COMPONENT_DEFINE ("LteRrcTest");
32
33 /**
34 * \ingroup lte-test
35 * \ingroup tests
36 *
37 * \brief Test rrc connection establishment.
38 */
39 class LteRrcConnectionEstablishmentTestCase : public TestCase
40 {
41 public:
42 /**
43 *
44 *
45 * \param nUes number of UEs in the test
46 * \param nBearers number of bearers to be setup in each connection
47 * \param tConnBase connection time base value for all UEs in ms
48 * \param tConnIncrPerUe additional connection time increment for each UE index (0...nUes-1) in ms
49 * \param delayDiscStart expected duration to perform connection establishment in ms
50 * \param errorExpected if true, test case will wait a bit longer to accommodate for transmission error
51 * \param useIdealRrc If set to false, real RRC protocol model will be used
52 * \param admitRrcConnectionRequest If set to false, eNb will not allow UE connections
53 * \param description additional description of the test case
54 */
55 LteRrcConnectionEstablishmentTestCase (uint32_t nUes,
56 uint32_t nBearers,
57 uint32_t tConnBase,
58 uint32_t tConnIncrPerUe,
59 uint32_t delayDiscStart,
60 bool errorExpected,
61 bool useIdealRrc,
62 bool admitRrcConnectionRequest,
63 std::string description = "");
64
65 protected:
66
67 virtual void DoRun (void);
68 uint32_t m_nUes; ///< number of UEs in the test
69
70 /**
71 * Build name string function
72 *
73 * \param nUes number of UEs in the test
74 * \param nBearers number of bearers to be setup in each connection
75 * \param tConnBase connection time base value for all UEs in ms
76 * \param tConnIncrPerUe additional connection time increment for each UE index (0...nUes-1) in ms
77 * \param delayDiscStart expected duration to perform connection establishment in ms
78 * \param useIdealRrc If set to false, real RRC protocol model will be used
79 * \param admitRrcConnectionRequest If set to false, eNb will not allow UE connections
80 * \param description additional description of the test case
81 * \returns the name string
82 */
83 static std::string BuildNameString (uint32_t nUes,
84 uint32_t nBearers,
85 uint32_t tConnBase,
86 uint32_t tConnIncrPerUe,
87 uint32_t delayDiscStart,
88 bool useIdealRrc,
89 bool admitRrcConnectionRequest,
90 std::string description = "");
91 /**
92 * Connect function
93 * \param ueDevice the UE device
94 * \param enbDevice the ENB device
95 */
96 void Connect (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
97 /**
98 * Check connected function
99 * \param ueDevice the UE device
100 * \param enbDevice the ENB device
101 */
102 void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
103 /**
104 * Check not connected function
105 * \param ueDevice the UE device
106 * \param enbDevice the ENB device
107 */
108 void CheckNotConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
109 /**
110 * Connection established callback function
111 * \param context the context string
112 * \param imsi the IMSI
113 * \param cellId the cell ID
114 * \param rnti the RNTI
115 */
116 void ConnectionEstablishedCallback (std::string context, uint64_t imsi,
117 uint16_t cellId, uint16_t rnti);
118 /**
119 * Connection timeout callback function
120 * \param context the context string
121 * \param imsi the IMSI
122 * \param cellId the cell ID
123 * \param rnti the RNTI
124 * \param connEstFailCount the T300 timer expiration counter value
125 */
126 void ConnectionTimeoutCallback (std::string context, uint64_t imsi,
127 uint16_t cellId, uint16_t rnti,
128 uint8_t connEstFailCount);
129
130 uint32_t m_nBearers; ///< number of bearers to be setup in each connection
131 uint32_t m_tConnBase; ///< connection time base value for all UEs in ms
132 uint32_t m_tConnIncrPerUe; ///< additional connection time increment for each UE index (0...nUes-1) in ms
133 uint32_t m_delayConnEnd; ///< expected duration to perform connection establishment in ms
134 uint32_t m_delayDiscStart; ///< delay between connection completed and disconnection request in ms
135 uint32_t m_delayDiscEnd; ///< expected duration to complete disconnection in ms
136 bool m_useIdealRrc; ///< If set to false, real RRC protocol model will be used
137 bool m_admitRrcConnectionRequest; ///< If set to false, eNb will not allow UE connections
138 Ptr<LteHelper> m_lteHelper; ///< LTE helper
139
140 /// key: IMSI
141 std::map<uint64_t, bool> m_isConnectionEstablished;
142 };
143
144
145 std::string
BuildNameString(uint32_t nUes,uint32_t nBearers,uint32_t tConnBase,uint32_t tConnIncrPerUe,uint32_t delayDiscStart,bool useIdealRrc,bool admitRrcConnectionRequest,std::string description)146 LteRrcConnectionEstablishmentTestCase::BuildNameString (uint32_t nUes,
147 uint32_t nBearers,
148 uint32_t tConnBase,
149 uint32_t tConnIncrPerUe,
150 uint32_t delayDiscStart,
151 bool useIdealRrc,
152 bool admitRrcConnectionRequest,
153 std::string description)
154 {
155 std::ostringstream oss;
156 oss << "nUes=" << nUes
157 << ", nBearers=" << nBearers
158 << ", tConnBase=" << tConnBase
159 << ", tConnIncrPerUe=" << tConnIncrPerUe
160 << ", delayDiscStart=" << delayDiscStart;
161
162 if (useIdealRrc)
163 {
164 oss << ", ideal RRC";
165 }
166 else
167 {
168 oss << ", real RRC";
169 }
170
171 if (admitRrcConnectionRequest)
172 {
173 oss << ", admitRrcConnectionRequest = true";
174 }
175 else
176 {
177 oss << ", admitRrcConnectionRequest = false";
178 }
179
180 if (!description.empty ())
181 {
182 oss << ", " << description;
183 }
184
185 return oss.str ();
186 }
187
LteRrcConnectionEstablishmentTestCase(uint32_t nUes,uint32_t nBearers,uint32_t tConnBase,uint32_t tConnIncrPerUe,uint32_t delayDiscStart,bool errorExpected,bool useIdealRrc,bool admitRrcConnectionRequest,std::string description)188 LteRrcConnectionEstablishmentTestCase::LteRrcConnectionEstablishmentTestCase (
189 uint32_t nUes, uint32_t nBearers,
190 uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart,
191 bool errorExpected, bool useIdealRrc, bool admitRrcConnectionRequest,
192 std::string description)
193 : TestCase (BuildNameString (nUes, nBearers,
194 tConnBase, tConnIncrPerUe, delayDiscStart,
195 useIdealRrc, admitRrcConnectionRequest,
196 description)),
197 m_nUes (nUes),
198 m_nBearers (nBearers),
199 m_tConnBase (tConnBase),
200 m_tConnIncrPerUe (tConnIncrPerUe),
201
202 m_delayDiscStart (delayDiscStart),
203 m_delayDiscEnd (10),
204 m_useIdealRrc (useIdealRrc),
205 m_admitRrcConnectionRequest (admitRrcConnectionRequest)
206 {
207 NS_LOG_FUNCTION (this << GetName ());
208
209 // see the description of d^e in the LTE testing docs
210 double dsi = 90;
211 double nRaAttempts = 0;
212 if (nUes <= 20)
213 {
214 nRaAttempts += 5;
215 }
216 else
217 {
218 NS_ASSERT (nUes <= 50);
219 nRaAttempts += 10;
220 }
221
222 nRaAttempts += std::ceil (nUes / 4.0);
223 double dra = nRaAttempts * 7;
224 double dce = 10.0 + (2.0 * nUes) / 4.0;
225 if (errorExpected)
226 {
227 /*
228 * If transmission error happens, the UE has to repeat again from
229 * acquiring system information.
230 */
231 dce += dsi + dce;
232 }
233 double nCrs;
234 if (nUes <= 2)
235 {
236 nCrs = 0;
237 }
238 else if (nUes <= 5)
239 {
240 nCrs = 1;
241 }
242 else if (nUes <= 10)
243 {
244 nCrs = 2;
245 }
246 else if (nUes <= 20)
247 {
248 nCrs = 3;
249 }
250 else
251 {
252 nCrs = 4;
253 }
254 double dcr = (10.0 + (2.0 * nUes) / 4.0) * (m_nBearers + nCrs);
255
256 m_delayConnEnd = round (dsi + dra + dce + dcr);
257 NS_LOG_LOGIC (this << " " << GetName () << " dsi=" << dsi << " dra=" << dra << " dce=" << dce << " dcr=" << dcr << " m_delayConnEnd=" << m_delayConnEnd);
258 }
259
260 void
DoRun()261 LteRrcConnectionEstablishmentTestCase::DoRun ()
262 {
263 NS_LOG_FUNCTION (this << GetName ());
264 Config::Reset ();
265
266 if (m_nUes < 25)
267 {
268 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (40));
269 }
270 else if (m_nUes < 60)
271 {
272 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (80));
273 }
274 else if (m_nUes < 120)
275 {
276 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (160));
277 }
278 else
279 {
280 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (320));
281 }
282
283 // normal code
284 m_lteHelper = CreateObject<LteHelper> ();
285 m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc));
286
287 NodeContainer enbNodes;
288 NodeContainer ueNodes;
289
290
291 enbNodes.Create (1);
292 ueNodes.Create (m_nUes);
293
294 // the following positions all nodes at (0, 0, 0)
295 MobilityHelper mobility;
296 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
297 mobility.Install (enbNodes);
298 mobility.Install (ueNodes);
299
300 int64_t stream = 1;
301 NetDeviceContainer enbDevs;
302 enbDevs = m_lteHelper->InstallEnbDevice (enbNodes);
303 stream += m_lteHelper->AssignStreams (enbDevs, stream);
304
305 NetDeviceContainer ueDevs;
306 ueDevs = m_lteHelper->InstallUeDevice (ueNodes);
307 stream += m_lteHelper->AssignStreams (ueDevs, stream);
308
309 // custom code used for testing purposes
310 // instead of lteHelper->Attach () and lteHelper->ActivateXxx
311
312 // Set AdmitConnectionRequest attribute
313 for (NetDeviceContainer::Iterator it = enbDevs.Begin ();
314 it != enbDevs.End ();
315 ++it)
316 {
317 Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice> ()->GetRrc ();
318 enbRrc->SetAttribute ("AdmitRrcConnectionRequest",
319 BooleanValue (m_admitRrcConnectionRequest));
320 }
321
322
323 uint32_t i = 0;
324 uint32_t tmax = 0;
325 for (NetDeviceContainer::Iterator it = ueDevs.Begin (); it != ueDevs.End (); ++it)
326 {
327 Ptr<NetDevice> ueDevice = *it;
328 Ptr<NetDevice> enbDevice = enbDevs.Get (0);
329 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
330
331 uint32_t tc = m_tConnBase + m_tConnIncrPerUe * i; // time connection start
332 uint32_t tcc = tc + m_delayConnEnd; // time check connection completed;
333 uint32_t td = tcc + m_delayDiscStart; // time disconnect start
334 uint32_t tcd = td + m_delayDiscEnd; // time check disconnection completed
335 tmax = std::max (tmax, tcd);
336
337 // trick to resolve overloading
338 //void (LteHelper::* overloadedAttachFunctionPointer) (Ptr<NetDevice>, Ptr<NetDevice>) = &LteHelper::Attach;
339 //Simulator::Schedule (MilliSeconds (tc), overloadedAttachFunctionPointer, lteHelper, *it, enbDevice);
340 Simulator::Schedule (MilliSeconds (tc), &LteRrcConnectionEstablishmentTestCase::Connect, this, ueDevice, enbDevice);
341
342 Simulator::Schedule (MilliSeconds (tcc), &LteRrcConnectionEstablishmentTestCase::CheckConnected, this, *it, enbDevice);
343
344 // disconnection not supported yet
345
346 uint64_t imsi = ueLteDevice->GetImsi ();
347 m_isConnectionEstablished[imsi] = false;
348
349 ++i;
350 }
351
352 // Connect to trace sources in UEs
353 Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionEstablished",
354 MakeCallback (&LteRrcConnectionEstablishmentTestCase::ConnectionEstablishedCallback,
355 this));
356 Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionTimeout",
357 MakeCallback (&LteRrcConnectionEstablishmentTestCase::ConnectionTimeoutCallback,
358 this));
359
360 Simulator::Stop (MilliSeconds (tmax + 1));
361
362 Simulator::Run ();
363
364 Simulator::Destroy ();
365
366 }
367
368 void
Connect(Ptr<NetDevice> ueDevice,Ptr<NetDevice> enbDevice)369 LteRrcConnectionEstablishmentTestCase::Connect (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
370 {
371 NS_LOG_FUNCTION (this);
372 m_lteHelper->Attach (ueDevice, enbDevice);
373
374 for (uint32_t b = 0; b < m_nBearers; ++b)
375 {
376 enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
377 EpsBearer bearer (q);
378 m_lteHelper->ActivateDataRadioBearer (ueDevice, bearer);
379 }
380 }
381
382 void
CheckConnected(Ptr<NetDevice> ueDevice,Ptr<NetDevice> enbDevice)383 LteRrcConnectionEstablishmentTestCase::CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
384 {
385 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
386 Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
387 const uint64_t imsi = ueLteDevice->GetImsi ();
388 const uint16_t rnti = ueRrc->GetRnti ();
389 NS_LOG_FUNCTION (this << imsi << rnti);
390 NS_ASSERT_MSG (m_isConnectionEstablished.find (imsi) != m_isConnectionEstablished.end (),
391 "Invalid IMSI " << imsi);
392
393 if (!m_admitRrcConnectionRequest)
394 {
395 NS_TEST_ASSERT_MSG_EQ (m_isConnectionEstablished[imsi], false,
396 "Connection with RNTI " << rnti << " should have been rejected");
397 return;
398 }
399
400 /*
401 * Verifying UE state in UE RRC. Try to increase the test case duration if
402 * the following checks.
403 */
404 NS_TEST_ASSERT_MSG_EQ (m_isConnectionEstablished[imsi], true,
405 "RNTI " << rnti << " fails to establish connection");
406 NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY,
407 "RNTI " << rnti << " is not at CONNECTED_NORMALLY state");
408
409 // Verifying UE context state in eNodeB RRC.
410
411 Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
412 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc ();
413 const bool hasContext = enbRrc->HasUeManager (rnti);
414
415 if (hasContext)
416 {
417 Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
418 NS_ASSERT (ueManager != 0);
419 NS_TEST_ASSERT_MSG_EQ (ueManager->GetState (),
420 UeManager::CONNECTED_NORMALLY,
421 "The context of RNTI " << rnti << " is in invalid state");
422 }
423 else
424 {
425 NS_LOG_WARN (this << " RNTI " << rnti << " thinks that it has"
426 << " established connection but the eNodeB thinks"
427 << " that the UE has failed on connection setup.");
428 /*
429 * The standard specifies that this case would exceed the maximum
430 * retransmission limit at UE RLC (SRB1), which will then trigger an RLF.
431 * However, this behaviour is not implemented yet.
432 */
433 }
434
435 // Verifying other attributes on both sides.
436
437 uint16_t ueCellId = ueRrc->GetCellId ();
438 uint16_t enbCellId = enbLteDevice->GetCellId ();
439 uint16_t ueImsi = ueLteDevice->GetImsi ();
440
441 uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth ();
442 uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth ();
443 uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth ();
444 uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth ();
445 uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn ();
446 uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn ();
447 uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn ();
448 uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn ();
449
450 NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId");
451 NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
452 NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
453 NS_TEST_ASSERT_MSG_EQ (ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
454 NS_TEST_ASSERT_MSG_EQ (ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
455
456 if (hasContext)
457 {
458 Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
459 NS_ASSERT (ueManager != 0);
460 UeManager::State state = ueManager->GetState ();
461 uint16_t enbImsi = ueManager->GetImsi ();
462 NS_TEST_ASSERT_MSG_EQ (ueImsi, enbImsi, "inconsistent Imsi");
463
464 if (state == UeManager::CONNECTED_NORMALLY)
465 {
466 ObjectMapValue enbDataRadioBearerMapValue;
467 ueManager->GetAttribute ("DataRadioBearerMap", enbDataRadioBearerMapValue);
468 NS_TEST_ASSERT_MSG_EQ (enbDataRadioBearerMapValue.GetN (), m_nBearers, "wrong num bearers at eNB");
469 ObjectMapValue ueDataRadioBearerMapValue;
470 ueRrc->GetAttribute ("DataRadioBearerMap", ueDataRadioBearerMapValue);
471 NS_TEST_ASSERT_MSG_EQ (ueDataRadioBearerMapValue.GetN (), m_nBearers, "wrong num bearers at UE");
472
473 ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin ();
474 ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin ();
475 while (enbBearerIt != enbDataRadioBearerMapValue.End ()
476 && ueBearerIt != ueDataRadioBearerMapValue.End ())
477 {
478 Ptr<LteDataRadioBearerInfo> enbDrbInfo = enbBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
479 Ptr<LteDataRadioBearerInfo> ueDrbInfo = ueBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
480 //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer differs");
481 NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_epsBearerIdentity, (uint32_t) ueDrbInfo->m_epsBearerIdentity, "epsBearerIdentity differs");
482 NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_drbIdentity, (uint32_t) ueDrbInfo->m_drbIdentity, "drbIdentity differs");
483 //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig differs");
484 NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_logicalChannelIdentity, (uint32_t) ueDrbInfo->m_logicalChannelIdentity, "logicalChannelIdentity differs");
485 //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig, ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
486
487 ++enbBearerIt;
488 ++ueBearerIt;
489 }
490
491 NS_ASSERT_MSG (enbBearerIt == enbDataRadioBearerMapValue.End (), "too many bearers at eNB");
492 NS_ASSERT_MSG (ueBearerIt == ueDataRadioBearerMapValue.End (), "too many bearers at UE");
493 }
494 }
495 }
496
497 void
CheckNotConnected(Ptr<NetDevice> ueDevice,Ptr<NetDevice> enbDevice)498 LteRrcConnectionEstablishmentTestCase::CheckNotConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
499 {
500 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
501 Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
502 const uint64_t imsi = ueLteDevice->GetImsi ();
503 const uint16_t rnti = ueRrc->GetRnti ();
504 NS_LOG_FUNCTION (this << imsi << rnti);
505 NS_ASSERT_MSG (m_isConnectionEstablished.find (imsi) != m_isConnectionEstablished.end (),
506 "Invalid IMSI " << imsi);
507
508 bool ueStateIsConnectedNormally = (LteUeRrc::CONNECTED_NORMALLY == ueRrc->GetState ());
509
510 Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
511 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc ();
512 const bool hasContext = enbRrc->HasUeManager (rnti);
513 bool contextStateIsConnectedNormally = false;
514 if (hasContext)
515 {
516 Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
517 NS_ASSERT (ueManager != 0);
518 contextStateIsConnectedNormally = (UeManager::CONNECTED_NORMALLY == ueManager->GetState ());
519 }
520 NS_TEST_ASSERT_MSG_EQ ((!m_isConnectionEstablished[imsi]
521 || !ueStateIsConnectedNormally
522 || !hasContext
523 || !contextStateIsConnectedNormally),
524 true,
525 "it should not happen that connection is completed both at the UE and at the eNB side");
526 }
527
528 void
ConnectionEstablishedCallback(std::string context,uint64_t imsi,uint16_t cellId,uint16_t rnti)529 LteRrcConnectionEstablishmentTestCase::ConnectionEstablishedCallback (
530 std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
531 {
532 NS_LOG_FUNCTION (this << imsi << cellId);
533 m_isConnectionEstablished[imsi] = true;
534 }
535
536
537 void
ConnectionTimeoutCallback(std::string context,uint64_t imsi,uint16_t cellId,uint16_t rnti,uint8_t connEstFailCount)538 LteRrcConnectionEstablishmentTestCase::ConnectionTimeoutCallback (
539 std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
540 uint8_t connEstFailCount)
541 {
542 NS_LOG_FUNCTION (this << imsi << cellId);
543 }
544
545
546
547 /**
548 * \ingroup lte-test
549 * \ingroup tests
550 *
551 * \brief Lte Rrc Connection Establishment Error Test Case
552 */
553 class LteRrcConnectionEstablishmentErrorTestCase
554 : public LteRrcConnectionEstablishmentTestCase
555 {
556 public:
557 /**
558 *
559 *
560 * \param jumpAwayTime the time when all the UEs 'teleport' to a pre-defined
561 * high-interference position and stay there for 100 ms
562 * \param description additional description of the test case
563 */
564 LteRrcConnectionEstablishmentErrorTestCase (Time jumpAwayTime,
565 std::string description = "");
566 protected:
567 virtual void DoRun (void);
568
569 private:
570 /// Jump away function
571 void JumpAway ();
572 /// Jump back function
573 void JumpBack ();
574
575 Time m_jumpAwayTime; ///< jump away time
576 Ptr<MobilityModel> m_ueMobility; ///< UE mobility model
577 };
578
579
LteRrcConnectionEstablishmentErrorTestCase(Time jumpAwayTime,std::string description)580 LteRrcConnectionEstablishmentErrorTestCase::LteRrcConnectionEstablishmentErrorTestCase (
581 Time jumpAwayTime, std::string description)
582 : LteRrcConnectionEstablishmentTestCase (1, 1, 0, 0, 1, true, false, true,
583 description),
584 m_jumpAwayTime (jumpAwayTime)
585 {
586 NS_LOG_FUNCTION (this << GetName ());
587 }
588
589
590 void
DoRun()591 LteRrcConnectionEstablishmentErrorTestCase::DoRun ()
592 {
593 NS_LOG_FUNCTION (this << GetName ());
594 Config::Reset ();
595
596 if (m_nUes < 25)
597 {
598 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (40));
599 }
600 else if (m_nUes < 60)
601 {
602 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (80));
603 }
604 else if (m_nUes < 120)
605 {
606 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (160));
607 }
608 else
609 {
610 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (320));
611 }
612
613 // normal code
614 m_lteHelper = CreateObject<LteHelper> ();
615 m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc));
616
617 NodeContainer enbNodes;
618 NodeContainer ueNodes;
619
620
621 enbNodes.Create (4);
622 ueNodes.Create (1);
623
624 MobilityHelper mobility;
625 mobility.Install (ueNodes); // UE position at (0, 0, 0)
626 m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
627
628 Ptr<ListPositionAllocator> enbPosition = CreateObject<ListPositionAllocator> ();
629 enbPosition->Add (Vector (0, 0, 0));
630 enbPosition->Add (Vector (100.0, 0, 0));
631 enbPosition->Add (Vector (0, 100.0, 0));
632 enbPosition->Add (Vector (100.0, 100.0, 0));
633 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
634 mobility.SetPositionAllocator (enbPosition);
635 mobility.Install (enbNodes);
636
637 int64_t stream = 1;
638 NetDeviceContainer enbDevs;
639 enbDevs = m_lteHelper->InstallEnbDevice (enbNodes);
640 stream += m_lteHelper->AssignStreams (enbDevs, stream);
641
642 NetDeviceContainer ueDevs;
643 ueDevs = m_lteHelper->InstallUeDevice (ueNodes);
644 stream += m_lteHelper->AssignStreams (ueDevs, stream);
645
646 // custom code used for testing purposes
647 // instead of lteHelper->Attach () and lteHelper->ActivateXxx
648
649 // Set AdmitConnectionRequest attribute
650 for (NetDeviceContainer::Iterator it = enbDevs.Begin ();
651 it != enbDevs.End ();
652 ++it)
653 {
654 Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice> ()->GetRrc ();
655 enbRrc->SetAttribute ("AdmitRrcConnectionRequest",
656 BooleanValue (m_admitRrcConnectionRequest));
657 }
658
659
660 uint32_t i = 0;
661 uint32_t tmax = 0;
662 for (NetDeviceContainer::Iterator it = ueDevs.Begin (); it != ueDevs.End (); ++it)
663 {
664 Ptr<NetDevice> ueDevice = *it;
665 Ptr<NetDevice> enbDevice = enbDevs.Get (0);
666 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
667
668 uint32_t tc = m_tConnBase + m_tConnIncrPerUe * i; // time connection start
669 uint32_t tcc = tc + m_delayConnEnd; // time check connection completed;
670 uint32_t td = tcc + m_delayDiscStart; // time disconnect start
671 uint32_t tcd = td + m_delayDiscEnd; // time check disconnection completed
672 tmax = std::max (tmax, tcd);
673
674 // trick to resolve overloading
675 //void (LteHelper::* overloadedAttachFunctionPointer) (Ptr<NetDevice>, Ptr<NetDevice>) = &LteHelper::Attach;
676 //Simulator::Schedule (MilliSeconds (tc), overloadedAttachFunctionPointer, lteHelper, *it, enbDevice);
677 Simulator::Schedule (MilliSeconds (tc), &LteRrcConnectionEstablishmentErrorTestCase::Connect, this, ueDevice, enbDevice);
678
679 // disconnection not supported yet
680
681 uint64_t imsi = ueLteDevice->GetImsi ();
682 m_isConnectionEstablished[imsi] = false;
683
684 ++i;
685 }
686
687 // Connect to trace sources in UEs
688 Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionEstablished",
689 MakeCallback (&LteRrcConnectionEstablishmentErrorTestCase::ConnectionEstablishedCallback,
690 this));
691 Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionTimeout",
692 MakeCallback (&LteRrcConnectionEstablishmentErrorTestCase::ConnectionTimeoutCallback,
693 this));
694
695
696 Simulator::Schedule (m_jumpAwayTime,
697 &LteRrcConnectionEstablishmentErrorTestCase::JumpAway,
698 this);
699 Simulator::Schedule (m_jumpAwayTime + MilliSeconds (99),
700 &LteRrcConnectionEstablishmentErrorTestCase::CheckNotConnected,
701 this, ueDevs.Get (0), enbDevs.Get (0));
702 Simulator::Schedule (m_jumpAwayTime + MilliSeconds (100),
703 &LteRrcConnectionEstablishmentErrorTestCase::JumpBack,
704 this);
705
706 Simulator::Stop (MilliSeconds (tmax + 1));
707
708 Simulator::Run ();
709
710 Simulator::Destroy ();
711
712 }
713
714
715 void
JumpAway()716 LteRrcConnectionEstablishmentErrorTestCase::JumpAway ()
717 {
718 NS_LOG_FUNCTION (this);
719 // move to a really far away location so that transmission errors occur
720 m_ueMobility->SetPosition (Vector (100000.0, 100000.0, 0.0));
721 }
722
723
724 void
JumpBack()725 LteRrcConnectionEstablishmentErrorTestCase::JumpBack ()
726 {
727 NS_LOG_FUNCTION (this);
728 m_ueMobility->SetPosition (Vector (0.0, 0.0, 0.0));
729 }
730
731
732 /**
733 * \ingroup lte-test
734 * \ingroup tests
735 *
736 * \brief Lte Rrc Test Suite
737 */
738 class LteRrcTestSuite : public TestSuite
739 {
740 public:
741 LteRrcTestSuite ();
742 };
743
744
LteRrcTestSuite()745 LteRrcTestSuite::LteRrcTestSuite ()
746 : TestSuite ("lte-rrc", SYSTEM)
747 {
748 // LogComponentEnableAll (LOG_PREFIX_ALL);
749 // LogComponentEnable ("LteRrcTest", LOG_LEVEL_ALL);
750 // LogComponentEnable ("LteEnbRrc", LOG_INFO);
751 // LogComponentEnable ("LteUeRrc", LOG_INFO);
752
753 NS_LOG_FUNCTION (this);
754
755 for (uint32_t useIdealRrc = 0; useIdealRrc <= 1; ++useIdealRrc)
756 {
757 // <----- all times in ms ----------------->
758
759 // nUes tConnBase delayDiscStart useIdealRrc
760 // nBearers tConnIncrPerUe errorExpected admitRrcConnectionRequest
761 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 0, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
762 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 100, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
763 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 0, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
764 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 100, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
765 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 0, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
766 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 100, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
767 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
768 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 10, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
769 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 100, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
770 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
771 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 10, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
772 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 100, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
773 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
774 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 10, 1, false, useIdealRrc, true), TestCase::QUICK);
775 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 100, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
776 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 3, 0, 20, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
777 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
778 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 300, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
779 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 20, 0, 10, 1, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
780 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 50, 0, 0, 0, 1, false, useIdealRrc, true), TestCase::EXTENSIVE);
781
782 // Test cases to check admitRrcConnectionRequest=false
783 // nUes tConnBase delayDiscStart useIdealRrc
784 // nBearers tConnIncrPerUe errorExpected admitRrcConnectionRequest
785 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 0, 0, 1, false, useIdealRrc, false), TestCase::EXTENSIVE);
786 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 100, 0, 1, false, useIdealRrc, false), TestCase::EXTENSIVE);
787 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 0, 1, false, useIdealRrc, false), TestCase::EXTENSIVE);
788 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 0, 1, false, useIdealRrc, false), TestCase::QUICK);
789 AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 3, 0, 20, 0, 1, false, useIdealRrc, false), TestCase::EXTENSIVE);
790 }
791
792 // Test cases with transmission error
793 AddTestCase (new LteRrcConnectionEstablishmentErrorTestCase (
794 Seconds (0.020214),
795 "failure at RRC Connection Request"),
796 TestCase::QUICK);
797 AddTestCase (new LteRrcConnectionEstablishmentErrorTestCase (
798 Seconds (0.025),
799 "failure at RRC Connection Setup"),
800 TestCase::QUICK);
801 /*
802 * With RLF implementation we now do support the Idle mode,
803 * thus it solve Bug 1762 Comment #25.
804 */
805 AddTestCase (new LteRrcConnectionEstablishmentErrorTestCase (
806 Seconds (0.030),
807 "failure at RRC Connection Setup Complete"),
808 TestCase::QUICK);
809
810 }
811
812 static LteRrcTestSuite g_lteRrcTestSuiteInstance;
813