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  * Budiarto Herman <budiarto.herman@magister.fi>
20  */
21 
22 #include "lte-ue-rrc.h"
23 
24 #include <ns3/fatal-error.h>
25 #include <ns3/log.h>
26 #include <ns3/object-map.h>
27 #include <ns3/object-factory.h>
28 #include <ns3/simulator.h>
29 
30 #include <ns3/lte-rlc.h>
31 #include <ns3/lte-rlc-tm.h>
32 #include <ns3/lte-rlc-um.h>
33 #include <ns3/lte-rlc-am.h>
34 #include <ns3/lte-pdcp.h>
35 #include <ns3/lte-radio-bearer-info.h>
36 
37 #include <cmath>
38 
39 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
40 
41 namespace ns3 {
42 
43 
45 // CMAC SAP forwarder
47 
49 {
50 public:
52 
53  virtual void SetTemporaryCellRnti (uint16_t rnti);
54  virtual void NotifyRandomAccessSuccessful ();
55  virtual void NotifyRandomAccessFailed ();
56 
57 private:
59 };
60 
62  : m_rrc (rrc)
63 {
64 }
65 
66 void
68 {
70 }
71 
72 
73 void
75 {
77 }
78 
79 void
81 {
83 }
84 
85 
86 
87 
88 
89 
90 
91 static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES] =
92 {
93  "IDLE_START",
94  "IDLE_CELL_SEARCH",
95  "IDLE_WAIT_MIB_SIB1",
96  "IDLE_WAIT_MIB",
97  "IDLE_WAIT_SIB1",
98  "IDLE_CAMPED_NORMALLY",
99  "IDLE_WAIT_SIB2",
100  "IDLE_RANDOM_ACCESS",
101  "IDLE_CONNECTING",
102  "CONNECTED_NORMALLY",
103  "CONNECTED_HANDOVER",
104  "CONNECTED_PHY_PROBLEM",
105  "CONNECTED_REESTABLISHING"
106 };
107 
108 static const std::string & ToString (LteUeRrc::State s)
109 {
110  return 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_START),
128  m_imsi (0),
129  m_rnti (0),
130  m_cellId (0),
131  m_useRlcSm (true),
132  m_connectionPending (false),
133  m_hasReceivedMib (false),
134  m_hasReceivedSib1 (false),
135  m_hasReceivedSib2 (false),
136  m_csgWhiteList (0)
137 {
138  NS_LOG_FUNCTION (this);
144 }
145 
146 
148 {
149  NS_LOG_FUNCTION (this);
150 }
151 
152 void
154 {
155  NS_LOG_FUNCTION (this);
156  delete m_cphySapUser;
157  delete m_cmacSapUser;
158  delete m_rrcSapProvider;
159  delete m_drbPdcpSapUser;
160  delete m_asSapProvider;
161  m_drbMap.clear ();
162 }
163 
164 TypeId
166 {
167  static TypeId tid = TypeId ("ns3::LteUeRrc")
168  .SetParent<Object> ()
169  .AddConstructor<LteUeRrc> ()
170  .AddAttribute ("DataRadioBearerMap", "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
171  ObjectMapValue (),
173  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
174  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
175  PointerValue (),
176  MakePointerAccessor (&LteUeRrc::m_srb0),
177  MakePointerChecker<LteSignalingRadioBearerInfo> ())
178  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
179  PointerValue (),
180  MakePointerAccessor (&LteUeRrc::m_srb1),
181  MakePointerChecker<LteSignalingRadioBearerInfo> ())
182  .AddAttribute ("CellId",
183  "Serving cell identifier",
184  UintegerValue (0), // unused, read-only attribute
185  MakeUintegerAccessor (&LteUeRrc::GetCellId),
186  MakeUintegerChecker<uint16_t> ())
187  .AddAttribute ("C-RNTI",
188  "Cell Radio Network Temporary Identifier",
189  UintegerValue (0), // unused, read-only attribute
190  MakeUintegerAccessor (&LteUeRrc::GetRnti),
191  MakeUintegerChecker<uint16_t> ())
192  .AddTraceSource ("MibReceived",
193  "trace fired upon reception of Master Information Block",
195  .AddTraceSource ("Sib1Received",
196  "trace fired upon reception of System Information Block Type 1",
198  .AddTraceSource ("Sib2Received",
199  "trace fired upon reception of System Information Block Type 2",
201  .AddTraceSource ("StateTransition",
202  "trace fired upon every UE RRC state transition",
204  .AddTraceSource ("InitialCellSelectionEndOk",
205  "trace fired upon successful initial cell selection procedure",
207  .AddTraceSource ("InitialCellSelectionEndError",
208  "trace fired upon failed initial cell selection procedure",
210  .AddTraceSource ("RandomAccessSuccessful",
211  "trace fired upon successful completion of the random access procedure",
213  .AddTraceSource ("RandomAccessError",
214  "trace fired upon failure of the random access procedure",
216  .AddTraceSource ("ConnectionEstablished",
217  "trace fired upon successful RRC connection establishment",
219  .AddTraceSource ("ConnectionReconfiguration",
220  "trace fired upon RRC connection reconfiguration",
222  .AddTraceSource ("HandoverStart",
223  "trace fired upon start of a handover procedure",
225  .AddTraceSource ("HandoverEndOk",
226  "trace fired upon successful termination of a handover procedure",
228  .AddTraceSource ("HandoverEndError",
229  "trace fired upon failure of a handover procedure",
231  ;
232  return tid;
233 }
234 
235 
236 void
238 {
239  NS_LOG_FUNCTION (this << s);
241 }
242 
245 {
246  NS_LOG_FUNCTION (this);
247  return m_cphySapUser;
248 }
249 
250 void
252 {
253  NS_LOG_FUNCTION (this << s);
255 }
256 
259 {
260  NS_LOG_FUNCTION (this);
261  return m_cmacSapUser;
262 }
263 
264 void
266 {
267  NS_LOG_FUNCTION (this << s);
268  m_rrcSapUser = s;
269 }
270 
273 {
274  NS_LOG_FUNCTION (this);
275  return m_rrcSapProvider;
276 }
277 
278 void
280 {
281  NS_LOG_FUNCTION (this << s);
283 }
284 
285 void
287 {
288  m_asSapUser = s;
289 }
290 
293 {
294  return m_asSapProvider;
295 }
296 
297 void
298 LteUeRrc::SetImsi (uint64_t imsi)
299 {
300  NS_LOG_FUNCTION (this << imsi);
301  m_imsi = imsi;
302 }
303 
304 uint64_t
305 LteUeRrc::GetImsi (void) const
306 {
307  return m_imsi;
308 }
309 
310 uint16_t
312 {
313  NS_LOG_FUNCTION (this);
314  return m_rnti;
315 }
316 
317 uint16_t
319 {
320  NS_LOG_FUNCTION (this);
321  return m_cellId;
322 }
323 
324 
325 uint8_t
327 {
328  NS_LOG_FUNCTION (this);
329  return m_ulBandwidth;
330 }
331 
332 uint8_t
334 {
335  NS_LOG_FUNCTION (this);
336  return m_dlBandwidth;
337 }
338 
339 uint16_t
341 {
342  return m_dlEarfcn;
343 }
344 
345 uint16_t
347 {
348  NS_LOG_FUNCTION (this);
349  return m_ulEarfcn;
350 }
351 
353 LteUeRrc::GetState (void) const
354 {
355  NS_LOG_FUNCTION (this);
356  return m_state;
357 }
358 
359 void
361 {
362  NS_LOG_FUNCTION (this);
363  m_useRlcSm = val;
364 }
365 
366 
367 void
369 {
370  NS_LOG_FUNCTION (this);
371 
372  // setup the UE side of SRB0
373  uint8_t lcid = 0;
374 
375  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
377  rlc->SetRnti (m_rnti);
378  rlc->SetLcId (lcid);
379 
380  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
381  m_srb0->m_rlc = rlc;
382  m_srb0->m_srbIdentity = 0;
384  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
385  ueParams.srb1SapProvider = 0;
386  m_rrcSapUser->Setup (ueParams);
387 
388  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
390  lcConfig.priority = 0; // highest priority
391  lcConfig.prioritizedBitRateKbps = 65535; // maximum
392  lcConfig.bucketSizeDurationMs = 65535; // maximum
393  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
394 
395  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
396 
397 }
398 
399 
400 void
401 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
402 {
403  NS_LOG_FUNCTION (this << packet);
404 
405  uint8_t drbid = Bid2Drbid (bid);
406 
407  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
408  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
409 
411  params.pdcpSdu = packet;
412  params.rnti = m_rnti;
413  params.lcid = it->second->m_logicalChannelIdentity;
414 
415  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending packet " << packet
416  << " on DRBID " << (uint32_t) drbid
417  << " (LCID " << (uint32_t) params.lcid << ")"
418  << " (" << packet->GetSize () << " bytes)");
419  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
420 }
421 
422 
423 void
425 {
426  NS_LOG_FUNCTION (this);
427 
428  switch (m_state)
429  {
430  case IDLE_START:
431  case IDLE_CELL_SEARCH:
432  case IDLE_WAIT_MIB_SIB1:
433  case IDLE_WAIT_MIB:
434  case IDLE_WAIT_SIB1:
436  NS_LOG_INFO ("already disconnected");
437  break;
438 
439  case IDLE_WAIT_SIB2:
440  case IDLE_CONNECTING:
441  NS_FATAL_ERROR ("cannot abort connection setup procedure");
442  break;
443 
444  case CONNECTED_NORMALLY:
445  case CONNECTED_HANDOVER:
449  break;
450 
451  default: // i.e. IDLE_RANDOM_ACCESS
452  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
453  break;
454  }
455 }
456 
457 void
459 {
460  NS_LOG_FUNCTION (this);
461  m_asSapUser->RecvData (params.pdcpSdu);
462 }
463 
464 
465 void
467 {
468  NS_LOG_FUNCTION (this << rnti);
469  m_rnti = rnti;
470  m_srb0->m_rlc->SetRnti (m_rnti);
472 }
473 
474 void
476 {
477  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
479 
480  switch (m_state)
481  {
482  case IDLE_RANDOM_ACCESS:
483  {
484  // we just received a RAR with a T-C-RNTI and an UL grant
485  // send RRC connection request as message 3 of the random access procedure
488  msg.ueIdentity = m_imsi;
490  }
491  break;
492 
493  case CONNECTED_HANDOVER:
494  {
498 
499  // 3GPP TS 36.331 section 5.5.6.1 Measurements related actions upon handover
500  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
501  for (measIdIt = m_varMeasConfig.measIdList.begin ();
502  measIdIt != m_varMeasConfig.measIdList.end ();
503  ++measIdIt)
504  {
505  VarMeasReportListClear (measIdIt->second.measId);
506  }
507 
510  }
511  break;
512 
513  default:
514  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
515  break;
516  }
517 }
518 
519 void
521 {
522  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
524 
525  switch (m_state)
526  {
527  case IDLE_RANDOM_ACCESS:
528  {
531  }
532  break;
533 
534  case CONNECTED_HANDOVER:
535  {
542  }
543  break;
544 
545  default:
546  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
547  break;
548  }
549 }
550 
551 
552 void
554 {
555  NS_LOG_FUNCTION (this << m_imsi << csgId);
556  m_csgWhiteList = csgId;
557 }
558 
559 void
561 {
562  NS_LOG_FUNCTION (this << m_imsi << dlEarfcn);
564  "cannot start cell selection from state " << ToString (m_state));
565  m_dlEarfcn = dlEarfcn;
568 }
569 
570 void
571 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint16_t dlEarfcn)
572 {
573  NS_LOG_FUNCTION (this << m_imsi << cellId << dlEarfcn);
574 
575  switch (m_state)
576  {
577  case IDLE_START:
578  m_cellId = cellId;
579  m_dlEarfcn = dlEarfcn;
582  break;
583 
584  case IDLE_CELL_SEARCH:
585  case IDLE_WAIT_MIB_SIB1:
586  case IDLE_WAIT_SIB1:
587  NS_FATAL_ERROR ("cannot abort cell selection " << ToString (m_state));
588  break;
589 
590  case IDLE_WAIT_MIB:
591  NS_LOG_INFO ("already forced to camp to cell " << m_cellId);
592  break;
593 
595  case IDLE_WAIT_SIB2:
596  case IDLE_RANDOM_ACCESS:
597  case IDLE_CONNECTING:
598  NS_LOG_INFO ("already camped to cell " << m_cellId);
599  break;
600 
601  case CONNECTED_NORMALLY:
602  case CONNECTED_HANDOVER:
605  NS_LOG_INFO ("already connected to cell " << m_cellId);
606  break;
607 
608  default:
609  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
610  break;
611  }
612 
613 }
614 
615 void
617 {
618  NS_LOG_FUNCTION (this << m_imsi);
619 
620  switch (m_state)
621  {
622  case IDLE_START:
623  case IDLE_CELL_SEARCH:
624  case IDLE_WAIT_MIB_SIB1:
625  case IDLE_WAIT_SIB1:
626  case IDLE_WAIT_MIB:
627  m_connectionPending = true;
628  break;
629 
631  m_connectionPending = true;
633  break;
634 
635  case IDLE_WAIT_SIB2:
636  case IDLE_RANDOM_ACCESS:
637  case IDLE_CONNECTING:
638  NS_LOG_INFO ("already connecting");
639  break;
640 
641  case CONNECTED_NORMALLY:
643  case CONNECTED_HANDOVER:
644  NS_LOG_INFO ("already connected");
645  break;
646 
647  default:
648  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
649  break;
650  }
651 }
652 
653 
654 
655 // CPHY SAP methods
656 
657 void
660 {
663  m_hasReceivedMib = true;
665 
666  switch (m_state)
667  {
668  case IDLE_WAIT_MIB:
669  // manual attachment
671  break;
672 
673  case IDLE_WAIT_MIB_SIB1:
674  // automatic attachment from Idle mode cell selection
676  break;
677 
678  default:
679  // do nothing extra
680  break;
681  }
682 }
683 
684 void
687 {
688  switch (m_state)
689  {
690  case IDLE_WAIT_SIB1:
692  "Cell identity in SIB1 does not match with the originating cell");
693  m_hasReceivedSib1 = true;
694  m_lastSib1 = msg;
697  break;
698 
700  case IDLE_RANDOM_ACCESS:
701  case IDLE_CONNECTING:
702  case CONNECTED_NORMALLY:
703  case CONNECTED_HANDOVER:
707  "Cell identity in SIB1 does not match with the originating cell");
708  m_hasReceivedSib1 = true;
709  m_lastSib1 = msg;
711  break;
712 
713  case IDLE_WAIT_MIB_SIB1:
714  // MIB has not been received, so ignore this SIB1
715  break;
716 
717  default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
718  // do nothing
719  break;
720  }
721 }
722 
723 void
725 {
726  NS_LOG_FUNCTION (this);
727 
728  // layer 3 filtering does not apply in IDLE mode
729  bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
730 
731  std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
732  for (newMeasIt = params.m_ueMeasurementsList.begin ();
733  newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
734  {
735  SaveUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
736  newMeasIt->m_rsrq, useLayer3Filtering);
737  }
738 
739  if (m_state == IDLE_CELL_SEARCH)
740  {
741  // start decoding BCH
743  }
744  else
745  {
746  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
747  for (measIdIt = m_varMeasConfig.measIdList.begin ();
748  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
749  {
750  MeasurementReportTriggering (measIdIt->first);
751  }
752  }
753 
754 } // end of LteUeRrc::DoReportUeMeasurements
755 
756 
757 
758 // RRC SAP methods
759 
760 void
762 {
763  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
764  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
765  if (m_srb1)
766  {
767  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
768  }
769 }
770 
771 
772 void
774 {
775  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
776 
777  if (msg.haveSib2)
778  {
779  switch (m_state)
780  {
782  case IDLE_WAIT_SIB2:
783  case IDLE_RANDOM_ACCESS:
784  case IDLE_CONNECTING:
785  case CONNECTED_NORMALLY:
786  case CONNECTED_HANDOVER:
789  m_hasReceivedSib2 = true;
799  if (m_state == IDLE_WAIT_SIB2)
800  {
802  StartConnection ();
803  }
804  break;
805 
806  default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
807  // do nothing
808  break;
809  }
810  }
811 
812 }
813 
814 
815 void
817 {
818  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
819  switch (m_state)
820  {
821  case IDLE_CONNECTING:
822  {
830  }
831  break;
832 
833  default:
834  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
835  break;
836  }
837 }
838 
839 void
841 {
842  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
843  switch (m_state)
844  {
845  case CONNECTED_NORMALLY:
846  if (msg.haveMobilityControlInfo)
847  {
848  NS_LOG_INFO ("haveMobilityControlInfo == true");
861  m_srb0->m_rlc->SetRnti (m_rnti);
862  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
867 
868  // we re-establish SRB1 by creating a new entity
869  // note that we can't dispose the old entity now, because
870  // it's in the current stack, so we would corrupt the stack
871  // if we did so. Hence we schedule it for later disposal
872  m_srb1Old = m_srb1;
874  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
875 
876  m_drbMap.clear (); // dispose all DRBs
878 
879  if (msg.haveMeasConfig)
880  {
882  }
883  // RRC connection reconfiguration completed will be sent
884  // after handover is complete
885  }
886  else
887  {
888  NS_LOG_INFO ("haveMobilityControlInfo == false");
890  {
892  }
893  if (msg.haveMeasConfig)
894  {
896  }
901  }
902  break;
903 
904  default:
905  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
906  break;
907  }
908 }
909 
910 void
912 {
913  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
914  switch (m_state)
915  {
917  {
925  }
926  break;
927 
928  default:
929  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
930  break;
931  }
932 }
933 
934 void
936 {
937  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
938  switch (m_state)
939  {
941  {
947  }
948  break;
949 
950  default:
951  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
952  break;
953  }
954 }
955 
956 void
958 {
959  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
961 }
962 
963 void
965 {
966  NS_LOG_FUNCTION (this);
969 }
970 
971 
972 
973 void
975 {
976  NS_LOG_FUNCTION (this);
978 
979  uint16_t maxRsrpCellId = 0;
980  double maxRsrp = -std::numeric_limits<double>::infinity ();
981 
982  std::map<uint16_t, MeasValues>::iterator it;
983  for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
984  {
985  /*
986  * This block attempts to find a cell with strongest RSRP and has not
987  * yet been identified as "acceptable cell".
988  */
989  if (maxRsrp < it->second.rsrp)
990  {
991  std::set<uint16_t>::const_iterator itCell;
992  itCell = m_acceptableCell.find (it->first);
993  if (itCell == m_acceptableCell.end ())
994  {
995  maxRsrpCellId = it->first;
996  maxRsrp = it->second.rsrp;
997  }
998  }
999  }
1000 
1001  if (maxRsrpCellId == 0)
1002  {
1003  NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
1004  }
1005  else
1006  {
1007  NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
1008  << " is the strongest untried surrounding cell");
1011  }
1012 
1013 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1014 
1015 
1016 void
1018 {
1019  NS_LOG_FUNCTION (this);
1023  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1024 
1025  // Cell selection criteria evaluation
1026 
1027  bool isSuitableCell = false;
1028  bool isAcceptableCell = false;
1029  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1030  double qRxLevMeas = storedMeasIt->second.rsrp;
1032  NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
1033  << " qrxlevmeas=" << qRxLevMeas << " dBm"
1034  << " qrxlevmin=" << qRxLevMin << " dBm");
1035 
1036  if (qRxLevMeas - qRxLevMin > 0)
1037  {
1038  isAcceptableCell = true;
1039 
1040  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1041  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1042 
1043  isSuitableCell = (cellCsgIndication == false) || (cellCsgId == m_csgWhiteList);
1044 
1045  NS_LOG_LOGIC (this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
1046  << cellCsgId << "/" << cellCsgIndication);
1047  }
1048 
1049  // Cell selection decision
1050 
1051  if (isSuitableCell)
1052  {
1053  m_cellId = cellId;
1058  }
1059  else
1060  {
1061  // ignore the MIB and SIB1 received from this cell
1062  m_hasReceivedMib = false;
1063  m_hasReceivedSib1 = false;
1064 
1066 
1067  if (isAcceptableCell)
1068  {
1069  /*
1070  * The cells inserted into this list will not be considered for
1071  * subsequent cell search attempt.
1072  */
1073  m_acceptableCell.insert (cellId);
1074  }
1075 
1077  SynchronizeToStrongestCell (); // retry to a different cell
1078  }
1079 
1080 } // end of void LteUeRrc::EvaluateCellForSelection ()
1081 
1082 
1083 void
1085 {
1086  NS_LOG_FUNCTION (this);
1088 
1089  if (pcd.haveAntennaInfoDedicated)
1090  {
1092  }
1094  {
1096  }
1097 
1098  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1099  if (stamIt != rrcd.srbToAddModList.end ())
1100  {
1101  if (m_srb1 == 0)
1102  {
1103  // SRB1 not setup yet
1105  "unexpected state " << ToString (m_state));
1106  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1107 
1108  const uint8_t lcid = 1; // fixed LCID for SRB1
1109 
1110  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1112  rlc->SetRnti (m_rnti);
1113  rlc->SetLcId (lcid);
1114 
1115  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1116  pdcp->SetRnti (m_rnti);
1117  pdcp->SetLcId (lcid);
1118  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1119  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1120  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1121 
1122  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1123  m_srb1->m_rlc = rlc;
1124  m_srb1->m_pdcp = pdcp;
1125  m_srb1->m_srbIdentity = 1;
1126 
1127  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1128  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1129  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1130  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1131 
1133  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1134  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1135  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1136  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1137 
1138  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
1139 
1140  ++stamIt;
1141  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1142 
1144  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1145  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1146  m_rrcSapUser->Setup (ueParams);
1147  }
1148  else
1149  {
1150  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1151  // would need to modify m_srb1, and then propagate changes to the MAC
1152  }
1153  }
1154 
1155 
1156  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1157  for (dtamIt = rrcd.drbToAddModList.begin ();
1158  dtamIt != rrcd.drbToAddModList.end ();
1159  ++dtamIt)
1160  {
1161  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1162  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1163 
1164  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1165  if (drbMapIt == m_drbMap.end ())
1166  {
1167  NS_LOG_INFO ("New Data Radio Bearer");
1168 
1169  TypeId rlcTypeId;
1170  if (m_useRlcSm)
1171  {
1172  rlcTypeId = LteRlcSm::GetTypeId ();
1173  }
1174  else
1175  {
1176  switch (dtamIt->rlcConfig.choice)
1177  {
1179  rlcTypeId = LteRlcAm::GetTypeId ();
1180  break;
1181 
1183  rlcTypeId = LteRlcUm::GetTypeId ();
1184  break;
1185 
1186  default:
1187  NS_FATAL_ERROR ("unsupported RLC configuration");
1188  break;
1189  }
1190  }
1191 
1192  ObjectFactory rlcObjectFactory;
1193  rlcObjectFactory.SetTypeId (rlcTypeId);
1194  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1196  rlc->SetRnti (m_rnti);
1197  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1198 
1199  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1200  drbInfo->m_rlc = rlc;
1201  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1202  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1203  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1204 
1205  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1206  // if we are using RLC/SM we don't care of anything above RLC
1207  if (rlcTypeId != LteRlcSm::GetTypeId ())
1208  {
1209  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1210  pdcp->SetRnti (m_rnti);
1211  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1212  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1213  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1214  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1215  drbInfo->m_pdcp = pdcp;
1216  }
1217 
1218  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1219 
1220  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1221 
1222 
1224  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1225  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1226  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1227  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1228 
1229  m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
1230  lcConfig,
1231  rlc->GetLteMacSapUser ());
1232  rlc->Initialize ();
1233  }
1234  else
1235  {
1236  NS_LOG_INFO ("request to modify existing DRBID");
1237  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1239  }
1240  }
1241 
1242  std::list<uint8_t>::iterator dtdmIt;
1243  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1244  dtdmIt != rrcd.drbToReleaseList.end ();
1245  ++dtdmIt)
1246  {
1247  uint8_t drbid = *dtdmIt;
1248  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
1249  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1250  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1251  m_drbMap.erase (it);
1252  m_bid2DrbidMap.erase (drbid);
1253  }
1254 }
1255 
1256 
1257 void
1259 {
1260  NS_LOG_FUNCTION (this);
1261 
1262  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1263 
1264  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1265  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1266  it != mc.measObjectToRemoveList.end ();
1267  ++it)
1268  {
1269  uint8_t measObjectId = *it;
1270  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1271  m_varMeasConfig.measObjectList.erase (measObjectId);
1272  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1273  while (measIdIt != m_varMeasConfig.measIdList.end ())
1274  {
1275  if (measIdIt->second.measObjectId == measObjectId)
1276  {
1277  uint8_t measId = measIdIt->second.measId;
1278  NS_ASSERT (measId == measIdIt->first);
1279  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1280  // note: postfix operator preserves iterator validity
1281  m_varMeasConfig.measIdList.erase (measIdIt++);
1282  VarMeasReportListClear (measId);
1283  }
1284  else
1285  {
1286  ++measIdIt;
1287  }
1288  }
1289 
1290  }
1291 
1292  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1293  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1294  it != mc.measObjectToAddModList.end ();
1295  ++it)
1296  {
1297  // simplifying assumptions
1298  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1299  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1300  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1301  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1302  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
1303 
1304  uint8_t measObjectId = it->measObjectId;
1305  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1306  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1307  {
1308  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1309  measObjectIt->second = *it;
1310  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1311  = m_varMeasConfig.measIdList.begin ();
1312  measIdIt != m_varMeasConfig.measIdList.end ();
1313  ++measIdIt)
1314  {
1315  if (measIdIt->second.measObjectId == measObjectId)
1316  {
1317  uint8_t measId = measIdIt->second.measId;
1318  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1319  VarMeasReportListClear (measId);
1320  }
1321  }
1322  }
1323  else
1324  {
1325  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1326  m_varMeasConfig.measObjectList[measObjectId] = *it;
1327  }
1328 
1329  }
1330 
1331  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1332  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1333  it != mc.reportConfigToRemoveList.end ();
1334  ++it)
1335  {
1336  uint8_t reportConfigId = *it;
1337  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1338  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1339  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1340  while (measIdIt != m_varMeasConfig.measIdList.end ())
1341  {
1342  if (measIdIt->second.reportConfigId == reportConfigId)
1343  {
1344  uint8_t measId = measIdIt->second.measId;
1345  NS_ASSERT (measId == measIdIt->first);
1346  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1347  // note: postfix operator preserves iterator validity
1348  m_varMeasConfig.measIdList.erase (measIdIt++);
1349  VarMeasReportListClear (measId);
1350  }
1351  else
1352  {
1353  ++measIdIt;
1354  }
1355  }
1356 
1357  }
1358 
1359  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1360  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1361  it != mc.reportConfigToAddModList.end ();
1362  ++it)
1363  {
1364  // simplifying assumptions
1365  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1366  "only trigger type EVENT is supported");
1367 
1368  uint8_t reportConfigId = it->reportConfigId;
1369  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1370  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1371  {
1372  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1373  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1374  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1375  = m_varMeasConfig.measIdList.begin ();
1376  measIdIt != m_varMeasConfig.measIdList.end ();
1377  ++measIdIt)
1378  {
1379  if (measIdIt->second.reportConfigId == reportConfigId)
1380  {
1381  uint8_t measId = measIdIt->second.measId;
1382  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1383  VarMeasReportListClear (measId);
1384  }
1385  }
1386  }
1387  else
1388  {
1389  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1390  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1391  }
1392 
1393  }
1394 
1395  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1396  if (mc.haveQuantityConfig)
1397  {
1398  NS_LOG_LOGIC (this << " setting quantityConfig");
1400  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1401  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP/4.0);
1402  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ/4.0);
1403  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1404 
1405  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1406  = m_varMeasConfig.measIdList.begin ();
1407  measIdIt != m_varMeasConfig.measIdList.end ();
1408  ++measIdIt)
1409  {
1410  VarMeasReportListClear (measIdIt->second.measId);
1411  }
1412  }
1413 
1414  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1415  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1416  it != mc.measIdToRemoveList.end ();
1417  ++it)
1418  {
1419  uint8_t measId = *it;
1420  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1421  m_varMeasConfig.measIdList.erase (measId);
1422  VarMeasReportListClear (measId);
1423 
1424  // removing time-to-trigger queues
1425  m_enteringTriggerQueue.erase (measId);
1426  m_leavingTriggerQueue.erase (measId);
1427  }
1428 
1429  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1430  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1431  it != mc.measIdToAddModList.end ();
1432  ++it)
1433  {
1434  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId
1435  << " (measObjectId=" << (uint32_t) it->measObjectId
1436  << ", reportConfigId=" << (uint32_t) it->reportConfigId
1437  << ")");
1438  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1439  != m_varMeasConfig.measObjectList.end ());
1440  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1441  != m_varMeasConfig.reportConfigList.end ());
1442  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1443  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1444  if (measReportIt != m_varMeasReportList.end ())
1445  {
1446  measReportIt->second.periodicReportTimer.Cancel ();
1447  m_varMeasReportList.erase (measReportIt);
1448  }
1449  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1450  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1451 
1452  // new empty queues for time-to-trigger
1453  std::list<PendingTrigger_t> s;
1454  m_enteringTriggerQueue[it->measId] = s;
1455  m_leavingTriggerQueue[it->measId] = s;
1456  }
1457 
1458  if (mc.haveMeasGapConfig)
1459  {
1460  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1461  }
1462 
1463  if (mc.haveSmeasure)
1464  {
1465  NS_FATAL_ERROR ("s-measure is currently not supported");
1466  }
1467 
1468  if (mc.haveSpeedStatePars)
1469  {
1470  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1471  }
1472 }
1473 
1474 void
1475 LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
1476  bool useLayer3Filtering)
1477 {
1478  NS_LOG_FUNCTION (this << cellId << rsrp << rsrq << useLayer3Filtering);
1479 
1480  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);;
1481 
1482  if (storedMeasIt != m_storedMeasValues.end ())
1483  {
1484  if (useLayer3Filtering)
1485  {
1486  // F_n = (1-a) F_{n-1} + a M_n
1487  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
1488  + m_varMeasConfig.aRsrp * rsrp;
1489 
1490  if (std::isnan (storedMeasIt->second.rsrq))
1491  {
1492  // the previous RSRQ measurements provided UE PHY are invalid
1493  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1494  }
1495  else
1496  {
1497  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
1498  + m_varMeasConfig.aRsrq * rsrq;
1499  }
1500  }
1501  else
1502  {
1503  storedMeasIt->second.rsrp = rsrp;
1504  storedMeasIt->second.rsrq = rsrq;
1505  }
1506  }
1507  else
1508  {
1509  // first value is always unfiltered
1510  MeasValues v;
1511  v.rsrp = rsrp;
1512  v.rsrq = rsrq;
1513  std::pair<uint16_t, MeasValues> val (cellId, v);
1514  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
1515  ret = m_storedMeasValues.insert (val);
1516  NS_ASSERT_MSG (ret.second == true, "element already existed");
1517  storedMeasIt = ret.first;
1518  }
1519 
1520  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
1521  << ", measured cell " << m_cellId
1522  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
1523  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
1524  storedMeasIt->second.timestamp = Simulator::Now ();
1525 
1526 } // end of void SaveUeMeasurements
1527 
1528 void
1530 {
1531  NS_LOG_FUNCTION (this << (uint16_t) measId);
1532 
1533  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt =
1534  m_varMeasConfig.measIdList.find (measId);
1535  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1536  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
1537 
1538  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1539  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1540  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1541  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1542 
1543  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
1544  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
1545  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
1546  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1547 
1548  std::map<uint8_t, VarMeasReport>::iterator
1549  measReportIt = m_varMeasReportList.find (measId);
1550  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end ());
1551 
1552  // we don't check the purpose field, as it is only included for
1553  // triggerType == periodical, which is not supported
1554  NS_ASSERT_MSG (reportConfigEutra.triggerType
1556  "only triggerType == event is supported");
1557  // only EUTRA is supported, no need to check for it
1558 
1559  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
1560  bool eventEntryCondApplicable = false;
1561  bool eventLeavingCondApplicable = false;
1562  ConcernedCells_t concernedCellsEntry;
1563  ConcernedCells_t concernedCellsLeaving;
1564 
1565  switch (reportConfigEutra.eventId)
1566  {
1568  {
1569  /*
1570  * Event A1 (Serving becomes better than threshold)
1571  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1572  */
1573 
1574  double ms; // Ms, the measurement result of the serving cell
1575  double thresh; // Thresh, the threshold parameter for this event
1576  // Hys, the hysteresis parameter for this event.
1577  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1578 
1579  switch (reportConfigEutra.triggerQuantity)
1580  {
1582  ms = m_storedMeasValues[m_cellId].rsrp;
1583  NS_ASSERT (reportConfigEutra.threshold1.choice
1585  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1586  break;
1588  ms = m_storedMeasValues[m_cellId].rsrq;
1589  NS_ASSERT (reportConfigEutra.threshold1.choice
1591  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1592  break;
1593  default:
1594  NS_FATAL_ERROR ("unsupported triggerQuantity");
1595  break;
1596  }
1597 
1598  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1599  bool entryCond = ms - hys > thresh;
1600 
1601  if (entryCond)
1602  {
1603  if (!isMeasIdInReportList)
1604  {
1605  concernedCellsEntry.push_back (m_cellId);
1606  eventEntryCondApplicable = true;
1607  }
1608  else
1609  {
1610  /*
1611  * This is to check that the triggered cell recorded in the
1612  * VarMeasReportList is the serving cell.
1613  */
1614  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1615  != measReportIt->second.cellsTriggeredList.end ());
1616  }
1617  }
1618  else if (reportConfigEutra.timeToTrigger > 0)
1619  {
1620  CancelEnteringTrigger (measId);
1621  }
1622 
1623  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
1624  bool leavingCond = ms + hys < thresh;
1625 
1626  if (leavingCond)
1627  {
1628  if (isMeasIdInReportList)
1629  {
1630  /*
1631  * This is to check that the triggered cell recorded in the
1632  * VarMeasReportList is the serving cell.
1633  */
1634  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1635  != measReportIt->second.cellsTriggeredList.end ());
1636  concernedCellsLeaving.push_back (m_cellId);
1637  eventLeavingCondApplicable = true;
1638  }
1639  }
1640  else if (reportConfigEutra.timeToTrigger > 0)
1641  {
1642  CancelLeavingTrigger (measId);
1643  }
1644 
1645  NS_LOG_LOGIC (this << " event A1: serving cell " << m_cellId
1646  << " ms=" << ms << " thresh=" << thresh
1647  << " entryCond=" << entryCond
1648  << " leavingCond=" << leavingCond);
1649 
1650  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
1651 
1652  break;
1653 
1655  {
1656  /*
1657  * Event A2 (Serving becomes worse than threshold)
1658  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
1659  */
1660 
1661  double ms; // Ms, the measurement result of the serving cell
1662  double thresh; // Thresh, the threshold parameter for this event
1663  // Hys, the hysteresis parameter for this event.
1664  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1665 
1666  switch (reportConfigEutra.triggerQuantity)
1667  {
1669  ms = m_storedMeasValues[m_cellId].rsrp;
1670  NS_ASSERT (reportConfigEutra.threshold1.choice
1672  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1673  break;
1675  ms = m_storedMeasValues[m_cellId].rsrq;
1676  NS_ASSERT (reportConfigEutra.threshold1.choice
1678  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1679  break;
1680  default:
1681  NS_FATAL_ERROR ("unsupported triggerQuantity");
1682  break;
1683  }
1684 
1685  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
1686  bool entryCond = ms + hys < thresh;
1687 
1688  if (entryCond)
1689  {
1690  if (!isMeasIdInReportList)
1691  {
1692  concernedCellsEntry.push_back (m_cellId);
1693  eventEntryCondApplicable = true;
1694  }
1695  else
1696  {
1697  /*
1698  * This is to check that the triggered cell recorded in the
1699  * VarMeasReportList is the serving cell.
1700  */
1701  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1702  != measReportIt->second.cellsTriggeredList.end ());
1703  }
1704  }
1705  else if (reportConfigEutra.timeToTrigger > 0)
1706  {
1707  CancelEnteringTrigger (measId);
1708  }
1709 
1710  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
1711  bool leavingCond = ms - hys > thresh;
1712 
1713  if (leavingCond)
1714  {
1715  if (isMeasIdInReportList)
1716  {
1717  /*
1718  * This is to check that the triggered cell recorded in the
1719  * VarMeasReportList is the serving cell.
1720  */
1721  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1722  != measReportIt->second.cellsTriggeredList.end ());
1723  concernedCellsLeaving.push_back (m_cellId);
1724  eventLeavingCondApplicable = true;
1725  }
1726  }
1727  else if (reportConfigEutra.timeToTrigger > 0)
1728  {
1729  CancelLeavingTrigger (measId);
1730  }
1731 
1732  NS_LOG_LOGIC (this << " event A2: serving cell " << m_cellId
1733  << " ms=" << ms << " thresh=" << thresh
1734  << " entryCond=" << entryCond
1735  << " leavingCond=" << leavingCond);
1736 
1737  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
1738 
1739  break;
1740 
1742  {
1743  /*
1744  * Event A3 (Neighbour becomes offset better than PCell)
1745  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
1746  */
1747 
1748  double mn; // Mn, the measurement result of the neighbouring cell
1749  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1750  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1751  double mp; // Mp, the measurement result of the PCell
1752  double ofp = measObjectEutra.offsetFreq; // Ofp, the frequency specific offset of the primary frequency
1753  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
1754  // Off, the offset parameter for this event.
1755  double off = EutranMeasurementMapping::IeValue2ActualA3Offset (reportConfigEutra.a3Offset);
1756  // Hys, the hysteresis parameter for this event.
1757  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1758 
1759  switch (reportConfigEutra.triggerQuantity)
1760  {
1762  mp = m_storedMeasValues[m_cellId].rsrp;
1763  NS_ASSERT (reportConfigEutra.threshold1.choice
1765  break;
1767  mp = m_storedMeasValues[m_cellId].rsrq;
1768  NS_ASSERT (reportConfigEutra.threshold1.choice
1770  break;
1771  default:
1772  NS_FATAL_ERROR ("unsupported triggerQuantity");
1773  break;
1774  }
1775 
1776  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1777  storedMeasIt != m_storedMeasValues.end ();
1778  ++storedMeasIt)
1779  {
1780  uint16_t cellId = storedMeasIt->first;
1781  if (cellId == m_cellId)
1782  {
1783  continue;
1784  }
1785 
1786  switch (reportConfigEutra.triggerQuantity)
1787  {
1789  mn = storedMeasIt->second.rsrp;
1790  break;
1792  mn = storedMeasIt->second.rsrq;
1793  break;
1794  default:
1795  NS_FATAL_ERROR ("unsupported triggerQuantity");
1796  break;
1797  }
1798 
1799  bool hasTriggered = isMeasIdInReportList
1800  && (measReportIt->second.cellsTriggeredList.find (cellId)
1801  != measReportIt->second.cellsTriggeredList.end ());
1802 
1803  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
1804  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
1805 
1806  if (entryCond)
1807  {
1808  if (!hasTriggered)
1809  {
1810  concernedCellsEntry.push_back (cellId);
1811  eventEntryCondApplicable = true;
1812  }
1813  }
1814  else if (reportConfigEutra.timeToTrigger > 0)
1815  {
1816  CancelEnteringTrigger (measId, cellId);
1817  }
1818 
1819  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
1820  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
1821 
1822  if (leavingCond)
1823  {
1824  if (hasTriggered)
1825  {
1826  concernedCellsLeaving.push_back (cellId);
1827  eventLeavingCondApplicable = true;
1828  }
1829  }
1830  else if (reportConfigEutra.timeToTrigger > 0)
1831  {
1832  CancelLeavingTrigger (measId, cellId);
1833  }
1834 
1835  NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId
1836  << " mn=" << mn << " mp=" << mp << " offset=" << off
1837  << " entryCond=" << entryCond
1838  << " leavingCond=" << leavingCond);
1839 
1840  } // end of for (storedMeasIt)
1841 
1842  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
1843 
1844  break;
1845 
1847  {
1848  /*
1849  * Event A4 (Neighbour becomes better than threshold)
1850  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
1851  */
1852 
1853  double mn; // Mn, the measurement result of the neighbouring cell
1854  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1855  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1856  double thresh; // Thresh, the threshold parameter for this event
1857  // Hys, the hysteresis parameter for this event.
1858  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1859 
1860  switch (reportConfigEutra.triggerQuantity)
1861  {
1863  NS_ASSERT (reportConfigEutra.threshold1.choice
1865  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1866  break;
1868  NS_ASSERT (reportConfigEutra.threshold1.choice
1870  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1871  break;
1872  default:
1873  NS_FATAL_ERROR ("unsupported triggerQuantity");
1874  break;
1875  }
1876 
1877  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1878  storedMeasIt != m_storedMeasValues.end ();
1879  ++storedMeasIt)
1880  {
1881  uint16_t cellId = storedMeasIt->first;
1882  if (cellId == m_cellId)
1883  {
1884  continue;
1885  }
1886 
1887  switch (reportConfigEutra.triggerQuantity)
1888  {
1890  mn = storedMeasIt->second.rsrp;
1891  break;
1893  mn = storedMeasIt->second.rsrq;
1894  break;
1895  default:
1896  NS_FATAL_ERROR ("unsupported triggerQuantity");
1897  break;
1898  }
1899 
1900  bool hasTriggered = isMeasIdInReportList
1901  && (measReportIt->second.cellsTriggeredList.find (cellId)
1902  != measReportIt->second.cellsTriggeredList.end ());
1903 
1904  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
1905  bool entryCond = mn + ofn + ocn - hys > thresh;
1906 
1907  if (entryCond)
1908  {
1909  if (!hasTriggered)
1910  {
1911  concernedCellsEntry.push_back (cellId);
1912  eventEntryCondApplicable = true;
1913  }
1914  }
1915  else if (reportConfigEutra.timeToTrigger > 0)
1916  {
1917  CancelEnteringTrigger (measId, cellId);
1918  }
1919 
1920  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
1921  bool leavingCond = mn + ofn + ocn + hys < thresh;
1922 
1923  if (leavingCond)
1924  {
1925  if (hasTriggered)
1926  {
1927  concernedCellsLeaving.push_back (cellId);
1928  eventLeavingCondApplicable = true;
1929  }
1930  }
1931  else if (reportConfigEutra.timeToTrigger > 0)
1932  {
1933  CancelLeavingTrigger (measId, cellId);
1934  }
1935 
1936  NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId
1937  << " mn=" << mn << " thresh=" << thresh
1938  << " entryCond=" << entryCond
1939  << " leavingCond=" << leavingCond);
1940 
1941  } // end of for (storedMeasIt)
1942 
1943  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
1944 
1945  break;
1946 
1948  {
1949  /*
1950  * Event A5 (PCell becomes worse than threshold1 and neighbour
1951  * becomes better than threshold2)
1952  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
1953  */
1954 
1955  double mp; // Mp, the measurement result of the PCell
1956  double mn; // Mn, the measurement result of the neighbouring cell
1957  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1958  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1959  double thresh1; // Thresh1, the threshold parameter for this event
1960  double thresh2; // Thresh2, the threshold parameter for this event
1961  // Hys, the hysteresis parameter for this event.
1962  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1963 
1964  switch (reportConfigEutra.triggerQuantity)
1965  {
1967  mp = m_storedMeasValues[m_cellId].rsrp;
1968  NS_ASSERT (reportConfigEutra.threshold1.choice
1970  NS_ASSERT (reportConfigEutra.threshold2.choice
1972  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1973  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range);
1974  break;
1976  mp = m_storedMeasValues[m_cellId].rsrq;
1977  NS_ASSERT (reportConfigEutra.threshold1.choice
1979  NS_ASSERT (reportConfigEutra.threshold2.choice
1981  thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1982  thresh2 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold2.range);
1983  break;
1984  default:
1985  NS_FATAL_ERROR ("unsupported triggerQuantity");
1986  break;
1987  }
1988 
1989  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
1990  bool entryCond = mp + hys < thresh1;
1991 
1992  if (entryCond)
1993  {
1994  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1995  storedMeasIt != m_storedMeasValues.end ();
1996  ++storedMeasIt)
1997  {
1998  uint16_t cellId = storedMeasIt->first;
1999  if (cellId == m_cellId)
2000  {
2001  continue;
2002  }
2003 
2004  switch (reportConfigEutra.triggerQuantity)
2005  {
2007  mn = storedMeasIt->second.rsrp;
2008  break;
2010  mn = storedMeasIt->second.rsrq;
2011  break;
2012  default:
2013  NS_FATAL_ERROR ("unsupported triggerQuantity");
2014  break;
2015  }
2016 
2017  bool hasTriggered = isMeasIdInReportList
2018  && (measReportIt->second.cellsTriggeredList.find (cellId)
2019  != measReportIt->second.cellsTriggeredList.end ());
2020 
2021  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2022 
2023  entryCond = mn + ofn + ocn - hys > thresh2;
2024 
2025  if (entryCond)
2026  {
2027  if (!hasTriggered)
2028  {
2029  concernedCellsEntry.push_back (cellId);
2030  eventEntryCondApplicable = true;
2031  }
2032  }
2033  else if (reportConfigEutra.timeToTrigger > 0)
2034  {
2035  CancelEnteringTrigger (measId, cellId);
2036  }
2037 
2038  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2039  << " mn=" << mn << " mp=" << mp
2040  << " thresh2=" << thresh2
2041  << " thresh1=" << thresh1
2042  << " entryCond=" << entryCond);
2043 
2044  } // end of for (storedMeasIt)
2045 
2046  } // end of if (entryCond)
2047  else
2048  {
2049  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2050  << " mp=" << mp << " thresh1=" << thresh1
2051  << " entryCond=" << entryCond);
2052 
2053  if (reportConfigEutra.timeToTrigger > 0)
2054  {
2055  CancelEnteringTrigger (measId);
2056  }
2057  }
2058 
2059  if (isMeasIdInReportList)
2060  {
2061  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2062  bool leavingCond = mp - hys > thresh1;
2063 
2064  if (leavingCond)
2065  {
2066  if (reportConfigEutra.timeToTrigger == 0)
2067  {
2068  // leaving condition #2 does not have to be checked
2069 
2070  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2071  storedMeasIt != m_storedMeasValues.end ();
2072  ++storedMeasIt)
2073  {
2074  uint16_t cellId = storedMeasIt->first;
2075  if (cellId == m_cellId)
2076  {
2077  continue;
2078  }
2079 
2080  if (measReportIt->second.cellsTriggeredList.find (cellId)
2081  != measReportIt->second.cellsTriggeredList.end ())
2082  {
2083  concernedCellsLeaving.push_back (cellId);
2084  eventLeavingCondApplicable = true;
2085  }
2086  }
2087  } // end of if (reportConfigEutra.timeToTrigger == 0)
2088  else
2089  {
2090  // leaving condition #2 has to be checked to cancel time-to-trigger
2091 
2092  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2093  storedMeasIt != m_storedMeasValues.end ();
2094  ++storedMeasIt)
2095  {
2096  uint16_t cellId = storedMeasIt->first;
2097  if (cellId == m_cellId)
2098  {
2099  continue;
2100  }
2101 
2102  if (measReportIt->second.cellsTriggeredList.find (cellId)
2103  != measReportIt->second.cellsTriggeredList.end ())
2104  {
2105  switch (reportConfigEutra.triggerQuantity)
2106  {
2108  mn = storedMeasIt->second.rsrp;
2109  break;
2111  mn = storedMeasIt->second.rsrq;
2112  break;
2113  default:
2114  NS_FATAL_ERROR ("unsupported triggerQuantity");
2115  break;
2116  }
2117 
2118  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2119 
2120  leavingCond = mn + ofn + ocn + hys < thresh2;
2121 
2122  if (!leavingCond)
2123  {
2124  CancelLeavingTrigger (measId, cellId);
2125  }
2126 
2127  /*
2128  * Whatever the result of leaving condition #2, this
2129  * cell is still "in", because leaving condition #1
2130  * is already true.
2131  */
2132  concernedCellsLeaving.push_back (cellId);
2133  eventLeavingCondApplicable = true;
2134 
2135  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2136  << " mn=" << mn << " mp=" << mp
2137  << " thresh2=" << thresh2
2138  << " thresh1=" << thresh1
2139  << " leavingCond=" << leavingCond);
2140 
2141  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2142  // != measReportIt->second.cellsTriggeredList.end ())
2143 
2144  } // end of for (storedMeasIt)
2145 
2146  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2147 
2148  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2149  << " mp=" << mp << " thresh1=" << thresh1
2150  << " leavingCond=" << leavingCond);
2151 
2152  } // end of if (leavingCond)
2153  else
2154  {
2155  if (reportConfigEutra.timeToTrigger > 0)
2156  {
2157  CancelLeavingTrigger (measId);
2158  }
2159 
2160  // check leaving condition #2
2161 
2162  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2163  storedMeasIt != m_storedMeasValues.end ();
2164  ++storedMeasIt)
2165  {
2166  uint16_t cellId = storedMeasIt->first;
2167  if (cellId == m_cellId)
2168  {
2169  continue;
2170  }
2171 
2172  if (measReportIt->second.cellsTriggeredList.find (cellId)
2173  != measReportIt->second.cellsTriggeredList.end ())
2174  {
2175  switch (reportConfigEutra.triggerQuantity)
2176  {
2178  mn = storedMeasIt->second.rsrp;
2179  break;
2181  mn = storedMeasIt->second.rsrq;
2182  break;
2183  default:
2184  NS_FATAL_ERROR ("unsupported triggerQuantity");
2185  break;
2186  }
2187 
2188  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2189  leavingCond = mn + ofn + ocn + hys < thresh2;
2190 
2191  if (leavingCond)
2192  {
2193  concernedCellsLeaving.push_back (cellId);
2194  eventLeavingCondApplicable = true;
2195  }
2196 
2197  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2198  << " mn=" << mn << " mp=" << mp
2199  << " thresh2=" << thresh2
2200  << " thresh1=" << thresh1
2201  << " leavingCond=" << leavingCond);
2202 
2203  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2204  // != measReportIt->second.cellsTriggeredList.end ())
2205 
2206  } // end of for (storedMeasIt)
2207 
2208  } // end of else of if (leavingCond)
2209 
2210  } // end of if (isMeasIdInReportList)
2211 
2212  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2213 
2214  break;
2215 
2216  default:
2217  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
2218  break;
2219 
2220  } // switch (event type)
2221 
2222  NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2223  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2224 
2225  if (eventEntryCondApplicable)
2226  {
2227  if (reportConfigEutra.timeToTrigger == 0)
2228  {
2229  VarMeasReportListAdd (measId, concernedCellsEntry);
2230  }
2231  else
2232  {
2233  PendingTrigger_t t;
2234  t.measId = measId;
2235  t.concernedCells = concernedCellsEntry;
2236  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2238  measId, concernedCellsEntry);
2239  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2240  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2241  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2242  enteringTriggerIt->second.push_back (t);
2243  }
2244  }
2245 
2246  if (eventLeavingCondApplicable)
2247  {
2248  // reportOnLeave will only be set when eventId = eventA3
2249  bool reportOnLeave = (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
2250  && reportConfigEutra.reportOnLeave;
2251 
2252  if (reportConfigEutra.timeToTrigger == 0)
2253  {
2254  VarMeasReportListErase (measId, concernedCellsLeaving, reportOnLeave);
2255  }
2256  else
2257  {
2258  PendingTrigger_t t;
2259  t.measId = measId;
2260  t.concernedCells = concernedCellsLeaving;
2261  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2263  measId, concernedCellsLeaving, reportOnLeave);
2264  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2265  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2266  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2267  leavingTriggerIt->second.push_back (t);
2268  }
2269  }
2270 
2271 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2272 
2273 void
2275 {
2276  NS_LOG_FUNCTION (this << (uint16_t) measId);
2277 
2278  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2279  it1 = m_enteringTriggerQueue.find (measId);
2280  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2281 
2282  if (!it1->second.empty ())
2283  {
2284  std::list<PendingTrigger_t>::iterator it2;
2285  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2286  {
2287  NS_ASSERT (it2->measId == measId);
2288  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2289  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2290  Simulator::Cancel (it2->timer);
2291  }
2292 
2293  it1->second.clear ();
2294  }
2295 }
2296 
2297 void
2298 LteUeRrc::CancelEnteringTrigger (uint8_t measId, uint16_t cellId)
2299 {
2300  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2301 
2302  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2303  it1 = m_enteringTriggerQueue.find (measId);
2304  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2305 
2306  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2307  while (it2 != it1->second.end ())
2308  {
2309  NS_ASSERT (it2->measId == measId);
2310 
2311  ConcernedCells_t::iterator it3;
2312  for (it3 = it2->concernedCells.begin ();
2313  it3 != it2->concernedCells.end (); ++it3)
2314  {
2315  if (*it3 == cellId)
2316  {
2317  it3 = it2->concernedCells.erase (it3);
2318  }
2319  }
2320 
2321  if (it2->concernedCells.empty ())
2322  {
2323  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2324  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2325  Simulator::Cancel (it2->timer);
2326  it2 = it1->second.erase (it2);
2327  }
2328  else
2329  {
2330  it2++;
2331  }
2332  }
2333 }
2334 
2335 void
2337 {
2338  NS_LOG_FUNCTION (this << (uint16_t) measId);
2339 
2340  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2341  it1 = m_leavingTriggerQueue.find (measId);
2342  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2343 
2344  if (!it1->second.empty ())
2345  {
2346  std::list<PendingTrigger_t>::iterator it2;
2347  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2348  {
2349  NS_ASSERT (it2->measId == measId);
2350  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2351  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2352  Simulator::Cancel (it2->timer);
2353  }
2354 
2355  it1->second.clear ();
2356  }
2357 }
2358 
2359 void
2360 LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
2361 {
2362  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2363 
2364  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2365  it1 = m_leavingTriggerQueue.find (measId);
2366  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2367 
2368  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2369  while (it2 != it1->second.end ())
2370  {
2371  NS_ASSERT (it2->measId == measId);
2372 
2373  ConcernedCells_t::iterator it3;
2374  for (it3 = it2->concernedCells.begin ();
2375  it3 != it2->concernedCells.end (); ++it3)
2376  {
2377  if (*it3 == cellId)
2378  {
2379  it3 = it2->concernedCells.erase (it3);
2380  }
2381  }
2382 
2383  if (it2->concernedCells.empty ())
2384  {
2385  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2386  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2387  Simulator::Cancel (it2->timer);
2388  it2 = it1->second.erase (it2);
2389  }
2390  else
2391  {
2392  it2++;
2393  }
2394  }
2395 }
2396 
2397 void
2398 LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
2399 {
2400  NS_LOG_FUNCTION (this << (uint16_t) measId);
2401  NS_ASSERT (!enteringCells.empty ());
2402 
2403  std::map<uint8_t, VarMeasReport>::iterator
2404  measReportIt = m_varMeasReportList.find (measId);
2405 
2406  if (measReportIt == m_varMeasReportList.end ())
2407  {
2408  VarMeasReport r;
2409  r.measId = measId;
2410  std::pair<uint8_t, VarMeasReport> val (measId, r);
2411  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
2412  ret = m_varMeasReportList.insert (val);
2413  NS_ASSERT_MSG (ret.second == true, "element already existed");
2414  measReportIt = ret.first;
2415  }
2416 
2417  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2418 
2419  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2420  it != enteringCells.end ();
2421  ++it)
2422  {
2423  measReportIt->second.cellsTriggeredList.insert (*it);
2424  }
2425 
2426  NS_ASSERT (!measReportIt->second.cellsTriggeredList.empty ());
2427  measReportIt->second.numberOfReportsSent = 0;
2428  measReportIt->second.periodicReportTimer
2431  this, measId);
2432 
2433  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2434  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2435  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2436  if (!enteringTriggerIt->second.empty ())
2437  {
2438  /*
2439  * Assumptions at this point:
2440  * - the call to this function was delayed by time-to-trigger;
2441  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2442  * - the first element in the list is associated with this function call.
2443  */
2444  enteringTriggerIt->second.pop_front ();
2445 
2446  if (!enteringTriggerIt->second.empty ())
2447  {
2448  /*
2449  * To prevent the same set of cells triggering again in the future,
2450  * we clean up the time-to-trigger queue. This case might occur when
2451  * time-to-trigger > 200 ms.
2452  */
2453  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2454  it != enteringCells.end (); ++it)
2455  {
2456  CancelEnteringTrigger (measId, *it);
2457  }
2458  }
2459 
2460  } // end of if (!enteringTriggerIt->second.empty ())
2461 
2462 } // end of LteUeRrc::VarMeasReportListAdd
2463 
2464 void
2466  bool reportOnLeave)
2467 {
2468  NS_LOG_FUNCTION (this << (uint16_t) measId);
2469  NS_ASSERT (!leavingCells.empty ());
2470 
2471  std::map<uint8_t, VarMeasReport>::iterator
2472  measReportIt = m_varMeasReportList.find (measId);
2473  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2474 
2475  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2476  it != leavingCells.end ();
2477  ++it)
2478  {
2479  measReportIt->second.cellsTriggeredList.erase (*it);
2480  }
2481 
2482  if (reportOnLeave)
2483  {
2484  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2485  SendMeasurementReport (measId);
2486  }
2487 
2488  if (measReportIt->second.cellsTriggeredList.empty ())
2489  {
2490  measReportIt->second.periodicReportTimer.Cancel ();
2491  m_varMeasReportList.erase (measReportIt);
2492  }
2493 
2494  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2495  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2496  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2497  if (!leavingTriggerIt->second.empty ())
2498  {
2499  /*
2500  * Assumptions at this point:
2501  * - the call to this function was delayed by time-to-trigger; and
2502  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2503  * - the first element in the list is associated with this function call.
2504  */
2505  leavingTriggerIt->second.pop_front ();
2506 
2507  if (!leavingTriggerIt->second.empty ())
2508  {
2509  /*
2510  * To prevent the same set of cells triggering again in the future,
2511  * we clean up the time-to-trigger queue. This case might occur when
2512  * time-to-trigger > 200 ms.
2513  */
2514  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2515  it != leavingCells.end (); ++it)
2516  {
2517  CancelLeavingTrigger (measId, *it);
2518  }
2519  }
2520 
2521  } // end of if (!leavingTriggerIt->second.empty ())
2522 
2523 } // end of LteUeRrc::VarMeasReportListErase
2524 
2525 void
2527 {
2528  NS_LOG_FUNCTION (this << (uint16_t) measId);
2529 
2530  // remove the measurement reporting entry for this measId from the VarMeasReportList
2531  std::map<uint8_t, VarMeasReport>::iterator
2532  measReportIt = m_varMeasReportList.find (measId);
2533  if (measReportIt != m_varMeasReportList.end ())
2534  {
2535  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint16_t) measId);
2536  measReportIt->second.periodicReportTimer.Cancel ();
2537  m_varMeasReportList.erase (measReportIt);
2538  }
2539 
2540  CancelEnteringTrigger (measId);
2541  CancelLeavingTrigger (measId);
2542 }
2543 
2544 void
2546 {
2547  NS_LOG_FUNCTION (this << (uint16_t) measId);
2548  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2549 
2550  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
2551  measIdIt = m_varMeasConfig.measIdList.find (measId);
2552  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
2553 
2554  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
2555  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
2556  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
2557  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2558 
2559  LteRrcSap::MeasurementReport measurementReport;
2560  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2561  measResults.measId = measId;
2562 
2563  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
2564  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
2565  measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
2566  measResults.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
2567  NS_LOG_INFO (this << " reporting serving cell "
2568  "RSRP " << (uint32_t) measResults.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
2569  "RSRQ " << (uint32_t) measResults.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
2570  measResults.haveMeasResultNeighCells = false;
2571  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
2572  if (measReportIt == m_varMeasReportList.end ())
2573  {
2574  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
2575  }
2576  else
2577  {
2578  if (!(measReportIt->second.cellsTriggeredList.empty ()))
2579  {
2580  std::multimap<double, uint16_t> sortedNeighCells;
2581  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
2582  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
2583  ++cellsTriggeredIt)
2584  {
2585  uint16_t cellId = *cellsTriggeredIt;
2586  if (cellId != m_cellId)
2587  {
2588  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2589  double triggerValue;
2590  switch (reportConfigEutra.triggerQuantity)
2591  {
2593  triggerValue = neighborMeasIt->second.rsrp;
2594  break;
2596  triggerValue = neighborMeasIt->second.rsrq;
2597  break;
2598  default:
2599  NS_FATAL_ERROR ("unsupported triggerQuantity");
2600  break;
2601  }
2602  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
2603  }
2604  }
2605 
2606  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
2607  uint32_t count;
2608  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
2609  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
2610  ++sortedNeighCellsIt, ++count)
2611  {
2612  uint16_t cellId = sortedNeighCellsIt->second;
2613  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2614  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
2615  LteRrcSap::MeasResultEutra measResultEutra;
2616  measResultEutra.physCellId = cellId;
2617  measResultEutra.haveCgiInfo = false;
2618  measResultEutra.haveRsrpResult = true;
2619  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
2620  measResultEutra.haveRsrqResult = true;
2621  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
2622  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
2623  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
2624  << " (" << neighborMeasIt->second.rsrp << " dBm)"
2625  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
2626  << " (" << neighborMeasIt->second.rsrq << " dB)");
2627  measResults.measResultListEutra.push_back (measResultEutra);
2628  measResults.haveMeasResultNeighCells = true;
2629  }
2630  }
2631  else
2632  {
2633  NS_LOG_WARN (this << " cellsTriggeredList is empty");
2634  }
2635 
2636  /*
2637  * The current LteRrcSap implementation is broken in that it does not
2638  * allow for infinite values of reportAmount, which is probably the most
2639  * reasonable setting. So we just always assume infinite reportAmount.
2640  */
2641  measReportIt->second.numberOfReportsSent++;
2642  measReportIt->second.periodicReportTimer.Cancel ();
2643 
2644  Time reportInterval;
2645  switch (reportConfigEutra.reportInterval)
2646  {
2648  reportInterval = MilliSeconds (120);
2649  break;
2651  reportInterval = MilliSeconds (240);
2652  break;
2654  reportInterval = MilliSeconds (480);
2655  break;
2657  reportInterval = MilliSeconds (640);
2658  break;
2660  reportInterval = MilliSeconds (1024);
2661  break;
2663  reportInterval = MilliSeconds (2048);
2664  break;
2666  reportInterval = MilliSeconds (5120);
2667  break;
2669  reportInterval = MilliSeconds (10240);
2670  break;
2672  reportInterval = Seconds (60);
2673  break;
2675  reportInterval = Seconds (360);
2676  break;
2678  reportInterval = Seconds (720);
2679  break;
2681  reportInterval = Seconds (1800);
2682  break;
2684  reportInterval = Seconds (3600);
2685  break;
2686  default:
2687  NS_FATAL_ERROR ("Unsupported reportInterval " << (uint16_t) reportConfigEutra.reportInterval);
2688  break;
2689  }
2690 
2691  // schedule the next measurement reporting
2692  measReportIt->second.periodicReportTimer
2693  = Simulator::Schedule (reportInterval,
2695  this, measId);
2696 
2697  // send the measurement report to eNodeB
2698  m_rrcSapUser->SendMeasurementReport (measurementReport);
2699  }
2700 }
2701 
2702 void
2704 {
2705  NS_LOG_FUNCTION (this << m_imsi);
2708  m_connectionPending = false; // reset the flag
2711 }
2712 
2713 void
2715 {
2716  NS_LOG_FUNCTION (this << m_imsi);
2719  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
2720  for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
2721  {
2722  m_cmacSapProvider->RemoveLc (it->second->m_logicalChannelIdentity);
2723  }
2724  m_drbMap.clear ();
2725  m_bid2DrbidMap.clear ();
2726  m_srb1 = 0;
2728 }
2729 
2730 void
2732 {
2733  NS_LOG_FUNCTION (this);
2734  m_srb1Old = 0;
2735 }
2736 
2737 uint8_t
2738 LteUeRrc::Bid2Drbid (uint8_t bid)
2739 {
2740  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
2741  NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
2742  return it->second;
2743 }
2744 
2745 
2746 void
2748 {
2749  NS_LOG_FUNCTION (this << ToString (newState));
2750  State oldState = m_state;
2751  m_state = newState;
2752  NS_LOG_INFO (this << "IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc "
2753  << ToString (oldState) << " --> " << ToString (newState));
2754  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
2755 
2756  switch (newState)
2757  {
2758  case IDLE_START:
2759  NS_FATAL_ERROR ("cannot switch to an initial state");
2760  break;
2761 
2762  case IDLE_CELL_SEARCH:
2763  case IDLE_WAIT_MIB_SIB1:
2764  case IDLE_WAIT_MIB:
2765  case IDLE_WAIT_SIB1:
2766  break;
2767 
2768  case IDLE_CAMPED_NORMALLY:
2769  if (m_connectionPending)
2770  {
2772  }
2773  break;
2774 
2775  case IDLE_WAIT_SIB2:
2776  if (m_hasReceivedSib2)
2777  {
2779  StartConnection ();
2780  }
2781  break;
2782 
2783  case IDLE_RANDOM_ACCESS:
2784  case IDLE_CONNECTING:
2785  case CONNECTED_NORMALLY:
2786  case CONNECTED_HANDOVER:
2787  case CONNECTED_PHY_PROBLEM:
2789  break;
2790 
2791  default:
2792  break;
2793  }
2794 }
2795 
2796 
2797 
2798 
2799 } // namespace ns3
2800 
static Time GetDelayLeft(const EventId &id)
Definition: simulator.cc:189
LtePdcpSapProvider * srb1SapProvider
Definition: lte-rrc-sap.h:614
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
virtual void Reset()=0
reset the PHY
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Part of the RRC protocol.
Definition: lte-rrc-sap.h:676
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionSetup interface...
Definition: lte-ue-rrc.cc:816
void DoRecvMasterInformationBlock(uint16_t cellId, LteRrcSap::MasterInformationBlock msg)
Definition: lte-ue-rrc.cc:658
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
Definition: lte-ue-rrc.h:564
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:300
std::vector< struct UeMeasurementsElement > m_ueMeasurementsList
void CancelEnteringTrigger(uint8_t measId)
Clear all the waiting triggers in m_enteringTriggerQueue which are associated with the given measurem...
Definition: lte-ue-rrc.cc:2274
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Definition: lte-ue-rrc.cc:685
static TypeId GetTypeId(void)
Definition: lte-ue-rrc.cc:165
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
Definition: lte-common.cc:246
std::list< MeasObjectToAddMod > measObjectToAddModList
Definition: lte-rrc-sap.h:400
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
LtePdcpSapUser * m_drbPdcpSapUser
Definition: lte-ue-rrc.h:484
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvSystemInformation interface...
Definition: lte-ue-rrc.cc:773
Template for the implementation of the LteUeCphySapUser as a member of an owner class of type C to wh...
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
Definition: lte-rrc-sap.h:140
static TypeId GetTypeId(void)
Definition: lte-rlc.cc:183
void SetAsSapUser(LteAsSapUser *s)
Set the AS SAP user to interact with the NAS entity.
Definition: lte-ue-rrc.cc:286
void MeasurementReportTriggering(uint8_t measId)
Evaluate the reporting criteria of a measurement identity and invoke some reporting actions based on ...
Definition: lte-ue-rrc.cc:1529
QuantityConfig quantityConfig
Definition: lte-rrc-sap.h:406
void DoRecvRrcConnectionReject(LteRrcSap::RrcConnectionReject msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReject interface...
Definition: lte-ue-rrc.cc:964
std::list< uint8_t > reportConfigToRemoveList
Definition: lte-rrc-sap.h:401
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:268
bool m_hasReceivedSib2
true if SIB2 was received for the current cell
Definition: lte-ue-rrc.h:540
std::list< MeasResultEutra > measResultListEutra
Definition: lte-rrc-sap.h:519
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
Definition: lte-rrc-sap.h:82
std::map< uint8_t, Ptr< LteDataRadioBearerInfo > > m_drbMap
Definition: lte-ue-rrc.h:498
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Update the current measurement configuration m_varMeasConfig.
Definition: lte-ue-rrc.cc:1258
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:258
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: lte-ue-rrc.cc:153
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:360
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
virtual void Reset()=0
reset the MAC
uint8_t measId
The measurement identity which raised the trigger.
Definition: lte-ue-rrc.h:691
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
std::list< SrbToAddMod > srbToAddModList
Definition: lte-rrc-sap.h:190
void DoSetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:466
Represents a single triggered event from a measurement identity which reporting criteria have been fu...
Definition: lte-ue-rrc.h:689
RadioResourceConfigDedicated radioResourceConfigDedicated
Definition: lte-rrc-sap.h:548
LteUeRrc()
create an RRC instance for use within an ue
Definition: lte-ue-rrc.cc:121
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
std::list< uint8_t > measObjectToRemoveList
Definition: lte-rrc-sap.h:399
void SetTypeId(TypeId tid)
virtual void StartContentionBasedRandomAccessProcedure()=0
tell the MAC to start a contention-based random access procedure, e.g., to perform RRC connection est...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
virtual void SynchronizeWithEnb(uint16_t cellId)=0
Tell the PHY entity to synchronize with a given eNodeB over the currently active EARFCN for communica...
virtual ~LteUeRrc()
Destructor.
Definition: lte-ue-rrc.cc:147
uint16_t m_cellId
Definition: lte-ue-rrc.h:493
EventId timer
The pending reporting event, scheduled at the end of the time-to-trigger.
Definition: lte-ue-rrc.h:693
void CancelLeavingTrigger(uint8_t measId)
Clear all the waiting triggers in m_leavingTriggerQueue which are associated with the given measureme...
Definition: lte-ue-rrc.cc:2336
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
virtual void NotifyRandomAccessSuccessful()
Notify the RRC that the MAC Random Access procedure completed successfully.
Definition: lte-ue-rrc.cc:74
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberContainer)
Definition: object-map.h:51
virtual void SetRnti(uint16_t rnti)=0
virtual void NotifyConnectionSuccessful()=0
Notify the NAS that RRC Connection Establishment was successful.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
uint16_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:346
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:41
virtual void RemoveLc(uint8_t lcId)=0
remove an existing LC
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
bool m_hasReceivedMib
true if MIB was received for the current cell
Definition: lte-ue-rrc.h:538
RachConfigDedicated rachConfigDedicated
Definition: lte-rrc-sap.h:443
void DoRecvRrcConnectionReestablishmentReject(LteRrcSap::RrcConnectionReestablishmentReject msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReestablishmentReject i...
Definition: lte-ue-rrc.cc:935
void SetRnti(uint16_t rnti)
Definition: lte-rlc.cc:125
bool m_connectionPending
true if a connection request by upper layers is pending
Definition: lte-ue-rrc.h:537
bool m_hasReceivedSib1
true if SIB1 was received for the current cell
Definition: lte-ue-rrc.h:539
LteMacSapProvider * m_macSapProvider
Definition: lte-ue-rrc.h:483
static double RsrqRange2Db(uint8_t range)
converts an RSRQ range to dB as per 3GPP TS 36.133 section 9.1.7 RSRQ Measurement Report Mapping ...
Definition: lte-common.cc:218
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
Send an RRCConnectionSetupComplete message to the serving eNodeB during an RRC connection establishme...
uint8_t Bid2Drbid(uint8_t bid)
Definition: lte-ue-rrc.cc:2738
Event A3: Neighbour becomes amount of offset better than PCell.
Definition: lte-rrc-sap.h:270
double GetSeconds(void) const
Definition: nstime.h:272
Event A2: Serving becomes worse than absolute threshold.
Definition: lte-rrc-sap.h:269
Parameters for LtePdcpSapUser::ReceivePdcpSdu.
Definition: lte-pdcp-sap.h:76
Event A4: Neighbour becomes better than absolute threshold.
Definition: lte-rrc-sap.h:271
RSRP is used for the threshold.
Definition: lte-rrc-sap.h:251
LteUeCmacSapUser * GetLteUeCmacSapUser()
Definition: lte-ue-rrc.cc:258
friend class UeMemberLteUeCmacSapUser
Definition: lte-ue-rrc.h:73
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:56
LteRrcSap::QuantityConfig quantityConfig
Definition: lte-ue-rrc.h:566
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
Definition: lte-rrc-sap.h:272
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
set the RRC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:265
LteUeRrcSapUser * m_rrcSapUser
Definition: lte-ue-rrc.h:480
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndOkTrace
Definition: lte-ue-rrc.h:533
uint16_t m_dlEarfcn
downlink carrier frequency
Definition: lte-ue-rrc.h:507
Ptr< LteSignalingRadioBearerInfo > m_srb0
Definition: lte-ue-rrc.h:495
ConcernedCells_t concernedCells
The list of cells responsible for this trigger.
Definition: lte-ue-rrc.h:692
static TypeId GetTypeId(void)
Definition: lte-rlc-um.cc:55
Represents a measurement result from a certain cell.
Definition: lte-ue-rrc.h:662
void DisposeOldSrb1()
Definition: lte-ue-rrc.cc:2731
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:277
Ptr< Object > Create(void) const
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
Definition: lte-ue-rrc.h:531
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReconfiguration interfa...
Definition: lte-ue-rrc.cc:840
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:252
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReestablishment interfa...
Definition: lte-ue-rrc.cc:911
uint8_t m_dlBandwidth
downlink bandwidth in RBs
Definition: lte-ue-rrc.h:504
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
Hold an unsigned integer type.
Definition: uinteger.h:46
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessErrorTrace
Definition: lte-ue-rrc.h:525
TracedCallback< uint64_t, uint16_t, uint16_t > m_sib2ReceivedTrace
Definition: lte-ue-rrc.h:515
Ptr< SampleEmitter > s
void EvaluateCellForSelection()
Performs cell selection evaluation to the current serving cell.
Definition: lte-ue-rrc.cc:1017
std::list< MeasIdToAddMod > measIdToAddModList
Definition: lte-rrc-sap.h:404
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
Definition: lte-ue-rrc.cc:368
std::map< uint16_t, MeasValues > m_storedMeasValues
Internal storage of the latest measurement results from all detected detected cells, indexed by the cell ID where the measurement was taken from.
Definition: lte-ue-rrc.h:682
PhysicalConfigDedicated physicalConfigDedicated
Definition: lte-rrc-sap.h:194
Ptr< LteSignalingRadioBearerInfo > m_srb1
Definition: lte-ue-rrc.h:496
LteUeCphySapProvider * m_cphySapProvider
Definition: lte-ue-rrc.h:475
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:326
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
set the CMAC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:251
Parameters for LtePdcpSapProvider::TransmitPdcpSdu.
Definition: lte-pdcp-sap.h:43
Template for the implementation of the LteAsSapProvider as a member of an owner class of type C to wh...
Definition: lte-as-sap.h:147
LteMacSapUser * GetLteMacSapUser()
Definition: lte-rlc.cc:160
uint32_t m_csgWhiteList
List of CSG ID which this UE entity has access to.
Definition: lte-ue-rrc.h:549
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
std::map< uint8_t, LteRrcSap::MeasIdToAddMod > measIdList
Definition: lte-ue-rrc.h:563
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
std::map< uint8_t, uint8_t > m_bid2DrbidMap
Definition: lte-ue-rrc.h:472
void SetLteMacSapProvider(LteMacSapProvider *s)
set the MAC SAP provider.
Definition: lte-ue-rrc.cc:279
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndOkTrace
Definition: lte-ue-rrc.h:519
RadioResourceConfigDedicated radioResourceConfigDedicated
Definition: lte-rrc-sap.h:532
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
set the CPHY SAP this RRC should use to interact with the PHY
Definition: lte-ue-rrc.cc:237
void SwitchToState(State s)
Definition: lte-ue-rrc.cc:2747
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
Definition: lte-common.cc:309
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndErrorTrace
Definition: lte-ue-rrc.h:521
VarMeasConfig m_varMeasConfig
Includes the accumulated configuration of the measurements to be performed by the UE...
Definition: lte-ue-rrc.h:577
std::map< uint8_t, std::list< PendingTrigger_t > > m_leavingTriggerQueue
List of triggers that were raised because leaving condition have been true, but are still delayed fro...
Definition: lte-ue-rrc.h:717
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
Definition: lte-ue-rrc.h:565
LteUeCphySapUser * m_cphySapUser
Definition: lte-ue-rrc.h:474
virtual void Setup(SetupParameters params)=0
virtual void SetSrsConfigurationIndex(uint16_t srcCi)=0
hold objects of type Ptr
Definition: pointer.h:33
void SetLteRlcSapUser(LteRlcSapUser *s)
Definition: lte-rlc.cc:139
LteAsSapUser * m_asSapUser
Definition: lte-ue-rrc.h:487
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Template for the implementation of the LteUeRrcSapProvider as a member of an owner class of type C to...
Definition: lte-rrc-sap.h:1013
virtual void StartCellSearch(uint16_t dlEarfcn)=0
Tell the PHY entity to listen to PSS from surrounding cells and measure the RSRP. ...
void DoNotifyRandomAccessSuccessful()
Definition: lte-ue-rrc.cc:475
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:333
uint16_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:340
Reference Signal Received Power.
Definition: lte-rrc-sap.h:299
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_sib1ReceivedTrace
Definition: lte-ue-rrc.h:513
double rsrq
Measured RSRQ in dB.
Definition: lte-ue-rrc.h:665
void DoSendData(Ptr< Packet > packet, uint8_t bid)
Definition: lte-ue-rrc.cc:401
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:105
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:986
RadioResourceConfigCommonSib radioResourceConfigCommon
Definition: lte-rrc-sap.h:473
uint16_t m_ulEarfcn
uplink carrier frequency
Definition: lte-ue-rrc.h:508
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void SetLcId(uint8_t lcId)
Definition: lte-rlc.cc:132
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionRelease interface...
Definition: lte-ue-rrc.cc:957
double rsrp
Measured RSRP in dBm.
Definition: lte-ue-rrc.h:664
virtual void AddLc(uint8_t lcId, LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
add a new Logical Channel (LC)
void VarMeasReportListErase(uint8_t measId, ConcernedCells_t leavingCells, bool reportOnLeave)
Remove some cells from an existing reporting entry in m_varMeasReportList.
Definition: lte-ue-rrc.cc:2465
CarrierBandwidthEutra carrierBandwidth
Definition: lte-rrc-sap.h:439
uint8_t m_ulBandwidth
uplink bandwidth in RBs
Definition: lte-ue-rrc.h:505
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:244
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
Definition: lte-ue-rrc.h:529
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
Definition: lte-ue-rrc.h:497
virtual void SendMeasurementReport(MeasurementReport msg)=0
Send a MeasurementReport message to the serving eNodeB during a measurement reporting procedure (Sect...
State
The states of the UE RRC entity.
Definition: lte-ue-rrc.h:86
virtual void StartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)=0
tell the MAC to start a non-contention-based random access procedure, e.g., as a consequence of hando...
virtual void SetDlBandwidth(uint8_t dlBandwidth)=0
uint64_t GetImsi(void) const
Definition: lte-ue-rrc.cc:305
void StartConnection()
Definition: lte-ue-rrc.cc:2703
instantiate subclasses of ns3::Object.
static uint8_t Dbm2RsrpRange(double dbm)
convert an RSRP value in dBm to the corresponding range as per 3GPP TS 36.133 section 9...
Definition: lte-common.cc:210
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:311
void SaveUeMeasurements(uint16_t cellId, double rsrp, double rsrq, bool useLayer3Filtering)
Keep the given measurement result as the latest measurement figures, to be utilised by UE RRC functio...
Definition: lte-ue-rrc.cc:1475
virtual void SetTransmissionMode(uint8_t txMode)=0
static const std::string & ToString(EpcUeNas::State s)
Definition: epc-ue-nas.cc:47
void DoSetCsgWhiteList(uint32_t csgId)
Definition: lte-ue-rrc.cc:553
void DoNotifyRandomAccessFailed()
Definition: lte-ue-rrc.cc:520
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::CompleteSetup interface.
Definition: lte-ue-rrc.cc:761
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
LteUeRrcSapProvider * m_rrcSapProvider
Definition: lte-ue-rrc.h:481
void DoConnect()
Definition: lte-ue-rrc.cc:616
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Definition: lte-ue-rrc.cc:1084
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
Definition: lte-ue-rrc.h:527
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:318
std::list< DrbToAddMod > drbToAddModList
Definition: lte-rrc-sap.h:191
virtual void NotifyConnectionReleased()=0
Notify the NAS that RRC Connection was released.
std::map< uint8_t, VarMeasReport > m_varMeasReportList
The list of active reporting entries, indexed by the measurement identity which triggered the reporti...
Definition: lte-ue-rrc.h:599
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
LteAsSapProvider * m_asSapProvider
Definition: lte-ue-rrc.h:486
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
void Initialize(void)
This method calls the virtual DoInitialize method on all the objects aggregated to this object...
Definition: object.cc:179
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_mibReceivedTrace
Definition: lte-ue-rrc.h:511
LteUeCmacSapProvider * m_cmacSapProvider
Definition: lte-ue-rrc.h:478
uint16_t m_rnti
Definition: lte-ue-rrc.h:492
uint64_t m_imsi
Definition: lte-ue-rrc.h:491
SystemInformationBlockType2 sib2
Definition: lte-rrc-sap.h:480
std::set< uint16_t > m_acceptableCell
List of cell ID of acceptable cells for cell selection that have been detected.
Definition: lte-ue-rrc.h:546
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:292
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:36
void DoReportUeMeasurements(LteUeCphySapUser::UeMeasurementsParameters params)
Definition: lte-ue-rrc.cc:724
void DoStartCellSelection(uint16_t dlEarfcn)
Definition: lte-ue-rrc.cc:560
Represents a single measurement reporting entry., which includes information about a measurement for ...
Definition: lte-ue-rrc.h:586
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
LteRlcSapProvider * GetLteRlcSapProvider()
Definition: lte-rlc.cc:146
TracedCallback< uint64_t, uint16_t, uint16_t, State, State > m_stateTransitionTrace
Definition: lte-ue-rrc.h:517
void SendMeasurementReport(uint8_t measId)
Produce a proper measurement report from the given measurement identity's reporting entry in m_varMea...
Definition: lte-ue-rrc.cc:2545
a base class which provides memory management and object aggregation
Definition: object.h:64
void SynchronizeToStrongestCell()
Go through the list of measurement results, choose the one with the strongest RSRP, and tell PHY to synchronize to it.
Definition: lte-ue-rrc.cc:974
contain a set of ns3::Object pointers.
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Definition: lte-ue-rrc.cc:458
virtual void SendRrcConnectionRequest(RrcConnectionRequest msg)=0
Send an _RRCConnectionRequest message to the serving eNodeB during an RRC connection establishment pr...
Part of the RRC protocol.
Definition: lte-rrc-sap.h:608
static uint8_t Db2RsrqRange(double db)
convert an RSRQ value in dB to the corresponding range as per 3GPP TS 36.133 section 9...
Definition: lte-common.cc:226
virtual void RecvData(Ptr< Packet > packet)=0
receive a data packet
State GetState() const
Definition: lte-ue-rrc.cc:353
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Definition: lte-ue-rrc.cc:61
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:272
static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES]
Definition: lte-ue-rrc.cc:91
std::list< uint16_t > ConcernedCells_t
List of cell IDs which are responsible for a certain trigger.
Definition: lte-ue-rrc.h:604
void VarMeasReportListAdd(uint8_t measId, ConcernedCells_t enteringCells)
Compose a new reporting entry of the given measurement identity, insert it into m_varMeasReportList, and set it up for submission to eNodeB.
Definition: lte-ue-rrc.cc:2398
void DoDisconnect()
Definition: lte-ue-rrc.cc:424
Ptr< T > GetObject(void) const
Definition: object.h:362
virtual void SetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:67
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessSuccessfulTrace
Definition: lte-ue-rrc.h:523
std::map< uint8_t, std::list< PendingTrigger_t > > m_enteringTriggerQueue
List of triggers that were raised because entering condition have been true, but are still delayed fr...
Definition: lte-ue-rrc.h:705
std::list< uint8_t > measIdToRemoveList
Definition: lte-rrc-sap.h:403
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE...
Definition: lte-rlc.h:50
a unique identifier for an interface.
Definition: type-id.h:49
virtual void ConfigureUplink(uint16_t ulEarfcn, uint8_t ulBandwidth)=0
Configure uplink (normally done after reception of SIB2)
std::list< ReportConfigToAddMod > reportConfigToAddModList
Definition: lte-rrc-sap.h:402
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:298
uint8_t m_lastRrcTransactionIdentifier
Definition: lte-ue-rrc.h:502
void VarMeasReportListClear(uint8_t measId)
Remove the reporting entry of the given measurement identity from m_varMeasReportList.
Definition: lte-ue-rrc.cc:2526
void LeaveConnectedMode()
Definition: lte-ue-rrc.cc:2714
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndErrorTrace
Definition: lte-ue-rrc.h:535
RaSupervisionInfo raSupervisionInfo
Definition: lte-rrc-sap.h:175
LteRrcSap::SystemInformationBlockType1 m_lastSib1
Stored content of the last SIB1 received.
Definition: lte-ue-rrc.h:543
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-rlc.cc:153
virtual void NotifyRandomAccessFailed()
Notify the RRC that the MAC Random Access procedure failed.
Definition: lte-ue-rrc.cc:80
LteUeCmacSapUser * m_cmacSapUser
Definition: lte-ue-rrc.h:477
static double RsrpRange2Dbm(uint8_t range)
converts an RSRP range to dBm as per 3GPP TS 36.133 section 9.1.4 RSRP Measurement Report Mapping ...
Definition: lte-common.cc:202
void DoForceCampedOnEnb(uint16_t cellId, uint16_t dlEarfcn)
Definition: lte-ue-rrc.cc:571