A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
test-lte-rrc.cc
Go to the documentation of this file.
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  */
20 
21 
22 #include <ns3/core-module.h>
23 #include <ns3/network-module.h>
24 #include <ns3/mobility-module.h>
25 #include <ns3/lte-module.h>
26 #include <cmath>
27 
28 NS_LOG_COMPONENT_DEFINE ("LteRrcTest");
29 
30 namespace ns3 {
31 
33 {
34 public:
44  LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tc, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc, bool admitRrcConnectionRequest);
45 
46 private:
47  static std::string BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tc, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc, bool admitRrcConnectionRequest);
48  virtual void DoRun (void);
49  void Connect (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
50  void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
51 
52 
53  uint32_t m_nUes; // number of UEs in the test
54  uint32_t m_nBearers; // number of UEs in the test
55  uint32_t m_tConnBase; // connection time base value for all UEs in ms
56  uint32_t m_tConnIncrPerUe; // additional connection time increment for each UE index (0...nUes-1) in ms
57  uint32_t m_delayConnEnd; // expected duration to perform connection establishment in ms
58  uint32_t m_delayDiscStart; // delay between connection completed and disconnection request in ms
59  uint32_t m_delayDiscEnd; // expected duration to complete disconnection in ms
61  bool m_admitRrcConnectionRequest; // If set to false, eNb will not allow ue connections
63 
64 };
65 
66 
67 std::string LteRrcConnectionEstablishmentTestCase::BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc, bool admitRrcConnectionRequest)
68 {
69  std::ostringstream oss;
70  oss << "nUes=" << nUes
71  << ", nBearers=" << nBearers
72  << ", tConnBase=" << tConnBase
73  << ", tConnIncrPerUe=" << tConnIncrPerUe
74  << ", delayDiscStart=" << delayDiscStart;
75  if (useIdealRrc)
76  {
77  oss << ", ideal RRC";
78  }
79  else
80  {
81  oss << ", real RRC";
82  }
83  if (admitRrcConnectionRequest)
84  {
85  oss << ", admitRrcConnectionRequest = true";
86  }
87  else
88  {
89  oss << ", admitRrcConnectionRequest = false";
90  }
91  return oss.str ();
92 }
93 
94 LteRrcConnectionEstablishmentTestCase::LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc, bool admitRrcConnectionRequest)
95  : TestCase (BuildNameString (nUes, nBearers, tConnBase, tConnIncrPerUe, delayDiscStart, useIdealRrc, admitRrcConnectionRequest)),
96  m_nUes (nUes),
97  m_nBearers (nBearers),
98  m_tConnBase (tConnBase),
99  m_tConnIncrPerUe (tConnIncrPerUe),
100 
101  m_delayDiscStart (delayDiscStart),
102  m_delayDiscEnd (10),
103  m_useIdealRrc (useIdealRrc),
104  m_admitRrcConnectionRequest (admitRrcConnectionRequest)
105 {
106  // see the description of d^e in the LTE testing docs
107  double dsi = 90;
108  double nRaAttempts = 0;
109  if (nUes <= 20)
110  {
111  nRaAttempts += 5;
112  }
113  else
114  {
115  NS_ASSERT (nUes <= 50);
116  nRaAttempts += 10;
117  }
118  nRaAttempts += std::ceil (nUes / 4.0);
119  double dra = nRaAttempts * 7;
120  double dce = 10.0 + (2.0 * nUes) / 4.0;
121  double nCrs;
122  if (nUes <= 2)
123  {
124  nCrs = 0;
125  }
126  else if (nUes <= 5)
127  {
128  nCrs = 1;
129  }
130  else if (nUes <= 10)
131  {
132  nCrs = 2;
133  }
134  else if (nUes <= 20)
135  {
136  nCrs = 3;
137  }
138  else
139  {
140  nCrs = 4;
141  }
142  double dcr = (10.0 + (2.0 * nUes) / 4.0) * (m_nBearers + nCrs);
143 
144  m_delayConnEnd = round (dsi + dra + dce + dcr);
145  NS_LOG_LOGIC (this << GetName () << " dsi=" << dsi << " dra=" << dra << " dce=" << dce << " dcr=" << dcr << " m_delayConnEnd=" << m_delayConnEnd);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this << GetName ());
152  Config::Reset ();
153 
154  if (m_nUes < 25)
155  {
156  Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (40));
157  }
158  else if (m_nUes < 60)
159  {
160  Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (80));
161  }
162  else if (m_nUes < 120)
163  {
164  Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (160));
165  }
166  else
167  {
168  Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (320));
169  }
170 
171  // normal code
172  m_lteHelper = CreateObject<LteHelper> ();
174 
175  NodeContainer enbNodes;
176  enbNodes.Create (1);
177  NodeContainer ueNodes;
178  ueNodes.Create (m_nUes);
179 
180  MobilityHelper mobility;
181  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
182  mobility.Install (enbNodes);
183  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
184  mobility.Install (ueNodes);
185 
186  NetDeviceContainer enbDevs;
187  enbDevs = m_lteHelper->InstallEnbDevice (enbNodes);
188 
189  NetDeviceContainer ueDevs;
190  ueDevs = m_lteHelper->InstallUeDevice (ueNodes);
191 
192  // custom code used for testing purposes
193  // instead of lteHelper->Attach () and lteHelper->ActivateXxx
194 
195  // Set AdmitConnectionRequest attribute
196  for (NetDeviceContainer::Iterator it = enbDevs.Begin ();
197  it != enbDevs.End ();
198  ++it)
199  {
200  Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice> ()->GetRrc ();
201  enbRrc->SetAttribute ("AdmitRrcConnectionRequest", BooleanValue (m_admitRrcConnectionRequest));
202  }
203 
204 
205  uint32_t i = 0;
206  uint32_t tmax = 0;
207  for (NetDeviceContainer::Iterator it = ueDevs.Begin (); it != ueDevs.End (); ++it)
208  {
209  Ptr<NetDevice> ueDevice = *it;
210  Ptr<NetDevice> enbDevice = enbDevs.Get (0);
211  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
212 
213  uint32_t tc = m_tConnBase + m_tConnIncrPerUe * i; // time connection start
214  uint32_t tcc = tc + m_delayConnEnd; // time check connection completed;
215  uint32_t td = tcc + m_delayDiscStart; // time disconnect start
216  uint32_t tcd = td + m_delayDiscEnd; // time check disconnection completed
217  tmax = std::max (tmax, tcd);
218 
219  // trick to resolve overloading
220  //void (LteHelper::* overloadedAttachFunctionPointer) (Ptr<NetDevice>, Ptr<NetDevice>) = &LteHelper::Attach;
221  //Simulator::Schedule (MilliSeconds (tc), overloadedAttachFunctionPointer, lteHelper, *it, enbDevice);
223 
225 
226  // disconnection not supported yet
227 
228  ++i;
229  }
230 
231 
232  Simulator::Stop (MilliSeconds (tmax + 1));
233 
234  Simulator::Run ();
235 
237 
238 }
239 
240 void
242 {
243  m_lteHelper->Attach (ueDevice, enbDevice);
244 
245  for (uint32_t b = 0; b < m_nBearers; ++b)
246  {
248  EpsBearer bearer (q);
249  m_lteHelper->ActivateDataRadioBearer (ueDevice, bearer);
250  }
251 }
252 void
254 {
255  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
256  Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
257 
259  {
260  NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::IDLE_CAMPED_NORMALLY, "Wrong LteUeRrc state!");
261  return;
262  }
263 
264  NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
265 
266  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
267  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc ();
268  uint16_t rnti = ueRrc->GetRnti ();
269  Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
270  NS_TEST_ASSERT_MSG_NE (ueManager, 0, "RNTI " << rnti << " not found in eNB");
271 
272  NS_TEST_ASSERT_MSG_EQ (ueManager->GetState (), UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
273 
274  uint16_t ueCellId = ueRrc->GetCellId ();
275  uint16_t enbCellId = enbLteDevice->GetCellId ();
276  uint16_t ueImsi = ueLteDevice->GetImsi ();
277  uint16_t enbImsi = ueManager->GetImsi ();
278  uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth ();
279  uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth ();
280  uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth ();
281  uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth ();
282  uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn ();
283  uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn ();
284  uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn ();
285  uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn ();
286 
287 
288  NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId");
289  NS_TEST_ASSERT_MSG_EQ (ueImsi, enbImsi, "inconsistent Imsi");
290  NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
291  NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
292  NS_TEST_ASSERT_MSG_EQ (ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
293  NS_TEST_ASSERT_MSG_EQ (ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
294 
295  ObjectMapValue enbDataRadioBearerMapValue;
296  ueManager->GetAttribute ("DataRadioBearerMap", enbDataRadioBearerMapValue);
297  NS_TEST_ASSERT_MSG_EQ (enbDataRadioBearerMapValue.GetN (), m_nBearers, "wrong num bearers at eNB");
298 
299  ObjectMapValue ueDataRadioBearerMapValue;
300  ueRrc->GetAttribute ("DataRadioBearerMap", ueDataRadioBearerMapValue);
301  NS_TEST_ASSERT_MSG_EQ (ueDataRadioBearerMapValue.GetN (), m_nBearers, "wrong num bearers at UE");
302 
303  ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin ();
304  ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin ();
305  while (enbBearerIt != enbDataRadioBearerMapValue.End ()
306  && ueBearerIt != ueDataRadioBearerMapValue.End ())
307  {
308  Ptr<LteDataRadioBearerInfo> enbDrbInfo = enbBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
309  Ptr<LteDataRadioBearerInfo> ueDrbInfo = ueBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
310  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer differs");
311  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_epsBearerIdentity, (uint32_t) ueDrbInfo->m_epsBearerIdentity, "epsBearerIdentity differs");
312  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_drbIdentity, (uint32_t) ueDrbInfo->m_drbIdentity, "drbIdentity differs");
313  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig differs");
314  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_logicalChannelIdentity, (uint32_t) ueDrbInfo->m_logicalChannelIdentity, "logicalChannelIdentity differs");
315  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig, ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
316 
317  ++enbBearerIt;
318  ++ueBearerIt;
319  }
320  NS_ASSERT_MSG (enbBearerIt == enbDataRadioBearerMapValue.End (), "too many bearers at eNB");
321  NS_ASSERT_MSG (ueBearerIt == ueDataRadioBearerMapValue.End (), "too many bearers at UE");
322 
323 }
324 
325 
326 
328 {
329 public:
330  LteRrcTestSuite ();
331 };
332 
333 
335  : TestSuite ("lte-rrc", SYSTEM)
336 {
337  NS_LOG_FUNCTION (this);
338 
339  for (uint32_t useIdealRrc = 0; useIdealRrc <= 1; ++useIdealRrc)
340  {
341  // <----- all times in ms ----------------->
342  // nUes, nBearers, tConnBase, tConnIncrPerUe, delayDiscStart, useIdealRrc, admitRrcConnectionRequest
343  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 0, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
344  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 100, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
345  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 0, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
346  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 100, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
347  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 0, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
348  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 100, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
349  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
350  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 10, 1, useIdealRrc, true), TestCase::EXTENSIVE);
351  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 100, 1, useIdealRrc, true), TestCase::EXTENSIVE);
352  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
353  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 10, 1, useIdealRrc, true), TestCase::EXTENSIVE);
354  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 100, 1, useIdealRrc, true), TestCase::EXTENSIVE);
355  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
356  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 10, 1, useIdealRrc, true), TestCase::QUICK);
357  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 100, 1, useIdealRrc, true), TestCase::EXTENSIVE);
358  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 3, 0, 20, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
359  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
360  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 300, 1, useIdealRrc, true), TestCase::EXTENSIVE);
361  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 20, 0, 10, 1, 1, useIdealRrc, true), TestCase::EXTENSIVE);
362  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 50, 0, 0, 0, 1, useIdealRrc, true), TestCase::EXTENSIVE);
363 
364  //Test cases to check admitRrcConnectionRequest=false
365  // nUes, nBearers, tConnBase, tConnIncrPerUe, delayDiscStart, useIdealRrc, admitRrcConnectionRequest
366  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 0, 0, 1, useIdealRrc, false), TestCase::EXTENSIVE);
367  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 100, 0, 1, useIdealRrc, false), TestCase::EXTENSIVE);
368  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 0, 1, useIdealRrc, false), TestCase::EXTENSIVE);
369  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 0, 1, useIdealRrc, false), TestCase::QUICK);
370  AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 3, 0, 20, 0, 1, useIdealRrc, false), TestCase::EXTENSIVE);
371 
372  //time consuming tests with a lot of UEs
373  // AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 0, 1, useIdealRrc, true), TestCase::TAKES_FOREVER);
374  // AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 1, 1, useIdealRrc, true), TestCase::TAKES_FOREVER);
375  // AddTestCase (new LteRrcConnectionEstablishmentTestCase (200, 0, 10, 0, 1, useIdealRrc, true), TestCase::TAKES_FOREVER);
376  // AddTestCase (new LteRrcConnectionEstablishmentTestCase (200, 0, 10, 1, 1, useIdealRrc, true), TestCase::TAKES_FOREVER);
377  }
378 }
379 
381 
382 
383 
384 } // namespace ns3