A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-ue-rrc.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011, 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 #include <ns3/fatal-error.h>
22 #include <ns3/log.h>
23 #include <ns3/object-map.h>
24 #include <ns3/object-factory.h>
25 #include <ns3/node-list.h>
26 #include <ns3/node.h>
27 #include <ns3/simulator.h>
28 
29 #include "lte-ue-rrc.h"
30 #include "lte-enb-rrc.h"
31 #include "lte-rlc.h"
32 #include "lte-rlc-tm.h"
33 #include "lte-rlc-um.h"
34 #include "lte-rlc-am.h"
35 #include "lte-pdcp.h"
36 #include "lte-pdcp-sap.h"
37 #include "lte-radio-bearer-info.h"
38 #include "lte-as-sap.h"
39 #include "lte-enb-net-device.h"
40 
41 #include <cmath>
42 
43 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
44 
45 namespace ns3 {
46 
47 
48 
50 // CMAC SAP forwarder
52 
54 {
55 public:
57 
58  virtual void SetTemporaryCellRnti (uint16_t rnti);
59  virtual void NotifyRandomAccessSuccessful ();
60  virtual void NotifyRandomAccessFailed ();
61 
62 private:
64 };
65 
67  : m_rrc (rrc)
68 {
69 }
70 
71 void
73 {
75 }
76 
77 
78 void
80 {
82 }
83 
84 void
86 {
88 }
89 
90 
91 
92 
93 
94 
95 
97  {
98  "IDLE_CELL_SELECTION",
99  "IDLE_WAIT_SYSTEM_INFO",
100  "IDLE_CAMPED_NORMALLY",
101  "IDLE_RANDOM_ACCESS",
102  "IDLE_CONNECTING",
103  "CONNECTED_NORMALLY",
104  "CONNECTED_REESTABLISHING",
105  "CONNECTED_HANDOVER"
106  };
107 
109 {
110  return std::string (g_ueRrcStateName[s]);
111 }
112 
113 
115 // ue RRC methods
117 
118 NS_OBJECT_ENSURE_REGISTERED (LteUeRrc);
119 
120 
122  : m_cphySapProvider (0),
123  m_cmacSapProvider (0),
124  m_rrcSapUser (0),
125  m_macSapProvider (0),
126  m_asSapUser (0),
127  m_state (IDLE_CELL_SELECTION),
128  m_imsi (0),
129  m_rnti (0),
130  m_cellId (0),
131  m_useRlcSm (true),
132  m_connectionPending (0),
133  m_receivedMib (0),
134  m_receivedSib2 (0)
135 
136 {
137  NS_LOG_FUNCTION (this);
143 }
144 
145 
147 {
148  NS_LOG_FUNCTION (this);
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION (this);
155  delete m_cphySapUser;
156  delete m_cmacSapUser;
157  delete m_rrcSapProvider;
158  delete m_drbPdcpSapUser;
159  delete m_asSapProvider;
160  m_drbMap.clear ();
161 }
162 
163 TypeId
165 {
166  static TypeId tid = TypeId ("ns3::LteUeRrc")
167  .SetParent<Object> ()
168  .AddConstructor<LteUeRrc> ()
169  .AddAttribute ("DataRadioBearerMap", "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
170  ObjectMapValue (),
172  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
173  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
174  PointerValue (),
175  MakePointerAccessor (&LteUeRrc::m_srb0),
176  MakePointerChecker<LteSignalingRadioBearerInfo> ())
177  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
178  PointerValue (),
179  MakePointerAccessor (&LteUeRrc::m_srb1),
180  MakePointerChecker<LteSignalingRadioBearerInfo> ())
181  .AddAttribute ("CellId",
182  "Serving cell identifier",
183  UintegerValue (0), // unused, read-only attribute
184  MakeUintegerAccessor (&LteUeRrc::GetCellId),
185  MakeUintegerChecker<uint16_t> ())
186  .AddAttribute ("C-RNTI",
187  "Cell Radio Network Temporary Identifier",
188  UintegerValue (0), // unused, read-only attribute
189  MakeUintegerAccessor (&LteUeRrc::GetRnti),
190  MakeUintegerChecker<uint16_t> ())
191  .AddTraceSource ("StateTransition",
192  "trace fired upon every UE RRC state transition",
194  .AddTraceSource ("RandomAccessSuccessful",
195  "trace fired upon successful completion of the random access procedure",
197  .AddTraceSource ("ConnectionEstablished",
198  "trace fired upon successful RRC connection establishment",
200  .AddTraceSource ("ConnectionReconfiguration",
201  "trace fired upon RRC connection reconfiguration",
203  .AddTraceSource ("HandoverStart",
204  "trace fired upon start of a handover procedure",
206  .AddTraceSource ("HandoverEndOk",
207  "trace fired upon successful termination of a handover procedure",
209  ;
210  return tid;
211 }
212 
213 
214 void
216 {
217  NS_LOG_FUNCTION (this << s);
219 }
220 
223 {
224  NS_LOG_FUNCTION (this);
225  return m_cphySapUser;
226 }
227 
228 void
230 {
231  NS_LOG_FUNCTION (this << s);
233 }
234 
237 {
238  NS_LOG_FUNCTION (this);
239  return m_cmacSapUser;
240 }
241 
242 void
244 {
245  NS_LOG_FUNCTION (this << s);
246  m_rrcSapUser = s;
247 }
248 
251 {
252  NS_LOG_FUNCTION (this);
253  return m_rrcSapProvider;
254 }
255 
256 void
258 {
259  NS_LOG_FUNCTION (this << s);
261 }
262 
263 void
265 {
266  m_asSapUser = s;
267 }
268 
271 {
272  return m_asSapProvider;
273 }
274 
275 void
276 LteUeRrc::SetImsi (uint64_t imsi)
277 {
278  NS_LOG_FUNCTION (this << imsi);
279  m_imsi = imsi;
280 }
281 
282 uint64_t
284 {
285  return m_imsi;
286 }
287 
288 uint16_t
290 {
291  NS_LOG_FUNCTION (this);
292  return m_rnti;
293 }
294 
295 uint16_t
297 {
298  NS_LOG_FUNCTION (this);
299  return m_cellId;
300 }
301 
302 
303 uint8_t
305 {
306  NS_LOG_FUNCTION (this);
307  return m_ulBandwidth;
308 }
309 
310 uint8_t
312 {
313  NS_LOG_FUNCTION (this);
314  return m_dlBandwidth;
315 }
316 
317 uint16_t
319 {
320  return m_dlEarfcn;
321 }
322 
323 uint16_t
325 {
326  NS_LOG_FUNCTION (this);
327  return m_ulEarfcn;
328 }
329 
330 
333 {
334  NS_LOG_FUNCTION (this);
335  return m_state;
336 }
337 
338 void
340 {
341  NS_LOG_FUNCTION (this);
342  m_useRlcSm = val;
343 }
344 
345 
346 void
348 {
349  NS_LOG_FUNCTION (this);
350 
351  // setup the UE side of SRB0
352  uint8_t lcid = 0;
353 
354  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
355  rlc->SetLteMacSapProvider (m_macSapProvider);
356  rlc->SetRnti (m_rnti);
357  rlc->SetLcId (lcid);
358 
359  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
360  m_srb0->m_rlc = rlc;
361  m_srb0->m_srbIdentity = 0;
363  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
364  ueParams.srb1SapProvider = 0;
365  m_rrcSapUser->Setup (ueParams);
366 
367  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
369  lcConfig.priority = 0; // highest priority
370  lcConfig.prioritizedBitRateKbps = 65535; // maximum
371  lcConfig.bucketSizeDurationMs = 65535; // maximum
372  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
373 
374  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
375 
376 }
377 
378 
379 void
380 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
381 {
382  NS_LOG_FUNCTION (this << packet);
383 
384 
385  uint8_t drbid = Bid2Drbid (bid);
386 
387  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
388  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
389 
391  params.pdcpSdu = packet;
392  params.rnti = m_rnti;
393  params.lcid = it->second->m_logicalChannelIdentity;
394 
395  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending " << packet << "on DRBID " << (uint32_t) drbid << " (LCID" << params.lcid << ")" << " (" << packet->GetSize () << " bytes)");
396  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
397 }
398 
399 void
401 {
402  NS_LOG_FUNCTION (this);
403 
404  switch (m_state)
405  {
406  case IDLE_CELL_SELECTION:
408  NS_LOG_INFO ("already disconnected");
409  break;
410 
411  case IDLE_CONNECTING:
412  NS_LOG_INFO ("aborting connection setup procedure");
414  break;
415 
416  case CONNECTED_NORMALLY:
418  case CONNECTED_HANDOVER:
420  break;
421 
422  default:
423  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
424  break;
425  }
426 }
427 
428 void
430 {
431  NS_LOG_FUNCTION (this);
432  m_asSapUser->RecvData (params.pdcpSdu);
433 }
434 
435 
436 void
438 {
439  NS_LOG_FUNCTION (this << rnti);
440  m_rnti = rnti;
441  m_srb0->m_rlc->SetRnti (m_rnti);
443 }
444 
445 void
447 {
448  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
450  switch (m_state)
451  {
452  case IDLE_RANDOM_ACCESS:
453  {
454  // we just received a RAR with a T-C-RNTI and an UL grant
455  // send RRC connection request as message 3 of the random access procedure
458  msg.ueIdentity = m_imsi;
460  }
461  break;
462 
463  case CONNECTED_HANDOVER:
464  {
470  }
471  break;
472 
473  default:
474  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
475  break;
476  }
477 }
478 
479 void
481 {
482  NS_LOG_FUNCTION (this);
483 }
484 
485 
486 void
487 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint16_t earfcn)
488 {
489  NS_LOG_FUNCTION (this << cellId << earfcn);
490 
491  m_cellId = cellId;
492  m_dlEarfcn = earfcn;
495 }
496 
497 void
499 {
500  NS_LOG_FUNCTION (this);
501  switch (m_state)
502  {
503  case IDLE_CELL_SELECTION:
505  m_connectionPending = true;
506  break;
507 
508  case IDLE_CAMPED_NORMALLY:
509  StartConnection ();
510  break;
511 
512  case IDLE_RANDOM_ACCESS:
513  case IDLE_CONNECTING:
514  NS_LOG_WARN ("already connecting (state " << ToString (m_state) << ")");
515  break;
516 
517  case CONNECTED_NORMALLY:
519  case CONNECTED_HANDOVER:
520  NS_LOG_WARN ("already connected (state " << ToString (m_state) << ")");
521  break;
522 
523  default:
524  NS_FATAL_ERROR ("cannot connect while in state " << ToString (m_state));
525  break;
526  }
527 
528 
529 }
530 
531 
532 
533 // CPHY SAP methods
534 
535 void
537 {
538  NS_LOG_FUNCTION (this);
541  m_receivedMib = true;
543  {
545  }
546 }
547 
548 void
550 {
551  NS_LOG_FUNCTION (this);
552 
553  for (std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt = params.m_ueMeasurementsList.begin (); newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
554  {
555  NS_LOG_LOGIC (this << " CellId " << newMeasIt->m_cellId << " RSRP " << newMeasIt->m_rsrp << " RSRQ " << newMeasIt->m_rsrq);
556 
557  // 3GPP TS 36.331 section 5.5.3.2 Layer 3 filtering
558  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (newMeasIt->m_cellId);
559  if (storedMeasIt == m_storedMeasValues.end ())
560  {
561  // first value is unfiltered
562  MeasValues v;
563  v.rsrp = newMeasIt->m_rsrp;
564  v.rsrq = newMeasIt->m_rsrq;
565  std::pair<uint16_t, MeasValues> val (newMeasIt->m_cellId, v);
566  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
567  ret = m_storedMeasValues.insert (val);
568  NS_ASSERT_MSG (ret.second == true, "element already existed");
569  storedMeasIt = ret.first;
570  }
571  else
572  {
573  // F_n = (1-a) F_{n-1} + a M_n
574  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
575  + m_varMeasConfig.aRsrp * newMeasIt->m_rsrp;
576  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
577  + m_varMeasConfig.aRsrq * newMeasIt->m_rsrq;
578  }
579  storedMeasIt->second.timestamp = Simulator::Now ();
580  }
581 
582 
583  // 3GPP TS 36.331 section 5.5.4.1 Measurement report triggering - General
584  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
585  = m_varMeasConfig.measIdList.begin ();
586  measIdIt != m_varMeasConfig.measIdList.end ();
587  ++measIdIt)
588  {
589  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
590  uint8_t measId = measIdIt->first;
591  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
592 
593  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
594  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
595  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
596  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
597 
598  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
599  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
600  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
601  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
602 
603  std::map<uint8_t, VarMeasReport>::iterator
604  measReportIt = m_varMeasReportList.find (measId);
605 
606  // we don't check the purpose field, as it is only included for
607  // triggerType == periodical, which is not supported
608  NS_ASSERT_MSG (reportConfigEutra.triggerType
610  "only triggerType == event is supported");
611  // only EUTRA is supported, no need to check for it
612 
613  bool eventEntryCondApplicable = false;
614  bool eventLeavingCondApplicable = false;
615 
616  std::list<uint16_t> concernedCellsEntry;
617  std::list<uint16_t> concernedCellsLeaving;
618 
619  switch (reportConfigEutra.eventId)
620  {
622  {
623  double ms; // Ms, the measurement for serving cell
624  double thresh; // Tresh, the threshold parameter for this event
625  double hys = (double) reportConfigEutra.hysteresis * 0.5; // Hys, the hysteresis parameter for this event. See 36.331 section 6.3.5 for the conversion.
626  switch (reportConfigEutra.triggerQuantity)
627  {
629  ms = m_storedMeasValues[m_cellId].rsrp;
630  //ms = EutranMeasurementMapping::QuantizeRsrp (m_storedMeasValues[m_cellId].rsrp);
631  NS_ASSERT (reportConfigEutra.threshold1.choice
633  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
634  break;
636  ms = m_storedMeasValues[m_cellId].rsrq;
637  //ms = EutranMeasurementMapping::QuantizeRsrq (m_storedMeasValues[m_cellId].rsrq);
638  NS_ASSERT (reportConfigEutra.threshold1.choice
640  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
641  break;
642  default:
643  NS_FATAL_ERROR ("unsupported triggerQuantity");
644  break;
645  }
646  // Inequality A2-1 (Entering condition) : Ms + Hys < Thresh
647  bool entryCond = ms + hys < thresh;
648  if (entryCond == true
649  && (measReportIt == m_varMeasReportList.end ()
650  || (measReportIt != m_varMeasReportList.end ()
651  && (measReportIt->second.cellsTriggeredList.find (m_cellId)
652  == measReportIt->second.cellsTriggeredList.end ()))))
653  {
654  concernedCellsEntry.push_back (m_cellId);
655  eventEntryCondApplicable = true;
656  }
657  // Inequality A2-2 (Leaving condition) : Ms − Hys > Thresh
658  bool leavingCond = ms - hys > thresh;
659  if (leavingCond
660  && measReportIt != m_varMeasReportList.end ()
661  && (measReportIt->second.cellsTriggeredList.find (m_cellId)
662  != measReportIt->second.cellsTriggeredList.end ()))
663  {
664  concernedCellsLeaving.push_back (m_cellId);
665  eventLeavingCondApplicable = true;
666  }
667  NS_LOG_LOGIC ("event A2: serving cell " << m_cellId << " ms=" << ms << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond);
668  }
669  break;
670 
672  {
673  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
674  storedMeasIt != m_storedMeasValues.end ();
675  ++storedMeasIt)
676  {
677  uint16_t cellId = storedMeasIt->first;
678  if (cellId != m_cellId)
679  {
680  double mn; // Mn, the measurement for neighboring cell
681  double thresh; // Tresh, the threshold parameter for this event
682  double hys = (double) reportConfigEutra.hysteresis * 0.5; // Hys, the hysteresis parameter for this event. See 36.331 section 6.3.5 for the conversion.
683  switch (reportConfigEutra.triggerQuantity)
684  {
686  mn = storedMeasIt->second.rsrp;
687  //mn = EutranMeasurementMapping::QuantizeRsrp (storedMeasIt->second.rsrp);
688  NS_ASSERT (reportConfigEutra.threshold1.choice
690  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
691  break;
693  mn = storedMeasIt->second.rsrq;
694  //mn = EutranMeasurementMapping::QuantizeRsrq (storedMeasIt->second.rsrq);
695  NS_ASSERT (reportConfigEutra.threshold1.choice
697  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
698  break;
699  default:
700  NS_FATAL_ERROR ("unsupported triggerQuantity");
701  break;
702  }
703  // Inequality A4-1 (Entering condition) : Mn + Ofn + Ocn − Hys > Thresh
704  bool entryCond = mn + measObjectEutra.offsetFreq + 0.0 - hys > thresh;
705  if (entryCond == true
706  && (measReportIt == m_varMeasReportList.end ()
707  || (measReportIt != m_varMeasReportList.end ()
708  && (measReportIt->second.cellsTriggeredList.find (cellId)
709  == measReportIt->second.cellsTriggeredList.end ()))))
710  {
711  concernedCellsEntry.push_back (cellId);
712  eventEntryCondApplicable = true;
713  }
714  // Inequality A4-2 (Leaving condition) : Mn + Ofn + Ocn + Hys < Thresh
715  bool leavingCond = mn + measObjectEutra.offsetFreq + 0.0 + hys < thresh;
716  if (leavingCond
717  && measReportIt != m_varMeasReportList.end ()
718  && (measReportIt->second.cellsTriggeredList.find (cellId)
719  != measReportIt->second.cellsTriggeredList.end ()))
720  {
721  concernedCellsLeaving.push_back (cellId);
722  eventLeavingCondApplicable = true;
723  }
724 
725  NS_LOG_LOGIC ("event A4: neighbor cell " << cellId << " mn=" << mn << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond);
726  }
727  }
728  }
729  break;
730 
731  default:
732  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
733  break;
734 
735  } // switch (event type)
736 
737  NS_LOG_LOGIC ("eventEntryCondApplicable=" << eventEntryCondApplicable
738  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
739 
740  bool initiateUeMeasurementReportingProcedure = false;
741 
742  if (eventEntryCondApplicable)
743  {
744  if (measReportIt == m_varMeasReportList.end ())
745  {
746  VarMeasReport r;
747  r.measId = measId;
748  std::pair<uint8_t, VarMeasReport> val (measId, r);
749  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
750  ret = m_varMeasReportList.insert (val);
751  NS_ASSERT_MSG (ret.second == true, "element already existed");
752  measReportIt = ret.first;
753  }
754  for (std::list<uint16_t>::iterator it = concernedCellsEntry.begin ();
755  it != concernedCellsEntry.end ();
756  ++it)
757  {
758  measReportIt->second.cellsTriggeredList.insert (*it);
759  }
760  measReportIt->second.numberOfReportsSent = 0;
761  initiateUeMeasurementReportingProcedure = true;
762  }
763 
764  if (eventLeavingCondApplicable)
765  {
766  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
767  for (std::list<uint16_t>::iterator it = concernedCellsLeaving.begin ();
768  it != concernedCellsLeaving.end ();
769  ++it)
770  {
771  measReportIt->second.cellsTriggeredList.erase (*it);
772  }
773 
774  // reportOnLeave will only be set when eventId = eventA3
775  if(reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
776  {
777  if (reportConfigEutra.reportOnLeave)
778  {
779  initiateUeMeasurementReportingProcedure = true;
780  }
781  }
782  }
783 
784  if (initiateUeMeasurementReportingProcedure)
785  {
786  SendMeasurementReport (measId);
787  }
788 
789  if ((measReportIt != m_varMeasReportList.end ())
790  && (measReportIt->second.cellsTriggeredList.empty ()))
791  {
792  measReportIt->second.periodicReportTimer.Cancel ();
793  m_varMeasReportList.erase (measReportIt);
794  }
795 
796  } // for each measId in m_varMeasConfig.measIdList
797 }
798 
799 
800 
801 // RRC SAP methods
802 
803 void
805 {
806  NS_LOG_FUNCTION (this);
807  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
808  if (m_srb1)
809  {
810  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
811  }
812 }
813 
814 
815 void
817 {
818  NS_LOG_FUNCTION (this);
819  // to be implemented
820 }
821 
822 
823 void
825 {
826  NS_LOG_FUNCTION (this);
827  if (msg.haveSib2)
828  {
829  m_receivedSib2 = true;
838  }
840  {
842  }
843 }
844 
845 
846 void
848 {
849  NS_LOG_FUNCTION (this);
850  switch (m_state)
851  {
852  case IDLE_CONNECTING:
853  {
861  }
862  break;
863 
864  default:
865  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
866  break;
867  }
868 }
869 
870 void
872 {
873  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
874  switch (m_state)
875  {
876  case CONNECTED_NORMALLY:
877  if (msg.haveMobilityControlInfo)
878  {
879  NS_LOG_INFO ("haveMobilityControlInfo == true");
892  m_srb0->m_rlc->SetRnti (m_rnti);
893  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
898 
899  // we re-establish SRB1 by creating a new entity
900  // note that we can't dispose the old entity now, because
901  // it's in the current stack, so we would corrupt the stack
902  // if we did so. Hence we schedule it for later disposal
903  m_srb1Old = m_srb1;
905  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
906 
907  m_drbMap.clear (); // dispose all DRBs
909 
910  if (msg.haveMeasConfig)
911  {
913  }
914  // RRC connection reconfiguration completed will be sent
915  // after handover is complete
916  }
917  else
918  {
919  NS_LOG_INFO ("haveMobilityControlInfo == false");
921  {
923  }
924  if (msg.haveMeasConfig)
925  {
927  }
932  }
933  break;
934 
935  default:
936  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
937  break;
938  }
939 }
940 
941 void
943 {
944  switch (m_state)
945  {
947  {
948  }
949  break;
950 
951  default:
952  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
953  break;
954  }
955 }
956 
957 void
959 {
960  NS_LOG_FUNCTION (this);
961  switch (m_state)
962  {
964  {
966  }
967  break;
968 
969  default:
970  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
971  break;
972  }
973 }
974 
975 void
977 {
978  NS_LOG_FUNCTION (this);
979 }
980 
981 void
983 {
984  NS_LOG_FUNCTION (this);
987 }
988 
989 
990 
991 void
993 {
994  NS_LOG_FUNCTION (this);
996 
997  if (pcd.haveAntennaInfoDedicated)
998  {
1000  }
1002  {
1004  }
1005 
1006  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1007  if (stamIt != rrcd.srbToAddModList.end ())
1008  {
1009  if (m_srb1 == 0)
1010  {
1011  // SRB1 not setup yet
1013  "unexpected state " << ToString (m_state));
1014  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1015 
1016  const uint8_t lcid = 1; // fixed LCID for SRB1
1017 
1018  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1019  rlc->SetLteMacSapProvider (m_macSapProvider);
1020  rlc->SetRnti (m_rnti);
1021  rlc->SetLcId (lcid);
1022 
1023  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1024  pdcp->SetRnti (m_rnti);
1025  pdcp->SetLcId (lcid);
1026  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1027  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1028  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1029 
1030  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1031  m_srb1->m_rlc = rlc;
1032  m_srb1->m_pdcp = pdcp;
1033  m_srb1->m_srbIdentity = 1;
1034 
1035  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1036  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1037  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1038  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1039 
1041  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1042  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1043  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1044  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1045 
1046  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
1047 
1048  ++stamIt;
1049  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1050 
1052  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1053  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1054  m_rrcSapUser->Setup (ueParams);
1055  }
1056  else
1057  {
1058  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1059  // would need to modify m_srb1, and then propagate changes to the MAC
1060  }
1061  }
1062 
1063 
1064  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1065  for (dtamIt = rrcd.drbToAddModList.begin ();
1066  dtamIt != rrcd.drbToAddModList.end ();
1067  ++dtamIt)
1068  {
1069  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1070  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1071 
1072  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1073  if (drbMapIt == m_drbMap.end ())
1074  {
1075  NS_LOG_INFO ("New Data Radio Bearer");
1076 
1077  TypeId rlcTypeId;
1078  if (m_useRlcSm)
1079  {
1080  rlcTypeId = LteRlcSm::GetTypeId ();
1081  }
1082  else
1083  {
1084  switch (dtamIt->rlcConfig.choice)
1085  {
1087  rlcTypeId = LteRlcAm::GetTypeId ();
1088  break;
1089 
1091  rlcTypeId = LteRlcUm::GetTypeId ();
1092  break;
1093 
1094  default:
1095  NS_FATAL_ERROR ("unsupported RLC configuration");
1096  break;
1097  }
1098  }
1099 
1100  ObjectFactory rlcObjectFactory;
1101  rlcObjectFactory.SetTypeId (rlcTypeId);
1102  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1103  rlc->SetLteMacSapProvider (m_macSapProvider);
1104  rlc->SetRnti (m_rnti);
1105  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1106 
1107  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1108  drbInfo->m_rlc = rlc;
1109  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1110  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1111  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1112 
1113  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1114  // if we are using RLC/SM we don't care of anything above RLC
1115  if (rlcTypeId != LteRlcSm::GetTypeId ())
1116  {
1117  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1118  pdcp->SetRnti (m_rnti);
1119  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1120  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1121  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1122  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1123  drbInfo->m_pdcp = pdcp;
1124  }
1125 
1126  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1127 
1128  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1129 
1130 
1132  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1133  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1134  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1135  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1136 
1137  m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
1138  lcConfig,
1139  rlc->GetLteMacSapUser ());
1140  rlc->Initialize ();
1141  }
1142  else
1143  {
1144  NS_LOG_INFO ("request to modify existing DRBID");
1145  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1147  }
1148  }
1149 
1150  std::list<uint8_t>::iterator dtdmIt;
1151  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1152  dtdmIt != rrcd.drbToReleaseList.end ();
1153  ++dtdmIt)
1154  {
1155  uint8_t drbid = *dtdmIt;
1156  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
1157  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1158  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1159  m_drbMap.erase (it);
1160  m_bid2DrbidMap.erase (drbid);
1161  }
1162 }
1163 
1164 
1165 void
1167 {
1168  NS_LOG_FUNCTION (this);
1169 
1170  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1171 
1172  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1173  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1174  it != mc.measObjectToRemoveList.end ();
1175  ++it)
1176  {
1177  uint8_t measObjectId = *it;
1178  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1179  m_varMeasConfig.measObjectList.erase (measObjectId);
1180  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1181  while (measIdIt != m_varMeasConfig.measIdList.end ())
1182  {
1183  if (measIdIt->second.measObjectId == measObjectId)
1184  {
1185  uint8_t measId = measIdIt->second.measId;
1186  NS_ASSERT (measId == measIdIt->first);
1187  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1188  // note: postfix operator preserves iterator validity
1189  m_varMeasConfig.measIdList.erase (measIdIt++);
1190  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1191  if (measReportIt != m_varMeasReportList.end ())
1192  {
1193  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1194  measReportIt->second.periodicReportTimer.Cancel ();
1195  m_varMeasReportList.erase (measReportIt);
1196  }
1197  }
1198  else
1199  {
1200  ++measIdIt;
1201  }
1202  }
1203 
1204  }
1205 
1206  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1207  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1208  it != mc.measObjectToAddModList.end ();
1209  ++it)
1210  {
1211  // simplifying assumptions
1212  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1213  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1214  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1215  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1216  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false , "cellForWhichToReportCGI is not supported");
1217 
1218 
1219  uint8_t measObjectId = it->measObjectId;
1220  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1221  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1222  {
1223  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1224  measObjectIt->second = *it;
1225  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1226  = m_varMeasConfig.measIdList.begin ();
1227  measIdIt != m_varMeasConfig.measIdList.end ();
1228  ++measIdIt)
1229  {
1230  if (measIdIt->second.measObjectId == measObjectId)
1231  {
1232  uint8_t measId = measIdIt->second.measId;
1233  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1234  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1235  if (measReportIt != m_varMeasReportList.end ())
1236  {
1237  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1238  measReportIt->second.periodicReportTimer.Cancel ();
1239  m_varMeasReportList.erase (measReportIt);
1240  }
1241  }
1242  }
1243  }
1244  else
1245  {
1246  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1247  m_varMeasConfig.measObjectList[measObjectId] = *it;
1248  }
1249  }
1250 
1251  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1252  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1253  it != mc.reportConfigToRemoveList.end ();
1254  ++it)
1255  {
1256  uint8_t reportConfigId = *it;
1257  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1258  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1259  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1260  while (measIdIt != m_varMeasConfig.measIdList.end ())
1261  {
1262  if (measIdIt->second.reportConfigId == reportConfigId)
1263  {
1264  uint8_t measId = measIdIt->second.measId;
1265  NS_ASSERT (measId == measIdIt->first);
1266  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1267  // note: postfix operator preserves iterator validity
1268  m_varMeasConfig.measIdList.erase (measIdIt++);
1269  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1270  if (measReportIt != m_varMeasReportList.end ())
1271  {
1272  NS_LOG_LOGIC (this << " deleting existing report for measId" << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1273  measReportIt->second.periodicReportTimer.Cancel ();
1274  m_varMeasReportList.erase (measReportIt);
1275  }
1276  }
1277  else
1278  {
1279  ++measIdIt;
1280  }
1281  }
1282 
1283  }
1284 
1285  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1286  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1287  it != mc.reportConfigToAddModList.end ();
1288  ++it)
1289  {
1290  // simplifying assumptions
1291  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1292  "only trigger type EVENT is supported");
1293  NS_ASSERT_MSG (it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A2
1294  || it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A4,
1295  "only events A2 and A4 are supported");
1296  NS_ASSERT_MSG (it->reportConfigEutra.timeToTrigger == 0, "timeToTrigger > 0 is not supported");
1297 
1298  uint8_t reportConfigId = it->reportConfigId;
1299  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1300  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1301  {
1302  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1303  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1304  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1305  = m_varMeasConfig.measIdList.begin ();
1306  measIdIt != m_varMeasConfig.measIdList.end ();
1307  ++measIdIt)
1308  {
1309  if (measIdIt->second.reportConfigId == reportConfigId)
1310  {
1311  uint8_t measId = measIdIt->second.measId;
1312  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1313  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1314  if (measReportIt != m_varMeasReportList.end ())
1315  {
1316  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1317  measReportIt->second.periodicReportTimer.Cancel ();
1318  m_varMeasReportList.erase (measReportIt);
1319  }
1320  }
1321  }
1322  }
1323  else
1324  {
1325  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1326  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1327  }
1328  }
1329 
1330 
1331  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1332  if (mc.haveQuantityConfig)
1333  {
1334  NS_LOG_LOGIC (this << " setting quantityConfig");
1336  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1337  while (measIdIt != m_varMeasConfig.measIdList.end ())
1338  {
1339  uint8_t measId = measIdIt->second.measId;
1340  NS_ASSERT (measId == measIdIt->first);
1341  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1342  // note: postfix operator preserves iterator validity
1343  m_varMeasConfig.measIdList.erase (measIdIt++);
1344  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1345  if (measReportIt != m_varMeasReportList.end ())
1346  {
1347  NS_LOG_LOGIC (this << " deleting existing report for measId" << (uint32_t) measId);
1348  measReportIt->second.periodicReportTimer.Cancel ();
1349  m_varMeasReportList.erase (measReportIt);
1350  }
1351  }
1352  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1353  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP/4.0);
1354  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ/4.0);
1355  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1356 
1357 
1358  }
1359 
1360 
1361  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1362  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1363  it != mc.measIdToRemoveList.end ();
1364  ++it)
1365  {
1366  uint8_t measId = *it;
1367  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1368  m_varMeasConfig.measIdList.erase (measId);
1369  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1370  if (measReportIt != m_varMeasReportList.end ())
1371  {
1372  NS_LOG_LOGIC (this << " deleting existing report for measId" << (uint32_t) measId);
1373  measReportIt->second.periodicReportTimer.Cancel ();
1374  m_varMeasReportList.erase (measReportIt);
1375  }
1376  }
1377 
1378  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1379  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1380  it != mc.measIdToAddModList.end ();
1381  ++it)
1382  {
1383  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId << " (measObjectId="
1384  << (uint32_t) it->measObjectId << ", reportConfigId=" << (uint32_t) it->reportConfigId << ")");
1385  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1386  != m_varMeasConfig.measObjectList.end ());
1387  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1388  != m_varMeasConfig.reportConfigList.end ());
1389  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1390  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1391  if (measReportIt != m_varMeasReportList.end ())
1392  {
1393  measReportIt->second.periodicReportTimer.Cancel ();
1394  m_varMeasReportList.erase (measReportIt);
1395  }
1396  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1397  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1398 
1399  }
1400 
1401  if (mc.haveMeasGapConfig)
1402  {
1403  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1404  }
1405 
1406  if (mc.haveSmeasure)
1407  {
1408  NS_FATAL_ERROR ("s-measure is currently not supported");
1409  }
1410 
1411  if (mc.haveSpeedStatePars)
1412  {
1413  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1414  }
1415 }
1416 
1417 void
1419 {
1420  NS_LOG_FUNCTION (this << (uint32_t) measId);
1421  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
1422 
1423  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
1424  measIdIt = m_varMeasConfig.measIdList.find (measId);
1425  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1426 
1427  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1428  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1429  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1430  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1431 
1432  LteRrcSap::MeasurementReport measurementReport;
1433  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
1434  measResults.measId = measId;
1435 
1436  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
1437  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
1438  measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
1439  measResults.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
1440  NS_LOG_INFO (this << " reporting serving cell "
1441  "RSRP " << (uint32_t) measResults.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
1442  "RSRQ " << (uint32_t) measResults.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
1443  measResults.haveMeasResultNeighCells = false;
1444  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
1445  if (measReportIt == m_varMeasReportList.end ())
1446  {
1447  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
1448  }
1449  else
1450  {
1451  if (!(measReportIt->second.cellsTriggeredList.empty ()))
1452  {
1453  measResults.haveMeasResultNeighCells = true;
1454 
1455  std::multimap<double, uint16_t> sortedNeighCells;
1456  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
1457  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
1458  ++cellsTriggeredIt)
1459  {
1460  uint16_t cellId = *cellsTriggeredIt;
1461  if (cellId != m_cellId)
1462  {
1463  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
1464  double triggerValue;
1465  switch (reportConfigEutra.triggerQuantity)
1466  {
1468  triggerValue = neighborMeasIt->second.rsrp;
1469  break;
1471  triggerValue = neighborMeasIt->second.rsrq;
1472  break;
1473  default:
1474  NS_FATAL_ERROR ("unsupported triggerQuantity");
1475  break;
1476  }
1477  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
1478  }
1479  }
1480 
1481  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
1482  uint32_t count;
1483  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
1484  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
1485  ++sortedNeighCellsIt, ++count)
1486  {
1487  uint16_t cellId = sortedNeighCellsIt->second;
1488  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
1489  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
1490  LteRrcSap::MeasResultEutra measResultEutra;
1491  measResultEutra.physCellId = cellId;
1492  measResultEutra.haveCgiInfo = false;
1493  measResultEutra.haveRsrpResult = true;
1494  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
1495  measResultEutra.haveRsrqResult = true;
1496  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
1497  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
1498  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
1499  << " (" << neighborMeasIt->second.rsrp << " dBm) "
1500  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
1501  << " (" << neighborMeasIt->second.rsrq << " dB)");
1502  measResults.measResultListEutra.push_back (measResultEutra);
1503  }
1504  }
1505  else
1506  {
1507  NS_LOG_WARN (this << " cellsTriggeredList is empty");
1508  }
1509  measReportIt->second.numberOfReportsSent++;
1510  measReportIt->second.periodicReportTimer.Cancel ();
1511 
1512  // the current LteRrcSap implementation is broken in that it does not allow for infinite values
1513  // which is probably the most reasonable setting. So we just assume infinite reportAmount
1514  // if (measReportIt->numberOfReportsSent < reportConfigEutra.reportAmount)
1515  uint32_t intervalMs;
1516  switch (reportConfigEutra.reportInterval)
1517  {
1519  intervalMs = 480;
1520  break;
1521 
1522  default:
1523  NS_FATAL_ERROR ("unsupported reportInterval");
1524  break;
1525  }
1526  measReportIt->second.periodicReportTimer
1527  = Simulator::Schedule (MilliSeconds (intervalMs),
1529  this,
1530  measId);
1531 
1532  m_rrcSapUser->SendMeasurementReport (measurementReport);
1533  }
1534 }
1535 
1536 void
1538 {
1539  NS_LOG_FUNCTION (this);
1540  m_connectionPending = false;
1543 }
1544 
1545 void
1547 {
1548  NS_LOG_FUNCTION (this << m_imsi);
1551  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
1552  for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
1553  {
1554  m_cmacSapProvider->RemoveLc (it->second->m_logicalChannelIdentity);
1555  }
1556  m_drbMap.clear ();
1557  m_bid2DrbidMap.clear ();
1558  m_srb1 = 0;
1560 }
1561 
1562 void
1564 {
1565  NS_LOG_FUNCTION (this);
1566  m_srb1Old = 0;
1567 }
1568 
1569 uint8_t
1570 LteUeRrc::Bid2Drbid (uint8_t bid)
1571 {
1572  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
1573  NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
1574  return it->second;
1575 }
1576 
1577 
1578 void
1580 {
1581  NS_LOG_FUNCTION (this << newState);
1582  State oldState = m_state;
1583  m_state = newState;
1584  NS_LOG_INFO ("IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc " << ToString (oldState) << " --> " << ToString (newState));
1585  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
1586 
1587  switch (newState)
1588  {
1589  case IDLE_CELL_SELECTION:
1590  break;
1591 
1592  case IDLE_WAIT_SYSTEM_INFO:
1593  break;
1594 
1595  case IDLE_CAMPED_NORMALLY:
1596  if (m_connectionPending)
1597  {
1598  StartConnection ();
1599  }
1600  break;
1601 
1602  case IDLE_RANDOM_ACCESS:
1603  break;
1604 
1605  case IDLE_CONNECTING:
1606  break;
1607 
1608  case CONNECTED_NORMALLY:
1609  break;
1610 
1612  break;
1613 
1614  case CONNECTED_HANDOVER:
1615  break;
1616 
1617  default:
1618  break;
1619  }
1620 }
1621 
1622 
1623 
1624 
1625 } // namespace ns3
1626 
LtePdcpSapProvider * srb1SapProvider
Definition: lte-rrc-sap.h:572
virtual void Reset()=0
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Definition: lte-ue-rrc.cc:847
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
Definition: lte-ue-rrc.h:336
std::vector< struct UeMeasurementsElement > m_ueMeasurementsList
static TypeId GetTypeId(void)
Definition: lte-ue-rrc.cc:164
std::list< MeasObjectToAddMod > measObjectToAddModList
Definition: lte-rrc-sap.h:359
LtePdcpSapUser * m_drbPdcpSapUser
Definition: lte-ue-rrc.h:283
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Definition: lte-ue-rrc.cc:824
void DoRecvSystemInformationBlockType1(LteRrcSap::SystemInformationBlockType1 msg)
Definition: lte-ue-rrc.cc:816
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
Definition: lte-rrc-sap.h:130
static TypeId GetTypeId(void)
Definition: lte-rlc.cc:183
void SetAsSapUser(LteAsSapUser *s)
Definition: lte-ue-rrc.cc:264
QuantityConfig quantityConfig
Definition: lte-rrc-sap.h:365
void DoRecvRrcConnectionReject(LteRrcSap::RrcConnectionReject msg)
Definition: lte-ue-rrc.cc:982
std::list< uint8_t > reportConfigToRemoveList
Definition: lte-rrc-sap.h:360
std::list< MeasResultEutra > measResultListEutra
Definition: lte-rrc-sap.h:477
std::map< uint8_t, Ptr< LteDataRadioBearerInfo > > m_drbMap
Definition: lte-ue-rrc.h:297
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Definition: lte-ue-rrc.cc:1166
virtual void DoDispose(void)
Definition: lte-ue-rrc.cc:152
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:339
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
virtual void Reset()=0
#define NS_ASSERT(condition)
Definition: assert.h:64
std::list< SrbToAddMod > srbToAddModList
Definition: lte-rrc-sap.h:180
void DoSetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:437
RadioResourceConfigDedicated radioResourceConfigDedicated
Definition: lte-rrc-sap.h:506
std::list< uint8_t > measObjectToRemoveList
Definition: lte-rrc-sap.h:358
void SetTypeId(TypeId tid)
virtual void StartContentionBasedRandomAccessProcedure()=0
uint32_t GetSize(void) const
Definition: packet.h:650
virtual ~LteUeRrc()
Definition: lte-ue-rrc.cc:146
uint16_t m_cellId
Definition: lte-ue-rrc.h:292
#define NS_LOG_INFO(msg)
Definition: log.h:264
virtual void NotifyRandomAccessSuccessful()
Definition: lte-ue-rrc.cc:79
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberContainer)
Definition: object-map.h:51
virtual void SetRnti(uint16_t rnti)=0
virtual void NotifyConnectionSuccessful()=0
uint16_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:324
virtual void RemoveLc(uint8_t lcId)=0
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
NS_LOG_COMPONENT_DEFINE("LteUeRrc")
RachConfigDedicated rachConfigDedicated
Definition: lte-rrc-sap.h:402
void DoRecvRrcConnectionReestablishmentReject(LteRrcSap::RrcConnectionReestablishmentReject msg)
Definition: lte-ue-rrc.cc:958
bool m_connectionPending
Definition: lte-ue-rrc.h:322
uint64_t GetImsi(void)
Definition: lte-ue-rrc.cc:283
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
LteMacSapProvider * m_macSapProvider
Definition: lte-ue-rrc.h:282
static double RsrqRange2Db(uint8_t range)
Definition: lte-common.cc:218
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
uint8_t Bid2Drbid(uint8_t bid)
Definition: lte-ue-rrc.cc:1570
LteUeCmacSapUser * GetLteUeCmacSapUser()
Definition: lte-ue-rrc.cc:236
friend class UeMemberLteUeCmacSapUser
Definition: lte-ue-rrc.h:53
LteRrcSap::QuantityConfig quantityConfig
Definition: lte-ue-rrc.h:338
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
Definition: lte-ue-rrc.cc:243
LteUeRrcSapUser * m_rrcSapUser
Definition: lte-ue-rrc.h:279
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndOkTrace
Definition: lte-ue-rrc.h:320
uint16_t m_dlEarfcn
Definition: lte-ue-rrc.h:306
Ptr< LteSignalingRadioBearerInfo > m_srb0
Definition: lte-ue-rrc.h:294
static TypeId GetTypeId(void)
Definition: lte-rlc-um.cc:55
void DisposeOldSrb1()
Definition: lte-ue-rrc.cc:1563
Ptr< Object > Create(void) const
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
Definition: lte-ue-rrc.h:318
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Definition: lte-ue-rrc.cc:871
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Definition: lte-ue-rrc.cc:942
uint8_t m_dlBandwidth
Definition: lte-ue-rrc.h:303
Hold an unsigned integer type.
Definition: uinteger.h:46
Ptr< SampleEmitter > s
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
std::list< MeasIdToAddMod > measIdToAddModList
Definition: lte-rrc-sap.h:363
virtual void DoInitialize(void)
Definition: lte-ue-rrc.cc:347
std::map< uint16_t, MeasValues > m_storedMeasValues
Definition: lte-ue-rrc.h:364
PhysicalConfigDedicated physicalConfigDedicated
Definition: lte-rrc-sap.h:184
Ptr< LteSignalingRadioBearerInfo > m_srb1
Definition: lte-ue-rrc.h:295
LteUeCphySapProvider * m_cphySapProvider
Definition: lte-ue-rrc.h:274
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:304
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
Definition: lte-ue-rrc.cc:229
std::map< uint8_t, LteRrcSap::MeasIdToAddMod > measIdList
Definition: lte-ue-rrc.h:335
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
std::map< uint8_t, uint8_t > m_bid2DrbidMap
Definition: lte-ue-rrc.h:271
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-ue-rrc.cc:257
RadioResourceConfigDedicated radioResourceConfigDedicated
Definition: lte-rrc-sap.h:490
virtual void SyncronizeWithEnb(uint16_t cellId, uint16_t dlEarfcn)=0
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
Definition: lte-ue-rrc.cc:215
void SwitchToState(State s)
Definition: lte-ue-rrc.cc:1579
VarMeasConfig m_varMeasConfig
Definition: lte-ue-rrc.h:352
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
Definition: lte-ue-rrc.h:337
LteUeCphySapUser * m_cphySapUser
Definition: lte-ue-rrc.h:273
virtual void Setup(SetupParameters params)=0
virtual void SetSrsConfigurationIndex(uint16_t srcCi)=0
hold objects of type Ptr
Definition: pointer.h:33
LteAsSapUser * m_asSapUser
Definition: lte-ue-rrc.h:286
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void DoNotifyRandomAccessSuccessful()
Definition: lte-ue-rrc.cc:446
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:311
uint16_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:318
const char * g_ueRrcStateName[LteUeRrc::NUM_STATES]
Definition: lte-ue-rrc.cc:96
void DoSendData(Ptr< Packet > packet, uint8_t bid)
Definition: lte-ue-rrc.cc:380
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:985
RadioResourceConfigCommonSib radioResourceConfigCommon
Definition: lte-rrc-sap.h:431
uint16_t m_ulEarfcn
Definition: lte-ue-rrc.h:307
static Time Now(void)
Definition: simulator.cc:180
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Definition: lte-ue-rrc.cc:976
virtual void AddLc(uint8_t lcId, LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
CarrierBandwidthEutra carrierBandwidth
Definition: lte-rrc-sap.h:398
uint8_t m_ulBandwidth
Definition: lte-ue-rrc.h:304
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:222
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
Definition: lte-ue-rrc.h:316
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
Definition: lte-ue-rrc.h:296
virtual void SendMeasurementReport(MeasurementReport msg)=0
virtual void StartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)=0
virtual void SetDlBandwidth(uint8_t dlBandwidth)=0
void StartConnection()
Definition: lte-ue-rrc.cc:1537
instantiate subclasses of ns3::Object.
static uint8_t Dbm2RsrpRange(double dbm)
Definition: lte-common.cc:210
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:289
std::string ToString(EpcUeNas::State s)
Definition: epc-ue-nas.cc:47
virtual void SetTransmissionMode(uint8_t txMode)=0
void DoRecvMasterInformationBlock(LteRrcSap::MasterInformationBlock msg)
Definition: lte-ue-rrc.cc:536
void DoNotifyRandomAccessFailed()
Definition: lte-ue-rrc.cc:480
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Definition: lte-ue-rrc.cc:804
#define NS_LOG_WARN(msg)
Definition: log.h:246
LteUeRrcSapProvider * m_rrcSapProvider
Definition: lte-ue-rrc.h:280
void DoConnect()
Definition: lte-ue-rrc.cc:498
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Definition: lte-ue-rrc.cc:992
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
Definition: lte-ue-rrc.h:314
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:296
std::list< DrbToAddMod > drbToAddModList
Definition: lte-rrc-sap.h:181
virtual void NotifyConnectionReleased()=0
std::map< uint8_t, VarMeasReport > m_varMeasReportList
Definition: lte-ue-rrc.h:354
LteAsSapProvider * m_asSapProvider
Definition: lte-ue-rrc.h:285
LteUeCmacSapProvider * m_cmacSapProvider
Definition: lte-ue-rrc.h:277
uint16_t m_rnti
Definition: lte-ue-rrc.h:291
uint64_t m_imsi
Definition: lte-ue-rrc.h:290
SystemInformationBlockType2 sib2
Definition: lte-rrc-sap.h:438
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:270
void DoReportUeMeasurements(LteUeCphySapUser::UeMeasurementsParameters params)
Definition: lte-ue-rrc.cc:549
#define NS_LOG_ERROR(msg)
Definition: log.h:237
bool m_receivedSib2
Definition: lte-ue-rrc.h:324
TracedCallback< uint64_t, uint16_t, uint16_t, State, State > m_stateTransitionTrace
Definition: lte-ue-rrc.h:310
void SendMeasurementReport(uint8_t measId)
Definition: lte-ue-rrc.cc:1418
a base class which provides memory management and object aggregation
Definition: object.h:63
contain a set of ns3::Object pointers.
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Definition: lte-ue-rrc.cc:429
virtual void SendRrcConnectionRequest(RrcConnectionRequest msg)=0
static uint8_t Db2RsrqRange(double db)
Definition: lte-common.cc:226
virtual void RecvData(Ptr< Packet > packet)=0
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Definition: lte-ue-rrc.cc:66
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:250
void DoForceCampedOnEnb(uint16_t cellId, uint16_t earfcn)
Definition: lte-ue-rrc.cc:487
void DoDisconnect()
Definition: lte-ue-rrc.cc:400
Ptr< T > GetObject(void) const
Definition: object.h:360
virtual void SetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:72
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessSuccessfulTrace
Definition: lte-ue-rrc.h:312
std::list< uint8_t > measIdToRemoveList
Definition: lte-rrc-sap.h:362
a unique identifier for an interface.
Definition: type-id.h:49
virtual void ConfigureUplink(uint16_t ulEarfcn, uint8_t ulBandwidth)=0
std::list< ReportConfigToAddMod > reportConfigToAddModList
Definition: lte-rrc-sap.h:361
virtual void ConfigureRach(RachConfig rc)=0
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
static TypeId GetTypeId(void)
Definition: lte-rlc-am.cc:86
void SetImsi(uint64_t imsi)
Definition: lte-ue-rrc.cc:276
uint8_t m_lastRrcTransactionIdentifier
Definition: lte-ue-rrc.h:301
void LeaveConnectedMode()
Definition: lte-ue-rrc.cc:1546
RaSupervisionInfo raSupervisionInfo
Definition: lte-rrc-sap.h:165
virtual void NotifyRandomAccessFailed()
Definition: lte-ue-rrc.cc:85
LteUeCmacSapUser * m_cmacSapUser
Definition: lte-ue-rrc.h:276
bool m_receivedMib
Definition: lte-ue-rrc.h:323
static double RsrpRange2Dbm(uint8_t range)
Definition: lte-common.cc:202
State GetState()
Definition: lte-ue-rrc.cc:332