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