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