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