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