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