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