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