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");
1069  //We should reset the MACs and PHYs for all the component carriers
1070  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1071  {
1072  m_cmacSapProvider.at(i)->Reset ();
1073  m_cphySapProvider.at(i)->Reset ();
1074  }
1077  m_cellId = mci.targetPhysCellId;
1078  NS_ASSERT (mci.haveCarrierFreq);
1080  m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
1081  m_cphySapProvider.at(0)->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
1082  m_cphySapProvider.at(0)->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
1084  m_srb0->m_rlc->SetRnti (m_rnti);
1085  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
1086  m_cmacSapProvider.at(0)->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
1087  m_cphySapProvider.at(0)->SetRnti (m_rnti);
1090 
1091  // we re-establish SRB1 by creating a new entity
1092  // note that we can't dispose the old entity now, because
1093  // it's in the current stack, so we would corrupt the stack
1094  // if we did so. Hence we schedule it for later disposal
1095  m_srb1Old = m_srb1;
1097  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
1098 
1099  m_drbMap.clear (); // dispose all DRBs
1101  if (msg.haveNonCriticalExtension)
1102  {
1103  NS_LOG_DEBUG (this << "RNTI " << m_rnti << " Handover. Configuring secondary carriers");
1105  }
1106 
1107  if (msg.haveMeasConfig)
1108  {
1110  }
1111  // RRC connection reconfiguration completed will be sent
1112  // after handover is complete
1113  }
1114  else
1115  {
1116  NS_LOG_INFO ("haveMobilityControlInfo == false");
1117  if (msg.haveNonCriticalExtension)
1118  {
1120  NS_LOG_DEBUG (this << "RNTI " << m_rnti << " Configured for CA" );
1121  }
1123  {
1125  }
1126  if (msg.haveMeasConfig)
1127  {
1129  }
1134  }
1135  break;
1136 
1137  default:
1138  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1139  break;
1140  }
1141 }
1142 
1143 void
1145 {
1146  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1147  switch (m_state)
1148  {
1150  {
1158  }
1159  break;
1160 
1161  default:
1162  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1163  break;
1164  }
1165 }
1166 
1167 void
1169 {
1170  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1171  switch (m_state)
1172  {
1174  {
1179  m_asSapUser->NotifyConnectionReleased (); // Inform upper layers
1180  }
1181  break;
1182 
1183  default:
1184  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1185  break;
1186  }
1187 }
1188 
1189 void
1191 {
1192  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1194 }
1195 
1196 void
1198 {
1199  NS_LOG_FUNCTION (this);
1201  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1202  {
1203  m_cmacSapProvider.at(i)->Reset (); // reset the MAC
1204  }
1205  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1207  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
1208 }
1209 
1210 void
1211 LteUeRrc::DoSetNumberOfComponentCarriers (uint16_t noOfComponentCarriers)
1212 {
1213  NS_LOG_FUNCTION (this);
1214  m_numberOfComponentCarriers = noOfComponentCarriers;
1215 }
1216 
1217 
1218 
1219 void
1221 {
1222  NS_LOG_FUNCTION (this);
1224 
1225  uint16_t maxRsrpCellId = 0;
1226  double maxRsrp = -std::numeric_limits<double>::infinity ();
1227  double minRsrp = -140.0; // Minimum RSRP in dBm a UE can report
1228 
1229  std::map<uint16_t, MeasValues>::iterator it;
1230  for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
1231  {
1232  /*
1233  * This block attempts to find a cell with strongest RSRP and has not
1234  * yet been identified as "acceptable cell".
1235  */
1236  if (maxRsrp < it->second.rsrp && it->second.rsrp > minRsrp)
1237  {
1238  std::set<uint16_t>::const_iterator itCell;
1239  itCell = m_acceptableCell.find (it->first);
1240  if (itCell == m_acceptableCell.end ())
1241  {
1242  maxRsrpCellId = it->first;
1243  maxRsrp = it->second.rsrp;
1244  }
1245  }
1246  }
1247 
1248  if (maxRsrpCellId == 0)
1249  {
1250  NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
1251  }
1252  else
1253  {
1254  NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
1255  << " is the strongest untried surrounding cell");
1256  m_cphySapProvider.at(0)->SynchronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
1258  }
1259 
1260 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1261 
1262 
1263 void
1265 {
1266  NS_LOG_FUNCTION (this);
1270  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1271 
1272  // Cell selection criteria evaluation
1273 
1274  bool isSuitableCell = false;
1275  bool isAcceptableCell = false;
1276  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1277  double qRxLevMeas = storedMeasIt->second.rsrp;
1279  NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
1280  << " qrxlevmeas=" << qRxLevMeas << " dBm"
1281  << " qrxlevmin=" << qRxLevMin << " dBm");
1282 
1283  if (qRxLevMeas - qRxLevMin > 0)
1284  {
1285  isAcceptableCell = true;
1286 
1287  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1288  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1289 
1290  isSuitableCell = (cellCsgIndication == false) || (cellCsgId == m_csgWhiteList);
1291 
1292  NS_LOG_LOGIC (this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
1293  << cellCsgId << "/" << cellCsgIndication);
1294  }
1295 
1296  // Cell selection decision
1297 
1298  if (isSuitableCell)
1299  {
1300  m_cellId = cellId;
1301  m_cphySapProvider.at(0)->SynchronizeWithEnb (cellId, m_dlEarfcn);
1302  m_cphySapProvider.at(0)->SetDlBandwidth (m_dlBandwidth);
1304  // Once the UE is connected, m_connectionPending is
1305  // set to false. So, when RLF occurs and UE performs
1306  // cell selection upon leaving RRC_CONNECTED state,
1307  // the following call to DoConnect will make the
1308  // m_connectionPending to be true again. Thus,
1309  // upon calling SwitchToState (IDLE_CAMPED_NORMALLY)
1310  // UE state is instantly change to IDLE_WAIT_SIB2.
1311  // This will make the UE to read the SIB2 message
1312  // and start random access.
1313  if (!m_connectionPending)
1314  {
1315  NS_LOG_DEBUG ("Calling DoConnect in state = " << ToString (m_state));
1316  DoConnect ();
1317  }
1319  }
1320  else
1321  {
1322  // ignore the MIB and SIB1 received from this cell
1323  m_hasReceivedMib = false;
1324  m_hasReceivedSib1 = false;
1325 
1327 
1328  if (isAcceptableCell)
1329  {
1330  /*
1331  * The cells inserted into this list will not be considered for
1332  * subsequent cell search attempt.
1333  */
1334  m_acceptableCell.insert (cellId);
1335  }
1336 
1338  SynchronizeToStrongestCell (); // retry to a different cell
1339  }
1340 
1341 } // end of void LteUeRrc::EvaluateCellForSelection ()
1342 
1343 
1344 void
1346 {
1347  NS_LOG_FUNCTION (this);
1348 
1350 
1351  for(std::list<LteRrcSap::SCellToAddMod>::iterator it = nonCec.sCellsToAddModList.begin(); it!=nonCec.sCellsToAddModList.end(); it++)
1352  {
1353  LteRrcSap::SCellToAddMod scell = *it;
1354  uint8_t ccId = scell.sCellIndex;
1355 
1356 
1357  uint16_t physCellId = scell.cellIdentification.physCellId;
1361  uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1364 
1365  m_cphySapProvider.at (ccId)->SynchronizeWithEnb (physCellId, dlEarfcn);
1366  m_cphySapProvider.at (ccId)->SetDlBandwidth (dlBand);
1367  m_cphySapProvider.at (ccId)->ConfigureUplink (ulEarfcn, ulBand);
1369  m_cphySapProvider.at (ccId)->SetTransmissionMode (txMode);
1370  m_cphySapProvider.at (ccId)->SetRnti(m_rnti);
1371  m_cmacSapProvider.at (ccId)->SetRnti(m_rnti);
1372  // update PdschConfigDedicated (i.e. P_A value)
1374  double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (pdschConfigDedicated);
1375  m_cphySapProvider.at (ccId)->SetPa (paDouble);
1376  m_cphySapProvider.at (ccId)->SetSrsConfigurationIndex (srsIndex);
1377  }
1378 
1380 }
1381 
1382 void
1384 {
1385  NS_LOG_FUNCTION (this);
1387 
1388  if (pcd.haveAntennaInfoDedicated)
1389  {
1390  m_cphySapProvider.at(0)->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
1391  }
1393  {
1394  m_cphySapProvider.at(0)->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
1395  }
1396 
1397  if (pcd.havePdschConfigDedicated)
1398  {
1399  // update PdschConfigDedicated (i.e. P_A value)
1402  m_cphySapProvider.at(0)->SetPa (paDouble);
1403  }
1404 
1405  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1406  if (stamIt != rrcd.srbToAddModList.end ())
1407  {
1408  if (m_srb1 == 0)
1409  {
1410  // SRB1 not setup yet
1412  "unexpected state " << ToString (m_state));
1413  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1414 
1415  const uint8_t lcid = 1; // fixed LCID for SRB1
1416 
1417  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1419  rlc->SetRnti (m_rnti);
1420  rlc->SetLcId (lcid);
1421 
1422  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1423  pdcp->SetRnti (m_rnti);
1424  pdcp->SetLcId (lcid);
1425  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1426  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1427  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1428 
1429  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1430  m_srb1->m_rlc = rlc;
1431  m_srb1->m_pdcp = pdcp;
1432  m_srb1->m_srbIdentity = 1;
1434 
1435  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1436  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1437  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1438  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1439 
1441  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1442  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1443  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1444  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1446  m_cmacSapProvider.at (0)->AddLc (lcid, lcConfig, msu);
1447  ++stamIt;
1448  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1449 
1451  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1452  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1453  m_rrcSapUser->Setup (ueParams);
1454  }
1455  else
1456  {
1457  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1458  // would need to modify m_srb1, and then propagate changes to the MAC
1459  }
1460  }
1461 
1462 
1463  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1464  for (dtamIt = rrcd.drbToAddModList.begin ();
1465  dtamIt != rrcd.drbToAddModList.end ();
1466  ++dtamIt)
1467  {
1468  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1469  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1470 
1471  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1472  if (drbMapIt == m_drbMap.end ())
1473  {
1474  NS_LOG_INFO ("New Data Radio Bearer");
1475 
1476  TypeId rlcTypeId;
1477  if (m_useRlcSm)
1478  {
1479  rlcTypeId = LteRlcSm::GetTypeId ();
1480  }
1481  else
1482  {
1483  switch (dtamIt->rlcConfig.choice)
1484  {
1486  rlcTypeId = LteRlcAm::GetTypeId ();
1487  break;
1488 
1490  rlcTypeId = LteRlcUm::GetTypeId ();
1491  break;
1492 
1493  default:
1494  NS_FATAL_ERROR ("unsupported RLC configuration");
1495  break;
1496  }
1497  }
1498 
1499  ObjectFactory rlcObjectFactory;
1500  rlcObjectFactory.SetTypeId (rlcTypeId);
1501  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1503  rlc->SetRnti (m_rnti);
1504  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1505 
1506  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1507  drbInfo->m_rlc = rlc;
1508  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1509  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1510  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1511 
1512  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1513  // if we are using RLC/SM we don't care of anything above RLC
1514  if (rlcTypeId != LteRlcSm::GetTypeId ())
1515  {
1516  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1517  pdcp->SetRnti (m_rnti);
1518  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1519  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1520  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1521  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1522  drbInfo->m_pdcp = pdcp;
1523  }
1524 
1525  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1526 
1527  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1528 
1529  m_drbCreatedTrace (m_imsi, m_cellId, m_rnti, dtamIt->drbIdentity);
1530 
1531 
1533  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1534  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1535  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1536  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1537 
1538  NS_LOG_DEBUG (this << " UE RRC RNTI " << m_rnti << " Number Of Component Carriers "<<m_numberOfComponentCarriers<< " lcID " << (uint16_t) dtamIt->logicalChannelIdentity);
1539  //Call AddLc of UE component carrier manager
1540  std::vector <LteUeCcmRrcSapProvider::LcsConfig> lcOnCcMapping = m_ccmRrcSapProvider->AddLc (dtamIt->logicalChannelIdentity, lcConfig, rlc->GetLteMacSapUser ());
1541 
1542  NS_LOG_DEBUG ("Size of lcOnCcMapping vector "<<lcOnCcMapping.size());
1543  std::vector<LteUeCcmRrcSapProvider::LcsConfig>::iterator itLcOnCcMapping = lcOnCcMapping.begin ();
1544  NS_ASSERT_MSG (itLcOnCcMapping != lcOnCcMapping.end (), "Component carrier manager failed to add LC for data radio bearer");
1545 
1546  for (itLcOnCcMapping = lcOnCcMapping.begin (); itLcOnCcMapping != lcOnCcMapping.end (); ++itLcOnCcMapping)
1547  {
1548  NS_LOG_DEBUG ("RNTI " << m_rnti
1549  << " LCG id " << (uint16_t) itLcOnCcMapping->lcConfig.logicalChannelGroup
1550  << " ComponentCarrierId " << (uint16_t) itLcOnCcMapping->componentCarrierId);
1551  uint8_t index = itLcOnCcMapping->componentCarrierId;
1552  LteUeCmacSapProvider::LogicalChannelConfig lcConfigFromCcm = itLcOnCcMapping->lcConfig;
1553  LteMacSapUser *msu = itLcOnCcMapping->msu;
1554  m_cmacSapProvider.at (index)->AddLc (dtamIt->logicalChannelIdentity, lcConfigFromCcm, msu);
1555  }
1556 
1557  rlc->Initialize ();
1558  }
1559  else
1560  {
1561  NS_LOG_INFO ("request to modify existing DRBID");
1562  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1564  }
1565  }
1566 
1567  std::list<uint8_t>::iterator dtdmIt;
1568  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1569  dtdmIt != rrcd.drbToReleaseList.end ();
1570  ++dtdmIt)
1571  {
1572  uint8_t drbid = *dtdmIt;
1573  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid);
1574  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1575  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1576  m_drbMap.erase (it);
1577  m_bid2DrbidMap.erase (drbid);
1578  //Remove LCID
1579  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1580  {
1581  m_cmacSapProvider.at (i)->RemoveLc (drbid + 2);
1582  }
1583  }
1584 }
1585 
1586 
1587 void
1589 {
1590  NS_LOG_FUNCTION (this);
1591 
1592  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1593 
1594  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1595  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1596  it != mc.measObjectToRemoveList.end ();
1597  ++it)
1598  {
1599  uint8_t measObjectId = *it;
1600  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1601  m_varMeasConfig.measObjectList.erase (measObjectId);
1602  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1603  while (measIdIt != m_varMeasConfig.measIdList.end ())
1604  {
1605  if (measIdIt->second.measObjectId == measObjectId)
1606  {
1607  uint8_t measId = measIdIt->second.measId;
1608  NS_ASSERT (measId == measIdIt->first);
1609  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1610  // note: postfix operator preserves iterator validity
1611  m_varMeasConfig.measIdList.erase (measIdIt++);
1612  VarMeasReportListClear (measId);
1613  }
1614  else
1615  {
1616  ++measIdIt;
1617  }
1618  }
1619 
1620  }
1621 
1622  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1623  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1624  it != mc.measObjectToAddModList.end ();
1625  ++it)
1626  {
1627  // simplifying assumptions
1628  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1629  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1630  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1631  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1632  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
1633 
1634  uint8_t measObjectId = it->measObjectId;
1635  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1636  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1637  {
1638  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1639  measObjectIt->second = *it;
1640  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1641  = m_varMeasConfig.measIdList.begin ();
1642  measIdIt != m_varMeasConfig.measIdList.end ();
1643  ++measIdIt)
1644  {
1645  if (measIdIt->second.measObjectId == measObjectId)
1646  {
1647  uint8_t measId = measIdIt->second.measId;
1648  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1649  VarMeasReportListClear (measId);
1650  }
1651  }
1652  }
1653  else
1654  {
1655  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1656  m_varMeasConfig.measObjectList[measObjectId] = *it;
1657  }
1658 
1659  }
1660 
1661  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1662  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1663  it != mc.reportConfigToRemoveList.end ();
1664  ++it)
1665  {
1666  uint8_t reportConfigId = *it;
1667  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1668  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1669  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1670  while (measIdIt != m_varMeasConfig.measIdList.end ())
1671  {
1672  if (measIdIt->second.reportConfigId == reportConfigId)
1673  {
1674  uint8_t measId = measIdIt->second.measId;
1675  NS_ASSERT (measId == measIdIt->first);
1676  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1677  // note: postfix operator preserves iterator validity
1678  m_varMeasConfig.measIdList.erase (measIdIt++);
1679  VarMeasReportListClear (measId);
1680  }
1681  else
1682  {
1683  ++measIdIt;
1684  }
1685  }
1686 
1687  }
1688 
1689  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1690  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1691  it != mc.reportConfigToAddModList.end ();
1692  ++it)
1693  {
1694  // simplifying assumptions
1695  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1696  "only trigger type EVENT is supported");
1697 
1698  uint8_t reportConfigId = it->reportConfigId;
1699  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1700  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1701  {
1702  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1703  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1704  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1705  = m_varMeasConfig.measIdList.begin ();
1706  measIdIt != m_varMeasConfig.measIdList.end ();
1707  ++measIdIt)
1708  {
1709  if (measIdIt->second.reportConfigId == reportConfigId)
1710  {
1711  uint8_t measId = measIdIt->second.measId;
1712  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1713  VarMeasReportListClear (measId);
1714  }
1715  }
1716  }
1717  else
1718  {
1719  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1720  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1721  }
1722 
1723  }
1724 
1725  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1726  if (mc.haveQuantityConfig)
1727  {
1728  NS_LOG_LOGIC (this << " setting quantityConfig");
1730  //Convey the filter coefficient to PHY layer so it can configure the power control parameter
1731  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1732  {
1733  m_cphySapProvider.at (i)->SetRsrpFilterCoefficient (mc.quantityConfig.filterCoefficientRSRP);
1734  }
1735  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1736  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1737  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1738  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1739 
1740  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1741  = m_varMeasConfig.measIdList.begin ();
1742  measIdIt != m_varMeasConfig.measIdList.end ();
1743  ++measIdIt)
1744  {
1745  VarMeasReportListClear (measIdIt->second.measId);
1746  }
1747  }
1748 
1749  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1750  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1751  it != mc.measIdToRemoveList.end ();
1752  ++it)
1753  {
1754  uint8_t measId = *it;
1755  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1756  m_varMeasConfig.measIdList.erase (measId);
1757  VarMeasReportListClear (measId);
1758 
1759  // removing time-to-trigger queues
1760  m_enteringTriggerQueue.erase (measId);
1761  m_leavingTriggerQueue.erase (measId);
1762  }
1763 
1764  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1765  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1766  it != mc.measIdToAddModList.end ();
1767  ++it)
1768  {
1769  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId
1770  << " (measObjectId=" << (uint32_t) it->measObjectId
1771  << ", reportConfigId=" << (uint32_t) it->reportConfigId
1772  << ")");
1773  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1774  != m_varMeasConfig.measObjectList.end ());
1775  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1776  != m_varMeasConfig.reportConfigList.end ());
1777  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1778  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1779  if (measReportIt != m_varMeasReportList.end ())
1780  {
1781  measReportIt->second.periodicReportTimer.Cancel ();
1782  m_varMeasReportList.erase (measReportIt);
1783  }
1784  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1785  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1786 
1787  // new empty queues for time-to-trigger
1788  std::list<PendingTrigger_t> s;
1789  m_enteringTriggerQueue[it->measId] = s;
1790  m_leavingTriggerQueue[it->measId] = s;
1791  }
1792 
1793  if (mc.haveMeasGapConfig)
1794  {
1795  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1796  }
1797 
1798  if (mc.haveSmeasure)
1799  {
1800  NS_FATAL_ERROR ("s-measure is currently not supported");
1801  }
1802 
1803  if (mc.haveSpeedStatePars)
1804  {
1805  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1806  }
1807 }
1808 
1809 void
1810 LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
1811  bool useLayer3Filtering)
1812 {
1813  NS_LOG_FUNCTION (this << cellId << rsrp << rsrq << useLayer3Filtering);
1814 
1815  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1816 
1817  if (storedMeasIt != m_storedMeasValues.end ())
1818  {
1819  if (useLayer3Filtering)
1820  {
1821  // F_n = (1-a) F_{n-1} + a M_n
1822  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
1823  + m_varMeasConfig.aRsrp * rsrp;
1824 
1825  if (std::isnan (storedMeasIt->second.rsrq))
1826  {
1827  // the previous RSRQ measurements provided UE PHY are invalid
1828  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1829  }
1830  else
1831  {
1832  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
1833  + m_varMeasConfig.aRsrq * rsrq;
1834  }
1835  }
1836  else
1837  {
1838  storedMeasIt->second.rsrp = rsrp;
1839  storedMeasIt->second.rsrq = rsrq;
1840  }
1841  }
1842  else
1843  {
1844  // first value is always unfiltered
1845  MeasValues v;
1846  v.rsrp = rsrp;
1847  v.rsrq = rsrq;
1848  std::pair<uint16_t, MeasValues> val (cellId, v);
1849  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
1850  ret = m_storedMeasValues.insert (val);
1851  NS_ASSERT_MSG (ret.second == true, "element already existed");
1852  storedMeasIt = ret.first;
1853  }
1854 
1855  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
1856  << ", measured cell " << m_cellId
1857  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
1858  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
1859  storedMeasIt->second.timestamp = Simulator::Now ();
1860 
1861 } // end of void SaveUeMeasurements
1862 
1863 void
1865 {
1866  NS_LOG_FUNCTION (this << (uint16_t) measId);
1867 
1868  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt =
1869  m_varMeasConfig.measIdList.find (measId);
1870  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1871  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
1872 
1873  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1874  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1875  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1876  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1877 
1878  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
1879  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
1880  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
1881  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1882 
1883  std::map<uint8_t, VarMeasReport>::iterator
1884  measReportIt = m_varMeasReportList.find (measId);
1885  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end ());
1886 
1887  // we don't check the purpose field, as it is only included for
1888  // triggerType == periodical, which is not supported
1889  NS_ASSERT_MSG (reportConfigEutra.triggerType
1891  "only triggerType == event is supported");
1892  // only EUTRA is supported, no need to check for it
1893 
1894  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
1895  bool eventEntryCondApplicable = false;
1896  bool eventLeavingCondApplicable = false;
1897  ConcernedCells_t concernedCellsEntry;
1898  ConcernedCells_t concernedCellsLeaving;
1899 
1900  switch (reportConfigEutra.eventId)
1901  {
1903  {
1904  /*
1905  * Event A1 (Serving becomes better than threshold)
1906  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1907  */
1908 
1909  double ms; // Ms, the measurement result of the serving cell
1910  double thresh; // Thresh, the threshold parameter for this event
1911  // Hys, the hysteresis parameter for this event.
1912  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1913 
1914  switch (reportConfigEutra.triggerQuantity)
1915  {
1917  ms = m_storedMeasValues[m_cellId].rsrp;
1918  NS_ASSERT (reportConfigEutra.threshold1.choice
1920  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1921  break;
1923  ms = m_storedMeasValues[m_cellId].rsrq;
1924  NS_ASSERT (reportConfigEutra.threshold1.choice
1926  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1927  break;
1928  default:
1929  NS_FATAL_ERROR ("unsupported triggerQuantity");
1930  break;
1931  }
1932 
1933  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1934  bool entryCond = ms - hys > thresh;
1935 
1936  if (entryCond)
1937  {
1938  if (!isMeasIdInReportList)
1939  {
1940  concernedCellsEntry.push_back (m_cellId);
1941  eventEntryCondApplicable = true;
1942  }
1943  else
1944  {
1945  /*
1946  * This is to check that the triggered cell recorded in the
1947  * VarMeasReportList is the serving cell.
1948  */
1949  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1950  != measReportIt->second.cellsTriggeredList.end ());
1951  }
1952  }
1953  else if (reportConfigEutra.timeToTrigger > 0)
1954  {
1955  CancelEnteringTrigger (measId);
1956  }
1957 
1958  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
1959  bool leavingCond = ms + hys < thresh;
1960 
1961  if (leavingCond)
1962  {
1963  if (isMeasIdInReportList)
1964  {
1965  /*
1966  * This is to check that the triggered cell recorded in the
1967  * VarMeasReportList is the serving cell.
1968  */
1969  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1970  != measReportIt->second.cellsTriggeredList.end ());
1971  concernedCellsLeaving.push_back (m_cellId);
1972  eventLeavingCondApplicable = true;
1973  }
1974  }
1975  else if (reportConfigEutra.timeToTrigger > 0)
1976  {
1977  CancelLeavingTrigger (measId);
1978  }
1979 
1980  NS_LOG_LOGIC (this << " event A1: serving cell " << m_cellId
1981  << " ms=" << ms << " thresh=" << thresh
1982  << " entryCond=" << entryCond
1983  << " leavingCond=" << leavingCond);
1984 
1985  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
1986 
1987  break;
1988 
1990  {
1991  /*
1992  * Event A2 (Serving becomes worse than threshold)
1993  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
1994  */
1995 
1996  double ms; // Ms, the measurement result of the serving cell
1997  double thresh; // Thresh, the threshold parameter for this event
1998  // Hys, the hysteresis parameter for this event.
1999  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2000 
2001  switch (reportConfigEutra.triggerQuantity)
2002  {
2004  ms = m_storedMeasValues[m_cellId].rsrp;
2005  NS_ASSERT (reportConfigEutra.threshold1.choice
2007  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2008  break;
2010  ms = m_storedMeasValues[m_cellId].rsrq;
2011  NS_ASSERT (reportConfigEutra.threshold1.choice
2013  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2014  break;
2015  default:
2016  NS_FATAL_ERROR ("unsupported triggerQuantity");
2017  break;
2018  }
2019 
2020  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
2021  bool entryCond = ms + hys < thresh;
2022 
2023  if (entryCond)
2024  {
2025  if (!isMeasIdInReportList)
2026  {
2027  concernedCellsEntry.push_back (m_cellId);
2028  eventEntryCondApplicable = true;
2029  }
2030  else
2031  {
2032  /*
2033  * This is to check that the triggered cell recorded in the
2034  * VarMeasReportList is the serving cell.
2035  */
2036  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
2037  != measReportIt->second.cellsTriggeredList.end ());
2038  }
2039  }
2040  else if (reportConfigEutra.timeToTrigger > 0)
2041  {
2042  CancelEnteringTrigger (measId);
2043  }
2044 
2045  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
2046  bool leavingCond = ms - hys > thresh;
2047 
2048  if (leavingCond)
2049  {
2050  if (isMeasIdInReportList)
2051  {
2052  /*
2053  * This is to check that the triggered cell recorded in the
2054  * VarMeasReportList is the serving cell.
2055  */
2056  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
2057  != measReportIt->second.cellsTriggeredList.end ());
2058  concernedCellsLeaving.push_back (m_cellId);
2059  eventLeavingCondApplicable = true;
2060  }
2061  }
2062  else if (reportConfigEutra.timeToTrigger > 0)
2063  {
2064  CancelLeavingTrigger (measId);
2065  }
2066 
2067  NS_LOG_LOGIC (this << " event A2: serving cell " << m_cellId
2068  << " ms=" << ms << " thresh=" << thresh
2069  << " entryCond=" << entryCond
2070  << " leavingCond=" << leavingCond);
2071 
2072  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
2073 
2074  break;
2075 
2077  {
2078  /*
2079  * Event A3 (Neighbour becomes offset better than PCell)
2080  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
2081  */
2082 
2083  double mn; // Mn, the measurement result of the neighbouring cell
2084  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2085  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2086  double mp; // Mp, the measurement result of the PCell
2087  double ofp = measObjectEutra.offsetFreq; // Ofp, the frequency specific offset of the primary frequency
2088  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
2089  // Off, the offset parameter for this event.
2090  double off = EutranMeasurementMapping::IeValue2ActualA3Offset (reportConfigEutra.a3Offset);
2091  // Hys, the hysteresis parameter for this event.
2092  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2093 
2094  switch (reportConfigEutra.triggerQuantity)
2095  {
2097  mp = m_storedMeasValues[m_cellId].rsrp;
2098  NS_ASSERT (reportConfigEutra.threshold1.choice
2100  break;
2102  mp = m_storedMeasValues[m_cellId].rsrq;
2103  NS_ASSERT (reportConfigEutra.threshold1.choice
2105  break;
2106  default:
2107  NS_FATAL_ERROR ("unsupported triggerQuantity");
2108  break;
2109  }
2110 
2111  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2112  storedMeasIt != m_storedMeasValues.end ();
2113  ++storedMeasIt)
2114  {
2115  uint16_t cellId = storedMeasIt->first;
2116  if (cellId == m_cellId)
2117  {
2118  continue;
2119  }
2120 
2121  switch (reportConfigEutra.triggerQuantity)
2122  {
2124  mn = storedMeasIt->second.rsrp;
2125  break;
2127  mn = storedMeasIt->second.rsrq;
2128  break;
2129  default:
2130  NS_FATAL_ERROR ("unsupported triggerQuantity");
2131  break;
2132  }
2133 
2134  bool hasTriggered = isMeasIdInReportList
2135  && (measReportIt->second.cellsTriggeredList.find (cellId)
2136  != measReportIt->second.cellsTriggeredList.end ());
2137 
2138  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
2139  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
2140 
2141  if (entryCond)
2142  {
2143  if (!hasTriggered)
2144  {
2145  concernedCellsEntry.push_back (cellId);
2146  eventEntryCondApplicable = true;
2147  }
2148  }
2149  else if (reportConfigEutra.timeToTrigger > 0)
2150  {
2151  CancelEnteringTrigger (measId, cellId);
2152  }
2153 
2154  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
2155  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2156 
2157  if (leavingCond)
2158  {
2159  if (hasTriggered)
2160  {
2161  concernedCellsLeaving.push_back (cellId);
2162  eventLeavingCondApplicable = true;
2163  }
2164  }
2165  else if (reportConfigEutra.timeToTrigger > 0)
2166  {
2167  CancelLeavingTrigger (measId, cellId);
2168  }
2169 
2170  NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId
2171  << " mn=" << mn << " mp=" << mp << " offset=" << off
2172  << " entryCond=" << entryCond
2173  << " leavingCond=" << leavingCond);
2174 
2175  } // end of for (storedMeasIt)
2176 
2177  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
2178 
2179  break;
2180 
2182  {
2183  /*
2184  * Event A4 (Neighbour becomes better than threshold)
2185  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
2186  */
2187 
2188  double mn; // Mn, the measurement result of the neighbouring cell
2189  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2190  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2191  double thresh; // Thresh, the threshold parameter for this event
2192  // Hys, the hysteresis parameter for this event.
2193  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2194 
2195  switch (reportConfigEutra.triggerQuantity)
2196  {
2198  NS_ASSERT (reportConfigEutra.threshold1.choice
2200  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2201  break;
2203  NS_ASSERT (reportConfigEutra.threshold1.choice
2205  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2206  break;
2207  default:
2208  NS_FATAL_ERROR ("unsupported triggerQuantity");
2209  break;
2210  }
2211 
2212  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2213  storedMeasIt != m_storedMeasValues.end ();
2214  ++storedMeasIt)
2215  {
2216  uint16_t cellId = storedMeasIt->first;
2217  if (cellId == m_cellId)
2218  {
2219  continue;
2220  }
2221 
2222  switch (reportConfigEutra.triggerQuantity)
2223  {
2225  mn = storedMeasIt->second.rsrp;
2226  break;
2228  mn = storedMeasIt->second.rsrq;
2229  break;
2230  default:
2231  NS_FATAL_ERROR ("unsupported triggerQuantity");
2232  break;
2233  }
2234 
2235  bool hasTriggered = isMeasIdInReportList
2236  && (measReportIt->second.cellsTriggeredList.find (cellId)
2237  != measReportIt->second.cellsTriggeredList.end ());
2238 
2239  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
2240  bool entryCond = mn + ofn + ocn - hys > thresh;
2241 
2242  if (entryCond)
2243  {
2244  if (!hasTriggered)
2245  {
2246  concernedCellsEntry.push_back (cellId);
2247  eventEntryCondApplicable = true;
2248  }
2249  }
2250  else if (reportConfigEutra.timeToTrigger > 0)
2251  {
2252  CancelEnteringTrigger (measId, cellId);
2253  }
2254 
2255  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
2256  bool leavingCond = mn + ofn + ocn + hys < thresh;
2257 
2258  if (leavingCond)
2259  {
2260  if (hasTriggered)
2261  {
2262  concernedCellsLeaving.push_back (cellId);
2263  eventLeavingCondApplicable = true;
2264  }
2265  }
2266  else if (reportConfigEutra.timeToTrigger > 0)
2267  {
2268  CancelLeavingTrigger (measId, cellId);
2269  }
2270 
2271  NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId
2272  << " mn=" << mn << " thresh=" << thresh
2273  << " entryCond=" << entryCond
2274  << " leavingCond=" << leavingCond);
2275 
2276  } // end of for (storedMeasIt)
2277 
2278  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
2279 
2280  break;
2281 
2283  {
2284  /*
2285  * Event A5 (PCell becomes worse than threshold1 and neighbour
2286  * becomes better than threshold2)
2287  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2288  */
2289 
2290  double mp; // Mp, the measurement result of the PCell
2291  double mn; // Mn, the measurement result of the neighbouring cell
2292  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2293  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2294  double thresh1; // Thresh1, the threshold parameter for this event
2295  double thresh2; // Thresh2, the threshold parameter for this event
2296  // Hys, the hysteresis parameter for this event.
2297  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2298 
2299  switch (reportConfigEutra.triggerQuantity)
2300  {
2302  mp = m_storedMeasValues[m_cellId].rsrp;
2303  NS_ASSERT (reportConfigEutra.threshold1.choice
2305  NS_ASSERT (reportConfigEutra.threshold2.choice
2307  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2308  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range);
2309  break;
2311  mp = m_storedMeasValues[m_cellId].rsrq;
2312  NS_ASSERT (reportConfigEutra.threshold1.choice
2314  NS_ASSERT (reportConfigEutra.threshold2.choice
2316  thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2317  thresh2 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold2.range);
2318  break;
2319  default:
2320  NS_FATAL_ERROR ("unsupported triggerQuantity");
2321  break;
2322  }
2323 
2324  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2325  bool entryCond = mp + hys < thresh1;
2326 
2327  if (entryCond)
2328  {
2329  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2330  storedMeasIt != m_storedMeasValues.end ();
2331  ++storedMeasIt)
2332  {
2333  uint16_t cellId = storedMeasIt->first;
2334  if (cellId == m_cellId)
2335  {
2336  continue;
2337  }
2338 
2339  switch (reportConfigEutra.triggerQuantity)
2340  {
2342  mn = storedMeasIt->second.rsrp;
2343  break;
2345  mn = storedMeasIt->second.rsrq;
2346  break;
2347  default:
2348  NS_FATAL_ERROR ("unsupported triggerQuantity");
2349  break;
2350  }
2351 
2352  bool hasTriggered = isMeasIdInReportList
2353  && (measReportIt->second.cellsTriggeredList.find (cellId)
2354  != measReportIt->second.cellsTriggeredList.end ());
2355 
2356  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2357 
2358  entryCond = mn + ofn + ocn - hys > thresh2;
2359 
2360  if (entryCond)
2361  {
2362  if (!hasTriggered)
2363  {
2364  concernedCellsEntry.push_back (cellId);
2365  eventEntryCondApplicable = true;
2366  }
2367  }
2368  else if (reportConfigEutra.timeToTrigger > 0)
2369  {
2370  CancelEnteringTrigger (measId, cellId);
2371  }
2372 
2373  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2374  << " mn=" << mn << " mp=" << mp
2375  << " thresh2=" << thresh2
2376  << " thresh1=" << thresh1
2377  << " entryCond=" << entryCond);
2378 
2379  } // end of for (storedMeasIt)
2380 
2381  } // end of if (entryCond)
2382  else
2383  {
2384  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2385  << " mp=" << mp << " thresh1=" << thresh1
2386  << " entryCond=" << entryCond);
2387 
2388  if (reportConfigEutra.timeToTrigger > 0)
2389  {
2390  CancelEnteringTrigger (measId);
2391  }
2392  }
2393 
2394  if (isMeasIdInReportList)
2395  {
2396  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2397  bool leavingCond = mp - hys > thresh1;
2398 
2399  if (leavingCond)
2400  {
2401  if (reportConfigEutra.timeToTrigger == 0)
2402  {
2403  // leaving condition #2 does not have to be checked
2404 
2405  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2406  storedMeasIt != m_storedMeasValues.end ();
2407  ++storedMeasIt)
2408  {
2409  uint16_t cellId = storedMeasIt->first;
2410  if (cellId == m_cellId)
2411  {
2412  continue;
2413  }
2414 
2415  if (measReportIt->second.cellsTriggeredList.find (cellId)
2416  != measReportIt->second.cellsTriggeredList.end ())
2417  {
2418  concernedCellsLeaving.push_back (cellId);
2419  eventLeavingCondApplicable = true;
2420  }
2421  }
2422  } // end of if (reportConfigEutra.timeToTrigger == 0)
2423  else
2424  {
2425  // leaving condition #2 has to be checked to cancel time-to-trigger
2426 
2427  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2428  storedMeasIt != m_storedMeasValues.end ();
2429  ++storedMeasIt)
2430  {
2431  uint16_t cellId = storedMeasIt->first;
2432  if (cellId == m_cellId)
2433  {
2434  continue;
2435  }
2436 
2437  if (measReportIt->second.cellsTriggeredList.find (cellId)
2438  != measReportIt->second.cellsTriggeredList.end ())
2439  {
2440  switch (reportConfigEutra.triggerQuantity)
2441  {
2443  mn = storedMeasIt->second.rsrp;
2444  break;
2446  mn = storedMeasIt->second.rsrq;
2447  break;
2448  default:
2449  NS_FATAL_ERROR ("unsupported triggerQuantity");
2450  break;
2451  }
2452 
2453  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2454 
2455  leavingCond = mn + ofn + ocn + hys < thresh2;
2456 
2457  if (!leavingCond)
2458  {
2459  CancelLeavingTrigger (measId, cellId);
2460  }
2461 
2462  /*
2463  * Whatever the result of leaving condition #2, this
2464  * cell is still "in", because leaving condition #1
2465  * is already true.
2466  */
2467  concernedCellsLeaving.push_back (cellId);
2468  eventLeavingCondApplicable = true;
2469 
2470  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2471  << " mn=" << mn << " mp=" << mp
2472  << " thresh2=" << thresh2
2473  << " thresh1=" << thresh1
2474  << " leavingCond=" << leavingCond);
2475 
2476  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2477  // != measReportIt->second.cellsTriggeredList.end ())
2478 
2479  } // end of for (storedMeasIt)
2480 
2481  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2482 
2483  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2484  << " mp=" << mp << " thresh1=" << thresh1
2485  << " leavingCond=" << leavingCond);
2486 
2487  } // end of if (leavingCond)
2488  else
2489  {
2490  if (reportConfigEutra.timeToTrigger > 0)
2491  {
2492  CancelLeavingTrigger (measId);
2493  }
2494 
2495  // check leaving condition #2
2496 
2497  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2498  storedMeasIt != m_storedMeasValues.end ();
2499  ++storedMeasIt)
2500  {
2501  uint16_t cellId = storedMeasIt->first;
2502  if (cellId == m_cellId)
2503  {
2504  continue;
2505  }
2506 
2507  if (measReportIt->second.cellsTriggeredList.find (cellId)
2508  != measReportIt->second.cellsTriggeredList.end ())
2509  {
2510  switch (reportConfigEutra.triggerQuantity)
2511  {
2513  mn = storedMeasIt->second.rsrp;
2514  break;
2516  mn = storedMeasIt->second.rsrq;
2517  break;
2518  default:
2519  NS_FATAL_ERROR ("unsupported triggerQuantity");
2520  break;
2521  }
2522 
2523  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2524  leavingCond = mn + ofn + ocn + hys < thresh2;
2525 
2526  if (leavingCond)
2527  {
2528  concernedCellsLeaving.push_back (cellId);
2529  eventLeavingCondApplicable = true;
2530  }
2531 
2532  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2533  << " mn=" << mn << " mp=" << mp
2534  << " thresh2=" << thresh2
2535  << " thresh1=" << thresh1
2536  << " leavingCond=" << leavingCond);
2537 
2538  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2539  // != measReportIt->second.cellsTriggeredList.end ())
2540 
2541  } // end of for (storedMeasIt)
2542 
2543  } // end of else of if (leavingCond)
2544 
2545  } // end of if (isMeasIdInReportList)
2546 
2547  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2548 
2549  break;
2550 
2551  default:
2552  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
2553  break;
2554 
2555  } // switch (event type)
2556 
2557  NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2558  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2559 
2560  if (eventEntryCondApplicable)
2561  {
2562  if (reportConfigEutra.timeToTrigger == 0)
2563  {
2564  VarMeasReportListAdd (measId, concernedCellsEntry);
2565  }
2566  else
2567  {
2568  PendingTrigger_t t;
2569  t.measId = measId;
2570  t.concernedCells = concernedCellsEntry;
2571  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2573  measId, concernedCellsEntry);
2574  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2575  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2576  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2577  enteringTriggerIt->second.push_back (t);
2578  }
2579  }
2580 
2581  if (eventLeavingCondApplicable)
2582  {
2583  // reportOnLeave will only be set when eventId = eventA3
2584  bool reportOnLeave = (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
2585  && reportConfigEutra.reportOnLeave;
2586 
2587  if (reportConfigEutra.timeToTrigger == 0)
2588  {
2589  VarMeasReportListErase (measId, concernedCellsLeaving, reportOnLeave);
2590  }
2591  else
2592  {
2593  PendingTrigger_t t;
2594  t.measId = measId;
2595  t.concernedCells = concernedCellsLeaving;
2596  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2598  measId, concernedCellsLeaving, reportOnLeave);
2599  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2600  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2601  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2602  leavingTriggerIt->second.push_back (t);
2603  }
2604  }
2605 
2606 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2607 
2608 void
2610 {
2611  NS_LOG_FUNCTION (this << (uint16_t) measId);
2612 
2613  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2614  it1 = m_enteringTriggerQueue.find (measId);
2615  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2616 
2617  if (!it1->second.empty ())
2618  {
2619  std::list<PendingTrigger_t>::iterator it2;
2620  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2621  {
2622  NS_ASSERT (it2->measId == measId);
2623  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2624  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2625  Simulator::Cancel (it2->timer);
2626  }
2627 
2628  it1->second.clear ();
2629  }
2630 }
2631 
2632 void
2633 LteUeRrc::CancelEnteringTrigger (uint8_t measId, uint16_t cellId)
2634 {
2635  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2636 
2637  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2638  it1 = m_enteringTriggerQueue.find (measId);
2639  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2640 
2641  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2642  while (it2 != it1->second.end ())
2643  {
2644  NS_ASSERT (it2->measId == measId);
2645 
2646  ConcernedCells_t::iterator it3;
2647  for (it3 = it2->concernedCells.begin ();
2648  it3 != it2->concernedCells.end (); ++it3)
2649  {
2650  if (*it3 == cellId)
2651  {
2652  it3 = it2->concernedCells.erase (it3);
2653  }
2654  }
2655 
2656  if (it2->concernedCells.empty ())
2657  {
2658  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2659  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2660  Simulator::Cancel (it2->timer);
2661  it2 = it1->second.erase (it2);
2662  }
2663  else
2664  {
2665  it2++;
2666  }
2667  }
2668 }
2669 
2670 void
2672 {
2673  NS_LOG_FUNCTION (this << (uint16_t) measId);
2674 
2675  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2676  it1 = m_leavingTriggerQueue.find (measId);
2677  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2678 
2679  if (!it1->second.empty ())
2680  {
2681  std::list<PendingTrigger_t>::iterator it2;
2682  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2683  {
2684  NS_ASSERT (it2->measId == measId);
2685  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2686  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2687  Simulator::Cancel (it2->timer);
2688  }
2689 
2690  it1->second.clear ();
2691  }
2692 }
2693 
2694 void
2695 LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
2696 {
2697  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2698 
2699  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2700  it1 = m_leavingTriggerQueue.find (measId);
2701  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2702 
2703  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2704  while (it2 != it1->second.end ())
2705  {
2706  NS_ASSERT (it2->measId == measId);
2707 
2708  ConcernedCells_t::iterator it3;
2709  for (it3 = it2->concernedCells.begin ();
2710  it3 != it2->concernedCells.end (); ++it3)
2711  {
2712  if (*it3 == cellId)
2713  {
2714  it3 = it2->concernedCells.erase (it3);
2715  }
2716  }
2717 
2718  if (it2->concernedCells.empty ())
2719  {
2720  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2721  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2722  Simulator::Cancel (it2->timer);
2723  it2 = it1->second.erase (it2);
2724  }
2725  else
2726  {
2727  it2++;
2728  }
2729  }
2730 }
2731 
2732 void
2733 LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
2734 {
2735  NS_LOG_FUNCTION (this << (uint16_t) measId);
2736  NS_ASSERT (!enteringCells.empty ());
2737 
2738  std::map<uint8_t, VarMeasReport>::iterator
2739  measReportIt = m_varMeasReportList.find (measId);
2740 
2741  if (measReportIt == m_varMeasReportList.end ())
2742  {
2743  VarMeasReport r;
2744  r.measId = measId;
2745  std::pair<uint8_t, VarMeasReport> val (measId, r);
2746  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
2747  ret = m_varMeasReportList.insert (val);
2748  NS_ASSERT_MSG (ret.second == true, "element already existed");
2749  measReportIt = ret.first;
2750  }
2751 
2752  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2753 
2754  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2755  it != enteringCells.end ();
2756  ++it)
2757  {
2758  measReportIt->second.cellsTriggeredList.insert (*it);
2759  }
2760 
2761  NS_ASSERT (!measReportIt->second.cellsTriggeredList.empty ());
2762  measReportIt->second.numberOfReportsSent = 0;
2763  measReportIt->second.periodicReportTimer
2766  this, measId);
2767 
2768  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2769  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2770  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2771  if (!enteringTriggerIt->second.empty ())
2772  {
2773  /*
2774  * Assumptions at this point:
2775  * - the call to this function was delayed by time-to-trigger;
2776  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2777  * - the first element in the list is associated with this function call.
2778  */
2779  enteringTriggerIt->second.pop_front ();
2780 
2781  if (!enteringTriggerIt->second.empty ())
2782  {
2783  /*
2784  * To prevent the same set of cells triggering again in the future,
2785  * we clean up the time-to-trigger queue. This case might occur when
2786  * time-to-trigger > 200 ms.
2787  */
2788  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2789  it != enteringCells.end (); ++it)
2790  {
2791  CancelEnteringTrigger (measId, *it);
2792  }
2793  }
2794 
2795  } // end of if (!enteringTriggerIt->second.empty ())
2796 
2797 } // end of LteUeRrc::VarMeasReportListAdd
2798 
2799 void
2801  bool reportOnLeave)
2802 {
2803  NS_LOG_FUNCTION (this << (uint16_t) measId);
2804  NS_ASSERT (!leavingCells.empty ());
2805 
2806  std::map<uint8_t, VarMeasReport>::iterator
2807  measReportIt = m_varMeasReportList.find (measId);
2808  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2809 
2810  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2811  it != leavingCells.end ();
2812  ++it)
2813  {
2814  measReportIt->second.cellsTriggeredList.erase (*it);
2815  }
2816 
2817  if (reportOnLeave)
2818  {
2819  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2820  SendMeasurementReport (measId);
2821  }
2822 
2823  if (measReportIt->second.cellsTriggeredList.empty ())
2824  {
2825  measReportIt->second.periodicReportTimer.Cancel ();
2826  m_varMeasReportList.erase (measReportIt);
2827  }
2828 
2829  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2830  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2831  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2832  if (!leavingTriggerIt->second.empty ())
2833  {
2834  /*
2835  * Assumptions at this point:
2836  * - the call to this function was delayed by time-to-trigger; and
2837  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2838  * - the first element in the list is associated with this function call.
2839  */
2840  leavingTriggerIt->second.pop_front ();
2841 
2842  if (!leavingTriggerIt->second.empty ())
2843  {
2844  /*
2845  * To prevent the same set of cells triggering again in the future,
2846  * we clean up the time-to-trigger queue. This case might occur when
2847  * time-to-trigger > 200 ms.
2848  */
2849  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2850  it != leavingCells.end (); ++it)
2851  {
2852  CancelLeavingTrigger (measId, *it);
2853  }
2854  }
2855 
2856  } // end of if (!leavingTriggerIt->second.empty ())
2857 
2858 } // end of LteUeRrc::VarMeasReportListErase
2859 
2860 void
2862 {
2863  NS_LOG_FUNCTION (this << (uint16_t) measId);
2864 
2865  // remove the measurement reporting entry for this measId from the VarMeasReportList
2866  std::map<uint8_t, VarMeasReport>::iterator
2867  measReportIt = m_varMeasReportList.find (measId);
2868  if (measReportIt != m_varMeasReportList.end ())
2869  {
2870  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint16_t) measId);
2871  measReportIt->second.periodicReportTimer.Cancel ();
2872  m_varMeasReportList.erase (measReportIt);
2873  }
2874 
2875  CancelEnteringTrigger (measId);
2876  CancelLeavingTrigger (measId);
2877 }
2878 
2879 void
2881 {
2882  NS_LOG_FUNCTION (this << (uint16_t) measId);
2883  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2884 
2885  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
2886  measIdIt = m_varMeasConfig.measIdList.find (measId);
2887  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
2888 
2889  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
2890  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
2891  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
2892  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2893 
2894  LteRrcSap::MeasurementReport measurementReport;
2895  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2896  measResults.measId = measId;
2897 
2898  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
2899  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
2900  measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
2901  measResults.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
2902  NS_LOG_INFO (this << " reporting serving cell "
2903  "RSRP " << (uint32_t) measResults.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
2904  "RSRQ " << (uint32_t) measResults.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
2905  measResults.haveMeasResultNeighCells = false;
2906  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
2907  if (measReportIt == m_varMeasReportList.end ())
2908  {
2909  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
2910  }
2911  else
2912  {
2913  if (!(measReportIt->second.cellsTriggeredList.empty ()))
2914  {
2915  std::multimap<double, uint16_t> sortedNeighCells;
2916  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
2917  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
2918  ++cellsTriggeredIt)
2919  {
2920  uint16_t cellId = *cellsTriggeredIt;
2921  if (cellId != m_cellId)
2922  {
2923  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2924  double triggerValue;
2925  switch (reportConfigEutra.triggerQuantity)
2926  {
2928  triggerValue = neighborMeasIt->second.rsrp;
2929  break;
2931  triggerValue = neighborMeasIt->second.rsrq;
2932  break;
2933  default:
2934  NS_FATAL_ERROR ("unsupported triggerQuantity");
2935  break;
2936  }
2937  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
2938  }
2939  }
2940 
2941  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
2942  uint32_t count;
2943  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
2944  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
2945  ++sortedNeighCellsIt, ++count)
2946  {
2947  uint16_t cellId = sortedNeighCellsIt->second;
2948  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2949  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
2950  LteRrcSap::MeasResultEutra measResultEutra;
2951  measResultEutra.physCellId = cellId;
2952  measResultEutra.haveCgiInfo = false;
2953  measResultEutra.haveRsrpResult = true;
2954  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
2955  measResultEutra.haveRsrqResult = true;
2956  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
2957  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
2958  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
2959  << " (" << neighborMeasIt->second.rsrp << " dBm)"
2960  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
2961  << " (" << neighborMeasIt->second.rsrq << " dB)");
2962  measResults.measResultListEutra.push_back (measResultEutra);
2963  measResults.haveMeasResultNeighCells = true;
2964  }
2965  }
2966  else
2967  {
2968  NS_LOG_WARN (this << " cellsTriggeredList is empty");
2969  }
2970 
2971  measResults.haveScellsMeas = false;
2972  std::map<uint16_t, MeasValues>::iterator sCellsMeasIt = m_storedScellMeasValues.begin ();
2973  if (sCellsMeasIt != m_storedScellMeasValues.end ())
2974  {
2975  measResults.haveScellsMeas = true;
2978 
2979 
2980  for ( sCellsMeasIt = m_storedScellMeasValues.begin ();
2981  sCellsMeasIt != m_storedScellMeasValues.end (); ++sCellsMeasIt)
2982  {
2983  LteRrcSap::MeasResultScell measResultScell;
2984  measResultScell.servFreqId = sCellsMeasIt->first;
2985  measResultScell.haveRsrpResult = true;
2986  measResultScell.haveRsrqResult = true;
2987  measResultScell.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (sCellsMeasIt->second.rsrp);
2988  measResultScell.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (sCellsMeasIt->second.rsrq);
2989  measResults.measScellResultList.measResultScell.push_back (measResultScell);
2990  }
2991  }
2992 
2993  /*
2994  * The current LteRrcSap implementation is broken in that it does not
2995  * allow for infinite values of reportAmount, which is probably the most
2996  * reasonable setting. So we just always assume infinite reportAmount.
2997  */
2998  measReportIt->second.numberOfReportsSent++;
2999  measReportIt->second.periodicReportTimer.Cancel ();
3000 
3001  Time reportInterval;
3002  switch (reportConfigEutra.reportInterval)
3003  {
3005  reportInterval = MilliSeconds (120);
3006  break;
3008  reportInterval = MilliSeconds (240);
3009  break;
3011  reportInterval = MilliSeconds (480);
3012  break;
3014  reportInterval = MilliSeconds (640);
3015  break;
3017  reportInterval = MilliSeconds (1024);
3018  break;
3020  reportInterval = MilliSeconds (2048);
3021  break;
3023  reportInterval = MilliSeconds (5120);
3024  break;
3026  reportInterval = MilliSeconds (10240);
3027  break;
3029  reportInterval = Seconds (60);
3030  break;
3032  reportInterval = Seconds (360);
3033  break;
3035  reportInterval = Seconds (720);
3036  break;
3038  reportInterval = Seconds (1800);
3039  break;
3041  reportInterval = Seconds (3600);
3042  break;
3043  default:
3044  NS_FATAL_ERROR ("Unsupported reportInterval " << (uint16_t) reportConfigEutra.reportInterval);
3045  break;
3046  }
3047 
3048  // schedule the next measurement reporting
3049  measReportIt->second.periodicReportTimer
3050  = Simulator::Schedule (reportInterval,
3052  this, measId);
3053 
3054  // send the measurement report to eNodeB
3055  m_rrcSapUser->SendMeasurementReport (measurementReport);
3056  }
3057 }
3058 
3059 void
3061 {
3062  NS_LOG_FUNCTION (this << m_imsi);
3065  m_connectionPending = false; // reset the flag
3067  m_cmacSapProvider.at (0)->StartContentionBasedRandomAccessProcedure ();
3068 }
3069 
3070 void
3072 {
3073  NS_LOG_FUNCTION (this << m_imsi);
3074  m_leaveConnectedMode = true;
3076  m_storedMeasValues.clear ();
3078 
3079  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
3080  for (measIdIt = m_varMeasConfig.measIdList.begin ();
3081  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
3082  {
3083  VarMeasReportListClear (measIdIt->second.measId);
3084  }
3085  m_varMeasConfig.measIdList.clear ();
3086 
3088 
3089  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3090  {
3091  m_cmacSapProvider.at (i)->Reset (); // reset the MAC
3092  }
3093 
3094  m_drbMap.clear ();
3095  m_bid2DrbidMap.clear ();
3096  m_srb1 = nullptr;
3097  m_hasReceivedMib = false;
3098  m_hasReceivedSib1 = false;
3099  m_hasReceivedSib2 = false;
3100 
3101  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3102  {
3103  m_cphySapProvider.at (i)->ResetPhyAfterRlf (); //reset the PHY
3104  }
3107  //Save the cell id UE was attached to
3109  m_cellId = 0;
3110  m_rnti = 0;
3111  m_srb0->m_rlc->SetRnti (m_rnti);
3112 }
3113 
3114 void
3116 {
3117  NS_LOG_FUNCTION (this << m_imsi);
3120  {
3123  //Assumption: The eNB connection request timer would expire
3124  //before the expiration of T300 at UE. Upon which, the eNB deletes
3125  //the UE context. Therefore, here we don't need to send the UE context
3126  //deletion request to the eNB.
3128  m_connEstFailCount = 0;
3129  }
3130  else
3131  {
3132  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
3133  {
3134  m_cmacSapProvider.at(i)->Reset (); // reset the MAC
3135  }
3136  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
3139  //Following call to UE NAS will force the UE to immediately
3140  //perform the random access to the same cell again.
3141  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
3142  }
3143 }
3144 
3145 void
3147 {
3148  NS_LOG_FUNCTION (this);
3149  m_srb1Old = 0;
3150 }
3151 
3152 uint8_t
3153 LteUeRrc::Bid2Drbid (uint8_t bid)
3154 {
3155  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
3156  //NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
3157  if (it == m_bid2DrbidMap.end ())
3158  {
3159  return 0;
3160  }
3161  else
3162  {
3163  return it->second;
3164  }
3165 }
3166 
3167 void
3169 {
3170  NS_LOG_FUNCTION (this << ToString (newState));
3171  State oldState = m_state;
3172  m_state = newState;
3173  NS_LOG_INFO (this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc "
3174  << ToString (oldState) << " --> " << ToString (newState));
3175  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
3176 
3177  switch (newState)
3178  {
3179  case IDLE_START:
3181  {
3182  NS_LOG_INFO ("Starting initial cell selection after RLF");
3183  }
3184  else
3185  {
3186  NS_FATAL_ERROR ("cannot switch to an initial state");
3187  }
3188  break;
3189 
3190  case IDLE_CELL_SEARCH:
3191  case IDLE_WAIT_MIB_SIB1:
3192  case IDLE_WAIT_MIB:
3193  case IDLE_WAIT_SIB1:
3194  break;
3195 
3196  case IDLE_CAMPED_NORMALLY:
3197  if (m_connectionPending)
3198  {
3200  }
3201  break;
3202 
3203  case IDLE_WAIT_SIB2:
3204  if (m_hasReceivedSib2)
3205  {
3207  StartConnection ();
3208  }
3209  break;
3210 
3211  case IDLE_RANDOM_ACCESS:
3212  case IDLE_CONNECTING:
3213  case CONNECTED_NORMALLY:
3214  case CONNECTED_HANDOVER:
3215  case CONNECTED_PHY_PROBLEM:
3217  break;
3218 
3219  default:
3220  break;
3221  }
3222 }
3223 
3224 
3225 void
3226 LteUeRrc::SaveScellUeMeasurements (uint16_t sCellId, double rsrp, double rsrq,
3227  bool useLayer3Filtering, uint16_t componentCarrierId)
3228 {
3229  NS_LOG_FUNCTION (this << sCellId << componentCarrierId << rsrp << rsrq << useLayer3Filtering);
3230  if (sCellId == m_cellId)
3231  {
3232 
3233  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedScellMeasValues.find (componentCarrierId);
3234 
3235  if (storedMeasIt != m_storedScellMeasValues.end ())
3236  {
3237  if (useLayer3Filtering)
3238  {
3239  // F_n = (1-a) F_{n-1} + a M_n
3240  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
3241  + m_varMeasConfig.aRsrp * rsrp;
3242 
3243  if (std::isnan (storedMeasIt->second.rsrq))
3244  {
3245  // the previous RSRQ measurements provided UE PHY are invalid
3246  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
3247  }
3248  else
3249  {
3250  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
3251  + m_varMeasConfig.aRsrq * rsrq;
3252  }
3253  }
3254  else
3255  {
3256  storedMeasIt->second.rsrp = rsrp;
3257  storedMeasIt->second.rsrq = rsrq;
3258  }
3259  }
3260  else
3261  {
3262  // first value is always unfiltered
3263  MeasValues v;
3264  v.rsrp = rsrp;
3265  v.rsrq = rsrq;
3266  std::pair<uint16_t, MeasValues> val (componentCarrierId, v);
3267  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
3268  ret = m_storedScellMeasValues.insert (val);
3269  NS_ASSERT_MSG (ret.second == true, "element already existed");
3270  storedMeasIt = ret.first;
3271  }
3272 
3273  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
3274  << ", measured cell " << sCellId
3275  << ", carrier component Id " << componentCarrierId
3276  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
3277  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
3278  storedMeasIt->second.timestamp = Simulator::Now ();
3279  }
3280  else
3281  {
3282  NS_LOG_DEBUG (this << " IMSI " << m_imsi << "measurement on SCC from not serving cell ");
3283  }
3284 
3285 } // end of void SaveUeMeasurements
3286 
3287 void
3289 {
3290  NS_LOG_FUNCTION (this << m_imsi << m_rnti);
3295 }
3296 
3297 void
3299 {
3300  NS_LOG_FUNCTION (this << m_imsi);
3302  NS_LOG_INFO ("noOfSyncIndications " << (uint16_t) m_noOfSyncIndications);
3305  {
3308  m_cphySapProvider.at (0)->ResetRlfParams ();
3309  }
3310 }
3311 
3312 void
3314 {
3315  NS_LOG_FUNCTION (this << m_imsi);
3317  NS_LOG_INFO (this << " Total Number of Sync indications from PHY "
3318  << (uint16_t) m_noOfSyncIndications << "N310 value : " << (uint16_t) m_n310);
3321  {
3324  {
3325  NS_LOG_INFO ("t310 started");
3326  }
3327  m_cphySapProvider.at (0)->StartInSnycDetection ();
3329  }
3330 }
3331 
3332 void
3334 {
3335  NS_LOG_FUNCTION (this << m_imsi);
3336 
3337  NS_LOG_DEBUG ("The number of sync indication received by RRC from PHY: " << (uint16_t) m_noOfSyncIndications);
3339 }
3340 
3341 
3342 
3343 } // namespace ns3
3344 
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:202
MemberLteUeCcmRrcSapUser class.
RrcConnectionRequest structure.
Definition: lte-rrc-sap.h:692
uint64_t GetImsi(void) const
Definition: lte-ue-rrc.cc:457
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:1211
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:102
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:2609
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:3313
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
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
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:1864
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:1197
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:1588
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:355
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:1327
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:204
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
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:2671
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:280
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:162
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:290
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:1168
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.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
static double RsrqRange2Db(uint8_t range)
converts an RSRQ range to dB as per 3GPP TS 36.133 section 9.1.7 RSRQ Measurement Report Mapping ...
Definition: lte-common.cc: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:3153
#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:3333
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:220
std::vector< LteUeCphySapProvider * > m_cphySapProvider
UE CPhy SAP provider.
Definition: lte-ue-rrc.h:762
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
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
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:1124
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:3146
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:1144
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:3115
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:1264
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
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:3168
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
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
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:3226
Reference Signal Received Power.
Definition: lte-rrc-sap.h:406
void RadioLinkFailureDetected()
Radio link failure detected function.
Definition: lte-ue-rrc.cc:3288
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
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1578
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:1125
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:193
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:1190
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:2800
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
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
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
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:3060
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:1810
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
if(desigRtr==addrLocal)
#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:264
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:1383
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:272
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
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:65
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:1345
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
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:256
AntennaInfoDedicated antennaInfo
antenna info
Definition: lte-rrc-sap.h:221
void DoNotifyInSync()
Do notify in sync function.
Definition: lte-ue-rrc.cc:3298
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:2880
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:1220
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:2733
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:915
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:2861
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:3071
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