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  * Copyright (c) 2018 Fraunhofer ESK : RLF extensions
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Nicola Baldo <nbaldo@cttc.es>
20  * Budiarto Herman <budiarto.herman@magister.fi>
21  * Modified by:
22  * Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015)
23  * Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation)
24  * Vignesh Babu <ns3-dev@esk.fraunhofer.de> (RLF extensions)
25  */
26 
27 #include "lte-ue-rrc.h"
28 
29 #include <ns3/fatal-error.h>
30 #include <ns3/log.h>
31 #include <ns3/object-map.h>
32 #include <ns3/object-factory.h>
33 #include <ns3/simulator.h>
34 
35 #include <ns3/lte-rlc.h>
36 #include <ns3/lte-rlc-tm.h>
37 #include <ns3/lte-rlc-um.h>
38 #include <ns3/lte-rlc-am.h>
39 #include <ns3/lte-pdcp.h>
40 #include <ns3/lte-radio-bearer-info.h>
41 
42 #include <cmath>
43 
44 namespace ns3 {
45 
46 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
47 
49 // CMAC SAP forwarder
51 
54 {
55 public:
62 
63  virtual void SetTemporaryCellRnti (uint16_t rnti);
64  virtual void NotifyRandomAccessSuccessful ();
65  virtual void NotifyRandomAccessFailed ();
66 
67 private:
69 };
70 
72  : m_rrc (rrc)
73 {}
74 
75 void
77 {
79 }
80 
81 
82 void
84 {
86 }
87 
88 void
90 {
92 }
93 
94 
95 
96 
97 
98 
100 static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES] =
101 {
102  "IDLE_START",
103  "IDLE_CELL_SEARCH",
104  "IDLE_WAIT_MIB_SIB1",
105  "IDLE_WAIT_MIB",
106  "IDLE_WAIT_SIB1",
107  "IDLE_CAMPED_NORMALLY",
108  "IDLE_WAIT_SIB2",
109  "IDLE_RANDOM_ACCESS",
110  "IDLE_CONNECTING",
111  "CONNECTED_NORMALLY",
112  "CONNECTED_HANDOVER",
113  "CONNECTED_PHY_PROBLEM",
114  "CONNECTED_REESTABLISHING"
115 };
116 
117 
119 // ue RRC methods
121 
122 NS_OBJECT_ENSURE_REGISTERED (LteUeRrc);
123 
124 
126  : m_cmacSapProvider (0),
127  m_rrcSapUser (0),
128  m_macSapProvider (0),
129  m_asSapUser (0),
130  m_ccmRrcSapProvider (0),
131  m_state (IDLE_START),
132  m_imsi (0),
133  m_rnti (0),
134  m_cellId (0),
135  m_useRlcSm (true),
136  m_connectionPending (false),
137  m_hasReceivedMib (false),
138  m_hasReceivedSib1 (false),
139  m_hasReceivedSib2 (false),
140  m_csgWhiteList (0),
141  m_noOfSyncIndications (0),
142  m_leaveConnectedMode (false),
143  m_previousCellId (0),
144  m_connEstFailCountLimit (0),
145  m_connEstFailCount (0),
146  m_numberOfComponentCarriers (MIN_NO_CC)
147 {
148  NS_LOG_FUNCTION (this);
149  m_cphySapUser.push_back (new MemberLteUeCphySapUser<LteUeRrc> (this));
150  m_cmacSapUser.push_back (new UeMemberLteUeCmacSapUser (this));
151  m_cphySapProvider.push_back (0);
152  m_cmacSapProvider.push_back (0);
157 }
158 
160 {
161  NS_LOG_FUNCTION (this);
162 }
163 
164 void
166 {
167  NS_LOG_FUNCTION (this);
168  for ( uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
169  {
170  delete m_cphySapUser.at (i);
171  delete m_cmacSapUser.at (i);
172  }
173  m_cphySapUser.clear ();
174  m_cmacSapUser.clear ();
175  delete m_rrcSapProvider;
176  delete m_drbPdcpSapUser;
177  delete m_asSapProvider;
178  delete m_ccmRrcSapUser;
179  m_cphySapProvider.erase (m_cphySapProvider.begin (), m_cphySapProvider.end ());
180  m_cphySapProvider.clear ();
181  m_cmacSapProvider.erase (m_cmacSapProvider.begin (), m_cmacSapProvider.end ());
182  m_cmacSapProvider.clear ();
183  m_drbMap.clear ();
184 }
185 
186 TypeId
188 {
189  static TypeId tid = TypeId ("ns3::LteUeRrc")
190  .SetParent<Object> ()
191  .SetGroupName ("Lte")
192  .AddConstructor<LteUeRrc> ()
193  .AddAttribute ("DataRadioBearerMap", "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
194  ObjectMapValue (),
196  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
197  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
198  PointerValue (),
200  MakePointerChecker<LteSignalingRadioBearerInfo> ())
201  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
202  PointerValue (),
204  MakePointerChecker<LteSignalingRadioBearerInfo> ())
205  .AddAttribute ("CellId",
206  "Serving cell identifier",
207  UintegerValue (0), // unused, read-only attribute
209  MakeUintegerChecker<uint16_t> ())
210  .AddAttribute ("C-RNTI",
211  "Cell Radio Network Temporary Identifier",
212  UintegerValue (0), // unused, read-only attribute
214  MakeUintegerChecker<uint16_t> ())
215  .AddAttribute ("T300",
216  "Timer for the RRC Connection Establishment procedure "
217  "(i.e., the procedure is deemed as failed if it takes longer than this). "
218  "Standard values: 100ms, 200ms, 300ms, 400ms, 600ms, 1000ms, 1500ms, 2000ms",
219  TimeValue (MilliSeconds (100)), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
221  MakeTimeChecker (MilliSeconds (100), MilliSeconds (2000)))
222  .AddAttribute ("T310",
223  "Timer for detecting the Radio link failure "
224  "(i.e., the radio link is deemed as failed if this timer expires). "
225  "Standard values: 0ms 50ms, 100ms, 200ms, 500ms, 1000ms, 2000ms",
226  TimeValue (MilliSeconds (1000)), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
229  .AddAttribute ("N310",
230  "This specifies the maximum number of out-of-sync indications. "
231  "Standard values: 1, 2, 3, 4, 6, 8, 10, 20",
232  UintegerValue (6), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
234  MakeUintegerChecker<uint8_t> (1, 20))
235  .AddAttribute ("N311",
236  "This specifies the maximum number of in-sync indications. "
237  "Standard values: 1, 2, 3, 4, 5, 6, 8, 10",
238  UintegerValue (2), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
240  MakeUintegerChecker<uint8_t> (1, 10))
241  .AddTraceSource ("MibReceived",
242  "trace fired upon reception of Master Information Block",
244  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
245  .AddTraceSource ("Sib1Received",
246  "trace fired upon reception of System Information Block Type 1",
248  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
249  .AddTraceSource ("Sib2Received",
250  "trace fired upon reception of System Information Block Type 2",
252  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
253  .AddTraceSource ("StateTransition",
254  "trace fired upon every UE RRC state transition",
256  "ns3::LteUeRrc::StateTracedCallback")
257  .AddTraceSource ("InitialCellSelectionEndOk",
258  "trace fired upon successful initial cell selection procedure",
260  "ns3::LteUeRrc::CellSelectionTracedCallback")
261  .AddTraceSource ("InitialCellSelectionEndError",
262  "trace fired upon failed initial cell selection procedure",
264  "ns3::LteUeRrc::CellSelectionTracedCallback")
265  .AddTraceSource ("RandomAccessSuccessful",
266  "trace fired upon successful completion of the random access procedure",
268  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
269  .AddTraceSource ("RandomAccessError",
270  "trace fired upon failure of the random access procedure",
272  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
273  .AddTraceSource ("ConnectionEstablished",
274  "trace fired upon successful RRC connection establishment",
276  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
277  .AddTraceSource ("ConnectionTimeout",
278  "trace fired upon timeout RRC connection establishment because of T300",
280  "ns3::LteUeRrc::ImsiCidRntiCountTracedCallback")
281  .AddTraceSource ("ConnectionReconfiguration",
282  "trace fired upon RRC connection reconfiguration",
284  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
285  .AddTraceSource ("HandoverStart",
286  "trace fired upon start of a handover procedure",
288  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
289  .AddTraceSource ("HandoverEndOk",
290  "trace fired upon successful termination of a handover procedure",
292  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
293  .AddTraceSource ("HandoverEndError",
294  "trace fired upon failure of a handover procedure",
296  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
297  .AddTraceSource ("SCarrierConfigured",
298  "trace fired after configuring secondary carriers",
300  "ns3::LteUeRrc::SCarrierConfiguredTracedCallback")
301  .AddTraceSource ("Srb1Created",
302  "trace fired after SRB1 is created",
304  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
305  .AddTraceSource ("DrbCreated",
306  "trace fired after DRB is created",
308  "ns3::LteUeRrc::ImsiCidRntiLcIdTracedCallback")
309  .AddTraceSource ("RadioLinkFailure",
310  "trace fired upon failure of radio link",
312  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
313  .AddTraceSource ("PhySyncDetection",
314  "trace fired upon receiving in Sync or out of Sync indications from UE PHY",
316  "ns3::LteUeRrc::PhySyncDetectionTracedCallback")
317  ;
318  return tid;
319 }
320 
321 
322 void
324 {
325  NS_LOG_FUNCTION (this << s);
326  m_cphySapProvider.at (0) = s;
327 }
328 
329 void
331 {
332  NS_LOG_FUNCTION (this << s);
333  m_cphySapProvider.at (index) = s;
334 }
335 
338 {
339  NS_LOG_FUNCTION (this);
340  return m_cphySapUser.at (0);
341 }
342 
345 {
346  NS_LOG_FUNCTION (this);
347  return m_cphySapUser.at (index);
348 }
349 
350 void
352 {
353  NS_LOG_FUNCTION (this << s);
354  m_cmacSapProvider.at (0) = s;
355 }
356 
357 void
359 {
360  NS_LOG_FUNCTION (this << s);
361  m_cmacSapProvider.at (index) = s;
362 }
363 
366 {
367  NS_LOG_FUNCTION (this);
368  return m_cmacSapUser.at (0);
369 }
370 
373 {
374  NS_LOG_FUNCTION (this);
375  return m_cmacSapUser.at (index);
376 }
377 
378 void
380 {
381  NS_LOG_FUNCTION (this << s);
382  m_rrcSapUser = s;
383 }
384 
387 {
388  NS_LOG_FUNCTION (this);
389  return m_rrcSapProvider;
390 }
391 
392 void
394 {
395  NS_LOG_FUNCTION (this << s);
396  m_macSapProvider = s;
397 }
398 
399 void
401 {
402  NS_LOG_FUNCTION (this << s);
404 }
405 
408 {
409  NS_LOG_FUNCTION (this);
410  return m_ccmRrcSapUser;
411 }
412 
413 void
415 {
416  m_asSapUser = s;
417 }
418 
421 {
422  return m_asSapProvider;
423 }
424 
425 void
426 LteUeRrc::SetImsi (uint64_t imsi)
427 {
428  NS_LOG_FUNCTION (this << imsi);
429  m_imsi = imsi;
430 
431  //Communicate the IMSI to MACs and PHYs for all the component carriers
432  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
433  {
434  m_cmacSapProvider.at (i)->SetImsi (m_imsi);
435  m_cphySapProvider.at (i)->SetImsi (m_imsi);
436  }
437 }
438 
439 void
441 {
442  NS_LOG_FUNCTION (this << cellId);
443  m_previousCellId = cellId;
444 }
445 
446 uint64_t
447 LteUeRrc::GetImsi (void) const
448 {
449  return m_imsi;
450 }
451 
452 uint16_t
454 {
455  NS_LOG_FUNCTION (this);
456  return m_rnti;
457 }
458 
459 uint16_t
461 {
462  NS_LOG_FUNCTION (this);
463  return m_cellId;
464 }
465 
466 bool
467 LteUeRrc::IsServingCell (uint16_t cellId) const
468 {
469  NS_LOG_FUNCTION (this);
470  for (auto &cphySap: m_cphySapProvider)
471  {
472  if (cellId == cphySap->GetCellId ())
473  {
474  return true;
475  }
476  }
477  return false;
478 }
479 
480 
481 uint8_t
483 {
484  NS_LOG_FUNCTION (this);
485  return m_ulBandwidth;
486 }
487 
488 uint8_t
490 {
491  NS_LOG_FUNCTION (this);
492  return m_dlBandwidth;
493 }
494 
495 uint32_t
497 {
498  return m_dlEarfcn;
499 }
500 
501 uint32_t
503 {
504  NS_LOG_FUNCTION (this);
505  return m_ulEarfcn;
506 }
507 
509 LteUeRrc::GetState (void) const
510 {
511  NS_LOG_FUNCTION (this);
512  return m_state;
513 }
514 
515 uint16_t
517 {
518  NS_LOG_FUNCTION (this);
519  return m_previousCellId;
520 }
521 
522 void
524 {
525  NS_LOG_FUNCTION (this);
526  m_useRlcSm = val;
527 }
528 
529 
530 void
532 {
533  NS_LOG_FUNCTION (this);
534 
535  // setup the UE side of SRB0
536  uint8_t lcid = 0;
537 
538  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
540  rlc->SetRnti (m_rnti);
541  rlc->SetLcId (lcid);
542 
543  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
544  m_srb0->m_rlc = rlc;
545  m_srb0->m_srbIdentity = 0;
547  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
548  ueParams.srb1SapProvider = 0;
549  m_rrcSapUser->Setup (ueParams);
550 
551  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
553  lcConfig.priority = 0; // highest priority
554  lcConfig.prioritizedBitRateKbps = 65535; // maximum
555  lcConfig.bucketSizeDurationMs = 65535; // maximum
556  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
558  m_cmacSapProvider.at (0)->AddLc (lcid, lcConfig, msu);
559 }
560 
561 void
563 {
564  if (m_numberOfComponentCarriers < MIN_NO_CC || m_numberOfComponentCarriers > MAX_NO_CC)
565  {
566  // this check is needed in order to maintain backward compatibility with scripts and tests
567  // if case lte-helper is not used (like in several tests) the m_numberOfComponentCarriers
568  // is not set and then an error is raised
569  // In this case m_numberOfComponentCarriers is set to 1
571  }
573  {
574  for ( uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
575  {
576  m_cphySapUser.push_back (new MemberLteUeCphySapUser<LteUeRrc> (this));
577  m_cmacSapUser.push_back (new UeMemberLteUeCmacSapUser (this));
578  m_cphySapProvider.push_back (0);
579  m_cmacSapProvider.push_back (0);
580  }
581  }
582 }
583 
584 
585 void
586 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
587 {
588  NS_LOG_FUNCTION (this << packet);
589 
590  uint8_t drbid = Bid2Drbid (bid);
591 
592  if (drbid != 0)
593  {
594  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
595  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
596 
598  params.pdcpSdu = packet;
599  params.rnti = m_rnti;
600  params.lcid = it->second->m_logicalChannelIdentity;
601 
602  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending packet " << packet
603  << " on DRBID " << (uint32_t) drbid
604  << " (LCID " << (uint32_t) params.lcid << ")"
605  << " (" << packet->GetSize () << " bytes)");
606  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
607  }
608 }
609 
610 
611 void
613 {
614  NS_LOG_FUNCTION (this);
615 
616  switch (m_state)
617  {
618  case IDLE_START:
619  case IDLE_CELL_SEARCH:
620  case IDLE_WAIT_MIB_SIB1:
621  case IDLE_WAIT_MIB:
622  case IDLE_WAIT_SIB1:
624  NS_LOG_INFO ("already disconnected");
625  break;
626 
627  case IDLE_WAIT_SIB2:
628  case IDLE_CONNECTING:
629  NS_FATAL_ERROR ("cannot abort connection setup procedure");
630  break;
631 
632  case CONNECTED_NORMALLY:
633  case CONNECTED_HANDOVER:
637  break;
638 
639  default: // i.e. IDLE_RANDOM_ACCESS
640  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
641  break;
642  }
643 }
644 
645 void
647 {
648  NS_LOG_FUNCTION (this);
649  m_asSapUser->RecvData (params.pdcpSdu);
650 }
651 
652 
653 void
655 {
656  NS_LOG_FUNCTION (this << rnti);
657  m_rnti = rnti;
658  m_srb0->m_rlc->SetRnti (m_rnti);
659  m_cphySapProvider.at (0)->SetRnti (m_rnti);
660 }
661 
662 void
664 {
665  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
667 
668  switch (m_state)
669  {
670  case IDLE_RANDOM_ACCESS:
671  {
672  // we just received a RAR with a T-C-RNTI and an UL grant
673  // send RRC connection request as message 3 of the random access procedure
676  msg.ueIdentity = m_imsi;
680  this);
681  }
682  break;
683 
684  case CONNECTED_HANDOVER:
685  {
689 
690  // 3GPP TS 36.331 section 5.5.6.1 Measurements related actions upon handover
691  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
692  for (measIdIt = m_varMeasConfig.measIdList.begin ();
693  measIdIt != m_varMeasConfig.measIdList.end ();
694  ++measIdIt)
695  {
696  VarMeasReportListClear (measIdIt->second.measId);
697  }
698 
700  m_cmacSapProvider.at (0)->NotifyConnectionSuccessful (); //RA successful during handover
702  }
703  break;
704 
705  default:
706  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
707  break;
708  }
709 }
710 
711 void
713 {
714  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
716 
717  switch (m_state)
718  {
719  case IDLE_RANDOM_ACCESS:
720  {
723  }
724  break;
725 
726  case CONNECTED_HANDOVER:
727  {
734  }
735  break;
736 
737  default:
738  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
739  break;
740  }
741 }
742 
743 
744 void
746 {
747  NS_LOG_FUNCTION (this << m_imsi << csgId);
748  m_csgWhiteList = csgId;
749 }
750 
751 void
753 {
754  NS_LOG_FUNCTION (this << m_imsi << dlEarfcn);
756  "cannot start cell selection from state " << ToString (m_state));
757  m_dlEarfcn = dlEarfcn;
758  m_cphySapProvider.at (0)->StartCellSearch (dlEarfcn);
760 }
761 
762 void
763 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint32_t dlEarfcn)
764 {
765  NS_LOG_FUNCTION (this << m_imsi << cellId << dlEarfcn);
766 
767  switch (m_state)
768  {
769  case IDLE_START:
770  m_cellId = cellId;
771  m_dlEarfcn = dlEarfcn;
772  m_cphySapProvider.at (0)->SynchronizeWithEnb (m_cellId, m_dlEarfcn);
774  break;
775 
776  case IDLE_CELL_SEARCH:
777  case IDLE_WAIT_MIB_SIB1:
778  case IDLE_WAIT_SIB1:
779  NS_FATAL_ERROR ("cannot abort cell selection " << ToString (m_state));
780  break;
781 
782  case IDLE_WAIT_MIB:
783  NS_LOG_INFO ("already forced to camp to cell " << m_cellId);
784  break;
785 
787  case IDLE_WAIT_SIB2:
788  case IDLE_RANDOM_ACCESS:
789  case IDLE_CONNECTING:
790  NS_LOG_INFO ("already camped to cell " << m_cellId);
791  break;
792 
793  case CONNECTED_NORMALLY:
794  case CONNECTED_HANDOVER:
797  NS_LOG_INFO ("already connected to cell " << m_cellId);
798  break;
799 
800  default:
801  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
802  break;
803  }
804 
805 }
806 
807 void
809 {
810  NS_LOG_FUNCTION (this << m_imsi);
811 
812  switch (m_state)
813  {
814  case IDLE_START:
815  case IDLE_CELL_SEARCH:
816  case IDLE_WAIT_MIB_SIB1:
817  case IDLE_WAIT_SIB1:
818  case IDLE_WAIT_MIB:
819  m_connectionPending = true;
820  break;
821 
823  m_connectionPending = true;
825  break;
826 
827  case IDLE_WAIT_SIB2:
828  case IDLE_RANDOM_ACCESS:
829  case IDLE_CONNECTING:
830  NS_LOG_INFO ("already connecting");
831  break;
832 
833  case CONNECTED_NORMALLY:
835  case CONNECTED_HANDOVER:
836  NS_LOG_INFO ("already connected");
837  break;
838 
839  default:
840  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
841  break;
842  }
843 }
844 
845 
846 
847 // CPHY SAP methods
848 
849 void
852 {
854  m_cphySapProvider.at (0)->SetDlBandwidth (msg.dlBandwidth);
855  m_hasReceivedMib = true;
857 
858  switch (m_state)
859  {
860  case IDLE_WAIT_MIB:
861  // manual attachment
863  break;
864 
865  case IDLE_WAIT_MIB_SIB1:
866  // automatic attachment from Idle mode cell selection
868  break;
869 
870  default:
871  // do nothing extra
872  break;
873  }
874 }
875 
876 void
879 {
880  NS_LOG_FUNCTION (this);
881  switch (m_state)
882  {
883  case IDLE_WAIT_SIB1:
885  "Cell identity in SIB1 does not match with the originating cell");
886  m_hasReceivedSib1 = true;
887  m_lastSib1 = msg;
890  break;
891 
893  case IDLE_RANDOM_ACCESS:
894  case IDLE_CONNECTING:
895  case CONNECTED_NORMALLY:
896  case CONNECTED_HANDOVER:
900  "Cell identity in SIB1 does not match with the originating cell");
901  m_hasReceivedSib1 = true;
902  m_lastSib1 = msg;
904  break;
905 
906  case IDLE_WAIT_MIB_SIB1:
907  // MIB has not been received, so ignore this SIB1
908  break;
909 
910  default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
911  // do nothing
912  break;
913  }
914 }
915 
916 void
918 {
919  NS_LOG_FUNCTION (this);
920 
921  // layer 3 filtering does not apply in IDLE mode
922  bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
923  bool triggering = true;
924  std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
925  for (newMeasIt = params.m_ueMeasurementsList.begin ();
926  newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
927  {
928  if (params.m_componentCarrierId != 0)
929  {
930  triggering = false; // report is triggered only when an event is on the primary carrier
931  // in this case the measurement received is related to secondary carriers
932  }
933  SaveUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
934  newMeasIt->m_rsrq, useLayer3Filtering,
935  params.m_componentCarrierId);
936  }
937 
938  if (m_state == IDLE_CELL_SEARCH)
939  {
940  // start decoding BCH
942  }
943  else
944  {
945  if (triggering)
946  {
947  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
948  for (measIdIt = m_varMeasConfig.measIdList.begin ();
949  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
950  {
951  MeasurementReportTriggering (measIdIt->first);
952  }
953  }
954  }
955 
956 } // end of LteUeRrc::DoReportUeMeasurements
957 
958 
959 
960 // RRC SAP methods
961 
962 void
964 {
965  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
966  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
967  if (m_srb1)
968  {
969  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
970  }
971 }
972 
973 
974 void
976 {
977  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
978 
979  if (msg.haveSib2)
980  {
981  switch (m_state)
982  {
984  case IDLE_WAIT_SIB2:
985  case IDLE_RANDOM_ACCESS:
986  case IDLE_CONNECTING:
987  case CONNECTED_NORMALLY:
988  case CONNECTED_HANDOVER:
991  m_hasReceivedSib2 = true;
1002  "SIB2 msg contains wrong value "
1003  << m_connEstFailCountLimit << "of connEstFailCount");
1004  m_cmacSapProvider.at (0)->ConfigureRach (rc);
1005  m_cphySapProvider.at (0)->ConfigureUplink (m_ulEarfcn, m_ulBandwidth);
1006  m_cphySapProvider.at (0)->ConfigureReferenceSignalPower (msg.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower);
1007  if (m_state == IDLE_WAIT_SIB2)
1008  {
1010  StartConnection ();
1011  }
1012  break;
1013 
1014  default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
1015  // do nothing
1016  break;
1017  }
1018  }
1019 
1020 }
1021 
1022 
1023 void
1025 {
1026  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1027  switch (m_state)
1028  {
1029  case IDLE_CONNECTING:
1030  {
1032  m_connEstFailCount = 0;
1035  m_leaveConnectedMode = false;
1040  m_cmacSapProvider.at (0)->NotifyConnectionSuccessful ();
1042  NS_ABORT_MSG_IF (m_noOfSyncIndications > 0, "Sync indications should be zero "
1043  "when a new RRC connection is established. Current value = " << (uint16_t) m_noOfSyncIndications);
1044  }
1045  break;
1046 
1047  default:
1048  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1049  break;
1050  }
1051 }
1052 
1053 void
1055 {
1056  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1057  NS_LOG_INFO ("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:" << msg.haveNonCriticalExtension);
1058  switch (m_state)
1059  {
1060  case CONNECTED_NORMALLY:
1061  if (msg.haveMobilityControlInfo)
1062  {
1063  NS_LOG_INFO ("haveMobilityControlInfo == true");
1066  {
1067  ResetRlfParams ();
1068  }
1071  //We should reset the MACs and PHYs for all the component carriers
1072  for (auto cmacSapProvider: m_cmacSapProvider)
1073  {
1074  cmacSapProvider->Reset ();
1075  }
1076  for (auto cphySapProvider: m_cphySapProvider)
1077  {
1078  cphySapProvider->Reset ();
1079  }
1082  m_cellId = mci.targetPhysCellId;
1083  NS_ASSERT (mci.haveCarrierFreq);
1085  m_cphySapProvider.at (0)->SynchronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
1086  m_cphySapProvider.at (0)->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
1087  m_cphySapProvider.at (0)->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
1089  m_srb0->m_rlc->SetRnti (m_rnti);
1090  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
1091  m_cmacSapProvider.at (0)->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
1092  m_cphySapProvider.at (0)->SetRnti (m_rnti);
1095 
1096  // we re-establish SRB1 by creating a new entity
1097  // note that we can't dispose the old entity now, because
1098  // it's in the current stack, so we would corrupt the stack
1099  // if we did so. Hence we schedule it for later disposal
1100  m_srb1Old = m_srb1;
1102  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
1103 
1104  m_drbMap.clear (); // dispose all DRBs
1106  if (msg.haveNonCriticalExtension)
1107  {
1108  NS_LOG_DEBUG (this << "RNTI " << m_rnti << " Handover. Configuring secondary carriers");
1110  }
1111 
1112  if (msg.haveMeasConfig)
1113  {
1115  }
1116  // RRC connection reconfiguration completed will be sent
1117  // after handover is complete
1118  }
1119  else
1120  {
1121  NS_LOG_INFO ("haveMobilityControlInfo == false");
1122  if (msg.haveNonCriticalExtension)
1123  {
1125  NS_LOG_DEBUG (this << "RNTI " << m_rnti << " Configured for CA" );
1126  }
1128  {
1130  }
1131  if (msg.haveMeasConfig)
1132  {
1134  }
1139  }
1140  break;
1141 
1142  default:
1143  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1144  break;
1145  }
1146 }
1147 
1148 void
1150 {
1151  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1152  switch (m_state)
1153  {
1155  {
1163  }
1164  break;
1165 
1166  default:
1167  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1168  break;
1169  }
1170 }
1171 
1172 void
1174 {
1175  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1176  switch (m_state)
1177  {
1179  {
1184  m_asSapUser->NotifyConnectionReleased (); // Inform upper layers
1185  }
1186  break;
1187 
1188  default:
1189  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1190  break;
1191  }
1192 }
1193 
1194 void
1196 {
1197  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1199 }
1200 
1201 void
1203 {
1204  NS_LOG_FUNCTION (this);
1206  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1207  {
1208  m_cmacSapProvider.at (i)->Reset (); // reset the MAC
1209  }
1210  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1212  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
1213 }
1214 
1215 void
1216 LteUeRrc::DoSetNumberOfComponentCarriers (uint16_t noOfComponentCarriers)
1217 {
1218  NS_LOG_FUNCTION (this);
1219  m_numberOfComponentCarriers = noOfComponentCarriers;
1220 }
1221 
1222 
1223 
1224 void
1226 {
1227  NS_LOG_FUNCTION (this);
1229 
1230  uint16_t maxRsrpCellId = 0;
1231  double maxRsrp = -std::numeric_limits<double>::infinity ();
1232  double minRsrp = -140.0; // Minimum RSRP in dBm a UE can report
1233 
1234  std::map<uint16_t, MeasValues>::iterator it;
1235  for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
1236  {
1237  /*
1238  * This block attempts to find a cell with strongest RSRP and has not
1239  * yet been identified as "acceptable cell".
1240  */
1241  if (maxRsrp < it->second.rsrp && it->second.rsrp > minRsrp)
1242  {
1243  std::set<uint16_t>::const_iterator itCell;
1244  itCell = m_acceptableCell.find (it->first);
1245  if (itCell == m_acceptableCell.end ())
1246  {
1247  maxRsrpCellId = it->first;
1248  maxRsrp = it->second.rsrp;
1249  }
1250  }
1251  }
1252 
1253  if (maxRsrpCellId == 0)
1254  {
1255  NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
1256  }
1257  else
1258  {
1259  NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
1260  << " is the strongest untried surrounding cell");
1261  m_cphySapProvider.at (0)->SynchronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
1263  }
1264 
1265 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1266 
1267 
1268 void
1270 {
1271  NS_LOG_FUNCTION (this);
1275  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1276 
1277  // Cell selection criteria evaluation
1278 
1279  bool isSuitableCell = false;
1280  bool isAcceptableCell = false;
1281  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1282  double qRxLevMeas = storedMeasIt->second.rsrp;
1284  NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
1285  << " qrxlevmeas=" << qRxLevMeas << " dBm"
1286  << " qrxlevmin=" << qRxLevMin << " dBm");
1287 
1288  if (qRxLevMeas - qRxLevMin > 0)
1289  {
1290  isAcceptableCell = true;
1291 
1292  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1293  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1294 
1295  isSuitableCell = (cellCsgIndication == false) || (cellCsgId == m_csgWhiteList);
1296 
1297  NS_LOG_LOGIC (this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
1298  << cellCsgId << "/" << cellCsgIndication);
1299  }
1300 
1301  // Cell selection decision
1302 
1303  if (isSuitableCell)
1304  {
1305  m_cellId = cellId;
1306  m_cphySapProvider.at (0)->SynchronizeWithEnb (cellId, m_dlEarfcn);
1307  m_cphySapProvider.at (0)->SetDlBandwidth (m_dlBandwidth);
1309  // Once the UE is connected, m_connectionPending is
1310  // set to false. So, when RLF occurs and UE performs
1311  // cell selection upon leaving RRC_CONNECTED state,
1312  // the following call to DoConnect will make the
1313  // m_connectionPending to be true again. Thus,
1314  // upon calling SwitchToState (IDLE_CAMPED_NORMALLY)
1315  // UE state is instantly change to IDLE_WAIT_SIB2.
1316  // This will make the UE to read the SIB2 message
1317  // and start random access.
1318  if (!m_connectionPending)
1319  {
1320  NS_LOG_DEBUG ("Calling DoConnect in state = " << ToString (m_state));
1321  DoConnect ();
1322  }
1324  }
1325  else
1326  {
1327  // ignore the MIB and SIB1 received from this cell
1328  m_hasReceivedMib = false;
1329  m_hasReceivedSib1 = false;
1330 
1332 
1333  if (isAcceptableCell)
1334  {
1335  /*
1336  * The cells inserted into this list will not be considered for
1337  * subsequent cell search attempt.
1338  */
1339  m_acceptableCell.insert (cellId);
1340  }
1341 
1343  SynchronizeToStrongestCell (); // retry to a different cell
1344  }
1345 
1346 } // end of void LteUeRrc::EvaluateCellForSelection ()
1347 
1348 
1349 void
1351 {
1352  NS_LOG_FUNCTION (this);
1353 
1355 
1356  for (uint32_t sCellIndex: nonCec.sCellToReleaseList)
1357  {
1358  m_cphySapProvider.at (sCellIndex)->Reset ();
1359  m_cmacSapProvider.at (sCellIndex)->Reset ();
1360  }
1361 
1362  for(auto &scell: nonCec.sCellToAddModList)
1363  {
1364  uint8_t ccId = scell.sCellIndex;
1365 
1366 
1367  uint16_t physCellId = scell.cellIdentification.physCellId;
1368  uint16_t ulBand = scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth;
1369  uint32_t ulEarfcn = scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq;
1370  uint16_t dlBand = scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth;
1371  uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1372  uint8_t txMode = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell.antennaInfo.transmissionMode;
1373  uint16_t srsIndex = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell.soundingRsUlConfigDedicated.srsConfigIndex;
1374 
1375  m_cphySapProvider.at (ccId)->SynchronizeWithEnb (physCellId, dlEarfcn);
1376  m_cphySapProvider.at (ccId)->SetDlBandwidth (dlBand);
1377  m_cphySapProvider.at (ccId)->ConfigureUplink (ulEarfcn, ulBand);
1378  m_cphySapProvider.at (ccId)->ConfigureReferenceSignalPower (scell.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.referenceSignalPower);
1379  m_cphySapProvider.at (ccId)->SetTransmissionMode (txMode);
1380  m_cphySapProvider.at (ccId)->SetRnti (m_rnti);
1381  m_cmacSapProvider.at (ccId)->SetRnti (m_rnti);
1382  // update PdschConfigDedicated (i.e. P_A value)
1383  LteRrcSap::PdschConfigDedicated pdschConfigDedicated = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell.pdschConfigDedicated;
1384  double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (pdschConfigDedicated);
1385  m_cphySapProvider.at (ccId)->SetPa (paDouble);
1386  m_cphySapProvider.at (ccId)->SetSrsConfigurationIndex (srsIndex);
1387  }
1388 
1390 }
1391 
1392 void
1394 {
1395  NS_LOG_FUNCTION (this);
1397 
1398  if (pcd.haveAntennaInfoDedicated)
1399  {
1400  m_cphySapProvider.at (0)->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
1401  }
1403  {
1404  m_cphySapProvider.at (0)->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
1405  }
1406 
1407  if (pcd.havePdschConfigDedicated)
1408  {
1409  // update PdschConfigDedicated (i.e. P_A value)
1412  m_cphySapProvider.at (0)->SetPa (paDouble);
1413  }
1414 
1415  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1416  if (stamIt != rrcd.srbToAddModList.end ())
1417  {
1418  if (m_srb1 == 0)
1419  {
1420  // SRB1 not setup yet
1422  "unexpected state " << ToString (m_state));
1423  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1424 
1425  const uint8_t lcid = 1; // fixed LCID for SRB1
1426 
1427  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1429  rlc->SetRnti (m_rnti);
1430  rlc->SetLcId (lcid);
1431 
1432  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1433  pdcp->SetRnti (m_rnti);
1434  pdcp->SetLcId (lcid);
1435  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1436  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1437  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1438 
1439  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1440  m_srb1->m_rlc = rlc;
1441  m_srb1->m_pdcp = pdcp;
1442  m_srb1->m_srbIdentity = 1;
1444 
1445  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1446  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1447  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1448  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1449 
1451  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1452  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1453  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1454  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1455  LteMacSapUser* msu = m_ccmRrcSapProvider->ConfigureSignalBearer (lcid, lcConfig, rlc->GetLteMacSapUser ());
1456  m_cmacSapProvider.at (0)->AddLc (lcid, lcConfig, msu);
1457  ++stamIt;
1458  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1459 
1461  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1462  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1463  m_rrcSapUser->Setup (ueParams);
1464  }
1465  else
1466  {
1467  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1468  // would need to modify m_srb1, and then propagate changes to the MAC
1469  }
1470  }
1471 
1472 
1473  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1474  for (dtamIt = rrcd.drbToAddModList.begin ();
1475  dtamIt != rrcd.drbToAddModList.end ();
1476  ++dtamIt)
1477  {
1478  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1479  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1480 
1481  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1482  if (drbMapIt == m_drbMap.end ())
1483  {
1484  NS_LOG_INFO ("New Data Radio Bearer");
1485 
1486  TypeId rlcTypeId;
1487  if (m_useRlcSm)
1488  {
1489  rlcTypeId = LteRlcSm::GetTypeId ();
1490  }
1491  else
1492  {
1493  switch (dtamIt->rlcConfig.choice)
1494  {
1496  rlcTypeId = LteRlcAm::GetTypeId ();
1497  break;
1498 
1500  rlcTypeId = LteRlcUm::GetTypeId ();
1501  break;
1502 
1503  default:
1504  NS_FATAL_ERROR ("unsupported RLC configuration");
1505  break;
1506  }
1507  }
1508 
1509  ObjectFactory rlcObjectFactory;
1510  rlcObjectFactory.SetTypeId (rlcTypeId);
1511  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1513  rlc->SetRnti (m_rnti);
1514  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1515 
1516  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1517  drbInfo->m_rlc = rlc;
1518  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1519  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1520  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1521 
1522  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1523  // if we are using RLC/SM we don't care of anything above RLC
1524  if (rlcTypeId != LteRlcSm::GetTypeId ())
1525  {
1526  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1527  pdcp->SetRnti (m_rnti);
1528  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1529  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1530  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1531  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1532  drbInfo->m_pdcp = pdcp;
1533  }
1534 
1535  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1536 
1537  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1538 
1539  m_drbCreatedTrace (m_imsi, m_cellId, m_rnti, dtamIt->drbIdentity);
1540 
1541 
1543  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1544  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1545  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1546  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1547 
1548  NS_LOG_DEBUG (this << " UE RRC RNTI " << m_rnti << " Number Of Component Carriers " << m_numberOfComponentCarriers << " lcID " << (uint16_t) dtamIt->logicalChannelIdentity);
1549  //Call AddLc of UE component carrier manager
1550  std::vector <LteUeCcmRrcSapProvider::LcsConfig> lcOnCcMapping = m_ccmRrcSapProvider->AddLc (dtamIt->logicalChannelIdentity, lcConfig, rlc->GetLteMacSapUser ());
1551 
1552  NS_LOG_DEBUG ("Size of lcOnCcMapping vector " << lcOnCcMapping.size ());
1553  std::vector<LteUeCcmRrcSapProvider::LcsConfig>::iterator itLcOnCcMapping = lcOnCcMapping.begin ();
1554  NS_ASSERT_MSG (itLcOnCcMapping != lcOnCcMapping.end (), "Component carrier manager failed to add LC for data radio bearer");
1555 
1556  for (itLcOnCcMapping = lcOnCcMapping.begin (); itLcOnCcMapping != lcOnCcMapping.end (); ++itLcOnCcMapping)
1557  {
1558  NS_LOG_DEBUG ("RNTI " << m_rnti
1559  << " LCG id " << (uint16_t) itLcOnCcMapping->lcConfig.logicalChannelGroup
1560  << " ComponentCarrierId " << (uint16_t) itLcOnCcMapping->componentCarrierId);
1561  uint8_t index = itLcOnCcMapping->componentCarrierId;
1562  LteUeCmacSapProvider::LogicalChannelConfig lcConfigFromCcm = itLcOnCcMapping->lcConfig;
1563  LteMacSapUser *msu = itLcOnCcMapping->msu;
1564  m_cmacSapProvider.at (index)->AddLc (dtamIt->logicalChannelIdentity, lcConfigFromCcm, msu);
1565  }
1566 
1567  rlc->Initialize ();
1568  }
1569  else
1570  {
1571  NS_LOG_INFO ("request to modify existing DRBID");
1572  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1574  }
1575  }
1576 
1577  std::list<uint8_t>::iterator dtdmIt;
1578  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1579  dtdmIt != rrcd.drbToReleaseList.end ();
1580  ++dtdmIt)
1581  {
1582  uint8_t drbid = *dtdmIt;
1583  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid);
1584  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1585  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1586  m_drbMap.erase (it);
1587  m_bid2DrbidMap.erase (drbid);
1588  //Remove LCID
1589  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1590  {
1591  m_cmacSapProvider.at (i)->RemoveLc (drbid + 2);
1592  }
1593  }
1594 }
1595 
1596 
1597 void
1599 {
1600  NS_LOG_FUNCTION (this);
1601 
1602  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1603 
1604  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1605  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1606  it != mc.measObjectToRemoveList.end ();
1607  ++it)
1608  {
1609  uint8_t measObjectId = *it;
1610  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1611  m_varMeasConfig.measObjectList.erase (measObjectId);
1612  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1613  while (measIdIt != m_varMeasConfig.measIdList.end ())
1614  {
1615  if (measIdIt->second.measObjectId == measObjectId)
1616  {
1617  uint8_t measId = measIdIt->second.measId;
1618  NS_ASSERT (measId == measIdIt->first);
1619  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1620  // note: postfix operator preserves iterator validity
1621  m_varMeasConfig.measIdList.erase (measIdIt++);
1622  VarMeasReportListClear (measId);
1623  }
1624  else
1625  {
1626  ++measIdIt;
1627  }
1628  }
1629 
1630  }
1631 
1632  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1633  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1634  it != mc.measObjectToAddModList.end ();
1635  ++it)
1636  {
1637  // simplifying assumptions
1638  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1639  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1640  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1641  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1642  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
1643 
1644  uint8_t measObjectId = it->measObjectId;
1645  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1646  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1647  {
1648  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1649  measObjectIt->second = *it;
1650  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1651  = m_varMeasConfig.measIdList.begin ();
1652  measIdIt != m_varMeasConfig.measIdList.end ();
1653  ++measIdIt)
1654  {
1655  if (measIdIt->second.measObjectId == measObjectId)
1656  {
1657  uint8_t measId = measIdIt->second.measId;
1658  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1659  VarMeasReportListClear (measId);
1660  }
1661  }
1662  }
1663  else
1664  {
1665  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1666  m_varMeasConfig.measObjectList[measObjectId] = *it;
1667  }
1668 
1669  }
1670 
1671  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1672  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1673  it != mc.reportConfigToRemoveList.end ();
1674  ++it)
1675  {
1676  uint8_t reportConfigId = *it;
1677  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1678  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1679  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1680  while (measIdIt != m_varMeasConfig.measIdList.end ())
1681  {
1682  if (measIdIt->second.reportConfigId == reportConfigId)
1683  {
1684  uint8_t measId = measIdIt->second.measId;
1685  NS_ASSERT (measId == measIdIt->first);
1686  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1687  // note: postfix operator preserves iterator validity
1688  m_varMeasConfig.measIdList.erase (measIdIt++);
1689  VarMeasReportListClear (measId);
1690  }
1691  else
1692  {
1693  ++measIdIt;
1694  }
1695  }
1696 
1697  }
1698 
1699  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1700  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1701  it != mc.reportConfigToAddModList.end ();
1702  ++it)
1703  {
1704  // simplifying assumptions
1705  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1706  "only trigger type EVENT is supported");
1707 
1708  uint8_t reportConfigId = it->reportConfigId;
1709  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1710  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1711  {
1712  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1713  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1714  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1715  = m_varMeasConfig.measIdList.begin ();
1716  measIdIt != m_varMeasConfig.measIdList.end ();
1717  ++measIdIt)
1718  {
1719  if (measIdIt->second.reportConfigId == reportConfigId)
1720  {
1721  uint8_t measId = measIdIt->second.measId;
1722  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1723  VarMeasReportListClear (measId);
1724  }
1725  }
1726  }
1727  else
1728  {
1729  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1730  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1731  }
1732 
1733  }
1734 
1735  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1736  if (mc.haveQuantityConfig)
1737  {
1738  NS_LOG_LOGIC (this << " setting quantityConfig");
1740  //Convey the filter coefficient to PHY layer so it can configure the power control parameter
1741  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1742  {
1743  m_cphySapProvider.at (i)->SetRsrpFilterCoefficient (mc.quantityConfig.filterCoefficientRSRP);
1744  }
1745  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1746  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1747  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1748  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1749 
1750  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1751  = m_varMeasConfig.measIdList.begin ();
1752  measIdIt != m_varMeasConfig.measIdList.end ();
1753  ++measIdIt)
1754  {
1755  VarMeasReportListClear (measIdIt->second.measId);
1756  }
1757  }
1758 
1759  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1760  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1761  it != mc.measIdToRemoveList.end ();
1762  ++it)
1763  {
1764  uint8_t measId = *it;
1765  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1766  m_varMeasConfig.measIdList.erase (measId);
1767  VarMeasReportListClear (measId);
1768 
1769  // removing time-to-trigger queues
1770  m_enteringTriggerQueue.erase (measId);
1771  m_leavingTriggerQueue.erase (measId);
1772  }
1773 
1774  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1775  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1776  it != mc.measIdToAddModList.end ();
1777  ++it)
1778  {
1779  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId
1780  << " (measObjectId=" << (uint32_t) it->measObjectId
1781  << ", reportConfigId=" << (uint32_t) it->reportConfigId
1782  << ")");
1783  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1784  != m_varMeasConfig.measObjectList.end ());
1785  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1786  != m_varMeasConfig.reportConfigList.end ());
1787  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1788  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1789  if (measReportIt != m_varMeasReportList.end ())
1790  {
1791  measReportIt->second.periodicReportTimer.Cancel ();
1792  m_varMeasReportList.erase (measReportIt);
1793  }
1794  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1795  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1796 
1797  // new empty queues for time-to-trigger
1798  std::list<PendingTrigger_t> s;
1799  m_enteringTriggerQueue[it->measId] = s;
1800  m_leavingTriggerQueue[it->measId] = s;
1801  }
1802 
1803  if (mc.haveMeasGapConfig)
1804  {
1805  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1806  }
1807 
1808  if (mc.haveSmeasure)
1809  {
1810  NS_FATAL_ERROR ("s-measure is currently not supported");
1811  }
1812 
1813  if (mc.haveSpeedStatePars)
1814  {
1815  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1816  }
1817 }
1818 
1819 void
1820 LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
1821  bool useLayer3Filtering, uint8_t componentCarrierId)
1822 {
1823  NS_LOG_FUNCTION (this << cellId << +componentCarrierId << rsrp << rsrq << useLayer3Filtering);
1824 
1825  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1826 
1827  if (storedMeasIt != m_storedMeasValues.end ())
1828  {
1829  if (useLayer3Filtering)
1830  {
1831  // F_n = (1-a) F_{n-1} + a M_n
1832  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
1833  + m_varMeasConfig.aRsrp * rsrp;
1834 
1835  if (std::isnan (storedMeasIt->second.rsrq))
1836  {
1837  // the previous RSRQ measurements provided UE PHY are invalid
1838  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1839  }
1840  else
1841  {
1842  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
1843  + m_varMeasConfig.aRsrq * rsrq;
1844  }
1845  }
1846  else
1847  {
1848  storedMeasIt->second.rsrp = rsrp;
1849  storedMeasIt->second.rsrq = rsrq;
1850  }
1851  }
1852  else
1853  {
1854  // first value is always unfiltered
1855  MeasValues v;
1856  v.rsrp = rsrp;
1857  v.rsrq = rsrq;
1858  v.carrierFreq = m_cphySapProvider.at (componentCarrierId)->GetDlEarfcn ();
1859 
1860  std::pair<uint16_t, MeasValues> val (cellId, v);
1861  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
1862  ret = m_storedMeasValues.insert (val);
1863  NS_ASSERT_MSG (ret.second == true, "element already existed");
1864  storedMeasIt = ret.first;
1865  }
1866 
1867  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
1868  << ", measured cell " << cellId
1869  << ", carrier component Id " << componentCarrierId
1870  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
1871  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
1872 
1873 } // end of void SaveUeMeasurements
1874 
1875 void
1877 {
1878  NS_LOG_FUNCTION (this << (uint16_t) measId);
1879 
1880  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt =
1881  m_varMeasConfig.measIdList.find (measId);
1882  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1883  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
1884 
1885  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1886  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1887  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1888  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1889 
1890  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
1891  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
1892  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
1893  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1894 
1895  std::map<uint8_t, VarMeasReport>::iterator
1896  measReportIt = m_varMeasReportList.find (measId);
1897  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end ());
1898 
1899  // we don't check the purpose field, as it is only included for
1900  // triggerType == periodical, which is not supported
1901  NS_ASSERT_MSG (reportConfigEutra.triggerType
1903  "only triggerType == event is supported");
1904  // only EUTRA is supported, no need to check for it
1905 
1906  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
1907  bool eventEntryCondApplicable = false;
1908  bool eventLeavingCondApplicable = false;
1909  ConcernedCells_t concernedCellsEntry;
1910  ConcernedCells_t concernedCellsLeaving;
1911 
1912  /*
1913  * Find which serving cell corresponds to measObjectEutra.carrierFreq
1914  * It is used, for example, by A1 event:
1915  * See TS 36.331 5.5.4.2: "for this measurement, consider the primary or
1916  * secondary cell that is configured on the frequency indicated in the
1917  * associated measObjectEUTRA to be the serving cell"
1918  */
1919  uint16_t servingCellId = 0;
1920  for (auto cphySapProvider: m_cphySapProvider)
1921  {
1922  if (cphySapProvider->GetDlEarfcn () == measObjectEutra.carrierFreq)
1923  {
1924  servingCellId = cphySapProvider->GetCellId ();
1925  }
1926  }
1927 
1928  if (servingCellId == 0)
1929  {
1930  return;
1931  }
1932 
1933  switch (reportConfigEutra.eventId)
1934  {
1936  {
1937  /*
1938  * Event A1 (Serving becomes better than threshold)
1939  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1940  */
1941 
1942  double ms; // Ms, the measurement result of the serving cell
1943  double thresh; // Thresh, the threshold parameter for this event
1944  // Hys, the hysteresis parameter for this event.
1945  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1946 
1947  switch (reportConfigEutra.triggerQuantity)
1948  {
1950  ms = m_storedMeasValues[servingCellId].rsrp;
1951 
1952  NS_ASSERT (reportConfigEutra.threshold1.choice
1954  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1955  break;
1957  ms = m_storedMeasValues[servingCellId].rsrq;
1958  NS_ASSERT (reportConfigEutra.threshold1.choice
1960  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1961  break;
1962  default:
1963  NS_FATAL_ERROR ("unsupported triggerQuantity");
1964  break;
1965  }
1966 
1967  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1968  bool entryCond = ms - hys > thresh;
1969 
1970  if (entryCond)
1971  {
1972  if (!isMeasIdInReportList)
1973  {
1974  concernedCellsEntry.push_back (servingCellId);
1975  eventEntryCondApplicable = true;
1976  }
1977  else
1978  {
1979  /*
1980  * This is to check that the triggered cell recorded in the
1981  * VarMeasReportList is the serving cell.
1982  */
1983  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (servingCellId)
1984  != measReportIt->second.cellsTriggeredList.end ());
1985  }
1986  }
1987  else if (reportConfigEutra.timeToTrigger > 0)
1988  {
1989  CancelEnteringTrigger (measId);
1990  }
1991 
1992  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
1993  bool leavingCond = ms + hys < thresh;
1994 
1995  if (leavingCond)
1996  {
1997  if (isMeasIdInReportList)
1998  {
1999  /*
2000  * This is to check that the triggered cell recorded in the
2001  * VarMeasReportList is the serving cell.
2002  */
2003  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
2004  != measReportIt->second.cellsTriggeredList.end ());
2005  concernedCellsLeaving.push_back (m_cellId);
2006  eventLeavingCondApplicable = true;
2007  }
2008  }
2009  else if (reportConfigEutra.timeToTrigger > 0)
2010  {
2011  CancelLeavingTrigger (measId);
2012  }
2013 
2014  NS_LOG_LOGIC (this << " event A1: serving cell " << servingCellId
2015  << " ms=" << ms << " thresh=" << thresh
2016  << " entryCond=" << entryCond
2017  << " leavingCond=" << leavingCond);
2018 
2019  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
2020 
2021  break;
2022 
2024  {
2025  /*
2026  * Event A2 (Serving becomes worse than threshold)
2027  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
2028  */
2029 
2030  double ms; // Ms, the measurement result of the serving cell
2031  double thresh; // Thresh, the threshold parameter for this event
2032  // Hys, the hysteresis parameter for this event.
2033  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2034 
2035  switch (reportConfigEutra.triggerQuantity)
2036  {
2038  ms = m_storedMeasValues[servingCellId].rsrp;
2039  NS_ASSERT (reportConfigEutra.threshold1.choice
2041  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2042  break;
2044  ms = m_storedMeasValues[servingCellId].rsrq;
2045  NS_ASSERT (reportConfigEutra.threshold1.choice
2047  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2048  break;
2049  default:
2050  NS_FATAL_ERROR ("unsupported triggerQuantity");
2051  break;
2052  }
2053 
2054  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
2055  bool entryCond = ms + hys < thresh;
2056 
2057  if (entryCond)
2058  {
2059  if (!isMeasIdInReportList)
2060  {
2061  concernedCellsEntry.push_back (servingCellId);
2062  eventEntryCondApplicable = true;
2063  }
2064  else
2065  {
2066  /*
2067  * This is to check that the triggered cell recorded in the
2068  * VarMeasReportList is the serving cell.
2069  */
2070  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (servingCellId)
2071  != measReportIt->second.cellsTriggeredList.end ());
2072  }
2073  }
2074  else if (reportConfigEutra.timeToTrigger > 0)
2075  {
2076  CancelEnteringTrigger (measId);
2077  }
2078 
2079  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
2080  bool leavingCond = ms - hys > thresh;
2081 
2082  if (leavingCond)
2083  {
2084  if (isMeasIdInReportList)
2085  {
2086  /*
2087  * This is to check that the triggered cell recorded in the
2088  * VarMeasReportList is the serving cell.
2089  */
2090  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (servingCellId)
2091  != measReportIt->second.cellsTriggeredList.end ());
2092  concernedCellsLeaving.push_back (servingCellId);
2093  eventLeavingCondApplicable = true;
2094  }
2095  }
2096  else if (reportConfigEutra.timeToTrigger > 0)
2097  {
2098  CancelLeavingTrigger (measId);
2099  }
2100 
2101  NS_LOG_LOGIC (this << " event A2: serving cell " << servingCellId
2102  << " ms=" << ms << " thresh=" << thresh
2103  << " entryCond=" << entryCond
2104  << " leavingCond=" << leavingCond);
2105 
2106  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
2107 
2108  break;
2109 
2111  {
2112  /*
2113  * Event A3 (Neighbour becomes offset better than PCell)
2114  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
2115  */
2116 
2117  double mn; // Mn, the measurement result of the neighbouring cell
2118  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2119  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2120  double mp; // Mp, the measurement result of the PCell
2121  double ofp = measObjectEutra.offsetFreq; // Ofp, the frequency specific offset of the primary frequency
2122  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
2123  // Off, the offset parameter for this event.
2124  double off = EutranMeasurementMapping::IeValue2ActualA3Offset (reportConfigEutra.a3Offset);
2125  // Hys, the hysteresis parameter for this event.
2126  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2127 
2128  switch (reportConfigEutra.triggerQuantity)
2129  {
2131  mp = m_storedMeasValues[m_cellId].rsrp;
2132  NS_ASSERT (reportConfigEutra.threshold1.choice
2134  break;
2136  mp = m_storedMeasValues[m_cellId].rsrq;
2137  NS_ASSERT (reportConfigEutra.threshold1.choice
2139  break;
2140  default:
2141  NS_FATAL_ERROR ("unsupported triggerQuantity");
2142  break;
2143  }
2144 
2145  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2146  storedMeasIt != m_storedMeasValues.end ();
2147  ++storedMeasIt)
2148  {
2149  uint16_t cellId = storedMeasIt->first;
2150  if (cellId == m_cellId)
2151  {
2152  continue;
2153  }
2154 
2155  // Only cell(s) on the frequency indicated in the associated measObject can trigger event.
2156  if (m_storedMeasValues.at (cellId).carrierFreq != measObjectEutra.carrierFreq)
2157  {
2158  continue;
2159  }
2160 
2161  switch (reportConfigEutra.triggerQuantity)
2162  {
2164  mn = storedMeasIt->second.rsrp;
2165  break;
2167  mn = storedMeasIt->second.rsrq;
2168  break;
2169  default:
2170  NS_FATAL_ERROR ("unsupported triggerQuantity");
2171  break;
2172  }
2173 
2174  bool hasTriggered = isMeasIdInReportList
2175  && (measReportIt->second.cellsTriggeredList.find (cellId)
2176  != measReportIt->second.cellsTriggeredList.end ());
2177 
2178  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
2179  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
2180 
2181  if (entryCond)
2182  {
2183  if (!hasTriggered)
2184  {
2185  concernedCellsEntry.push_back (cellId);
2186  eventEntryCondApplicable = true;
2187  }
2188  }
2189  else if (reportConfigEutra.timeToTrigger > 0)
2190  {
2191  CancelEnteringTrigger (measId, cellId);
2192  }
2193 
2194  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
2195  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2196 
2197  if (leavingCond)
2198  {
2199  if (hasTriggered)
2200  {
2201  concernedCellsLeaving.push_back (cellId);
2202  eventLeavingCondApplicable = true;
2203  }
2204  }
2205  else if (reportConfigEutra.timeToTrigger > 0)
2206  {
2207  CancelLeavingTrigger (measId, cellId);
2208  }
2209 
2210  NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId
2211  << " mn=" << mn << " mp=" << mp << " offset=" << off
2212  << " entryCond=" << entryCond
2213  << " leavingCond=" << leavingCond);
2214 
2215  } // end of for (storedMeasIt)
2216 
2217  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
2218 
2219  break;
2220 
2222  {
2223  /*
2224  * Event A4 (Neighbour becomes better than threshold)
2225  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
2226  */
2227 
2228  double mn; // Mn, the measurement result of the neighbouring cell
2229  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2230  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2231  double thresh; // Thresh, the threshold parameter for this event
2232  // Hys, the hysteresis parameter for this event.
2233  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2234 
2235  switch (reportConfigEutra.triggerQuantity)
2236  {
2238  NS_ASSERT (reportConfigEutra.threshold1.choice
2240  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2241  break;
2243  NS_ASSERT (reportConfigEutra.threshold1.choice
2245  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2246  break;
2247  default:
2248  NS_FATAL_ERROR ("unsupported triggerQuantity");
2249  break;
2250  }
2251 
2252  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2253  storedMeasIt != m_storedMeasValues.end ();
2254  ++storedMeasIt)
2255  {
2256  uint16_t cellId = storedMeasIt->first;
2257  if (cellId == m_cellId)
2258  {
2259  continue;
2260  }
2261 
2262  switch (reportConfigEutra.triggerQuantity)
2263  {
2265  mn = storedMeasIt->second.rsrp;
2266  break;
2268  mn = storedMeasIt->second.rsrq;
2269  break;
2270  default:
2271  NS_FATAL_ERROR ("unsupported triggerQuantity");
2272  break;
2273  }
2274 
2275  bool hasTriggered = isMeasIdInReportList
2276  && (measReportIt->second.cellsTriggeredList.find (cellId)
2277  != measReportIt->second.cellsTriggeredList.end ());
2278 
2279  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
2280  bool entryCond = mn + ofn + ocn - hys > thresh;
2281 
2282  if (entryCond)
2283  {
2284  if (!hasTriggered)
2285  {
2286  concernedCellsEntry.push_back (cellId);
2287  eventEntryCondApplicable = true;
2288  }
2289  }
2290  else if (reportConfigEutra.timeToTrigger > 0)
2291  {
2292  CancelEnteringTrigger (measId, cellId);
2293  }
2294 
2295  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
2296  bool leavingCond = mn + ofn + ocn + hys < thresh;
2297 
2298  if (leavingCond)
2299  {
2300  if (hasTriggered)
2301  {
2302  concernedCellsLeaving.push_back (cellId);
2303  eventLeavingCondApplicable = true;
2304  }
2305  }
2306  else if (reportConfigEutra.timeToTrigger > 0)
2307  {
2308  CancelLeavingTrigger (measId, cellId);
2309  }
2310 
2311  NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId
2312  << " mn=" << mn << " thresh=" << thresh
2313  << " entryCond=" << entryCond
2314  << " leavingCond=" << leavingCond);
2315 
2316  } // end of for (storedMeasIt)
2317 
2318  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
2319 
2320  break;
2321 
2323  {
2324  /*
2325  * Event A5 (PCell becomes worse than threshold1 and neighbour
2326  * becomes better than threshold2)
2327  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2328  */
2329 
2330  double mp; // Mp, the measurement result of the PCell
2331  double mn; // Mn, the measurement result of the neighbouring cell
2332  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2333  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2334  double thresh1; // Thresh1, the threshold parameter for this event
2335  double thresh2; // Thresh2, the threshold parameter for this event
2336  // Hys, the hysteresis parameter for this event.
2337  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2338 
2339  switch (reportConfigEutra.triggerQuantity)
2340  {
2342  mp = m_storedMeasValues[m_cellId].rsrp;
2343  NS_ASSERT (reportConfigEutra.threshold1.choice
2345  NS_ASSERT (reportConfigEutra.threshold2.choice
2347  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2348  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range);
2349  break;
2351  mp = m_storedMeasValues[m_cellId].rsrq;
2352  NS_ASSERT (reportConfigEutra.threshold1.choice
2354  NS_ASSERT (reportConfigEutra.threshold2.choice
2356  thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2357  thresh2 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold2.range);
2358  break;
2359  default:
2360  NS_FATAL_ERROR ("unsupported triggerQuantity");
2361  break;
2362  }
2363 
2364  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2365  bool entryCond = mp + hys < thresh1;
2366 
2367  if (entryCond)
2368  {
2369  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2370  storedMeasIt != m_storedMeasValues.end ();
2371  ++storedMeasIt)
2372  {
2373  uint16_t cellId = storedMeasIt->first;
2374  if (cellId == m_cellId)
2375  {
2376  continue;
2377  }
2378 
2379  switch (reportConfigEutra.triggerQuantity)
2380  {
2382  mn = storedMeasIt->second.rsrp;
2383  break;
2385  mn = storedMeasIt->second.rsrq;
2386  break;
2387  default:
2388  NS_FATAL_ERROR ("unsupported triggerQuantity");
2389  break;
2390  }
2391 
2392  bool hasTriggered = isMeasIdInReportList
2393  && (measReportIt->second.cellsTriggeredList.find (cellId)
2394  != measReportIt->second.cellsTriggeredList.end ());
2395 
2396  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2397 
2398  entryCond = mn + ofn + ocn - hys > thresh2;
2399 
2400  if (entryCond)
2401  {
2402  if (!hasTriggered)
2403  {
2404  concernedCellsEntry.push_back (cellId);
2405  eventEntryCondApplicable = true;
2406  }
2407  }
2408  else if (reportConfigEutra.timeToTrigger > 0)
2409  {
2410  CancelEnteringTrigger (measId, cellId);
2411  }
2412 
2413  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2414  << " mn=" << mn << " mp=" << mp
2415  << " thresh2=" << thresh2
2416  << " thresh1=" << thresh1
2417  << " entryCond=" << entryCond);
2418 
2419  } // end of for (storedMeasIt)
2420 
2421  } // end of if (entryCond)
2422  else
2423  {
2424  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2425  << " mp=" << mp << " thresh1=" << thresh1
2426  << " entryCond=" << entryCond);
2427 
2428  if (reportConfigEutra.timeToTrigger > 0)
2429  {
2430  CancelEnteringTrigger (measId);
2431  }
2432  }
2433 
2434  if (isMeasIdInReportList)
2435  {
2436  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2437  bool leavingCond = mp - hys > thresh1;
2438 
2439  if (leavingCond)
2440  {
2441  if (reportConfigEutra.timeToTrigger == 0)
2442  {
2443  // leaving condition #2 does not have to be checked
2444 
2445  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2446  storedMeasIt != m_storedMeasValues.end ();
2447  ++storedMeasIt)
2448  {
2449  uint16_t cellId = storedMeasIt->first;
2450  if (cellId == m_cellId)
2451  {
2452  continue;
2453  }
2454 
2455  if (measReportIt->second.cellsTriggeredList.find (cellId)
2456  != measReportIt->second.cellsTriggeredList.end ())
2457  {
2458  concernedCellsLeaving.push_back (cellId);
2459  eventLeavingCondApplicable = true;
2460  }
2461  }
2462  } // end of if (reportConfigEutra.timeToTrigger == 0)
2463  else
2464  {
2465  // leaving condition #2 has to be checked to cancel time-to-trigger
2466 
2467  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2468  storedMeasIt != m_storedMeasValues.end ();
2469  ++storedMeasIt)
2470  {
2471  uint16_t cellId = storedMeasIt->first;
2472  if (cellId == m_cellId)
2473  {
2474  continue;
2475  }
2476 
2477  if (measReportIt->second.cellsTriggeredList.find (cellId)
2478  != measReportIt->second.cellsTriggeredList.end ())
2479  {
2480  switch (reportConfigEutra.triggerQuantity)
2481  {
2483  mn = storedMeasIt->second.rsrp;
2484  break;
2486  mn = storedMeasIt->second.rsrq;
2487  break;
2488  default:
2489  NS_FATAL_ERROR ("unsupported triggerQuantity");
2490  break;
2491  }
2492 
2493  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2494 
2495  leavingCond = mn + ofn + ocn + hys < thresh2;
2496 
2497  if (!leavingCond)
2498  {
2499  CancelLeavingTrigger (measId, cellId);
2500  }
2501 
2502  /*
2503  * Whatever the result of leaving condition #2, this
2504  * cell is still "in", because leaving condition #1
2505  * is already true.
2506  */
2507  concernedCellsLeaving.push_back (cellId);
2508  eventLeavingCondApplicable = true;
2509 
2510  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2511  << " mn=" << mn << " mp=" << mp
2512  << " thresh2=" << thresh2
2513  << " thresh1=" << thresh1
2514  << " leavingCond=" << leavingCond);
2515 
2516  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2517  // != measReportIt->second.cellsTriggeredList.end ())
2518 
2519  } // end of for (storedMeasIt)
2520 
2521  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2522 
2523  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2524  << " mp=" << mp << " thresh1=" << thresh1
2525  << " leavingCond=" << leavingCond);
2526 
2527  } // end of if (leavingCond)
2528  else
2529  {
2530  if (reportConfigEutra.timeToTrigger > 0)
2531  {
2532  CancelLeavingTrigger (measId);
2533  }
2534 
2535  // check leaving condition #2
2536 
2537  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2538  storedMeasIt != m_storedMeasValues.end ();
2539  ++storedMeasIt)
2540  {
2541  uint16_t cellId = storedMeasIt->first;
2542  if (cellId == m_cellId)
2543  {
2544  continue;
2545  }
2546 
2547  if (measReportIt->second.cellsTriggeredList.find (cellId)
2548  != measReportIt->second.cellsTriggeredList.end ())
2549  {
2550  switch (reportConfigEutra.triggerQuantity)
2551  {
2553  mn = storedMeasIt->second.rsrp;
2554  break;
2556  mn = storedMeasIt->second.rsrq;
2557  break;
2558  default:
2559  NS_FATAL_ERROR ("unsupported triggerQuantity");
2560  break;
2561  }
2562 
2563  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2564  leavingCond = mn + ofn + ocn + hys < thresh2;
2565 
2566  if (leavingCond)
2567  {
2568  concernedCellsLeaving.push_back (cellId);
2569  eventLeavingCondApplicable = true;
2570  }
2571 
2572  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2573  << " mn=" << mn << " mp=" << mp
2574  << " thresh2=" << thresh2
2575  << " thresh1=" << thresh1
2576  << " leavingCond=" << leavingCond);
2577 
2578  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2579  // != measReportIt->second.cellsTriggeredList.end ())
2580 
2581  } // end of for (storedMeasIt)
2582 
2583  } // end of else of if (leavingCond)
2584 
2585  } // end of if (isMeasIdInReportList)
2586 
2587  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2588 
2589  break;
2590 
2591  default:
2592  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
2593  break;
2594 
2595  } // switch (event type)
2596 
2597  NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2598  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2599 
2600  if (eventEntryCondApplicable)
2601  {
2602  if (reportConfigEutra.timeToTrigger == 0)
2603  {
2604  VarMeasReportListAdd (measId, concernedCellsEntry);
2605  }
2606  else
2607  {
2608  PendingTrigger_t t;
2609  t.measId = measId;
2610  t.concernedCells = concernedCellsEntry;
2611  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2613  measId, concernedCellsEntry);
2614  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2615  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2616  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2617  enteringTriggerIt->second.push_back (t);
2618  }
2619  }
2620 
2621  if (eventLeavingCondApplicable)
2622  {
2623  // reportOnLeave will only be set when eventId = eventA3
2624  bool reportOnLeave = (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
2625  && reportConfigEutra.reportOnLeave;
2626 
2627  if (reportConfigEutra.timeToTrigger == 0)
2628  {
2629  VarMeasReportListErase (measId, concernedCellsLeaving, reportOnLeave);
2630  }
2631  else
2632  {
2633  PendingTrigger_t t;
2634  t.measId = measId;
2635  t.concernedCells = concernedCellsLeaving;
2636  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2638  measId, concernedCellsLeaving, reportOnLeave);
2639  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2640  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2641  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2642  leavingTriggerIt->second.push_back (t);
2643  }
2644  }
2645 
2646 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2647 
2648 void
2650 {
2651  NS_LOG_FUNCTION (this << (uint16_t) measId);
2652 
2653  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2654  it1 = m_enteringTriggerQueue.find (measId);
2655  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2656 
2657  if (!it1->second.empty ())
2658  {
2659  std::list<PendingTrigger_t>::iterator it2;
2660  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2661  {
2662  NS_ASSERT (it2->measId == measId);
2663  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2664  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2665  Simulator::Cancel (it2->timer);
2666  }
2667 
2668  it1->second.clear ();
2669  }
2670 }
2671 
2672 void
2673 LteUeRrc::CancelEnteringTrigger (uint8_t measId, uint16_t cellId)
2674 {
2675  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2676 
2677  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2678  it1 = m_enteringTriggerQueue.find (measId);
2679  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2680 
2681  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2682  while (it2 != it1->second.end ())
2683  {
2684  NS_ASSERT (it2->measId == measId);
2685 
2686  ConcernedCells_t::iterator it3;
2687  for (it3 = it2->concernedCells.begin ();
2688  it3 != it2->concernedCells.end (); ++it3)
2689  {
2690  if (*it3 == cellId)
2691  {
2692  it3 = it2->concernedCells.erase (it3);
2693  }
2694  }
2695 
2696  if (it2->concernedCells.empty ())
2697  {
2698  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2699  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2700  Simulator::Cancel (it2->timer);
2701  it2 = it1->second.erase (it2);
2702  }
2703  else
2704  {
2705  it2++;
2706  }
2707  }
2708 }
2709 
2710 void
2712 {
2713  NS_LOG_FUNCTION (this << (uint16_t) measId);
2714 
2715  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2716  it1 = m_leavingTriggerQueue.find (measId);
2717  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2718 
2719  if (!it1->second.empty ())
2720  {
2721  std::list<PendingTrigger_t>::iterator it2;
2722  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2723  {
2724  NS_ASSERT (it2->measId == measId);
2725  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2726  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2727  Simulator::Cancel (it2->timer);
2728  }
2729 
2730  it1->second.clear ();
2731  }
2732 }
2733 
2734 void
2735 LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
2736 {
2737  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2738 
2739  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2740  it1 = m_leavingTriggerQueue.find (measId);
2741  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2742 
2743  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2744  while (it2 != it1->second.end ())
2745  {
2746  NS_ASSERT (it2->measId == measId);
2747 
2748  ConcernedCells_t::iterator it3;
2749  for (it3 = it2->concernedCells.begin ();
2750  it3 != it2->concernedCells.end (); ++it3)
2751  {
2752  if (*it3 == cellId)
2753  {
2754  it3 = it2->concernedCells.erase (it3);
2755  }
2756  }
2757 
2758  if (it2->concernedCells.empty ())
2759  {
2760  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2761  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2762  Simulator::Cancel (it2->timer);
2763  it2 = it1->second.erase (it2);
2764  }
2765  else
2766  {
2767  it2++;
2768  }
2769  }
2770 }
2771 
2772 void
2773 LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
2774 {
2775  NS_LOG_FUNCTION (this << (uint16_t) measId);
2776  NS_ASSERT (!enteringCells.empty ());
2777 
2778  std::map<uint8_t, VarMeasReport>::iterator
2779  measReportIt = m_varMeasReportList.find (measId);
2780 
2781  if (measReportIt == m_varMeasReportList.end ())
2782  {
2783  VarMeasReport r;
2784  r.measId = measId;
2785  std::pair<uint8_t, VarMeasReport> val (measId, r);
2786  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
2787  ret = m_varMeasReportList.insert (val);
2788  NS_ASSERT_MSG (ret.second == true, "element already existed");
2789  measReportIt = ret.first;
2790  }
2791 
2792  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2793 
2794  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2795  it != enteringCells.end ();
2796  ++it)
2797  {
2798  measReportIt->second.cellsTriggeredList.insert (*it);
2799  }
2800 
2801  NS_ASSERT (!measReportIt->second.cellsTriggeredList.empty ());
2802 
2803  // #issue 224, schedule only when there is no periodic event scheduled already
2804  if (!measReportIt->second.periodicReportTimer.IsRunning ())
2805  {
2806  measReportIt->second.numberOfReportsSent = 0;
2807  measReportIt->second.periodicReportTimer
2810  this, measId);
2811  }
2812 
2813  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2814  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2815  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2816  if (!enteringTriggerIt->second.empty ())
2817  {
2818  /*
2819  * Assumptions at this point:
2820  * - the call to this function was delayed by time-to-trigger;
2821  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2822  * - the first element in the list is associated with this function call.
2823  */
2824  enteringTriggerIt->second.pop_front ();
2825 
2826  if (!enteringTriggerIt->second.empty ())
2827  {
2828  /*
2829  * To prevent the same set of cells triggering again in the future,
2830  * we clean up the time-to-trigger queue. This case might occur when
2831  * time-to-trigger > 200 ms.
2832  */
2833  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2834  it != enteringCells.end (); ++it)
2835  {
2836  CancelEnteringTrigger (measId, *it);
2837  }
2838  }
2839 
2840  } // end of if (!enteringTriggerIt->second.empty ())
2841 
2842 } // end of LteUeRrc::VarMeasReportListAdd
2843 
2844 void
2846  bool reportOnLeave)
2847 {
2848  NS_LOG_FUNCTION (this << (uint16_t) measId);
2849  NS_ASSERT (!leavingCells.empty ());
2850 
2851  std::map<uint8_t, VarMeasReport>::iterator
2852  measReportIt = m_varMeasReportList.find (measId);
2853  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2854 
2855  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2856  it != leavingCells.end ();
2857  ++it)
2858  {
2859  measReportIt->second.cellsTriggeredList.erase (*it);
2860  }
2861 
2862  if (reportOnLeave)
2863  {
2864  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2865  SendMeasurementReport (measId);
2866  }
2867 
2868  if (measReportIt->second.cellsTriggeredList.empty ())
2869  {
2870  measReportIt->second.periodicReportTimer.Cancel ();
2871  m_varMeasReportList.erase (measReportIt);
2872  }
2873 
2874  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2875  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2876  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2877  if (!leavingTriggerIt->second.empty ())
2878  {
2879  /*
2880  * Assumptions at this point:
2881  * - the call to this function was delayed by time-to-trigger; and
2882  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2883  * - the first element in the list is associated with this function call.
2884  */
2885  leavingTriggerIt->second.pop_front ();
2886 
2887  if (!leavingTriggerIt->second.empty ())
2888  {
2889  /*
2890  * To prevent the same set of cells triggering again in the future,
2891  * we clean up the time-to-trigger queue. This case might occur when
2892  * time-to-trigger > 200 ms.
2893  */
2894  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2895  it != leavingCells.end (); ++it)
2896  {
2897  CancelLeavingTrigger (measId, *it);
2898  }
2899  }
2900 
2901  } // end of if (!leavingTriggerIt->second.empty ())
2902 
2903 } // end of LteUeRrc::VarMeasReportListErase
2904 
2905 void
2907 {
2908  NS_LOG_FUNCTION (this << (uint16_t) measId);
2909 
2910  // remove the measurement reporting entry for this measId from the VarMeasReportList
2911  std::map<uint8_t, VarMeasReport>::iterator
2912  measReportIt = m_varMeasReportList.find (measId);
2913  if (measReportIt != m_varMeasReportList.end ())
2914  {
2915  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint16_t) measId);
2916  measReportIt->second.periodicReportTimer.Cancel ();
2917  m_varMeasReportList.erase (measReportIt);
2918  }
2919 
2920  CancelEnteringTrigger (measId);
2921  CancelLeavingTrigger (measId);
2922 }
2923 
2924 void
2926 {
2927  NS_LOG_FUNCTION (this << (uint16_t) measId);
2928  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2929 
2930  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
2931  measIdIt = m_varMeasConfig.measIdList.find (measId);
2932  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
2933 
2934  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
2935  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
2936  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
2937  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2938 
2939  LteRrcSap::MeasurementReport measurementReport;
2940  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2941  measResults.measId = measId;
2942 
2943  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
2944  if (measReportIt == m_varMeasReportList.end ())
2945  {
2946  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
2947  }
2948  else
2949  {
2950  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
2951  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
2952  measResults.measResultPCell.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
2953  measResults.measResultPCell.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
2954  NS_LOG_INFO (this << " reporting serving cell "
2955  "RSRP " << +measResults.measResultPCell.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
2956  "RSRQ " << +measResults.measResultPCell.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
2957 
2958  measResults.haveMeasResultServFreqList = false;
2959  for (uint8_t componentCarrierId = 1; componentCarrierId < m_numberOfComponentCarriers; componentCarrierId++)
2960  {
2961  const uint16_t cellId = m_cphySapProvider.at (componentCarrierId)->GetCellId ();
2962  auto measValuesIt = m_storedMeasValues.find (cellId);
2963  if (measValuesIt != m_storedMeasValues.end ())
2964  {
2965  measResults.haveMeasResultServFreqList = true;
2966  LteRrcSap::MeasResultServFreq measResultServFreq;
2967  measResultServFreq.servFreqId = componentCarrierId;
2968  measResultServFreq.haveMeasResultSCell = true;
2969  measResultServFreq.measResultSCell.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (measValuesIt->second.rsrp);
2970  measResultServFreq.measResultSCell.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (measValuesIt->second.rsrq);
2971  measResultServFreq.haveMeasResultBestNeighCell = false;
2972  measResults.measResultServFreqList.push_back (measResultServFreq);
2973  }
2974  }
2975 
2976  measResults.haveMeasResultNeighCells = false;
2977 
2978  if (!(measReportIt->second.cellsTriggeredList.empty ()))
2979  {
2980  std::multimap<double, uint16_t> sortedNeighCells;
2981  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
2982  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
2983  ++cellsTriggeredIt)
2984  {
2985  uint16_t cellId = *cellsTriggeredIt;
2986  if (cellId != m_cellId)
2987  {
2988  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2989  double triggerValue;
2990  switch (reportConfigEutra.triggerQuantity)
2991  {
2993  triggerValue = neighborMeasIt->second.rsrp;
2994  break;
2996  triggerValue = neighborMeasIt->second.rsrq;
2997  break;
2998  default:
2999  NS_FATAL_ERROR ("unsupported triggerQuantity");
3000  break;
3001  }
3002  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
3003  }
3004  }
3005 
3006  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
3007  uint32_t count;
3008  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
3009  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
3010  ++sortedNeighCellsIt, ++count)
3011  {
3012  uint16_t cellId = sortedNeighCellsIt->second;
3013  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
3014  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
3015  LteRrcSap::MeasResultEutra measResultEutra;
3016  measResultEutra.physCellId = cellId;
3017  measResultEutra.haveCgiInfo = false;
3018  measResultEutra.haveRsrpResult = true;
3019  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
3020  measResultEutra.haveRsrqResult = true;
3021  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
3022  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
3023  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
3024  << " (" << neighborMeasIt->second.rsrp << " dBm)"
3025  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
3026  << " (" << neighborMeasIt->second.rsrq << " dB)");
3027  measResults.measResultListEutra.push_back (measResultEutra);
3028  measResults.haveMeasResultNeighCells = true;
3029  }
3030  }
3031  else
3032  {
3033  NS_LOG_WARN (this << " cellsTriggeredList is empty");
3034  }
3035 
3036  /*
3037  * The current LteRrcSap implementation is broken in that it does not
3038  * allow for infinite values of reportAmount, which is probably the most
3039  * reasonable setting. So we just always assume infinite reportAmount.
3040  */
3041  measReportIt->second.numberOfReportsSent++;
3042  measReportIt->second.periodicReportTimer.Cancel ();
3043 
3044  Time reportInterval;
3045  switch (reportConfigEutra.reportInterval)
3046  {
3048  reportInterval = MilliSeconds (120);
3049  break;
3051  reportInterval = MilliSeconds (240);
3052  break;
3054  reportInterval = MilliSeconds (480);
3055  break;
3057  reportInterval = MilliSeconds (640);
3058  break;
3060  reportInterval = MilliSeconds (1024);
3061  break;
3063  reportInterval = MilliSeconds (2048);
3064  break;
3066  reportInterval = MilliSeconds (5120);
3067  break;
3069  reportInterval = MilliSeconds (10240);
3070  break;
3072  reportInterval = Seconds (60);
3073  break;
3075  reportInterval = Seconds (360);
3076  break;
3078  reportInterval = Seconds (720);
3079  break;
3081  reportInterval = Seconds (1800);
3082  break;
3084  reportInterval = Seconds (3600);
3085  break;
3086  default:
3087  NS_FATAL_ERROR ("Unsupported reportInterval " << (uint16_t) reportConfigEutra.reportInterval);
3088  break;
3089  }
3090 
3091  // schedule the next measurement reporting
3092  measReportIt->second.periodicReportTimer
3093  = Simulator::Schedule (reportInterval,
3095  this, measId);
3096 
3097  // send the measurement report to eNodeB
3098  m_rrcSapUser->SendMeasurementReport (measurementReport);
3099  }
3100 }
3101 
3102 void
3104 {
3105  NS_LOG_FUNCTION (this << m_imsi);
3108  m_connectionPending = false; // reset the flag
3110  m_cmacSapProvider.at (0)->StartContentionBasedRandomAccessProcedure ();
3111 }
3112 
3113 void
3115 {
3116  NS_LOG_FUNCTION (this << m_imsi);
3117  m_leaveConnectedMode = true;
3118  m_storedMeasValues.clear ();
3119  ResetRlfParams ();
3120 
3121  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
3122  for (measIdIt = m_varMeasConfig.measIdList.begin ();
3123  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
3124  {
3125  VarMeasReportListClear (measIdIt->second.measId);
3126  }
3127  m_varMeasConfig.measIdList.clear ();
3128 
3130 
3131  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3132  {
3133  m_cmacSapProvider.at (i)->Reset (); // reset the MAC
3134  }
3135 
3136  m_drbMap.clear ();
3137  m_bid2DrbidMap.clear ();
3138  m_srb1 = nullptr;
3139  m_hasReceivedMib = false;
3140  m_hasReceivedSib1 = false;
3141  m_hasReceivedSib2 = false;
3142 
3143  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3144  {
3145  m_cphySapProvider.at (i)->ResetPhyAfterRlf (); //reset the PHY
3146  }
3149  //Save the cell id UE was attached to
3151  m_cellId = 0;
3152  m_rnti = 0;
3153  m_srb0->m_rlc->SetRnti (m_rnti);
3154 }
3155 
3156 void
3158 {
3159  NS_LOG_FUNCTION (this << m_imsi);
3162  {
3165  //Assumption: The eNB connection request timer would expire
3166  //before the expiration of T300 at UE. Upon which, the eNB deletes
3167  //the UE context. Therefore, here we don't need to send the UE context
3168  //deletion request to the eNB.
3170  m_connEstFailCount = 0;
3171  }
3172  else
3173  {
3174  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
3175  {
3176  m_cmacSapProvider.at (i)->Reset (); // reset the MAC
3177  }
3178  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
3181  //Following call to UE NAS will force the UE to immediately
3182  //perform the random access to the same cell again.
3183  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
3184  }
3185 }
3186 
3187 void
3189 {
3190  NS_LOG_FUNCTION (this);
3191  m_srb1Old = 0;
3192 }
3193 
3194 uint8_t
3195 LteUeRrc::Bid2Drbid (uint8_t bid)
3196 {
3197  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
3198  //NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
3199  if (it == m_bid2DrbidMap.end ())
3200  {
3201  return 0;
3202  }
3203  else
3204  {
3205  return it->second;
3206  }
3207 }
3208 
3209 void
3211 {
3212  NS_LOG_FUNCTION (this << ToString (newState));
3213  State oldState = m_state;
3214  m_state = newState;
3215  NS_LOG_INFO (this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc "
3216  << ToString (oldState) << " --> " << ToString (newState));
3217  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
3218 
3219  switch (newState)
3220  {
3221  case IDLE_START:
3223  {
3224  NS_LOG_INFO ("Starting initial cell selection after RLF");
3225  }
3226  else
3227  {
3228  NS_FATAL_ERROR ("cannot switch to an initial state");
3229  }
3230  break;
3231 
3232  case IDLE_CELL_SEARCH:
3233  case IDLE_WAIT_MIB_SIB1:
3234  case IDLE_WAIT_MIB:
3235  case IDLE_WAIT_SIB1:
3236  break;
3237 
3238  case IDLE_CAMPED_NORMALLY:
3239  if (m_connectionPending)
3240  {
3242  }
3243  break;
3244 
3245  case IDLE_WAIT_SIB2:
3246  if (m_hasReceivedSib2)
3247  {
3249  StartConnection ();
3250  }
3251  break;
3252 
3253  case IDLE_RANDOM_ACCESS:
3254  case IDLE_CONNECTING:
3255  case CONNECTED_NORMALLY:
3256  case CONNECTED_HANDOVER:
3257  case CONNECTED_PHY_PROBLEM:
3259  break;
3260 
3261  default:
3262  break;
3263  }
3264 }
3265 
3266 
3267 
3268 void
3270 {
3271  NS_LOG_FUNCTION (this << m_imsi << m_rnti);
3276 }
3277 
3278 void
3280 {
3281  NS_LOG_FUNCTION (this << m_imsi);
3283  NS_LOG_INFO ("noOfSyncIndications " << (uint16_t) m_noOfSyncIndications);
3286  {
3287  ResetRlfParams ();
3288  }
3289 }
3290 
3291 void
3293 {
3294  NS_LOG_FUNCTION (this << m_imsi);
3296  NS_LOG_INFO (this << " Total Number of Sync indications from PHY "
3297  << (uint16_t) m_noOfSyncIndications << "N310 value : " << (uint16_t) m_n310);
3300  {
3303  {
3304  NS_LOG_INFO ("t310 started");
3305  }
3306  m_cphySapProvider.at (0)->StartInSnycDetection ();
3308  }
3309 }
3310 
3311 void
3313 {
3314  NS_LOG_FUNCTION (this << m_imsi);
3315 
3316  NS_LOG_DEBUG ("The number of sync indication received by RRC from PHY: " << (uint16_t) m_noOfSyncIndications);
3318 }
3319 
3320 void
3322 {
3323  NS_LOG_FUNCTION (this << m_imsi);
3326  m_cphySapProvider.at (0)->ResetRlfParams ();
3327 }
3328 
3329 const std::string
3331 {
3332  return g_ueRrcStateName[s];
3333 }
3334 
3335 
3336 } // namespace ns3
3337 
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:252
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:244
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:260
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
Definition: lte-common.cc:351
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
Definition: lte-common.cc:288
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:268
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:319
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:40
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:104
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
virtual void NotifyConnectionSuccessful()=0
Notify the NAS that RRC Connection Establishment was successful.
virtual void NotifyConnectionReleased()=0
Notify the NAS that RRC Connection was released.
virtual void RecvData(Ptr< Packet > packet)=0
receive a data packet
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:37
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:96
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc-am.cc:88
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE,...
Definition: lte-rlc.h:51
void SetLteRlcSapUser(LteRlcSapUser *s)
Definition: lte-rlc.cc:147
void SetRnti(uint16_t rnti)
Definition: lte-rlc.cc:133
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-rlc.cc:161
LteMacSapUser * GetLteMacSapUser()
Definition: lte-rlc.cc:168
void SetLcId(uint8_t lcId)
Definition: lte-rlc.cc:140
LteRlcSapProvider * GetLteRlcSapProvider()
Definition: lte-rlc.cc:154
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc.cc:191
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc-um.cc:55
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Convert PDSCH config dedicated function.
Definition: lte-rrc-sap.h:180
Service Access Point (SAP) offered by the UE component carrier manager to the UE RRC.
virtual std::vector< LteUeCcmRrcSapProvider::LcsConfig > AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
add a new Logical Channel (LC)
virtual void Reset()=0
Reset LC maps.
virtual LteMacSapUser * ConfigureSignalBearer(uint8_t lcid, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
Add the Signal Bearer for a specific Ue in LteUeComponenCarrierManager.
Service Access Point (SAP) offered by the UE RRC to the UE CCM.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
friend class MemberLteUeCcmRrcSapUser< LteUeRrc >
allow MemberLteUeCcmRrcSapUser<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:97
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1054
uint8_t m_lastRrcTransactionIdentifier
last RRC transaction identifier
Definition: lte-ue-rrc.h:816
bool m_connectionPending
True if a connection request by upper layers is pending.
Definition: lte-ue-rrc.h:931
bool m_hasReceivedSib1
True if SIB1 was received for the current cell.
Definition: lte-ue-rrc.h:935
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:2925
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:1125
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:963
void DoNotifyOutOfSync()
Do notify out of sync function.
Definition: lte-ue-rrc.cc:3292
LteUeCcmRrcSapUser * GetLteCcmRrcSapUser()
Get the Component Carrier Management SAP offered by this RRC.
Definition: lte-ue-rrc.cc:407
void DoRecvRrcConnectionReject(LteRrcSap::RrcConnectionReject msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1202
uint16_t m_previousCellId
the cell id of the previous cell UE was attached to
Definition: lte-ue-rrc.h:1275
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
SRB1 configuration before RRC connection reconfiguration.
Definition: lte-ue-rrc.h:803
void SwitchToState(State s)
Switch the UE RRC to the given state.
Definition: lte-ue-rrc.cc:3210
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:453
void DoDisconnect()
Disconnect function.
Definition: lte-ue-rrc.cc:612
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-rrc.h:765
void DoNotifyRandomAccessFailed()
Notify random access failed function.
Definition: lte-ue-rrc.cc:712
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_mibReceivedTrace
The MibReceived trace source.
Definition: lte-ue-rrc.h:831
LteUeCmacSapUser * GetLteUeCmacSapUser()
This function is overloaded to maintain backward compatibility.
Definition: lte-ue-rrc.cc:365
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
set the CMAC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:351
uint64_t m_imsi
The unique UE identifier.
Definition: lte-ue-rrc.h:781
uint8_t m_n311
The 'N311' attribute.
Definition: lte-ue-rrc.h:1258
Ptr< LteSignalingRadioBearerInfo > m_srb0
The Srb0 attribute.
Definition: lte-ue-rrc.h:794
uint8_t m_connEstFailCountLimit
the counter value for T300 timer expiration received from the eNB
Definition: lte-ue-rrc.h:1277
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:337
void DoConnect()
Connect function.
Definition: lte-ue-rrc.cc:808
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndErrorTrace
The HandoverEndError trace source.
Definition: lte-ue-rrc.h:899
State
The states of the UE RRC entity.
Definition: lte-ue-rrc.h:106
@ CONNECTED_REESTABLISHING
Definition: lte-ue-rrc.h:119
@ IDLE_CAMPED_NORMALLY
Definition: lte-ue-rrc.h:112
@ CONNECTED_PHY_PROBLEM
Definition: lte-ue-rrc.h:118
TracedCallback< uint64_t, uint16_t, uint16_t, State, State > m_stateTransitionTrace
The StateTransition trace source.
Definition: lte-ue-rrc.h:848
VarMeasConfig m_varMeasConfig
Includes the accumulated configuration of the measurements to be performed by the UE.
Definition: lte-ue-rrc.h:974
friend class MemberLteUeRrcSapProvider< LteUeRrc >
allow MemberLteUeRrcSapProvider<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:95
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Update the current measurement configuration m_varMeasConfig.
Definition: lte-ue-rrc.cc:1598
LteRrcSap::PdschConfigDedicated m_pdschConfigDedicated
the PDSCH condig dedicated
Definition: lte-ue-rrc.h:818
uint8_t m_n310
The 'N310' attribute.
Definition: lte-ue-rrc.h:1252
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:523
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndErrorTrace
The InitialCellSelectionEndError trace source.
Definition: lte-ue-rrc.h:858
EventId m_radioLinkFailureDetected
Time limit (given by m_t310) before the radio link is considered to have failed.
Definition: lte-ue-rrc.h:1269
virtual void DoInitialize(void)
Initialize() implementation.
Definition: lte-ue-rrc.cc:531
void DoRecvRrcConnectionReestablishmentReject(LteRrcSap::RrcConnectionReestablishmentReject msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1173
void DoNotifyRandomAccessSuccessful()
Notify random access successful function.
Definition: lte-ue-rrc.cc:663
LteUeRrcSapProvider * m_rrcSapProvider
RRC SAP provider.
Definition: lte-ue-rrc.h:763
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:2845
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1024
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:2711
void InitializeSap(void)
Initiaize SAP.
Definition: lte-ue-rrc.cc:562
bool m_leaveConnectedMode
true if UE NAS ask UE RRC to leave connected mode, e.g., after RLF, i.e. T310 has expired
Definition: lte-ue-rrc.h:1273
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1149
bool m_hasReceivedSib2
True if SIB2 was received for the current cell.
Definition: lte-ue-rrc.h:937
void SynchronizeToStrongestCell()
Go through the list of measurement results, choose the one with the strongest RSRP,...
Definition: lte-ue-rrc.cc:1225
std::map< uint8_t, uint8_t > m_bid2DrbidMap
bid to DR bid map
Definition: lte-ue-rrc.h:754
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
set the CPHY SAP this RRC should use to interact with the PHY
Definition: lte-ue-rrc.cc:323
std::vector< LteUeCmacSapProvider * > m_cmacSapProvider
UE CMac SAP provider.
Definition: lte-ue-rrc.h:760
State GetState() const
Definition: lte-ue-rrc.cc:509
uint32_t m_dlEarfcn
Downlink carrier frequency.
Definition: lte-ue-rrc.h:823
LteUeCcmRrcSapProvider * m_ccmRrcSapProvider
Interface to the LteUeComponentCarrierManage instance.
Definition: lte-ue-rrc.h:774
void DoSetCsgWhiteList(uint32_t csgId)
Set CSG white list function.
Definition: lte-ue-rrc.cc:745
void ApplyRadioResourceConfigDedicatedSecondaryCarrier(LteRrcSap::NonCriticalExtensionConfiguration nonCec)
Apply radio resource config dedicated secondary carrier.
Definition: lte-ue-rrc.cc:1350
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:420
void DoSetTemporaryCellRnti(uint16_t rnti)
Set temporary cell rnti function.
Definition: lte-ue-rrc.cc:654
void SetLteMacSapProvider(LteMacSapProvider *s)
set the MAC SAP provider.
Definition: lte-ue-rrc.cc:393
TracedCallback< uint64_t, uint16_t, uint16_t > m_radioLinkFailureTrace
The 'RadioLinkFailure' trace source.
Definition: lte-ue-rrc.h:928
uint32_t m_ulEarfcn
Uplink carrier frequency.
Definition: lte-ue-rrc.h:824
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
Definition: lte-ue-rrc.h:874
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:489
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_sib1ReceivedTrace
The Sib1Received trace source.
Definition: lte-ue-rrc.h:837
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessErrorTrace
The RandomAccessError trace source.
Definition: lte-ue-rrc.h:869
uint32_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:496
std::list< LteRrcSap::SCellToAddMod > m_sCellToAddModList
Secondary carriers.
Definition: lte-ue-rrc.h:825
LtePdcpSapUser * m_drbPdcpSapUser
DRB PDCP SAP user.
Definition: lte-ue-rrc.h:766
TracedCallback< Ptr< LteUeRrc >, std::list< LteRrcSap::SCellToAddMod > > m_sCarrierConfiguredTrace
The SCarrierConfigured trace source.
Definition: lte-ue-rrc.h:905
void DoStartCellSelection(uint32_t dlEarfcn)
Start cell selection function.
Definition: lte-ue-rrc.cc:752
friend class MemberLteAsSapProvider< LteUeRrc >
allow MemberLteAsSapProvider<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:91
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:814
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndOkTrace
The HandoverEndOk trace source.
Definition: lte-ue-rrc.h:894
TracedCallback< uint64_t, uint16_t, uint16_t, std::string, uint8_t > m_phySyncDetectionTrace
The 'PhySyncDetection' trace source.
Definition: lte-ue-rrc.h:923
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:1137
Time m_t310
The 'T310' attribute.
Definition: lte-ue-rrc.h:1246
void RadioLinkFailureDetected()
Radio link failure detected function.
Definition: lte-ue-rrc.cc:3269
State m_state
The current UE RRC state.
Definition: lte-ue-rrc.h:778
std::vector< LteUeCphySapProvider * > m_cphySapProvider
UE CPhy SAP provider.
Definition: lte-ue-rrc.h:757
LteUeCcmRrcSapUser * m_ccmRrcSapUser
CCM RRC SAP user.
Definition: lte-ue-rrc.h:775
TracedCallback< uint64_t, uint16_t, uint16_t, uint8_t > m_drbCreatedTrace
The DrbCreated trace source.
Definition: lte-ue-rrc.h:917
uint16_t m_numberOfComponentCarriers
The number of component carriers.
Definition: lte-ue-rrc.h:1338
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:996
std::vector< LteUeCmacSapUser * > m_cmacSapUser
UE CMac SAP user.
Definition: lte-ue-rrc.h:759
TracedCallback< uint64_t, uint16_t, uint16_t > m_srb1CreatedTrace
The Srb1Created trace source.
Definition: lte-ue-rrc.h:911
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndOkTrace
The InitialCellSelectionEndOk trace source.
Definition: lte-ue-rrc.h:853
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:482
void DoSendData(Ptr< Packet > packet, uint8_t bid)
Send data function.
Definition: lte-ue-rrc.cc:586
LteAsSapProvider * m_asSapProvider
AS SAP provider.
Definition: lte-ue-rrc.h:768
uint16_t m_rnti
The C-RNTI attribute.
Definition: lte-ue-rrc.h:785
uint8_t m_noOfSyncIndications
number of in-sync or out-of-sync indications coming from PHY layer
Definition: lte-ue-rrc.h:1271
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:460
void DoSetNumberOfComponentCarriers(uint16_t noOfComponentCarriers)
RRC CCM SAP USER Method.
Definition: lte-ue-rrc.cc:1216
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:2649
virtual ~LteUeRrc()
Destructor.
Definition: lte-ue-rrc.cc:159
std::map< uint16_t, MeasValues > m_storedMeasValues
Internal storage of the latest measurement results from all detected detected cells,...
Definition: lte-ue-rrc.h:1079
void DoReportUeMeasurements(LteUeCphySapUser::UeMeasurementsParameters params)
Report UE measurements function.
Definition: lte-ue-rrc.cc:917
LteUeRrcSapUser * m_rrcSapUser
RRC SAP user.
Definition: lte-ue-rrc.h:762
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
The ConnectionReconfiguration trace source.
Definition: lte-ue-rrc.h:884
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:1876
void SaveUeMeasurements(uint16_t cellId, double rsrp, double rsrq, bool useLayer3Filtering, uint8_t componentCarrierId)
Keep the given measurement result as the latest measurement figures, to be utilised by UE RRC functio...
Definition: lte-ue-rrc.cc:1820
void SetLteCcmRrcSapProvider(LteUeCcmRrcSapProvider *s)
set the Component Carrier Management SAP this RRC should interact with
Definition: lte-ue-rrc.cc:400
TracedCallback< uint64_t, uint16_t, uint16_t > m_sib2ReceivedTrace
The Sib2Received trace source.
Definition: lte-ue-rrc.h:842
void LeaveConnectedMode()
Leave connected mode method Resets the UE back to an appropiate state depending on the nature of caus...
Definition: lte-ue-rrc.cc:3114
uint32_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:502
void VarMeasReportListClear(uint8_t measId)
Remove the reporting entry of the given measurement identity from m_varMeasReportList.
Definition: lte-ue-rrc.cc:2906
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:386
std::map< uint8_t, Ptr< LteDataRadioBearerInfo > > m_drbMap
The DataRadioBearerMap attribute.
Definition: lte-ue-rrc.h:808
uint16_t m_cellId
The CellId attribute.
Definition: lte-ue-rrc.h:789
uint8_t m_connEstFailCount
the counter to count T300 timer expiration
Definition: lte-ue-rrc.h:1279
void DoRecvMasterInformationBlock(uint16_t cellId, LteRrcSap::MasterInformationBlock msg)
Receive master information block function.
Definition: lte-ue-rrc.cc:850
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Receive PDCP SDU function.
Definition: lte-ue-rrc.cc:646
TracedCallback< uint64_t, uint16_t, uint16_t, uint8_t > m_connectionTimeoutTrace
The ConnectionTimeout trace source.
Definition: lte-ue-rrc.h:879
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:943
Time m_t300
The T300 attribute.
Definition: lte-ue-rrc.h:1224
EventId m_connectionTimeout
Invokes ConnectionEstablishmentTimeout() if RRC connection establishment procedure for this UE takes ...
Definition: lte-ue-rrc.h:1230
void VarMeasReportListAdd(uint8_t measId, ConcernedCells_t enteringCells)
Compose a new reporting entry of the given measurement identity, insert it into m_varMeasReportList,...
Definition: lte-ue-rrc.cc:2773
std::vector< LteUeCphySapUser * > m_cphySapUser
UE CPhy SAP user.
Definition: lte-ue-rrc.h:756
uint64_t GetImsi(void) const
Definition: lte-ue-rrc.cc:447
void ConnectionTimeout()
Invoked after timer T300 expires, notifying upper layers that RRC connection establishment procedure ...
Definition: lte-ue-rrc.cc:3157
bool m_hasReceivedMib
True if MIB was received for the current cell.
Definition: lte-ue-rrc.h:933
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1195
std::list< uint16_t > ConcernedCells_t
List of cell IDs which are responsible for a certain trigger.
Definition: lte-ue-rrc.h:1001
void EvaluateCellForSelection()
Performs cell selection evaluation to the current serving cell.
Definition: lte-ue-rrc.cc:1269
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Receive system information block type 1 function.
Definition: lte-ue-rrc.cc:877
void StartConnection()
Start connection function.
Definition: lte-ue-rrc.cc:3103
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:975
void DoNotifyInSync()
Do notify in sync function.
Definition: lte-ue-rrc.cc:3279
uint16_t m_ulBandwidth
Uplink bandwidth in RBs.
Definition: lte-ue-rrc.h:821
LteUeRrc()
create an RRC instance for use within an ue
Definition: lte-ue-rrc.cc:125
uint32_t m_csgWhiteList
List of CSG ID which this UE entity has access to.
Definition: lte-ue-rrc.h:946
uint16_t GetPreviousCellId() const
Get the previous cell id.
Definition: lte-ue-rrc.cc:516
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-ue-rrc.cc:187
void DisposeOldSrb1()
Dispose old SRB1.
Definition: lte-ue-rrc.cc:3188
friend class LtePdcpSpecificLtePdcpSapUser< LteUeRrc >
allow LtePdcpSpecificLtePdcpSapUser<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:89
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessSuccessfulTrace
The RandomAccessSuccessful trace source.
Definition: lte-ue-rrc.h:864
bool IsServingCell(uint16_t cellId) const
Definition: lte-ue-rrc.cc:467
LteRrcSap::SystemInformationBlockType1 m_lastSib1
Stored content of the last SIB1 received.
Definition: lte-ue-rrc.h:940
static const std::string ToString(LteUeRrc::State s)
Definition: lte-ue-rrc.cc:3330
void SetAsSapUser(LteAsSapUser *s)
Set the AS SAP user to interact with the NAS entity.
Definition: lte-ue-rrc.cc:414
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
set the RRC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:379
uint16_t m_dlBandwidth
Downlink bandwidth in RBs.
Definition: lte-ue-rrc.h:820
Ptr< LteSignalingRadioBearerInfo > m_srb1
The Srb1 attribute.
Definition: lte-ue-rrc.h:798
LteAsSapUser * m_asSapUser
AS SAP user.
Definition: lte-ue-rrc.h:769
void SetImsi(uint64_t imsi)
Definition: lte-ue-rrc.cc:426
virtual void DoDispose(void)
Destructor implementation.
Definition: lte-ue-rrc.cc:165
void DoForceCampedOnEnb(uint16_t cellId, uint32_t dlEarfcn)
Force camped on ENB function.
Definition: lte-ue-rrc.cc:763
void StorePreviousCellId(uint16_t cellId)
Store the previous cell id.
Definition: lte-ue-rrc.cc:440
void ResetRlfParams()
Reset radio link failure parameters.
Definition: lte-ue-rrc.cc:3321
void DoResetSyncIndicationCounter()
Do reset sync indication counter function.
Definition: lte-ue-rrc.cc:3312
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Apply radio resource config dedicated.
Definition: lte-ue-rrc.cc:1393
uint8_t Bid2Drbid(uint8_t bid)
Bid 2 DR bid.
Definition: lte-ue-rrc.cc:3195
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
The HandoverStart trace source.
Definition: lte-ue-rrc.h:889
Part of the RRC protocol.
Definition: lte-rrc-sap.h:1001
Part of the RRC protocol.
Definition: lte-rrc-sap.h:917
virtual void Setup(SetupParameters params)=0
Setup function.
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
virtual void SendMeasurementReport(MeasurementReport msg)=0
Send a MeasurementReport message to the serving eNodeB during a measurement reporting procedure (Sect...
virtual void SendIdealUeContextRemoveRequest(uint16_t rnti)=0
Send UE context remove request function.
virtual void SendRrcConnectionRequest(RrcConnectionRequest msg)=0
Send an _RRCConnectionRequest message to the serving eNodeB during an RRC connection establishment pr...
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
Send an RRCConnectionSetupComplete message to the serving eNodeB during an RRC connection establishme...
Template for the implementation of the LteUeCphySapUser as a member of an owner class of type C to wh...
Instantiate subclasses of ns3::Object.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
A base class which provides memory management and object aggregation.
Definition: object.h:88
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
Container for a set of ns3::Object pointers.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Hold objects of type Ptr<T>.
Definition: pointer.h:37
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:587
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
UeMemberLteUeCmacSapUser class.
Definition: lte-ue-rrc.cc:54
virtual void NotifyRandomAccessSuccessful()
Notify the RRC that the MAC Random Access procedure completed successfully.
Definition: lte-ue-rrc.cc:83
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Constructor.
Definition: lte-ue-rrc.cc:71
LteUeRrc * m_rrc
the RRC class
Definition: lte-ue-rrc.cc:68
virtual void NotifyRandomAccessFailed()
Notify the RRC that the MAC Random Access procedure failed.
Definition: lte-ue-rrc.cc:89
virtual void SetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:76
Hold an unsigned integer type.
Definition: uinteger.h:44
#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
#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:88
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:80
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:227
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:1309
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
#define MIN_NO_CC
Definition: lte-enb-rrc.h:56
#define MAX_NO_CC
Definition: lte-enb-rrc.h:57
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:67
static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES]
Map each of UE RRC states to its string representation.
Definition: lte-ue-rrc.cc:100
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Definition: second.py:1
Parameters for LtePdcpSapProvider::TransmitPdcpSdu.
Definition: lte-pdcp-sap.h:44
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
Definition: lte-pdcp-sap.h:47
uint16_t rnti
the C-RNTI identifying the UE
Definition: lte-pdcp-sap.h:46
Parameters for LtePdcpSapUser::ReceivePdcpSdu.
Definition: lte-pdcp-sap.h:78
uint8_t transmissionMode
transmission mode
Definition: lte-rrc-sap.h:143
uint16_t dlBandwidth
DL bandwidth.
Definition: lte-rrc-sap.h:546
uint16_t ulBandwidth
UL bandwidth.
Definition: lte-rrc-sap.h:547
uint32_t dlCarrierFreq
DL carrier frequency.
Definition: lte-rrc-sap.h:539
uint32_t ulCarrierFreq
UL carrier frequency.
Definition: lte-rrc-sap.h:540
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
Definition: lte-rrc-sap.h:83
uint32_t ulCarrierFreq
UL carrier frequency.
Definition: lte-rrc-sap.h:90
uint16_t ulBandwidth
UL bandwidth.
Definition: lte-rrc-sap.h:91
MasterInformationBlock structure.
Definition: lte-rrc-sap.h:588
MeasConfig structure.
Definition: lte-rrc-sap.h:519
std::list< uint8_t > measIdToRemoveList
measure ID to remove list
Definition: lte-rrc-sap.h:524
std::list< MeasObjectToAddMod > measObjectToAddModList
measure object to add mod list
Definition: lte-rrc-sap.h:521
std::list< uint8_t > reportConfigToRemoveList
report config to remove list
Definition: lte-rrc-sap.h:522
std::list< uint8_t > measObjectToRemoveList
measure object to remove list
Definition: lte-rrc-sap.h:520
bool haveMeasGapConfig
have measure gap config?
Definition: lte-rrc-sap.h:528
QuantityConfig quantityConfig
quantity config
Definition: lte-rrc-sap.h:527
bool haveSmeasure
have S measure?
Definition: lte-rrc-sap.h:530
bool haveSpeedStatePars
have speed state parameters?
Definition: lte-rrc-sap.h:532
std::list< ReportConfigToAddMod > reportConfigToAddModList
report config to add mod list
Definition: lte-rrc-sap.h:523
std::list< MeasIdToAddMod > measIdToAddModList
measure ID to add mod list
Definition: lte-rrc-sap.h:525
bool haveQuantityConfig
have quantity config?
Definition: lte-rrc-sap.h:526
MeasObjectEutra structure.
Definition: lte-rrc-sap.h:326
int8_t offsetFreq
offset frequency
Definition: lte-rrc-sap.h:331
uint32_t carrierFreq
carrier frequency
Definition: lte-rrc-sap.h:327
MeasResultEutra structure.
Definition: lte-rrc-sap.h:644
uint8_t rsrqResult
RSRQ result.
Definition: lte-rrc-sap.h:651
uint8_t rsrpResult
RSRP result.
Definition: lte-rrc-sap.h:649
bool haveRsrpResult
have RSRP result
Definition: lte-rrc-sap.h:648
bool haveRsrqResult
have RSRQ result?
Definition: lte-rrc-sap.h:650
uint16_t physCellId
Phy cell ID.
Definition: lte-rrc-sap.h:645
bool haveCgiInfo
have CGI info?
Definition: lte-rrc-sap.h:646
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:639
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:638
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:657
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:658
MeasResultServFreq structure.
Definition: lte-rrc-sap.h:670
bool haveMeasResultSCell
have measResultSCell?
Definition: lte-rrc-sap.h:672
bool haveMeasResultBestNeighCell
have measResultBestNeighCell?
Definition: lte-rrc-sap.h:674
uint16_t servFreqId
serving cell index
Definition: lte-rrc-sap.h:671
MeasResultSCell measResultSCell
SCell measurement results.
Definition: lte-rrc-sap.h:673
MeasResults structure.
Definition: lte-rrc-sap.h:680
uint8_t measId
measure ID
Definition: lte-rrc-sap.h:681
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition: lte-rrc-sap.h:683
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition: lte-rrc-sap.h:684
bool haveMeasResultServFreqList
has measResultServFreqList-r10
Definition: lte-rrc-sap.h:685
std::list< MeasResultServFreq > measResultServFreqList
MeasResultServFreqList-r10.
Definition: lte-rrc-sap.h:686
MeasResultPCell measResultPCell
measurement result primary cell
Definition: lte-rrc-sap.h:682
MeasurementReport structure.
Definition: lte-rrc-sap.h:902
MeasResults measResults
measure results
Definition: lte-rrc-sap.h:903
MobilityControlInfo structure.
Definition: lte-rrc-sap.h:559
RachConfigDedicated rachConfigDedicated
RACH config dedicated.
Definition: lte-rrc-sap.h:568
bool haveRachConfigDedicated
Have RACH config dedicated?
Definition: lte-rrc-sap.h:567
uint16_t newUeIdentity
new UE identity
Definition: lte-rrc-sap.h:565
bool haveCarrierBandwidth
have carrier bandwidth?
Definition: lte-rrc-sap.h:563
bool haveCarrierFreq
have carrier frequency?
Definition: lte-rrc-sap.h:561
CarrierBandwidthEutra carrierBandwidth
carrier bandwidth
Definition: lte-rrc-sap.h:564
CarrierFreqEutra carrierFreq
carrier frequency
Definition: lte-rrc-sap.h:562
uint16_t targetPhysCellId
target Phy cell ID
Definition: lte-rrc-sap.h:560
NonCriticalExtensionConfiguration structure.
Definition: lte-rrc-sap.h:830
std::list< uint8_t > sCellToReleaseList
SCell to release list.
Definition: lte-rrc-sap.h:832
std::list< SCellToAddMod > sCellToAddModList
SCell to add mod list.
Definition: lte-rrc-sap.h:831
int8_t referenceSignalPower
INTEGER (-60..50),.
Definition: lte-rrc-sap.h:149
PdschConfigDedicated structure.
Definition: lte-rrc-sap.h:155
PhysicalConfigDedicated structure.
Definition: lte-rrc-sap.h:217
PdschConfigDedicated pdschConfigDedicated
PDSCH config dedicated.
Definition: lte-rrc-sap.h:223
bool haveAntennaInfoDedicated
have antenna info dedicated?
Definition: lte-rrc-sap.h:220
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
sounding RS UL config dedicated
Definition: lte-rrc-sap.h:219
bool haveSoundingRsUlConfigDedicated
have sounding RS UL config dedicated?
Definition: lte-rrc-sap.h:218
bool havePdschConfigDedicated
have PDSCH config dedicated?
Definition: lte-rrc-sap.h:222
AntennaInfoDedicated antennaInfo
antenna info
Definition: lte-rrc-sap.h:221
uint8_t numberOfRaPreambles
number of RA preambles
Definition: lte-rrc-sap.h:247
uint8_t filterCoefficientRSRQ
filter coefficient RSRQ
Definition: lte-rrc-sap.h:298
uint8_t filterCoefficientRSRP
filter coefficient RSRP
Definition: lte-rrc-sap.h:297
uint8_t raResponseWindowSize
RA response window size.
Definition: lte-rrc-sap.h:254
uint8_t preambleTransMax
preamble transmit maximum
Definition: lte-rrc-sap.h:253
TxFailParam txFailParam
txFailParams
Definition: lte-rrc-sap.h:268
PreambleInfo preambleInfo
preamble info
Definition: lte-rrc-sap.h:266
RaSupervisionInfo raSupervisionInfo
RA supervision info.
Definition: lte-rrc-sap.h:267
uint8_t raPreambleIndex
RA preamble index.
Definition: lte-rrc-sap.h:553
uint8_t raPrachMaskIndex
RA PRACH mask index.
Definition: lte-rrc-sap.h:554
RachConfigCommon rachConfigCommon
RACH config common.
Definition: lte-rrc-sap.h:280
PdschConfigCommon pdschConfigCommon
PDSCH config common.
Definition: lte-rrc-sap.h:281
RadioResourceConfigDedicated structure.
Definition: lte-rrc-sap.h:286
PhysicalConfigDedicated physicalConfigDedicated
physical config dedicated
Definition: lte-rrc-sap.h:291
std::list< uint8_t > drbToReleaseList
DRB to release list.
Definition: lte-rrc-sap.h:289
std::list< DrbToAddMod > drbToAddModList
DRB to add mod list.
Definition: lte-rrc-sap.h:288
std::list< SrbToAddMod > srbToAddModList
SRB to add mod list.
Definition: lte-rrc-sap.h:287
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:362
bool reportOnLeave
Indicates whether or not the UE shall initiate the measurement reporting procedure when the leaving c...
Definition: lte-rrc-sap.h:385
uint8_t maxReportCells
Maximum number of cells, excluding the serving cell, to be included in the measurement report.
Definition: lte-rrc-sap.h:418
@ EVENT_A2
Event A2: Serving becomes worse than absolute threshold.
Definition: lte-rrc-sap.h:374
@ EVENT_A3
Event A3: Neighbour becomes amount of offset better than PCell.
Definition: lte-rrc-sap.h:375
@ EVENT_A4
Event A4: Neighbour becomes better than absolute threshold.
Definition: lte-rrc-sap.h:376
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:373
@ EVENT_A5
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
Definition: lte-rrc-sap.h:377
uint8_t hysteresis
Parameter used within the entry and leave condition of an event triggered reporting condition....
Definition: lte-rrc-sap.h:391
@ RSRP
Reference Signal Received Power.
Definition: lte-rrc-sap.h:406
@ RSRQ
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:407
ThresholdEutra threshold2
Threshold for event A5.
Definition: lte-rrc-sap.h:382
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition: lte-rrc-sap.h:381
enum ns3::LteRrcSap::ReportConfigEutra::@67 triggerQuantity
Trigger type enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@66 eventId
Event enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@69 reportInterval
Report interval enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@65 triggerType
Trigger enumeration.
int8_t a3Offset
Offset value for Event A3. An integer between -30 and 30. The actual value is (value * 0....
Definition: lte-rrc-sap.h:388
uint16_t timeToTrigger
Time during which specific criteria for the event needs to be met in order to trigger a measurement r...
Definition: lte-rrc-sap.h:394
RrcConnectionReconfigurationCompleted structure.
Definition: lte-rrc-sap.h:852
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:853
RrcConnectionReconfiguration structure.
Definition: lte-rrc-sap.h:837
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:838
bool haveMobilityControlInfo
have mobility control info
Definition: lte-rrc-sap.h:841
NonCriticalExtensionConfiguration nonCriticalExtension
3GPP TS 36.331 v.11.10 R11 Sec. 6.2.2 pag. 147 (also known as ETSI TS 136 331 v.11....
Definition: lte-rrc-sap.h:847
bool haveRadioResourceConfigDedicated
have radio resource config dedicated
Definition: lte-rrc-sap.h:843
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:844
bool haveNonCriticalExtension
have critical extension?
Definition: lte-rrc-sap.h:845
MobilityControlInfo mobilityControlInfo
mobility control info
Definition: lte-rrc-sap.h:842
RrcConnectionReestablishment structure.
Definition: lte-rrc-sap.h:866
RrcConnectionReestablishmentReject structure.
Definition: lte-rrc-sap.h:879
RrcConnectionReject structure.
Definition: lte-rrc-sap.h:890
RrcConnectionRelease structure.
Definition: lte-rrc-sap.h:884
RrcConnectionRequest structure.
Definition: lte-rrc-sap.h:693
RrcConnectionSetupCompleted structure.
Definition: lte-rrc-sap.h:706
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:707
RrcConnectionSetup structure.
Definition: lte-rrc-sap.h:699
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:700
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:701
uint16_t srsConfigIndex
SRS config index.
Definition: lte-rrc-sap.h:137
SystemInformationBlockType1 structure.
Definition: lte-rrc-sap.h:595
CellSelectionInfo cellSelectionInfo
cell selection info
Definition: lte-rrc-sap.h:597
CellAccessRelatedInfo cellAccessRelatedInfo
cell access related info
Definition: lte-rrc-sap.h:596
RadioResourceConfigCommonSib radioResourceConfigCommon
radio resource config common
Definition: lte-rrc-sap.h:603
SystemInformation structure.
Definition: lte-rrc-sap.h:609
SystemInformationBlockType2 sib2
SIB2.
Definition: lte-rrc-sap.h:611
@ THRESHOLD_RSRP
RSRP is used for the threshold.
Definition: lte-rrc-sap.h:354
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:355
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:357
enum ns3::LteRrcSap::ThresholdEutra::@64 choice
Threshold enumeration.
uint8_t connEstFailCount
Number of times that the UE detects T300 expiry on the same cell.
Definition: lte-rrc-sap.h:260
uint16_t prioritizedBitRateKbps
prioritize bit rate Kbps
uint16_t bucketSizeDurationMs
bucket size duration ms
uint8_t logicalChannelGroup
logical channel group
uint8_t raResponseWindowSize
RA response window size.
uint8_t connEstFailCount
the counter value for T300 timer expiration
uint8_t preambleTransMax
preamble transmit maximum
uint8_t numberOfRaPreambles
number of RA preambles
UeMeasurementsParameters structure.
uint8_t m_componentCarrierId
component carrier ID
std::vector< struct UeMeasurementsElement > m_ueMeasurementsList
UE measurement list.
Represents a measurement result from a certain cell.
Definition: lte-ue-rrc.h:1060
uint32_t carrierFreq
Measurement object frequency.
Definition: lte-ue-rrc.h:1063
double rsrp
Measured RSRP in dBm.
Definition: lte-ue-rrc.h:1061
double rsrq
Measured RSRQ in dB.
Definition: lte-ue-rrc.h:1062
Represents a single triggered event from a measurement identity which reporting criteria have been fu...
Definition: lte-ue-rrc.h:1110
ConcernedCells_t concernedCells
The list of cells responsible for this trigger.
Definition: lte-ue-rrc.h:1112
EventId timer
The pending reporting event, scheduled at the end of the time-to-trigger.
Definition: lte-ue-rrc.h:1113
uint8_t measId
The measurement identity which raised the trigger.
Definition: lte-ue-rrc.h:1111
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
report config list
Definition: lte-ue-rrc.h:962
LteRrcSap::QuantityConfig quantityConfig
quantity config
Definition: lte-ue-rrc.h:963
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
measure object list
Definition: lte-ue-rrc.h:961
std::map< uint8_t, LteRrcSap::MeasIdToAddMod > measIdList
measure ID list
Definition: lte-ue-rrc.h:960
Represents a single measurement reporting entry., which includes information about a measurement for ...
Definition: lte-ue-rrc.h:984
uint8_t measId
measure ID
Definition: lte-ue-rrc.h:985
CompleteSetupParameters structure.
Definition: lte-rrc-sap.h:1005
LtePdcpSapUser * srb1SapUser
SRB1 SAP user.
Definition: lte-rrc-sap.h:1007
SetupParameters structure.
Definition: lte-rrc-sap.h:921
LteRlcSapProvider * srb0SapProvider
SRB0 SAP provider.
Definition: lte-rrc-sap.h:922
LtePdcpSapProvider * srb1SapProvider
SRB1 SAP provider.
Definition: lte-rrc-sap.h:923