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