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