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