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