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
905 default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
906 // do nothing
907 break;
908 }
909}
910
911void
913{
914 NS_LOG_FUNCTION(this);
915
916 // layer 3 filtering does not apply in IDLE mode
917 bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
918 bool triggering = true;
919 for (auto newMeasIt = params.m_ueMeasurementsList.begin();
920 newMeasIt != params.m_ueMeasurementsList.end();
921 ++newMeasIt)
922 {
923 if (params.m_componentCarrierId != 0)
924 {
925 triggering = false; // report is triggered only when an event is on the primary carrier
926 // in this case the measurement received is related to secondary carriers
927 }
928 SaveUeMeasurements(newMeasIt->m_cellId,
929 newMeasIt->m_rsrp,
930 newMeasIt->m_rsrq,
931 useLayer3Filtering,
932 params.m_componentCarrierId);
933 }
934
936 {
937 // start decoding BCH
939 }
940 else
941 {
942 if (triggering)
943 {
944 for (auto measIdIt = m_varMeasConfig.measIdList.begin();
945 measIdIt != m_varMeasConfig.measIdList.end();
946 ++measIdIt)
947 {
948 MeasurementReportTriggering(measIdIt->first);
949 }
950 }
951 }
952
953} // end of LteUeRrc::DoReportUeMeasurements
954
955// RRC SAP methods
956
957void
959{
960 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
961 m_srb0->m_rlc->SetLteRlcSapUser(params.srb0SapUser);
962 if (m_srb1)
963 {
964 m_srb1->m_pdcp->SetLtePdcpSapUser(params.srb1SapUser);
965 }
966}
967
968void
970{
971 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
972
973 if (msg.haveSib2)
974 {
975 switch (m_state)
976 {
978 case IDLE_WAIT_SIB2:
980 case IDLE_CONNECTING:
985 m_hasReceivedSib2 = true;
990 rc.numberOfRaPreambles = msg.sib2.radioResourceConfigCommon.rachConfigCommon
992 rc.preambleTransMax = msg.sib2.radioResourceConfigCommon.rachConfigCommon
994 rc.raResponseWindowSize = msg.sib2.radioResourceConfigCommon.rachConfigCommon
996 rc.connEstFailCount =
998 m_connEstFailCountLimit = rc.connEstFailCount;
1000 "SIB2 msg contains wrong value " << m_connEstFailCountLimit
1001 << "of connEstFailCount");
1002 m_cmacSapProvider.at(0)->ConfigureRach(rc);
1003 m_cphySapProvider.at(0)->ConfigureUplink(m_ulEarfcn, m_ulBandwidth);
1004 m_cphySapProvider.at(0)->ConfigureReferenceSignalPower(
1006 if (m_state == IDLE_WAIT_SIB2)
1007 {
1010 }
1011 break;
1012
1013 default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
1014 // do nothing
1015 break;
1016 }
1017 }
1018}
1019
1020void
1022{
1023 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1024 switch (m_state)
1025 {
1026 case IDLE_CONNECTING: {
1031 m_leaveConnectedMode = false;
1036 m_cmacSapProvider.at(0)->NotifyConnectionSuccessful();
1039 "Sync indications should be zero "
1040 "when a new RRC connection is established. Current value = "
1041 << (uint16_t)m_noOfSyncIndications);
1042 }
1043 break;
1044
1045 default:
1046 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1047 break;
1048 }
1049}
1050
1051void
1053{
1054 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1055 NS_LOG_INFO("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:"
1057 switch (m_state)
1058 {
1059 case CONNECTED_NORMALLY:
1061 {
1062 NS_LOG_INFO("haveMobilityControlInfo == true");
1065 {
1067 }
1070 // We should reset the MACs and PHYs for all the component carriers
1071 for (auto cmacSapProvider : m_cmacSapProvider)
1072 {
1073 cmacSapProvider->Reset();
1074 }
1075 for (auto cphySapProvider : m_cphySapProvider)
1076 {
1077 cphySapProvider->Reset();
1078 }
1084 m_cphySapProvider.at(0)->SynchronizeWithEnb(m_cellId, mci.carrierFreq.dlCarrierFreq);
1085 m_cphySapProvider.at(0)->SetDlBandwidth(mci.carrierBandwidth.dlBandwidth);
1086 m_cphySapProvider.at(0)->ConfigureUplink(mci.carrierFreq.ulCarrierFreq,
1089 m_srb0->m_rlc->SetRnti(m_rnti);
1092 "handover is only supported with non-contention-based random access procedure");
1093 m_cmacSapProvider.at(0)->StartNonContentionBasedRandomAccessProcedure(
1094 m_rnti,
1097 m_cphySapProvider.at(0)->SetRnti(m_rnti);
1100
1101 // we re-establish SRB1 by creating a new entity
1102 // note that we can't dispose the old entity now, because
1103 // it's in the current stack, so we would corrupt the stack
1104 // if we did so. Hence we schedule it for later disposal
1105 m_srb1Old = m_srb1;
1107 m_srb1 =
1108 nullptr; // new instance will be be created within ApplyRadioResourceConfigDedicated
1109
1110 m_drbMap.clear(); // dispose all DRBs
1113 {
1114 NS_LOG_DEBUG(this << "RNTI " << m_rnti
1115 << " Handover. Configuring secondary carriers");
1117 }
1118
1119 if (msg.haveMeasConfig)
1120 {
1122 }
1123 // RRC connection reconfiguration completed will be sent
1124 // after handover is complete
1125 }
1126 else
1127 {
1128 NS_LOG_INFO("haveMobilityControlInfo == false");
1130 {
1132 NS_LOG_DEBUG(this << "RNTI " << m_rnti << " Configured for CA");
1133 }
1135 {
1137 }
1138 if (msg.haveMeasConfig)
1139 {
1141 }
1146 }
1147 break;
1148
1149 default:
1150 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1151 break;
1152 }
1153}
1154
1155void
1157{
1158 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1159 switch (m_state)
1160 {
1162 /**
1163 * \todo After receiving RRC Connection Re-establishment, stop timer
1164 * T301, fire a new trace source, reply with RRC Connection
1165 * Re-establishment Complete, and finally switch to
1166 * CONNECTED_NORMALLY state. See Section 5.3.7.5 of 3GPP TS
1167 * 36.331.
1168 */
1169 }
1170 break;
1171
1172 default:
1173 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1174 break;
1175 }
1176}
1177
1178void
1181{
1182 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1183 switch (m_state)
1184 {
1186 /**
1187 * \todo After receiving RRC Connection Re-establishment Reject, stop
1188 * timer T301. See Section 5.3.7.8 of 3GPP TS 36.331.
1189 */
1190 m_asSapUser->NotifyConnectionReleased(); // Inform upper layers
1191 }
1192 break;
1193
1194 default:
1195 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1196 break;
1197 }
1198}
1199
1200void
1202{
1203 NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1204 /// \todo Currently not implemented, see Section 5.3.8 of 3GPP TS 36.331.
1205
1207 // release resources at UE
1209 {
1210 m_leaveConnectedMode = true;
1214 }
1215}
1216
1217void
1219{
1220 NS_LOG_FUNCTION(this);
1222 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1223 {
1224 m_cmacSapProvider.at(i)->Reset(); // reset the MAC
1225 }
1226 m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1228 m_asSapUser->NotifyConnectionFailed(); // inform upper layer
1229}
1230
1231void
1232LteUeRrc::DoSetNumberOfComponentCarriers(uint16_t noOfComponentCarriers)
1233{
1234 NS_LOG_FUNCTION(this);
1235 m_numberOfComponentCarriers = noOfComponentCarriers;
1236}
1237
1238void
1240{
1241 NS_LOG_FUNCTION(this);
1243
1244 uint16_t maxRsrpCellId = 0;
1245 double maxRsrp = -std::numeric_limits<double>::infinity();
1246 double minRsrp = -140.0; // Minimum RSRP in dBm a UE can report
1247
1248 for (auto it = m_storedMeasValues.begin(); it != m_storedMeasValues.end(); it++)
1249 {
1250 /*
1251 * This block attempts to find a cell with strongest RSRP and has not
1252 * yet been identified as "acceptable cell".
1253 */
1254 if (maxRsrp < it->second.rsrp && it->second.rsrp > minRsrp)
1255 {
1256 auto itCell = m_acceptableCell.find(it->first);
1257 if (itCell == m_acceptableCell.end())
1258 {
1259 maxRsrpCellId = it->first;
1260 maxRsrp = it->second.rsrp;
1261 }
1262 }
1263 }
1264
1265 if (maxRsrpCellId == 0)
1266 {
1267 NS_LOG_WARN(this << " Cell search is unable to detect surrounding cell to attach to");
1268 }
1269 else
1270 {
1271 NS_LOG_LOGIC(this << " cell " << maxRsrpCellId
1272 << " is the strongest untried surrounding cell");
1273 m_cphySapProvider.at(0)->SynchronizeWithEnb(maxRsrpCellId, m_dlEarfcn);
1275 }
1276
1277} // end of void LteUeRrc::SynchronizeToStrongestCell ()
1278
1279void
1281{
1282 NS_LOG_FUNCTION(this);
1287
1288 // Cell selection criteria evaluation
1289
1290 bool isSuitableCell = false;
1291 bool isAcceptableCell = false;
1292 auto storedMeasIt = m_storedMeasValues.find(cellId);
1293 double qRxLevMeas = storedMeasIt->second.rsrp;
1294 double qRxLevMin =
1296 NS_LOG_LOGIC(this << " cell selection to cellId=" << cellId << " qrxlevmeas=" << qRxLevMeas
1297 << " dBm"
1298 << " qrxlevmin=" << qRxLevMin << " dBm");
1299
1300 if (qRxLevMeas - qRxLevMin > 0)
1301 {
1302 isAcceptableCell = true;
1303
1305 bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1306
1307 isSuitableCell = (!cellCsgIndication || cellCsgId == m_csgWhiteList);
1308
1309 NS_LOG_LOGIC(this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/" << cellCsgId
1310 << "/" << cellCsgIndication);
1311 }
1312
1313 // Cell selection decision
1314
1315 if (isSuitableCell)
1316 {
1317 m_cellId = cellId;
1318 m_cphySapProvider.at(0)->SynchronizeWithEnb(cellId, m_dlEarfcn);
1319 m_cphySapProvider.at(0)->SetDlBandwidth(m_dlBandwidth);
1321 // Once the UE is connected, m_connectionPending is
1322 // set to false. So, when RLF occurs and UE performs
1323 // cell selection upon leaving RRC_CONNECTED state,
1324 // the following call to DoConnect will make the
1325 // m_connectionPending to be true again. Thus,
1326 // upon calling SwitchToState (IDLE_CAMPED_NORMALLY)
1327 // UE state is instantly change to IDLE_WAIT_SIB2.
1328 // This will make the UE to read the SIB2 message
1329 // and start random access.
1331 {
1332 NS_LOG_DEBUG("Calling DoConnect in state = " << ToString(m_state));
1333 DoConnect();
1334 }
1336 }
1337 else
1338 {
1339 // ignore the MIB and SIB1 received from this cell
1340 m_hasReceivedMib = false;
1341 m_hasReceivedSib1 = false;
1342
1344
1345 if (isAcceptableCell)
1346 {
1347 /*
1348 * The cells inserted into this list will not be considered for
1349 * subsequent cell search attempt.
1350 */
1351 m_acceptableCell.insert(cellId);
1352 }
1353
1355 SynchronizeToStrongestCell(); // retry to a different cell
1356 }
1357
1358} // end of void LteUeRrc::EvaluateCellForSelection ()
1359
1360void
1363{
1364 NS_LOG_FUNCTION(this);
1365
1367
1368 for (uint32_t sCellIndex : nonCec.sCellToReleaseList)
1369 {
1370 m_cphySapProvider.at(sCellIndex)->Reset();
1371 m_cmacSapProvider.at(sCellIndex)->Reset();
1372 }
1373
1374 for (auto& scell : nonCec.sCellToAddModList)
1375 {
1376 uint8_t ccId = scell.sCellIndex;
1377
1378 uint16_t physCellId = scell.cellIdentification.physCellId;
1379 uint16_t ulBand =
1380 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth;
1381 uint32_t ulEarfcn =
1382 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq;
1383 uint16_t dlBand = scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth;
1384 uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1385 uint8_t txMode = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1386 .antennaInfo.transmissionMode;
1387 uint16_t srsIndex = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1388 .soundingRsUlConfigDedicated.srsConfigIndex;
1389
1390 m_cphySapProvider.at(ccId)->SynchronizeWithEnb(physCellId, dlEarfcn);
1391 m_cphySapProvider.at(ccId)->SetDlBandwidth(dlBand);
1392 m_cphySapProvider.at(ccId)->ConfigureUplink(ulEarfcn, ulBand);
1393 m_cphySapProvider.at(ccId)->ConfigureReferenceSignalPower(
1394 scell.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon
1395 .referenceSignalPower);
1396 m_cphySapProvider.at(ccId)->SetTransmissionMode(txMode);
1397 m_cphySapProvider.at(ccId)->SetRnti(m_rnti);
1398 m_cmacSapProvider.at(ccId)->SetRnti(m_rnti);
1399 // update PdschConfigDedicated (i.e. P_A value)
1400 LteRrcSap::PdschConfigDedicated pdschConfigDedicated =
1401 scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1402 .pdschConfigDedicated;
1403 double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double(pdschConfigDedicated);
1404 m_cphySapProvider.at(ccId)->SetPa(paDouble);
1405 m_cphySapProvider.at(ccId)->SetSrsConfigurationIndex(srsIndex);
1406 }
1407
1409}
1410
1411void
1413{
1414 NS_LOG_FUNCTION(this);
1416
1418 {
1419 m_cphySapProvider.at(0)->SetTransmissionMode(pcd.antennaInfo.transmissionMode);
1420 }
1422 {
1423 m_cphySapProvider.at(0)->SetSrsConfigurationIndex(
1425 }
1426
1428 {
1429 // update PdschConfigDedicated (i.e. P_A value)
1432 m_cphySapProvider.at(0)->SetPa(paDouble);
1433 }
1434
1435 auto stamIt = rrcd.srbToAddModList.begin();
1436 if (stamIt != rrcd.srbToAddModList.end())
1437 {
1438 if (!m_srb1)
1439 {
1440 // SRB1 not setup yet
1442 "unexpected state " << ToString(m_state));
1443 NS_ASSERT_MSG(stamIt->srbIdentity == 1, "only SRB1 supported");
1444
1445 const uint8_t lcid = 1; // fixed LCID for SRB1
1446
1447 Ptr<LteRlc> rlc = CreateObject<LteRlcAm>();
1448 rlc->SetLteMacSapProvider(m_macSapProvider);
1449 rlc->SetRnti(m_rnti);
1450 rlc->SetLcId(lcid);
1451
1452 Ptr<LtePdcp> pdcp = CreateObject<LtePdcp>();
1453 pdcp->SetRnti(m_rnti);
1454 pdcp->SetLcId(lcid);
1455 pdcp->SetLtePdcpSapUser(m_drbPdcpSapUser);
1456 pdcp->SetLteRlcSapProvider(rlc->GetLteRlcSapProvider());
1457 rlc->SetLteRlcSapUser(pdcp->GetLteRlcSapUser());
1458
1459 m_srb1 = CreateObject<LteSignalingRadioBearerInfo>();
1460 m_srb1->m_rlc = rlc;
1461 m_srb1->m_pdcp = pdcp;
1462 m_srb1->m_srbIdentity = 1;
1464
1465 m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1466 m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps =
1467 stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1468 m_srb1->m_logicalChannelConfig.bucketSizeDurationMs =
1469 stamIt->logicalChannelConfig.bucketSizeDurationMs;
1470 m_srb1->m_logicalChannelConfig.logicalChannelGroup =
1471 stamIt->logicalChannelConfig.logicalChannelGroup;
1472
1474 lcConfig.priority = stamIt->logicalChannelConfig.priority;
1475 lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1476 lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1477 lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1478 LteMacSapUser* msu =
1479 m_ccmRrcSapProvider->ConfigureSignalBearer(lcid, lcConfig, rlc->GetLteMacSapUser());
1480 m_cmacSapProvider.at(0)->AddLc(lcid, lcConfig, msu);
1481 ++stamIt;
1482 NS_ASSERT_MSG(stamIt == rrcd.srbToAddModList.end(), "at most one SrbToAdd supported");
1483
1485 ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider();
1486 ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider();
1487 m_rrcSapUser->Setup(ueParams);
1488 }
1489 else
1490 {
1491 NS_LOG_INFO("request to modify SRB1 (skipping as currently not implemented)");
1492 // would need to modify m_srb1, and then propagate changes to the MAC
1493 }
1494 }
1495
1496 for (auto dtamIt = rrcd.drbToAddModList.begin(); dtamIt != rrcd.drbToAddModList.end(); ++dtamIt)
1497 {
1498 NS_LOG_INFO(this << " IMSI " << m_imsi << " adding/modifying DRBID "
1499 << (uint32_t)dtamIt->drbIdentity << " LC "
1500 << (uint32_t)dtamIt->logicalChannelIdentity);
1501 NS_ASSERT_MSG(dtamIt->logicalChannelIdentity > 2,
1502 "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1503
1504 auto drbMapIt = m_drbMap.find(dtamIt->drbIdentity);
1505 if (drbMapIt == m_drbMap.end())
1506 {
1507 NS_LOG_INFO("New Data Radio Bearer");
1508
1509 TypeId rlcTypeId;
1510 if (m_useRlcSm)
1511 {
1512 rlcTypeId = LteRlcSm::GetTypeId();
1513 }
1514 else
1515 {
1516 switch (dtamIt->rlcConfig.choice)
1517 {
1519 rlcTypeId = LteRlcAm::GetTypeId();
1520 break;
1521
1523 rlcTypeId = LteRlcUm::GetTypeId();
1524 break;
1525
1526 default:
1527 NS_FATAL_ERROR("unsupported RLC configuration");
1528 break;
1529 }
1530 }
1531
1532 ObjectFactory rlcObjectFactory;
1533 rlcObjectFactory.SetTypeId(rlcTypeId);
1534 Ptr<LteRlc> rlc = rlcObjectFactory.Create()->GetObject<LteRlc>();
1535 rlc->SetLteMacSapProvider(m_macSapProvider);
1536 rlc->SetRnti(m_rnti);
1537 rlc->SetLcId(dtamIt->logicalChannelIdentity);
1538
1539 Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo>();
1540 drbInfo->m_rlc = rlc;
1541 drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1542 drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1543 drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1544
1545 // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1546 // if we are using RLC/SM we don't care of anything above RLC
1547 if (rlcTypeId != LteRlcSm::GetTypeId())
1548 {
1549 Ptr<LtePdcp> pdcp = CreateObject<LtePdcp>();
1550 pdcp->SetRnti(m_rnti);
1551 pdcp->SetLcId(dtamIt->logicalChannelIdentity);
1552 pdcp->SetLtePdcpSapUser(m_drbPdcpSapUser);
1553 pdcp->SetLteRlcSapProvider(rlc->GetLteRlcSapProvider());
1554 rlc->SetLteRlcSapUser(pdcp->GetLteRlcSapUser());
1555 drbInfo->m_pdcp = pdcp;
1556 }
1557
1558 m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1559
1560 m_drbMap.insert(
1561 std::pair<uint8_t, Ptr<LteDataRadioBearerInfo>>(dtamIt->drbIdentity, drbInfo));
1562
1563 m_drbCreatedTrace(m_imsi, m_cellId, m_rnti, dtamIt->drbIdentity);
1564
1566 lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1567 lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1568 lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1569 lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1570
1571 NS_LOG_DEBUG(this << " UE RRC RNTI " << m_rnti << " Number Of Component Carriers "
1572 << m_numberOfComponentCarriers << " lcID "
1573 << (uint16_t)dtamIt->logicalChannelIdentity);
1574 // Call AddLc of UE component carrier manager
1575 std::vector<LteUeCcmRrcSapProvider::LcsConfig> lcOnCcMapping =
1576 m_ccmRrcSapProvider->AddLc(dtamIt->logicalChannelIdentity,
1577 lcConfig,
1578 rlc->GetLteMacSapUser());
1579
1580 NS_LOG_DEBUG("Size of lcOnCcMapping vector " << lcOnCcMapping.size());
1581 auto itLcOnCcMapping = lcOnCcMapping.begin();
1582 NS_ASSERT_MSG(itLcOnCcMapping != lcOnCcMapping.end(),
1583 "Component carrier manager failed to add LC for data radio bearer");
1584
1585 for (itLcOnCcMapping = lcOnCcMapping.begin(); itLcOnCcMapping != lcOnCcMapping.end();
1586 ++itLcOnCcMapping)
1587 {
1588 NS_LOG_DEBUG("RNTI " << m_rnti << " LCG id "
1589 << (uint16_t)itLcOnCcMapping->lcConfig.logicalChannelGroup
1590 << " ComponentCarrierId "
1591 << (uint16_t)itLcOnCcMapping->componentCarrierId);
1592 uint8_t index = itLcOnCcMapping->componentCarrierId;
1594 itLcOnCcMapping->lcConfig;
1595 LteMacSapUser* msu = itLcOnCcMapping->msu;
1596 m_cmacSapProvider.at(index)->AddLc(dtamIt->logicalChannelIdentity,
1597 lcConfigFromCcm,
1598 msu);
1599 }
1600
1601 rlc->Initialize();
1602 }
1603 else
1604 {
1605 NS_LOG_INFO("request to modify existing DRBID");
1606 Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1607 /// \todo currently not implemented. Would need to modify drbInfo, and then propagate
1608 /// changes to the MAC
1609 }
1610 }
1611
1612 for (auto dtdmIt = rrcd.drbToReleaseList.begin(); dtdmIt != rrcd.drbToReleaseList.end();
1613 ++dtdmIt)
1614 {
1615 uint8_t drbid = *dtdmIt;
1616 NS_LOG_INFO(this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t)drbid);
1617 auto it = m_drbMap.find(drbid);
1618 NS_ASSERT_MSG(it != m_drbMap.end(), "could not find bearer with given lcid");
1619 m_drbMap.erase(it);
1620 m_bid2DrbidMap.erase(drbid);
1621 // Remove LCID
1622 for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1623 {
1624 m_cmacSapProvider.at(i)->RemoveLc(drbid + 2);
1625 }
1626 }
1627}
1628
1629void
1631{
1632 NS_LOG_FUNCTION(this);
1633
1634 // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1635
1636 // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1637 for (auto it = mc.measObjectToRemoveList.begin(); it != mc.measObjectToRemoveList.end(); ++it)
1638 {
1639 uint8_t measObjectId = *it;
1640 NS_LOG_LOGIC(this << " deleting measObjectId " << (uint32_t)measObjectId);
1641 m_varMeasConfig.measObjectList.erase(measObjectId);
1642 auto measIdIt = m_varMeasConfig.measIdList.begin();
1643 while (measIdIt != m_varMeasConfig.measIdList.end())
1644 {
1645 if (measIdIt->second.measObjectId == measObjectId)
1646 {
1647 uint8_t measId = measIdIt->second.measId;
1648 NS_ASSERT(measId == measIdIt->first);
1649 NS_LOG_LOGIC(this << " deleting measId " << (uint32_t)measId
1650 << " because referring to measObjectId "
1651 << (uint32_t)measObjectId);
1652 // note: postfix operator preserves iterator validity
1653 m_varMeasConfig.measIdList.erase(measIdIt++);
1654 VarMeasReportListClear(measId);
1655 }
1656 else
1657 {
1658 ++measIdIt;
1659 }
1660 }
1661 }
1662
1663 // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1664 for (auto it = mc.measObjectToAddModList.begin(); it != mc.measObjectToAddModList.end(); ++it)
1665 {
1666 // simplifying assumptions
1667 NS_ASSERT_MSG(it->measObjectEutra.cellsToRemoveList.empty(),
1668 "cellsToRemoveList not supported");
1669 NS_ASSERT_MSG(it->measObjectEutra.cellsToAddModList.empty(),
1670 "cellsToAddModList not supported");
1671 NS_ASSERT_MSG(it->measObjectEutra.cellsToRemoveList.empty(),
1672 "blackCellsToRemoveList not supported");
1673 NS_ASSERT_MSG(it->measObjectEutra.blackCellsToAddModList.empty(),
1674 "blackCellsToAddModList not supported");
1675 NS_ASSERT_MSG(it->measObjectEutra.haveCellForWhichToReportCGI == false,
1676 "cellForWhichToReportCGI is not supported");
1677
1678 uint8_t measObjectId = it->measObjectId;
1679 auto measObjectIt = m_varMeasConfig.measObjectList.find(measObjectId);
1680 if (measObjectIt != m_varMeasConfig.measObjectList.end())
1681 {
1682 NS_LOG_LOGIC("measObjectId " << (uint32_t)measObjectId << " exists, updating entry");
1683 measObjectIt->second = *it;
1684 for (auto measIdIt = m_varMeasConfig.measIdList.begin();
1685 measIdIt != m_varMeasConfig.measIdList.end();
1686 ++measIdIt)
1687 {
1688 if (measIdIt->second.measObjectId == measObjectId)
1689 {
1690 uint8_t measId = measIdIt->second.measId;
1691 NS_LOG_LOGIC(this << " found measId " << (uint32_t)measId
1692 << " referring to measObjectId " << (uint32_t)measObjectId);
1693 VarMeasReportListClear(measId);
1694 }
1695 }
1696 }
1697 else
1698 {
1699 NS_LOG_LOGIC("measObjectId " << (uint32_t)measObjectId << " is new, adding entry");
1700 m_varMeasConfig.measObjectList[measObjectId] = *it;
1701 }
1702 }
1703
1704 // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1705 for (auto it = mc.reportConfigToRemoveList.begin(); it != mc.reportConfigToRemoveList.end();
1706 ++it)
1707 {
1708 uint8_t reportConfigId = *it;
1709 NS_LOG_LOGIC(this << " deleting reportConfigId " << (uint32_t)reportConfigId);
1710 m_varMeasConfig.reportConfigList.erase(reportConfigId);
1711 auto measIdIt = m_varMeasConfig.measIdList.begin();
1712 while (measIdIt != m_varMeasConfig.measIdList.end())
1713 {
1714 if (measIdIt->second.reportConfigId == reportConfigId)
1715 {
1716 uint8_t measId = measIdIt->second.measId;
1717 NS_ASSERT(measId == measIdIt->first);
1718 NS_LOG_LOGIC(this << " deleting measId " << (uint32_t)measId
1719 << " because referring to reportConfigId "
1720 << (uint32_t)reportConfigId);
1721 // note: postfix operator preserves iterator validity
1722 m_varMeasConfig.measIdList.erase(measIdIt++);
1723 VarMeasReportListClear(measId);
1724 }
1725 else
1726 {
1727 ++measIdIt;
1728 }
1729 }
1730 }
1731
1732 // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1733 for (auto it = mc.reportConfigToAddModList.begin(); it != mc.reportConfigToAddModList.end();
1734 ++it)
1735 {
1736 // simplifying assumptions
1737 NS_ASSERT_MSG(it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1738 "only trigger type EVENT is supported");
1739
1740 uint8_t reportConfigId = it->reportConfigId;
1741 auto reportConfigIt = m_varMeasConfig.reportConfigList.find(reportConfigId);
1742 if (reportConfigIt != m_varMeasConfig.reportConfigList.end())
1743 {
1744 NS_LOG_LOGIC("reportConfigId " << (uint32_t)reportConfigId
1745 << " exists, updating entry");
1746 m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1747 for (auto measIdIt = m_varMeasConfig.measIdList.begin();
1748 measIdIt != m_varMeasConfig.measIdList.end();
1749 ++measIdIt)
1750 {
1751 if (measIdIt->second.reportConfigId == reportConfigId)
1752 {
1753 uint8_t measId = measIdIt->second.measId;
1754 NS_LOG_LOGIC(this << " found measId " << (uint32_t)measId
1755 << " referring to reportConfigId "
1756 << (uint32_t)reportConfigId);
1757 VarMeasReportListClear(measId);
1758 }
1759 }
1760 }
1761 else
1762 {
1763 NS_LOG_LOGIC("reportConfigId " << (uint32_t)reportConfigId << " is new, adding entry");
1764 m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1765 }
1766 }
1767
1768 // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1769 if (mc.haveQuantityConfig)
1770 {
1771 NS_LOG_LOGIC(this << " setting quantityConfig");
1773 // Convey the filter coefficient to PHY layer so it can configure the power control
1774 // parameter
1775 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1776 {
1777 m_cphySapProvider.at(i)->SetRsrpFilterCoefficient(
1779 }
1780 // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331
1781 // section 5.5.3.2
1784 NS_LOG_LOGIC(this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp
1785 << ", aRsrq=" << m_varMeasConfig.aRsrq);
1786
1787 for (auto measIdIt = m_varMeasConfig.measIdList.begin();
1788 measIdIt != m_varMeasConfig.measIdList.end();
1789 ++measIdIt)
1790 {
1791 VarMeasReportListClear(measIdIt->second.measId);
1792 }
1793 }
1794
1795 // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1796 for (auto it = mc.measIdToRemoveList.begin(); it != mc.measIdToRemoveList.end(); ++it)
1797 {
1798 uint8_t measId = *it;
1799 NS_LOG_LOGIC(this << " deleting measId " << (uint32_t)measId);
1800 m_varMeasConfig.measIdList.erase(measId);
1801 VarMeasReportListClear(measId);
1802
1803 // removing time-to-trigger queues
1804 m_enteringTriggerQueue.erase(measId);
1805 m_leavingTriggerQueue.erase(measId);
1806 }
1807
1808 // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1809 for (auto it = mc.measIdToAddModList.begin(); it != mc.measIdToAddModList.end(); ++it)
1810 {
1811 NS_LOG_LOGIC(this << " measId " << (uint32_t)it->measId
1812 << " (measObjectId=" << (uint32_t)it->measObjectId
1813 << ", reportConfigId=" << (uint32_t)it->reportConfigId << ")");
1814 NS_ASSERT(m_varMeasConfig.measObjectList.find(it->measObjectId) !=
1816 NS_ASSERT(m_varMeasConfig.reportConfigList.find(it->reportConfigId) !=
1818 m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1819 auto measReportIt = m_varMeasReportList.find(it->measId);
1820 if (measReportIt != m_varMeasReportList.end())
1821 {
1822 measReportIt->second.periodicReportTimer.Cancel();
1823 m_varMeasReportList.erase(measReportIt);
1824 }
1825 NS_ASSERT(m_varMeasConfig.reportConfigList.find(it->reportConfigId)
1826 ->second.reportConfigEutra.triggerType !=
1828
1829 // new empty queues for time-to-trigger
1830 std::list<PendingTrigger_t> s;
1831 m_enteringTriggerQueue[it->measId] = s;
1832 m_leavingTriggerQueue[it->measId] = s;
1833 }
1834
1835 if (mc.haveMeasGapConfig)
1836 {
1837 NS_FATAL_ERROR("measurement gaps are currently not supported");
1838 }
1839
1840 if (mc.haveSmeasure)
1841 {
1842 NS_FATAL_ERROR("s-measure is currently not supported");
1843 }
1844
1845 if (mc.haveSpeedStatePars)
1846 {
1847 NS_FATAL_ERROR("SpeedStatePars are currently not supported");
1848 }
1849}
1850
1851void
1853 double rsrp,
1854 double rsrq,
1855 bool useLayer3Filtering,
1856 uint8_t componentCarrierId)
1857{
1858 NS_LOG_FUNCTION(this << cellId << +componentCarrierId << rsrp << rsrq << useLayer3Filtering);
1859
1860 auto storedMeasIt = m_storedMeasValues.find(cellId);
1861
1862 if (storedMeasIt != m_storedMeasValues.end())
1863 {
1864 if (useLayer3Filtering)
1865 {
1866 // F_n = (1-a) F_{n-1} + a M_n
1867 storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp +
1868 m_varMeasConfig.aRsrp * rsrp;
1869
1870 if (std::isnan(storedMeasIt->second.rsrq))
1871 {
1872 // the previous RSRQ measurements provided UE PHY are invalid
1873 storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1874 }
1875 else
1876 {
1877 storedMeasIt->second.rsrq =
1878 (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq +
1879 m_varMeasConfig.aRsrq * rsrq;
1880 }
1881 }
1882 else
1883 {
1884 storedMeasIt->second.rsrp = rsrp;
1885 storedMeasIt->second.rsrq = rsrq;
1886 }
1887 }
1888 else
1889 {
1890 // first value is always unfiltered
1891 MeasValues v;
1892 v.rsrp = rsrp;
1893 v.rsrq = rsrq;
1894 v.carrierFreq = m_cphySapProvider.at(componentCarrierId)->GetDlEarfcn();
1895
1896 std::pair<uint16_t, MeasValues> val(cellId, v);
1897 auto ret = m_storedMeasValues.insert(val);
1898 NS_ASSERT_MSG(ret.second == true, "element already existed");
1899 storedMeasIt = ret.first;
1900 }
1901
1902 NS_LOG_DEBUG(this << " IMSI " << m_imsi << " state " << ToString(m_state) << ", measured cell "
1903 << cellId << ", carrier component Id " << componentCarrierId << ", new RSRP "
1904 << rsrp << " stored " << storedMeasIt->second.rsrp << ", new RSRQ " << rsrq
1905 << " stored " << storedMeasIt->second.rsrq);
1906
1907} // end of void SaveUeMeasurements
1908
1909void
1911{
1912 NS_LOG_FUNCTION(this << (uint16_t)measId);
1913
1914 auto measIdIt = m_varMeasConfig.measIdList.find(measId);
1915 NS_ASSERT(measIdIt != m_varMeasConfig.measIdList.end());
1916 NS_ASSERT(measIdIt->first == measIdIt->second.measId);
1917
1918 auto reportConfigIt = m_varMeasConfig.reportConfigList.find(measIdIt->second.reportConfigId);
1919 NS_ASSERT(reportConfigIt != m_varMeasConfig.reportConfigList.end());
1920 LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1921
1922 auto measObjectIt = m_varMeasConfig.measObjectList.find(measIdIt->second.measObjectId);
1923 NS_ASSERT(measObjectIt != m_varMeasConfig.measObjectList.end());
1924 LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1925
1926 auto measReportIt = m_varMeasReportList.find(measId);
1927 bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end());
1928
1929 // we don't check the purpose field, as it is only included for
1930 // triggerType == periodical, which is not supported
1932 "only triggerType == event is supported");
1933 // only EUTRA is supported, no need to check for it
1934
1935 NS_LOG_LOGIC(this << " considering measId " << (uint32_t)measId);
1936 bool eventEntryCondApplicable = false;
1937 bool eventLeavingCondApplicable = false;
1938 ConcernedCells_t concernedCellsEntry;
1939 ConcernedCells_t concernedCellsLeaving;
1940
1941 /*
1942 * Find which serving cell corresponds to measObjectEutra.carrierFreq
1943 * It is used, for example, by A1 event:
1944 * See TS 36.331 5.5.4.2: "for this measurement, consider the primary or
1945 * secondary cell that is configured on the frequency indicated in the
1946 * associated measObjectEUTRA to be the serving cell"
1947 */
1948 uint16_t servingCellId = 0;
1949 for (auto cphySapProvider : m_cphySapProvider)
1950 {
1951 if (cphySapProvider->GetDlEarfcn() == measObjectEutra.carrierFreq)
1952 {
1953 servingCellId = cphySapProvider->GetCellId();
1954 }
1955 }
1956
1957 if (servingCellId == 0)
1958 {
1959 return;
1960 }
1961
1962 switch (reportConfigEutra.eventId)
1963 {
1965 /*
1966 * Event A1 (Serving becomes better than threshold)
1967 * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1968 */
1969
1970 double ms; // Ms, the measurement result of the serving cell
1971 double thresh; // Thresh, the threshold parameter for this event
1972 // Hys, the hysteresis parameter for this event.
1973 double hys =
1975
1976 switch (reportConfigEutra.triggerQuantity)
1977 {
1979 ms = m_storedMeasValues[servingCellId].rsrp;
1980
1981 NS_ASSERT(reportConfigEutra.threshold1.choice ==
1983 thresh = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
1984 break;
1986 ms = m_storedMeasValues[servingCellId].rsrq;
1987 NS_ASSERT(reportConfigEutra.threshold1.choice ==
1989 thresh = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
1990 break;
1991 default:
1992 NS_FATAL_ERROR("unsupported triggerQuantity");
1993 break;
1994 }
1995
1996 // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1997 bool entryCond = ms - hys > thresh;
1998
1999 if (entryCond)
2000 {
2001 if (!isMeasIdInReportList)
2002 {
2003 concernedCellsEntry.push_back(servingCellId);
2004 eventEntryCondApplicable = true;
2005 }
2006 else
2007 {
2008 /*
2009 * This is to check that the triggered cell recorded in the
2010 * VarMeasReportList is the serving cell.
2011 */
2012 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2013 measReportIt->second.cellsTriggeredList.end());
2014 }
2015 }
2016 else if (reportConfigEutra.timeToTrigger > 0)
2017 {
2018 CancelEnteringTrigger(measId);
2019 }
2020
2021 // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
2022 bool leavingCond = ms + hys < thresh;
2023
2024 if (leavingCond)
2025 {
2026 if (isMeasIdInReportList)
2027 {
2028 /*
2029 * This is to check that the triggered cell recorded in the
2030 * VarMeasReportList is the serving cell.
2031 */
2032 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(m_cellId) !=
2033 measReportIt->second.cellsTriggeredList.end());
2034 concernedCellsLeaving.push_back(m_cellId);
2035 eventLeavingCondApplicable = true;
2036 }
2037 }
2038 else if (reportConfigEutra.timeToTrigger > 0)
2039 {
2040 CancelLeavingTrigger(measId);
2041 }
2042
2043 NS_LOG_LOGIC(this << " event A1: serving cell " << servingCellId << " ms=" << ms
2044 << " thresh=" << thresh << " entryCond=" << entryCond
2045 << " leavingCond=" << leavingCond);
2046
2047 } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
2048
2049 break;
2050
2052 /*
2053 * Event A2 (Serving becomes worse than threshold)
2054 * Please refer to 3GPP TS 36.331 Section 5.5.4.3
2055 */
2056
2057 double ms; // Ms, the measurement result of the serving cell
2058 double thresh; // Thresh, the threshold parameter for this event
2059 // Hys, the hysteresis parameter for this event.
2060 double hys =
2062
2063 switch (reportConfigEutra.triggerQuantity)
2064 {
2066 ms = m_storedMeasValues[servingCellId].rsrp;
2067 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2069 thresh = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
2070 break;
2072 ms = m_storedMeasValues[servingCellId].rsrq;
2073 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2075 thresh = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
2076 break;
2077 default:
2078 NS_FATAL_ERROR("unsupported triggerQuantity");
2079 break;
2080 }
2081
2082 // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
2083 bool entryCond = ms + hys < thresh;
2084
2085 if (entryCond)
2086 {
2087 if (!isMeasIdInReportList)
2088 {
2089 concernedCellsEntry.push_back(servingCellId);
2090 eventEntryCondApplicable = true;
2091 }
2092 else
2093 {
2094 /*
2095 * This is to check that the triggered cell recorded in the
2096 * VarMeasReportList is the serving cell.
2097 */
2098 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2099 measReportIt->second.cellsTriggeredList.end());
2100 }
2101 }
2102 else if (reportConfigEutra.timeToTrigger > 0)
2103 {
2104 CancelEnteringTrigger(measId);
2105 }
2106
2107 // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
2108 bool leavingCond = ms - hys > thresh;
2109
2110 if (leavingCond)
2111 {
2112 if (isMeasIdInReportList)
2113 {
2114 /*
2115 * This is to check that the triggered cell recorded in the
2116 * VarMeasReportList is the serving cell.
2117 */
2118 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2119 measReportIt->second.cellsTriggeredList.end());
2120 concernedCellsLeaving.push_back(servingCellId);
2121 eventLeavingCondApplicable = true;
2122 }
2123 }
2124 else if (reportConfigEutra.timeToTrigger > 0)
2125 {
2126 CancelLeavingTrigger(measId);
2127 }
2128
2129 NS_LOG_LOGIC(this << " event A2: serving cell " << servingCellId << " ms=" << ms
2130 << " thresh=" << thresh << " entryCond=" << entryCond
2131 << " leavingCond=" << leavingCond);
2132
2133 } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
2134
2135 break;
2136
2138 /*
2139 * Event A3 (Neighbour becomes offset better than PCell)
2140 * Please refer to 3GPP TS 36.331 Section 5.5.4.4
2141 */
2142
2143 double mn; // Mn, the measurement result of the neighbouring cell
2144 double ofn = measObjectEutra
2145 .offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2146 double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2147 double mp; // Mp, the measurement result of the PCell
2148 double ofp = measObjectEutra
2149 .offsetFreq; // Ofp, the frequency specific offset of the primary frequency
2150 double ocp = 0.0; // Ocp, the cell specific offset of the PCell
2151 // Off, the offset parameter for this event.
2152 double off = EutranMeasurementMapping::IeValue2ActualA3Offset(reportConfigEutra.a3Offset);
2153 // Hys, the hysteresis parameter for this event.
2154 double hys =
2156
2157 switch (reportConfigEutra.triggerQuantity)
2158 {
2160 mp = m_storedMeasValues[m_cellId].rsrp;
2161 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2163 break;
2165 mp = m_storedMeasValues[m_cellId].rsrq;
2166 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2168 break;
2169 default:
2170 NS_FATAL_ERROR("unsupported triggerQuantity");
2171 break;
2172 }
2173
2174 for (auto storedMeasIt = m_storedMeasValues.begin();
2175 storedMeasIt != m_storedMeasValues.end();
2176 ++storedMeasIt)
2177 {
2178 uint16_t cellId = storedMeasIt->first;
2179 if (cellId == m_cellId)
2180 {
2181 continue;
2182 }
2183
2184 // Only cell(s) on the frequency indicated in the associated measObject can trigger
2185 // event.
2186 if (m_storedMeasValues.at(cellId).carrierFreq != measObjectEutra.carrierFreq)
2187 {
2188 continue;
2189 }
2190
2191 switch (reportConfigEutra.triggerQuantity)
2192 {
2194 mn = storedMeasIt->second.rsrp;
2195 break;
2197 mn = storedMeasIt->second.rsrq;
2198 break;
2199 default:
2200 NS_FATAL_ERROR("unsupported triggerQuantity");
2201 break;
2202 }
2203
2204 bool hasTriggered =
2205 isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2206 measReportIt->second.cellsTriggeredList.end());
2207
2208 // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
2209 bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
2210
2211 if (entryCond)
2212 {
2213 if (!hasTriggered)
2214 {
2215 concernedCellsEntry.push_back(cellId);
2216 eventEntryCondApplicable = true;
2217 }
2218 }
2219 else if (reportConfigEutra.timeToTrigger > 0)
2220 {
2221 CancelEnteringTrigger(measId, cellId);
2222 }
2223
2224 // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
2225 bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2226
2227 if (leavingCond)
2228 {
2229 if (hasTriggered)
2230 {
2231 concernedCellsLeaving.push_back(cellId);
2232 eventLeavingCondApplicable = true;
2233 }
2234 }
2235 else if (reportConfigEutra.timeToTrigger > 0)
2236 {
2237 CancelLeavingTrigger(measId, cellId);
2238 }
2239
2240 NS_LOG_LOGIC(this << " event A3: neighbor cell " << cellId << " mn=" << mn
2241 << " mp=" << mp << " offset=" << off << " entryCond=" << entryCond
2242 << " leavingCond=" << leavingCond);
2243
2244 } // end of for (storedMeasIt)
2245
2246 } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
2247
2248 break;
2249
2251 /*
2252 * Event A4 (Neighbour becomes better than threshold)
2253 * Please refer to 3GPP TS 36.331 Section 5.5.4.5
2254 */
2255
2256 double mn; // Mn, the measurement result of the neighbouring cell
2257 double ofn = measObjectEutra
2258 .offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2259 double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2260 double thresh; // Thresh, the threshold parameter for this event
2261 // Hys, the hysteresis parameter for this event.
2262 double hys =
2264
2265 switch (reportConfigEutra.triggerQuantity)
2266 {
2268 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2270 thresh = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
2271 break;
2273 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2275 thresh = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
2276 break;
2277 default:
2278 NS_FATAL_ERROR("unsupported triggerQuantity");
2279 break;
2280 }
2281
2282 for (auto storedMeasIt = m_storedMeasValues.begin();
2283 storedMeasIt != m_storedMeasValues.end();
2284 ++storedMeasIt)
2285 {
2286 uint16_t cellId = storedMeasIt->first;
2287 if (cellId == m_cellId)
2288 {
2289 continue;
2290 }
2291
2292 switch (reportConfigEutra.triggerQuantity)
2293 {
2295 mn = storedMeasIt->second.rsrp;
2296 break;
2298 mn = storedMeasIt->second.rsrq;
2299 break;
2300 default:
2301 NS_FATAL_ERROR("unsupported triggerQuantity");
2302 break;
2303 }
2304
2305 bool hasTriggered =
2306 isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2307 measReportIt->second.cellsTriggeredList.end());
2308
2309 // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
2310 bool entryCond = mn + ofn + ocn - hys > thresh;
2311
2312 if (entryCond)
2313 {
2314 if (!hasTriggered)
2315 {
2316 concernedCellsEntry.push_back(cellId);
2317 eventEntryCondApplicable = true;
2318 }
2319 }
2320 else if (reportConfigEutra.timeToTrigger > 0)
2321 {
2322 CancelEnteringTrigger(measId, cellId);
2323 }
2324
2325 // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
2326 bool leavingCond = mn + ofn + ocn + hys < thresh;
2327
2328 if (leavingCond)
2329 {
2330 if (hasTriggered)
2331 {
2332 concernedCellsLeaving.push_back(cellId);
2333 eventLeavingCondApplicable = true;
2334 }
2335 }
2336 else if (reportConfigEutra.timeToTrigger > 0)
2337 {
2338 CancelLeavingTrigger(measId, cellId);
2339 }
2340
2341 NS_LOG_LOGIC(this << " event A4: neighbor cell " << cellId << " mn=" << mn
2342 << " thresh=" << thresh << " entryCond=" << entryCond
2343 << " leavingCond=" << leavingCond);
2344
2345 } // end of for (storedMeasIt)
2346
2347 } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
2348
2349 break;
2350
2352 /*
2353 * Event A5 (PCell becomes worse than threshold1 and neighbour
2354 * becomes better than threshold2)
2355 * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2356 */
2357
2358 double mp; // Mp, the measurement result of the PCell
2359 double mn; // Mn, the measurement result of the neighbouring cell
2360 double ofn = measObjectEutra
2361 .offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2362 double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2363 double thresh1; // Thresh1, the threshold parameter for this event
2364 double thresh2; // Thresh2, the threshold parameter for this event
2365 // Hys, the hysteresis parameter for this event.
2366 double hys =
2368
2369 switch (reportConfigEutra.triggerQuantity)
2370 {
2372 mp = m_storedMeasValues[m_cellId].rsrp;
2373 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2375 NS_ASSERT(reportConfigEutra.threshold2.choice ==
2377 thresh1 = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
2378 thresh2 = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold2.range);
2379 break;
2381 mp = m_storedMeasValues[m_cellId].rsrq;
2382 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2384 NS_ASSERT(reportConfigEutra.threshold2.choice ==
2386 thresh1 = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
2387 thresh2 = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold2.range);
2388 break;
2389 default:
2390 NS_FATAL_ERROR("unsupported triggerQuantity");
2391 break;
2392 }
2393
2394 // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2395 bool entryCond = mp + hys < thresh1;
2396
2397 if (entryCond)
2398 {
2399 for (auto storedMeasIt = m_storedMeasValues.begin();
2400 storedMeasIt != m_storedMeasValues.end();
2401 ++storedMeasIt)
2402 {
2403 uint16_t cellId = storedMeasIt->first;
2404 if (cellId == m_cellId)
2405 {
2406 continue;
2407 }
2408
2409 switch (reportConfigEutra.triggerQuantity)
2410 {
2412 mn = storedMeasIt->second.rsrp;
2413 break;
2415 mn = storedMeasIt->second.rsrq;
2416 break;
2417 default:
2418 NS_FATAL_ERROR("unsupported triggerQuantity");
2419 break;
2420 }
2421
2422 bool hasTriggered =
2423 isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2424 measReportIt->second.cellsTriggeredList.end());
2425
2426 // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2427
2428 entryCond = mn + ofn + ocn - hys > thresh2;
2429
2430 if (entryCond)
2431 {
2432 if (!hasTriggered)
2433 {
2434 concernedCellsEntry.push_back(cellId);
2435 eventEntryCondApplicable = true;
2436 }
2437 }
2438 else if (reportConfigEutra.timeToTrigger > 0)
2439 {
2440 CancelEnteringTrigger(measId, cellId);
2441 }
2442
2443 NS_LOG_LOGIC(this << " event A5: neighbor cell " << cellId << " mn=" << mn
2444 << " mp=" << mp << " thresh2=" << thresh2
2445 << " thresh1=" << thresh1 << " entryCond=" << entryCond);
2446
2447 } // end of for (storedMeasIt)
2448
2449 } // end of if (entryCond)
2450 else
2451 {
2452 NS_LOG_LOGIC(this << " event A5: serving cell " << m_cellId << " mp=" << mp
2453 << " thresh1=" << thresh1 << " entryCond=" << entryCond);
2454
2455 if (reportConfigEutra.timeToTrigger > 0)
2456 {
2457 CancelEnteringTrigger(measId);
2458 }
2459 }
2460
2461 if (isMeasIdInReportList)
2462 {
2463 // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2464 bool leavingCond = mp - hys > thresh1;
2465
2466 if (leavingCond)
2467 {
2468 if (reportConfigEutra.timeToTrigger == 0)
2469 {
2470 // leaving condition #2 does not have to be checked
2471
2472 for (auto storedMeasIt = m_storedMeasValues.begin();
2473 storedMeasIt != m_storedMeasValues.end();
2474 ++storedMeasIt)
2475 {
2476 uint16_t cellId = storedMeasIt->first;
2477 if (cellId == m_cellId)
2478 {
2479 continue;
2480 }
2481
2482 if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2483 measReportIt->second.cellsTriggeredList.end())
2484 {
2485 concernedCellsLeaving.push_back(cellId);
2486 eventLeavingCondApplicable = true;
2487 }
2488 }
2489 } // end of if (reportConfigEutra.timeToTrigger == 0)
2490 else
2491 {
2492 // leaving condition #2 has to be checked to cancel time-to-trigger
2493
2494 for (auto storedMeasIt = m_storedMeasValues.begin();
2495 storedMeasIt != m_storedMeasValues.end();
2496 ++storedMeasIt)
2497 {
2498 uint16_t cellId = storedMeasIt->first;
2499 if (cellId == m_cellId)
2500 {
2501 continue;
2502 }
2503
2504 if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2505 measReportIt->second.cellsTriggeredList.end())
2506 {
2507 switch (reportConfigEutra.triggerQuantity)
2508 {
2510 mn = storedMeasIt->second.rsrp;
2511 break;
2513 mn = storedMeasIt->second.rsrq;
2514 break;
2515 default:
2516 NS_FATAL_ERROR("unsupported triggerQuantity");
2517 break;
2518 }
2519
2520 // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2521
2522 leavingCond = mn + ofn + ocn + hys < thresh2;
2523
2524 if (!leavingCond)
2525 {
2526 CancelLeavingTrigger(measId, cellId);
2527 }
2528
2529 /*
2530 * Whatever the result of leaving condition #2, this
2531 * cell is still "in", because leaving condition #1
2532 * is already true.
2533 */
2534 concernedCellsLeaving.push_back(cellId);
2535 eventLeavingCondApplicable = true;
2536
2537 NS_LOG_LOGIC(this << " event A5: neighbor cell " << cellId
2538 << " mn=" << mn << " mp=" << mp
2539 << " thresh2=" << thresh2 << " thresh1=" << thresh1
2540 << " leavingCond=" << leavingCond);
2541
2542 } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2543 // != measReportIt->second.cellsTriggeredList.end ())
2544
2545 } // end of for (storedMeasIt)
2546
2547 } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2548
2549 NS_LOG_LOGIC(this << " event A5: serving cell " << m_cellId << " mp=" << mp
2550 << " thresh1=" << thresh1 << " leavingCond=" << leavingCond);
2551
2552 } // end of if (leavingCond)
2553 else
2554 {
2555 if (reportConfigEutra.timeToTrigger > 0)
2556 {
2557 CancelLeavingTrigger(measId);
2558 }
2559
2560 // check leaving condition #2
2561
2562 for (auto storedMeasIt = m_storedMeasValues.begin();
2563 storedMeasIt != m_storedMeasValues.end();
2564 ++storedMeasIt)
2565 {
2566 uint16_t cellId = storedMeasIt->first;
2567 if (cellId == m_cellId)
2568 {
2569 continue;
2570 }
2571
2572 if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2573 measReportIt->second.cellsTriggeredList.end())
2574 {
2575 switch (reportConfigEutra.triggerQuantity)
2576 {
2578 mn = storedMeasIt->second.rsrp;
2579 break;
2581 mn = storedMeasIt->second.rsrq;
2582 break;
2583 default:
2584 NS_FATAL_ERROR("unsupported triggerQuantity");
2585 break;
2586 }
2587
2588 // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2589 leavingCond = mn + ofn + ocn + hys < thresh2;
2590
2591 if (leavingCond)
2592 {
2593 concernedCellsLeaving.push_back(cellId);
2594 eventLeavingCondApplicable = true;
2595 }
2596
2597 NS_LOG_LOGIC(this << " event A5: neighbor cell " << cellId << " mn=" << mn
2598 << " mp=" << mp << " thresh2=" << thresh2 << " thresh1="
2599 << thresh1 << " leavingCond=" << leavingCond);
2600
2601 } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2602 // != measReportIt->second.cellsTriggeredList.end ())
2603
2604 } // end of for (storedMeasIt)
2605
2606 } // end of else of if (leavingCond)
2607
2608 } // end of if (isMeasIdInReportList)
2609
2610 } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2611
2612 break;
2613
2614 default:
2615 NS_FATAL_ERROR("unsupported eventId " << reportConfigEutra.eventId);
2616 break;
2617
2618 } // switch (event type)
2619
2620 NS_LOG_LOGIC(this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2621 << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2622
2623 if (eventEntryCondApplicable)
2624 {
2625 if (reportConfigEutra.timeToTrigger == 0)
2626 {
2627 VarMeasReportListAdd(measId, concernedCellsEntry);
2628 }
2629 else
2630 {
2632 t.measId = measId;
2633 t.concernedCells = concernedCellsEntry;
2634 t.timer = Simulator::Schedule(MilliSeconds(reportConfigEutra.timeToTrigger),
2636 this,
2637 measId,
2638 concernedCellsEntry);
2639 auto enteringTriggerIt = m_enteringTriggerQueue.find(measId);
2640 NS_ASSERT(enteringTriggerIt != m_enteringTriggerQueue.end());
2641 enteringTriggerIt->second.push_back(t);
2642 }
2643 }
2644
2645 if (eventLeavingCondApplicable)
2646 {
2647 // reportOnLeave will only be set when eventId = eventA3
2648 bool reportOnLeave =
2649 (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3) &&
2650 reportConfigEutra.reportOnLeave;
2651
2652 if (reportConfigEutra.timeToTrigger == 0)
2653 {
2654 VarMeasReportListErase(measId, concernedCellsLeaving, reportOnLeave);
2655 }
2656 else
2657 {
2659 t.measId = measId;
2660 t.concernedCells = concernedCellsLeaving;
2661 t.timer = Simulator::Schedule(MilliSeconds(reportConfigEutra.timeToTrigger),
2663 this,
2664 measId,
2665 concernedCellsLeaving,
2666 reportOnLeave);
2667 auto leavingTriggerIt = m_leavingTriggerQueue.find(measId);
2668 NS_ASSERT(leavingTriggerIt != m_leavingTriggerQueue.end());
2669 leavingTriggerIt->second.push_back(t);
2670 }
2671 }
2672
2673} // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2674
2675void
2677{
2678 NS_LOG_FUNCTION(this << (uint16_t)measId);
2679
2680 auto it1 = m_enteringTriggerQueue.find(measId);
2681 NS_ASSERT(it1 != m_enteringTriggerQueue.end());
2682
2683 if (!it1->second.empty())
2684 {
2685 for (auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
2686 {
2687 NS_ASSERT(it2->measId == measId);
2688 NS_LOG_LOGIC(this << " canceling entering time-to-trigger event at "
2689 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2690 Simulator::Cancel(it2->timer);
2691 }
2692
2693 it1->second.clear();
2694 }
2695}
2696
2697void
2698LteUeRrc::CancelEnteringTrigger(uint8_t measId, uint16_t cellId)
2699{
2700 NS_LOG_FUNCTION(this << (uint16_t)measId << cellId);
2701
2702 auto it1 = m_enteringTriggerQueue.find(measId);
2703 NS_ASSERT(it1 != m_enteringTriggerQueue.end());
2704
2705 auto it2 = it1->second.begin();
2706 while (it2 != it1->second.end())
2707 {
2708 NS_ASSERT(it2->measId == measId);
2709
2710 for (auto it3 = it2->concernedCells.begin(); it3 != it2->concernedCells.end(); ++it3)
2711 {
2712 if (*it3 == cellId)
2713 {
2714 it3 = it2->concernedCells.erase(it3);
2715 }
2716 }
2717
2718 if (it2->concernedCells.empty())
2719 {
2720 NS_LOG_LOGIC(this << " canceling entering time-to-trigger event at "
2721 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2722 Simulator::Cancel(it2->timer);
2723 it2 = it1->second.erase(it2);
2724 }
2725 else
2726 {
2727 it2++;
2728 }
2729 }
2730}
2731
2732void
2734{
2735 NS_LOG_FUNCTION(this << (uint16_t)measId);
2736
2737 auto it1 = m_leavingTriggerQueue.find(measId);
2738 NS_ASSERT(it1 != m_leavingTriggerQueue.end());
2739
2740 if (!it1->second.empty())
2741 {
2742 for (auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
2743 {
2744 NS_ASSERT(it2->measId == measId);
2745 NS_LOG_LOGIC(this << " canceling leaving time-to-trigger event at "
2746 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2747 Simulator::Cancel(it2->timer);
2748 }
2749
2750 it1->second.clear();
2751 }
2752}
2753
2754void
2755LteUeRrc::CancelLeavingTrigger(uint8_t measId, uint16_t cellId)
2756{
2757 NS_LOG_FUNCTION(this << (uint16_t)measId << cellId);
2758
2759 auto it1 = m_leavingTriggerQueue.find(measId);
2760 NS_ASSERT(it1 != m_leavingTriggerQueue.end());
2761
2762 auto it2 = it1->second.begin();
2763 while (it2 != it1->second.end())
2764 {
2765 NS_ASSERT(it2->measId == measId);
2766
2767 for (auto it3 = it2->concernedCells.begin(); it3 != it2->concernedCells.end(); ++it3)
2768 {
2769 if (*it3 == cellId)
2770 {
2771 it3 = it2->concernedCells.erase(it3);
2772 }
2773 }
2774
2775 if (it2->concernedCells.empty())
2776 {
2777 NS_LOG_LOGIC(this << " canceling leaving time-to-trigger event at "
2778 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2779 Simulator::Cancel(it2->timer);
2780 it2 = it1->second.erase(it2);
2781 }
2782 else
2783 {
2784 it2++;
2785 }
2786 }
2787}
2788
2789void
2791{
2792 NS_LOG_FUNCTION(this << (uint16_t)measId);
2793 NS_ASSERT(!enteringCells.empty());
2794
2795 auto measReportIt = m_varMeasReportList.find(measId);
2796
2797 if (measReportIt == m_varMeasReportList.end())
2798 {
2799 VarMeasReport r;
2800 r.measId = measId;
2801 std::pair<uint8_t, VarMeasReport> val(measId, r);
2802 auto ret = m_varMeasReportList.insert(val);
2803 NS_ASSERT_MSG(ret.second == true, "element already existed");
2804 measReportIt = ret.first;
2805 }
2806
2807 NS_ASSERT(measReportIt != m_varMeasReportList.end());
2808
2809 for (auto it = enteringCells.begin(); it != enteringCells.end(); ++it)
2810 {
2811 measReportIt->second.cellsTriggeredList.insert(*it);
2812 }
2813
2814 NS_ASSERT(!measReportIt->second.cellsTriggeredList.empty());
2815
2816 // #issue 224, schedule only when there is no periodic event scheduled already
2817 if (!measReportIt->second.periodicReportTimer.IsPending())
2818 {
2819 measReportIt->second.numberOfReportsSent = 0;
2820 measReportIt->second.periodicReportTimer =
2823 this,
2824 measId);
2825 }
2826
2827 auto enteringTriggerIt = m_enteringTriggerQueue.find(measId);
2828 NS_ASSERT(enteringTriggerIt != m_enteringTriggerQueue.end());
2829 if (!enteringTriggerIt->second.empty())
2830 {
2831 /*
2832 * Assumptions at this point:
2833 * - the call to this function was delayed by time-to-trigger;
2834 * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2835 * - the first element in the list is associated with this function call.
2836 */
2837 enteringTriggerIt->second.pop_front();
2838
2839 if (!enteringTriggerIt->second.empty())
2840 {
2841 /*
2842 * To prevent the same set of cells triggering again in the future,
2843 * we clean up the time-to-trigger queue. This case might occur when
2844 * time-to-trigger > 200 ms.
2845 */
2846 for (auto it = enteringCells.begin(); it != enteringCells.end(); ++it)
2847 {
2848 CancelEnteringTrigger(measId, *it);
2849 }
2850 }
2851
2852 } // end of if (!enteringTriggerIt->second.empty ())
2853
2854} // end of LteUeRrc::VarMeasReportListAdd
2855
2856void
2857LteUeRrc::VarMeasReportListErase(uint8_t measId, ConcernedCells_t leavingCells, bool reportOnLeave)
2858{
2859 NS_LOG_FUNCTION(this << (uint16_t)measId);
2860 NS_ASSERT(!leavingCells.empty());
2861
2862 auto measReportIt = m_varMeasReportList.find(measId);
2863 NS_ASSERT(measReportIt != m_varMeasReportList.end());
2864
2865 for (auto it = leavingCells.begin(); it != leavingCells.end(); ++it)
2866 {
2867 measReportIt->second.cellsTriggeredList.erase(*it);
2868 }
2869
2870 if (reportOnLeave)
2871 {
2872 // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2873 SendMeasurementReport(measId);
2874 }
2875
2876 if (measReportIt->second.cellsTriggeredList.empty())
2877 {
2878 measReportIt->second.periodicReportTimer.Cancel();
2879 m_varMeasReportList.erase(measReportIt);
2880 }
2881
2882 auto leavingTriggerIt = m_leavingTriggerQueue.find(measId);
2883 NS_ASSERT(leavingTriggerIt != m_leavingTriggerQueue.end());
2884 if (!leavingTriggerIt->second.empty())
2885 {
2886 /*
2887 * Assumptions at this point:
2888 * - the call to this function was delayed by time-to-trigger; and
2889 * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2890 * - the first element in the list is associated with this function call.
2891 */
2892 leavingTriggerIt->second.pop_front();
2893
2894 if (!leavingTriggerIt->second.empty())
2895 {
2896 /*
2897 * To prevent the same set of cells triggering again in the future,
2898 * we clean up the time-to-trigger queue. This case might occur when
2899 * time-to-trigger > 200 ms.
2900 */
2901 for (auto it = leavingCells.begin(); it != leavingCells.end(); ++it)
2902 {
2903 CancelLeavingTrigger(measId, *it);
2904 }
2905 }
2906
2907 } // end of if (!leavingTriggerIt->second.empty ())
2908
2909} // end of LteUeRrc::VarMeasReportListErase
2910
2911void
2913{
2914 NS_LOG_FUNCTION(this << (uint16_t)measId);
2915
2916 // remove the measurement reporting entry for this measId from the VarMeasReportList
2917 auto measReportIt = m_varMeasReportList.find(measId);
2918 if (measReportIt != m_varMeasReportList.end())
2919 {
2920 NS_LOG_LOGIC(this << " deleting existing report for measId " << (uint16_t)measId);
2921 measReportIt->second.periodicReportTimer.Cancel();
2922 m_varMeasReportList.erase(measReportIt);
2923 }
2924
2925 CancelEnteringTrigger(measId);
2926 CancelLeavingTrigger(measId);
2927}
2928
2929void
2931{
2932 NS_LOG_FUNCTION(this << (uint16_t)measId);
2933 // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2934
2935 auto measIdIt = m_varMeasConfig.measIdList.find(measId);
2936 NS_ASSERT(measIdIt != m_varMeasConfig.measIdList.end());
2937
2938 auto reportConfigIt = m_varMeasConfig.reportConfigList.find(measIdIt->second.reportConfigId);
2939 NS_ASSERT(reportConfigIt != m_varMeasConfig.reportConfigList.end());
2940 LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2941
2942 LteRrcSap::MeasurementReport measurementReport;
2943 LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2944 measResults.measId = measId;
2945
2946 auto measReportIt = m_varMeasReportList.find(measId);
2947 if (measReportIt == m_varMeasReportList.end())
2948 {
2949 NS_LOG_ERROR("no entry found in m_varMeasReportList for measId " << (uint32_t)measId);
2950 }
2951 else
2952 {
2953 auto servingMeasIt = m_storedMeasValues.find(m_cellId);
2954 NS_ASSERT(servingMeasIt != m_storedMeasValues.end());
2955 measResults.measResultPCell.rsrpResult =
2956 EutranMeasurementMapping::Dbm2RsrpRange(servingMeasIt->second.rsrp);
2957 measResults.measResultPCell.rsrqResult =
2958 EutranMeasurementMapping::Db2RsrqRange(servingMeasIt->second.rsrq);
2959 NS_LOG_INFO(this << " reporting serving cell "
2960 "RSRP "
2961 << +measResults.measResultPCell.rsrpResult << " ("
2962 << servingMeasIt->second.rsrp
2963 << " dBm) "
2964 "RSRQ "
2965 << +measResults.measResultPCell.rsrqResult << " ("
2966 << servingMeasIt->second.rsrq << " dB)");
2967
2968 measResults.haveMeasResultServFreqList = false;
2969 for (uint16_t componentCarrierId = 1; componentCarrierId < m_numberOfComponentCarriers;
2970 componentCarrierId++)
2971 {
2972 const uint16_t cellId = m_cphySapProvider.at(componentCarrierId)->GetCellId();
2973 auto measValuesIt = m_storedMeasValues.find(cellId);
2974 if (measValuesIt != m_storedMeasValues.end())
2975 {
2976 measResults.haveMeasResultServFreqList = true;
2977 LteRrcSap::MeasResultServFreq measResultServFreq;
2978 measResultServFreq.servFreqId = componentCarrierId;
2979 measResultServFreq.haveMeasResultSCell = true;
2980 measResultServFreq.measResultSCell.rsrpResult =
2981 EutranMeasurementMapping::Dbm2RsrpRange(measValuesIt->second.rsrp);
2982 measResultServFreq.measResultSCell.rsrqResult =
2983 EutranMeasurementMapping::Db2RsrqRange(measValuesIt->second.rsrq);
2984 measResultServFreq.haveMeasResultBestNeighCell = false;
2985 measResults.measResultServFreqList.push_back(measResultServFreq);
2986 }
2987 }
2988
2989 measResults.haveMeasResultNeighCells = false;
2990
2991 if (!(measReportIt->second.cellsTriggeredList.empty()))
2992 {
2993 std::multimap<double, uint16_t> sortedNeighCells;
2994 for (auto cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin();
2995 cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end();
2996 ++cellsTriggeredIt)
2997 {
2998 uint16_t cellId = *cellsTriggeredIt;
2999 if (cellId != m_cellId)
3000 {
3001 auto neighborMeasIt = m_storedMeasValues.find(cellId);
3002 double triggerValue;
3003 switch (reportConfigEutra.triggerQuantity)
3004 {
3006 triggerValue = neighborMeasIt->second.rsrp;
3007 break;
3009 triggerValue = neighborMeasIt->second.rsrq;
3010 break;
3011 default:
3012 NS_FATAL_ERROR("unsupported triggerQuantity");
3013 break;
3014 }
3015 sortedNeighCells.insert(std::pair<double, uint16_t>(triggerValue, cellId));
3016 }
3017 }
3018
3019 std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
3020 uint32_t count;
3021 for (sortedNeighCellsIt = sortedNeighCells.rbegin(), count = 0;
3022 sortedNeighCellsIt != sortedNeighCells.rend() &&
3023 count < reportConfigEutra.maxReportCells;
3024 ++sortedNeighCellsIt, ++count)
3025 {
3026 uint16_t cellId = sortedNeighCellsIt->second;
3027 auto neighborMeasIt = m_storedMeasValues.find(cellId);
3028 NS_ASSERT(neighborMeasIt != m_storedMeasValues.end());
3029 LteRrcSap::MeasResultEutra measResultEutra;
3030 measResultEutra.physCellId = cellId;
3031 measResultEutra.haveCgiInfo = false;
3032 measResultEutra.haveRsrpResult = true;
3033 measResultEutra.rsrpResult =
3034 EutranMeasurementMapping::Dbm2RsrpRange(neighborMeasIt->second.rsrp);
3035 measResultEutra.haveRsrqResult = true;
3036 measResultEutra.rsrqResult =
3037 EutranMeasurementMapping::Db2RsrqRange(neighborMeasIt->second.rsrq);
3038 NS_LOG_INFO(this << " reporting neighbor cell "
3039 << (uint32_t)measResultEutra.physCellId << " RSRP "
3040 << (uint32_t)measResultEutra.rsrpResult << " ("
3041 << neighborMeasIt->second.rsrp << " dBm)"
3042 << " RSRQ " << (uint32_t)measResultEutra.rsrqResult << " ("
3043 << neighborMeasIt->second.rsrq << " dB)");
3044 measResults.measResultListEutra.push_back(measResultEutra);
3045 measResults.haveMeasResultNeighCells = true;
3046 }
3047 }
3048 else
3049 {
3050 NS_LOG_WARN(this << " cellsTriggeredList is empty");
3051 }
3052
3053 /*
3054 * The current LteRrcSap implementation is broken in that it does not
3055 * allow for infinite values of reportAmount, which is probably the most
3056 * reasonable setting. So we just always assume infinite reportAmount.
3057 */
3058 measReportIt->second.numberOfReportsSent++;
3059 measReportIt->second.periodicReportTimer.Cancel();
3060
3061 Time reportInterval;
3062 switch (reportConfigEutra.reportInterval)
3063 {
3065 reportInterval = MilliSeconds(120);
3066 break;
3068 reportInterval = MilliSeconds(240);
3069 break;
3071 reportInterval = MilliSeconds(480);
3072 break;
3074 reportInterval = MilliSeconds(640);
3075 break;
3077 reportInterval = MilliSeconds(1024);
3078 break;
3080 reportInterval = MilliSeconds(2048);
3081 break;
3083 reportInterval = MilliSeconds(5120);
3084 break;
3086 reportInterval = MilliSeconds(10240);
3087 break;
3089 reportInterval = Seconds(60);
3090 break;
3092 reportInterval = Seconds(360);
3093 break;
3095 reportInterval = Seconds(720);
3096 break;
3098 reportInterval = Seconds(1800);
3099 break;
3101 reportInterval = Seconds(3600);
3102 break;
3103 default:
3104 NS_FATAL_ERROR("Unsupported reportInterval "
3105 << (uint16_t)reportConfigEutra.reportInterval);
3106 break;
3107 }
3108
3109 // schedule the next measurement reporting
3110 measReportIt->second.periodicReportTimer =
3111 Simulator::Schedule(reportInterval, &LteUeRrc::SendMeasurementReport, this, measId);
3112
3113 // send the measurement report to eNodeB
3114 m_rrcSapUser->SendMeasurementReport(measurementReport);
3115 }
3116}
3117
3118void
3120{
3121 NS_LOG_FUNCTION(this << m_imsi);
3124 m_connectionPending = false; // reset the flag
3126 m_cmacSapProvider.at(0)->StartContentionBasedRandomAccessProcedure();
3127}
3128
3129void
3131{
3132 NS_LOG_FUNCTION(this << m_imsi);
3133 m_leaveConnectedMode = true;
3134 m_storedMeasValues.clear();
3136
3137 for (auto measIdIt = m_varMeasConfig.measIdList.begin();
3138 measIdIt != m_varMeasConfig.measIdList.end();
3139 ++measIdIt)
3140 {
3141 VarMeasReportListClear(measIdIt->second.measId);
3142 }
3144
3146
3147 for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3148 {
3149 m_cmacSapProvider.at(i)->Reset(); // reset the MAC
3150 }
3151
3152 m_drbMap.clear();
3153 m_bid2DrbidMap.clear();
3154 m_srb1 = nullptr;
3155 m_hasReceivedMib = false;
3156 m_hasReceivedSib1 = false;
3157 m_hasReceivedSib2 = false;
3158
3159 for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3160 {
3161 m_cphySapProvider.at(i)->ResetPhyAfterRlf(); // reset the PHY
3162 }
3165 // Save the cell id UE was attached to
3167 m_cellId = 0;
3168 m_rnti = 0;
3169 m_srb0->m_rlc->SetRnti(m_rnti);
3170}
3171
3172void
3174{
3175 NS_LOG_FUNCTION(this << m_imsi);
3178 {
3181 // Assumption: The eNB connection request timer would expire
3182 // before the expiration of T300 at UE. Upon which, the eNB deletes
3183 // the UE context. Therefore, here we don't need to send the UE context
3184 // deletion request to the eNB.
3187 }
3188 else
3189 {
3190 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
3191 {
3192 m_cmacSapProvider.at(i)->Reset(); // reset the MAC
3193 }
3194 m_hasReceivedSib2 = false; // invalidate the previously received SIB2
3197 // Following call to UE NAS will force the UE to immediately
3198 // perform the random access to the same cell again.
3199 m_asSapUser->NotifyConnectionFailed(); // inform upper layer
3200 }
3201}
3202
3203void
3205{
3206 NS_LOG_FUNCTION(this);
3207 m_srb1Old = nullptr;
3208}
3209
3210uint8_t
3212{
3213 auto it = m_bid2DrbidMap.find(bid);
3214 // NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
3215 if (it == m_bid2DrbidMap.end())
3216 {
3217 return 0;
3218 }
3219 else
3220 {
3221 return it->second;
3222 }
3223}
3224
3225void
3227{
3228 NS_LOG_FUNCTION(this << ToString(newState));
3229 State oldState = m_state;
3230 m_state = newState;
3231 NS_LOG_INFO(this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc " << ToString(oldState)
3232 << " --> " << ToString(newState));
3233 m_stateTransitionTrace(m_imsi, m_cellId, m_rnti, oldState, newState);
3234
3235 switch (newState)
3236 {
3237 case IDLE_START:
3239 {
3240 NS_LOG_INFO("Starting initial cell selection after RLF");
3241 }
3242 else
3243 {
3244 NS_FATAL_ERROR("cannot switch to an initial state");
3245 }
3246 break;
3247
3248 case IDLE_CELL_SEARCH:
3249 case IDLE_WAIT_MIB_SIB1:
3250 case IDLE_WAIT_MIB:
3251 case IDLE_WAIT_SIB1:
3252 break;
3253
3256 {
3258 }
3259 break;
3260
3261 case IDLE_WAIT_SIB2:
3263 {
3266 }
3267 break;
3268
3269 case IDLE_RANDOM_ACCESS:
3270 case IDLE_CONNECTING:
3271 case CONNECTED_NORMALLY:
3272 case CONNECTED_HANDOVER:
3275 default:
3276 break;
3277 }
3278}
3279
3280void
3282{
3283 NS_LOG_FUNCTION(this << m_imsi << m_rnti);
3288}
3289
3290void
3292{
3293 NS_LOG_FUNCTION(this << m_imsi);
3295 NS_LOG_INFO("noOfSyncIndications " << (uint16_t)m_noOfSyncIndications);
3298 {
3300 }
3301}
3302
3303void
3305{
3306 NS_LOG_FUNCTION(this << m_imsi);
3308 NS_LOG_INFO(this << " Total Number of Sync indications from PHY "
3309 << (uint16_t)m_noOfSyncIndications << "N310 value : " << (uint16_t)m_n310);
3312 {
3316 {
3317 NS_LOG_INFO("t310 started");
3318 }
3319 m_cphySapProvider.at(0)->StartInSyncDetection();
3321 }
3322}
3323
3324void
3326{
3327 NS_LOG_FUNCTION(this << m_imsi);
3328
3329 NS_LOG_DEBUG("The number of sync indication received by RRC from PHY: "
3330 << (uint16_t)m_noOfSyncIndications);
3332}
3333
3334void
3336{
3337 NS_LOG_FUNCTION(this << m_imsi);
3340 m_cphySapProvider.at(0)->ResetRlfParams();
3341}
3342
3343const std::string
3345{
3346 return g_ueRrcStateName[s];
3347}
3348
3349} // 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:234
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:226
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:242
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
Definition: lte-common.cc:331
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
Definition: lte-common.cc:270
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:250
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:300
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:39
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:98
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
virtual void NotifyConnectionSuccessful()=0
Notify the NAS that RRC Connection Establishment was successful.
virtual void NotifyConnectionReleased()=0
Notify the NAS that RRC Connection was released.
virtual void RecvData(Ptr< Packet > packet)=0
receive a data packet
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:36
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:96
static TypeId GetTypeId()
Get the type ID.
Definition: lte-rlc-am.cc:87
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE,...
Definition: lte-rlc.h:49
static TypeId GetTypeId()
Get the type ID.
Definition: lte-rlc.cc:197
static TypeId GetTypeId()
Get the type ID.
Definition: lte-rlc-um.cc:56
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Convert PDSCH config dedicated function.
Definition: lte-rrc-sap.h:189
Service Access Point (SAP) offered by the UE component carrier manager to the UE RRC.
virtual void Reset()=0
Reset LC maps.
virtual LteMacSapUser * ConfigureSignalBearer(uint8_t lcid, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
Add the Signal Bearer for a specific Ue in LteUeComponenCarrierManager.
virtual std::vector< LteUeCcmRrcSapProvider::LcsConfig > AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
add a new Logical Channel (LC)
Service Access Point (SAP) offered by the UE RRC to the UE CCM.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
friend class MemberLteUeCcmRrcSapUser< LteUeRrc >
allow MemberLteUeCcmRrcSapUser<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:91
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1052
uint8_t m_lastRrcTransactionIdentifier
last RRC transaction identifier
Definition: lte-ue-rrc.h:819
bool m_connectionPending
True if a connection request by upper layers is pending.
Definition: lte-ue-rrc.h:934
bool m_hasReceivedSib1
True if SIB1 was received for the current cell.
Definition: lte-ue-rrc.h:938
void SendMeasurementReport(uint8_t measId)
Produce a proper measurement report from the given measurement identity's reporting entry in m_varMea...
Definition: lte-ue-rrc.cc:2930
std::map< uint8_t, std::list< PendingTrigger_t > > m_enteringTriggerQueue
List of triggers that were raised because entering condition have been true, but are still delayed fr...
Definition: lte-ue-rrc.h:1127
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:958
void DoNotifyOutOfSync()
Do notify out of sync function.
Definition: lte-ue-rrc.cc:3304
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:1218
uint16_t m_previousCellId
the cell id of the previous cell UE was attached to
Definition: lte-ue-rrc.h:1279
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
SRB1 configuration before RRC connection reconfiguration.
Definition: lte-ue-rrc.h:806
static TypeId GetTypeId()
Get the type ID.
Definition: lte-ue-rrc.cc:181
void SwitchToState(State s)
Switch the UE RRC to the given state.
Definition: lte-ue-rrc.cc:3226
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc: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:1630
LteRrcSap::PdschConfigDedicated m_pdschConfigDedicated
the PDSCH config dedicated
Definition: lte-ue-rrc.h:821
uint8_t m_n310
The 'N310' attribute.
Definition: lte-ue-rrc.h:1254
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc: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:1179
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:2857
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1021
void CancelLeavingTrigger(uint8_t measId)
Clear all the waiting triggers in m_leavingTriggerQueue which are associated with the given measureme...
Definition: lte-ue-rrc.cc:2733
bool m_leaveConnectedMode
true if UE NAS ask UE RRC to leave connected mode, e.g., after RLF, i.e.
Definition: lte-ue-rrc.h:1276
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1156
bool m_hasReceivedSib2
True if SIB2 was received for the current cell.
Definition: lte-ue-rrc.h:940
void SynchronizeToStrongestCell()
Go through the list of measurement results, choose the one with the strongest RSRP,...
Definition: lte-ue-rrc.cc:1239
std::map< uint8_t, uint8_t > m_bid2DrbidMap
bid to DR bid map
Definition: lte-ue-rrc.h:757
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
set the CPHY SAP this RRC should use to interact with the PHY
Definition: lte-ue-rrc.cc: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:1361
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:3281
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:1232
~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:2676
std::map< uint16_t, MeasValues > m_storedMeasValues
Internal storage of the latest measurement results from all detected detected cells,...
Definition: lte-ue-rrc.h:1080
void DoReportUeMeasurements(LteUeCphySapUser::UeMeasurementsParameters params)
Report UE measurements function.
Definition: lte-ue-rrc.cc:912
LteUeRrcSapUser * m_rrcSapUser
RRC SAP user.
Definition: lte-ue-rrc.h:765
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
The ConnectionReconfiguration trace source.
Definition: lte-ue-rrc.h:887
void MeasurementReportTriggering(uint8_t measId)
Evaluate the reporting criteria of a measurement identity and invoke some reporting actions based on ...
Definition: lte-ue-rrc.cc:1910
void SaveUeMeasurements(uint16_t cellId, double rsrp, double rsrq, bool useLayer3Filtering, uint8_t componentCarrierId)
Keep the given measurement result as the latest measurement figures, to be utilised by UE RRC functio...
Definition: lte-ue-rrc.cc:1852
void SetLteCcmRrcSapProvider(LteUeCcmRrcSapProvider *s)
set the Component Carrier Management SAP this RRC should interact with
Definition: lte-ue-rrc.cc: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:3130
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:2912
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:2790
std::vector< LteUeCphySapUser * > m_cphySapUser
UE CPhy SAP user.
Definition: lte-ue-rrc.h:759
void ConnectionTimeout()
Invoked after timer T300 expires, notifying upper layers that RRC connection establishment procedure ...
Definition: lte-ue-rrc.cc:3173
bool m_hasReceivedMib
True if MIB was received for the current cell.
Definition: lte-ue-rrc.h:936
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1201
std::list< uint16_t > ConcernedCells_t
List of cell IDs which are responsible for a certain trigger.
Definition: lte-ue-rrc.h:1003
void EvaluateCellForSelection()
Performs cell selection evaluation to the current serving cell.
Definition: lte-ue-rrc.cc:1280
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Receive system information block type 1 function.
Definition: lte-ue-rrc.cc:873
void StartConnection()
Start connection function.
Definition: lte-ue-rrc.cc:3119
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:969
void DoNotifyInSync()
Do notify in sync function.
Definition: lte-ue-rrc.cc:3291
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:3204
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:3344
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:3335
void DoResetSyncIndicationCounter()
Do reset sync indication counter function.
Definition: lte-ue-rrc.cc:3325
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Apply radio resource config dedicated.
Definition: lte-ue-rrc.cc:1412
uint8_t Bid2Drbid(uint8_t bid)
Bid 2 DR bid.
Definition: lte-ue-rrc.cc:3211
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
The HandoverStart trace source.
Definition: lte-ue-rrc.h:892
Part of the RRC protocol.
Definition: lte-rrc-sap.h:1045
Part of the RRC protocol.
Definition: lte-rrc-sap.h:960
virtual void Setup(SetupParameters params)=0
Setup function.
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
virtual void SendMeasurementReport(MeasurementReport msg)=0
Send a MeasurementReport message to the serving eNodeB during a measurement reporting procedure (Sect...
virtual void SendIdealUeContextRemoveRequest(uint16_t rnti)=0
Send UE context remove request function.
virtual void SendRrcConnectionRequest(RrcConnectionRequest msg)=0
Send an _RRCConnectionRequest message to the serving eNodeB during an RRC connection establishment pr...
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
Send an RRCConnectionSetupComplete message to the serving eNodeB during an RRC connection establishme...
Template for the implementation of the LteUeCphySapUser as a member of an owner class of type C to wh...
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:285
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:217
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
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
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
#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.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
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
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition: object-map.h:40
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
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:76
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
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