17#include "nr-radio-bearer-info.h"
23#include "ns3/fatal-error.h"
25#include "ns3/object-factory.h"
26#include "ns3/object-map.h"
27#include "ns3/simulator.h"
33const Time NR_UE_MEASUREMENT_REPORT_DELAY = MicroSeconds(1);
35NS_LOG_COMPONENT_DEFINE(
"NrUeRrc");
42class UeMemberNrUeCmacSapUser :
public NrUeCmacSapUser
50 UeMemberNrUeCmacSapUser(NrUeRrc* rrc);
52 void SetTemporaryCellRnti(uint16_t rnti)
override;
53 void NotifyRandomAccessSuccessful()
override;
54 void NotifyRandomAccessFailed()
override;
60UeMemberNrUeCmacSapUser::UeMemberNrUeCmacSapUser(NrUeRrc* rrc)
66UeMemberNrUeCmacSapUser::SetTemporaryCellRnti(uint16_t rnti)
68 m_rrc->DoSetTemporaryCellRnti(rnti);
72UeMemberNrUeCmacSapUser::NotifyRandomAccessSuccessful()
74 m_rrc->DoNotifyRandomAccessSuccessful();
78UeMemberNrUeCmacSapUser::NotifyRandomAccessFailed()
80 m_rrc->DoNotifyRandomAccessFailed();
84static const std::string g_ueRrcStateName[NrUeRrc::NUM_STATES] = {
90 "IDLE_CAMPED_NORMALLY",
96 "CONNECTED_PHY_PROBLEM",
97 "CONNECTED_REESTABLISHING",
104NS_OBJECT_ENSURE_REGISTERED(NrUeRrc);
107 : m_cmacSapProvider(0),
108 m_rrcSapUser(nullptr),
109 m_macSapProvider(nullptr),
110 m_asSapUser(nullptr),
111 m_ccmRrcSapProvider(nullptr),
117 m_connectionPending(false),
118 m_hasReceivedMib(false),
119 m_hasReceivedSib1(false),
120 m_hasReceivedSib2(false),
122 m_noOfSyncIndications(0),
123 m_leaveConnectedMode(false),
125 m_connEstFailCountLimit(0),
126 m_connEstFailCount(0),
127 m_numberOfComponentCarriers(nr::MIN_NO_CC)
129 NS_LOG_FUNCTION(
this);
132 m_cphySapProvider.push_back(
nullptr);
133 m_cmacSapProvider.push_back(
nullptr);
142 NS_LOG_FUNCTION(
this);
148 NS_LOG_FUNCTION(
this);
151 delete m_cphySapUser.at(i);
152 delete m_cmacSapUser.at(i);
154 m_cphySapUser.clear();
155 m_cmacSapUser.clear();
156 delete m_rrcSapProvider;
157 delete m_drbPdcpSapUser;
158 delete m_asSapProvider;
159 delete m_ccmRrcSapUser;
160 m_cphySapProvider.erase(m_cphySapProvider.begin(), m_cphySapProvider.end());
161 m_cphySapProvider.clear();
162 m_cmacSapProvider.erase(m_cmacSapProvider.begin(), m_cmacSapProvider.end());
163 m_cmacSapProvider.clear();
171 TypeId(
"ns3::NrUeRrc")
175 .AddAttribute(
"DataRadioBearerMap",
176 "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
178 MakeObjectMapAccessor(&NrUeRrc::m_drbMap),
179 MakeObjectMapChecker<NrDataRadioBearerInfo>())
180 .AddAttribute(
"Srb0",
181 "SignalingRadioBearerInfo for SRB0",
183 MakePointerAccessor(&NrUeRrc::m_srb0),
184 MakePointerChecker<NrSignalingRadioBearerInfo>())
185 .AddAttribute(
"Srb1",
186 "SignalingRadioBearerInfo for SRB1",
188 MakePointerAccessor(&NrUeRrc::m_srb1),
189 MakePointerChecker<NrSignalingRadioBearerInfo>())
190 .AddAttribute(
"CellId",
191 "Serving cell identifier",
194 MakeUintegerChecker<uint16_t>())
195 .AddAttribute(
"C-RNTI",
196 "Cell Radio Network Temporary Identifier",
199 MakeUintegerChecker<uint16_t>())
202 "Timer for the RRC Connection Establishment procedure "
203 "(i.e., the procedure is deemed as failed if it takes longer than this). "
204 "Standard values: 100ms, 200ms, 300ms, 400ms, 600ms, 1000ms, 1500ms, 2000ms",
205 TimeValue(MilliSeconds(
207 MakeTimeAccessor(&NrUeRrc::m_t300),
208 MakeTimeChecker(MilliSeconds(100), MilliSeconds(2000)))
211 "Timer for detecting the Radio link failure "
212 "(i.e., the radio link is deemed as failed if this timer expires). "
213 "Standard values: 0ms 50ms, 100ms, 200ms, 500ms, 1000ms, 2000ms",
214 TimeValue(MilliSeconds(
216 MakeTimeAccessor(&NrUeRrc::m_t310),
217 MakeTimeChecker(MilliSeconds(0), MilliSeconds(2000)))
220 "This specifies the maximum number of out-of-sync indications. "
221 "Standard values: 1, 2, 3, 4, 6, 8, 10, 20",
223 MakeUintegerAccessor(&NrUeRrc::m_n310),
224 MakeUintegerChecker<uint8_t>(1, 20))
227 "This specifies the maximum number of in-sync indications. "
228 "Standard values: 1, 2, 3, 4, 5, 6, 8, 10",
230 MakeUintegerAccessor(&NrUeRrc::m_n311),
231 MakeUintegerChecker<uint8_t>(1, 10))
232 .AddTraceSource(
"MibReceived",
233 "trace fired upon reception of Master Information Block",
234 MakeTraceSourceAccessor(&NrUeRrc::m_mibReceivedTrace),
235 "ns3::NrUeRrc::MibSibHandoverTracedCallback")
236 .AddTraceSource(
"Sib1Received",
237 "trace fired upon reception of System Information Block Type 1",
238 MakeTraceSourceAccessor(&NrUeRrc::m_sib1ReceivedTrace),
239 "ns3::NrUeRrc::MibSibHandoverTracedCallback")
240 .AddTraceSource(
"Sib2Received",
241 "trace fired upon reception of System Information Block Type 2",
242 MakeTraceSourceAccessor(&NrUeRrc::m_sib2ReceivedTrace),
243 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
244 .AddTraceSource(
"StateTransition",
245 "trace fired upon every UE RRC state transition",
246 MakeTraceSourceAccessor(&NrUeRrc::m_stateTransitionTrace),
247 "ns3::NrUeRrc::StateTracedCallback")
248 .AddTraceSource(
"InitialCellSelectionEndOk",
249 "trace fired upon successful initial cell selection procedure",
250 MakeTraceSourceAccessor(&NrUeRrc::m_initialCellSelectionEndOkTrace),
251 "ns3::NrUeRrc::CellSelectionTracedCallback")
252 .AddTraceSource(
"InitialCellSelectionEndError",
253 "trace fired upon failed initial cell selection procedure",
254 MakeTraceSourceAccessor(&NrUeRrc::m_initialCellSelectionEndErrorTrace),
255 "ns3::NrUeRrc::CellSelectionTracedCallback")
256 .AddTraceSource(
"RandomAccessSuccessful",
257 "trace fired upon successful completion of the random access procedure",
258 MakeTraceSourceAccessor(&NrUeRrc::m_randomAccessSuccessfulTrace),
259 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
260 .AddTraceSource(
"RandomAccessError",
261 "trace fired upon failure of the random access procedure",
262 MakeTraceSourceAccessor(&NrUeRrc::m_randomAccessErrorTrace),
263 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
264 .AddTraceSource(
"ConnectionEstablished",
265 "trace fired upon successful RRC connection establishment",
266 MakeTraceSourceAccessor(&NrUeRrc::m_connectionEstablishedTrace),
267 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
268 .AddTraceSource(
"ConnectionTimeout",
269 "trace fired upon timeout RRC connection establishment because of T300",
270 MakeTraceSourceAccessor(&NrUeRrc::m_connectionTimeoutTrace),
271 "ns3::NrUeRrc::ImsiCidRntiCountTracedCallback")
272 .AddTraceSource(
"ConnectionReconfiguration",
273 "trace fired upon RRC connection reconfiguration",
274 MakeTraceSourceAccessor(&NrUeRrc::m_connectionReconfigurationTrace),
275 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
276 .AddTraceSource(
"HandoverStart",
277 "trace fired upon start of a handover procedure",
278 MakeTraceSourceAccessor(&NrUeRrc::m_handoverStartTrace),
279 "ns3::NrUeRrc::MibSibHandoverTracedCallback")
280 .AddTraceSource(
"HandoverEndOk",
281 "trace fired upon successful termination of a handover procedure",
282 MakeTraceSourceAccessor(&NrUeRrc::m_handoverEndOkTrace),
283 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
284 .AddTraceSource(
"HandoverEndError",
285 "trace fired upon failure of a handover procedure",
286 MakeTraceSourceAccessor(&NrUeRrc::m_handoverEndErrorTrace),
287 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
288 .AddTraceSource(
"SCarrierConfigured",
289 "trace fired after configuring secondary carriers",
290 MakeTraceSourceAccessor(&NrUeRrc::m_sCarrierConfiguredTrace),
291 "ns3::NrUeRrc::SCarrierConfiguredTracedCallback")
292 .AddTraceSource(
"Srb1Created",
293 "trace fired after SRB1 is created",
294 MakeTraceSourceAccessor(&NrUeRrc::m_srb1CreatedTrace),
295 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
296 .AddTraceSource(
"DrbCreated",
297 "trace fired after DRB is created",
298 MakeTraceSourceAccessor(&NrUeRrc::m_drbCreatedTrace),
299 "ns3::NrUeRrc::ImsiCidRntiLcIdTracedCallback")
300 .AddTraceSource(
"RadioLinkFailure",
301 "trace fired upon failure of radio link",
302 MakeTraceSourceAccessor(&NrUeRrc::m_radioLinkFailureTrace),
303 "ns3::NrUeRrc::ImsiCidRntiTracedCallback")
306 "trace fired upon receiving in Sync or out of Sync indications from UE PHY",
307 MakeTraceSourceAccessor(&NrUeRrc::m_phySyncDetectionTrace),
308 "ns3::NrUeRrc::PhySyncDetectionTracedCallback");
315 NS_LOG_FUNCTION(
this << s);
322 NS_LOG_FUNCTION(
this << s);
323 m_cphySapProvider.at(index) = s;
329 NS_LOG_FUNCTION(
this);
336 NS_LOG_FUNCTION(
this);
337 return m_cphySapUser.at(index);
343 NS_LOG_FUNCTION(
this << s);
350 NS_LOG_FUNCTION(
this << s);
351 m_cmacSapProvider.at(index) = s;
357 NS_LOG_FUNCTION(
this);
364 NS_LOG_FUNCTION(
this);
365 return m_cmacSapUser.at(index);
371 NS_LOG_FUNCTION(
this << s);
378 NS_LOG_FUNCTION(
this);
379 return m_rrcSapProvider;
385 NS_LOG_FUNCTION(
this << s);
386 m_macSapProvider = s;
392 NS_LOG_FUNCTION(
this << s);
393 m_ccmRrcSapProvider = s;
399 NS_LOG_FUNCTION(
this);
400 return m_ccmRrcSapUser;
412 return m_asSapProvider;
418 NS_LOG_FUNCTION(
this << imsi);
424 m_cmacSapProvider.at(i)->SetImsi(m_imsi);
425 m_cphySapProvider.at(i)->SetImsi(m_imsi);
432 NS_LOG_FUNCTION(
this << cellId);
433 m_previousCellId = cellId;
445 NS_LOG_FUNCTION(
this);
452 NS_LOG_FUNCTION(
this);
459 NS_LOG_FUNCTION(
this);
460 for (
auto& cphySap : m_cphySapProvider)
462 if (cellId == cphySap->GetCellId())
473 NS_LOG_FUNCTION(
this);
474 return m_ulBandwidth;
480 NS_LOG_FUNCTION(
this);
481 return m_dlBandwidth;
493 NS_LOG_FUNCTION(
this);
500 NS_LOG_FUNCTION(
this);
507 NS_LOG_FUNCTION(
this);
508 return m_previousCellId;
514 NS_LOG_FUNCTION(
this);
521 m_primaryUlIndex = ulIndex;
527 return m_primaryUlIndex;
533 m_primaryDlIndex = dlIndex;
539 return m_primaryDlIndex;
545 NS_LOG_FUNCTION(
this);
550 Ptr<NrRlc> rlc = CreateObject<NrRlcTm>()->GetObject<
NrRlc>();
552 rlc->SetRnti(m_rnti);
555 m_srb0 = CreateObject<NrSignalingRadioBearerInfo>();
557 m_srb0->m_srbIdentity = 0;
561 m_rrcSapUser->
Setup(ueParams);
577 NS_LOG_FUNCTION(
this);
578 if (m_numberOfComponentCarriers < nr::MIN_NO_CC || m_numberOfComponentCarriers > nr::MAX_NO_CC)
592 m_cphySapProvider.push_back(
nullptr);
593 m_cmacSapProvider.push_back(
nullptr);
599NrUeRrc::DoSendData(Ptr<Packet> packet, uint8_t bid)
601 NS_LOG_FUNCTION(
this << packet);
603 uint8_t drbid = Bid2Drbid(bid);
607 auto it = m_drbMap.find(drbid);
608 NS_ASSERT_MSG(it != m_drbMap.end(),
"could not find bearer with drbid == " << drbid);
612 params.
rnti = m_rnti;
613 params.
lcid = it->second->m_logicalChannelIdentity;
615 NS_LOG_LOGIC(
this <<
" RNTI=" << m_rnti <<
" sending packet " << packet <<
" on DRBID "
616 << (uint32_t)drbid <<
" (LCID " << (uint32_t)params.
lcid <<
")"
617 <<
" (" << packet->GetSize() <<
" bytes)");
618 it->second->m_pdcp->GetNrPdcpSapProvider()->TransmitPdcpSdu(params);
623NrUeRrc::DoDisconnect()
625 NS_LOG_FUNCTION(
this);
630 case IDLE_CELL_SEARCH:
631 case IDLE_WAIT_MIB_SIB1:
634 case IDLE_CAMPED_NORMALLY:
635 NS_LOG_INFO(
"already disconnected");
639 case IDLE_CONNECTING:
640 NS_FATAL_ERROR(
"cannot abort connection setup procedure");
643 case CONNECTED_NORMALLY:
644 case CONNECTED_HANDOVER:
645 case CONNECTED_PHY_PROBLEM:
646 case CONNECTED_REESTABLISHING:
647 LeaveConnectedMode();
651 NS_FATAL_ERROR(
"method unexpected in state " <<
ToString(m_state));
657NrUeRrc::DoReceivePdcpSdu(NrPdcpSapUser::ReceivePdcpSduParameters params)
659 NS_LOG_FUNCTION(
this);
660 m_asSapUser->
RecvData(params.pdcpSdu);
664NrUeRrc::DoSetTemporaryCellRnti(uint16_t rnti)
666 NS_LOG_FUNCTION(
this << rnti);
668 m_srb0->m_rlc->SetRnti(m_rnti);
676NrUeRrc::DoNotifyRandomAccessSuccessful()
678 NS_LOG_FUNCTION(
this << m_imsi <<
ToString(m_state));
679 m_randomAccessSuccessfulTrace(m_imsi, m_cellId, m_rnti);
683 case IDLE_RANDOM_ACCESS: {
686 SwitchToState(IDLE_CONNECTING);
687 NrRrcSap::RrcConnectionRequest msg;
688 msg.ueIdentity = m_imsi;
690 m_connectionTimeout = Simulator::Schedule(m_t300, &NrUeRrc::ConnectionTimeout,
this);
694 case CONNECTED_HANDOVER: {
695 NrRrcSap::RrcConnectionReconfigurationCompleted msg;
696 msg.rrcTransactionIdentifier = m_lastRrcTransactionIdentifier;
700 for (
auto measIdIt = m_varMeasConfig.measIdList.begin();
701 measIdIt != m_varMeasConfig.measIdList.end();
704 VarMeasReportListClear(measIdIt->second.measId);
707 SwitchToState(CONNECTED_NORMALLY);
709 ->NotifyConnectionSuccessful();
710 m_handoverEndOkTrace(m_imsi, m_cellId, m_rnti);
715 NS_FATAL_ERROR(
"unexpected event in state " <<
ToString(m_state));
721NrUeRrc::DoNotifyRandomAccessFailed()
723 NS_LOG_FUNCTION(
this << m_imsi <<
ToString(m_state));
724 m_randomAccessErrorTrace(m_imsi, m_cellId, m_rnti);
728 case IDLE_RANDOM_ACCESS: {
729 SwitchToState(IDLE_CAMPED_NORMALLY);
734 case CONNECTED_HANDOVER: {
735 m_handoverEndErrorTrace(m_imsi, m_cellId, m_rnti);
741 if (!m_leaveConnectedMode)
743 m_leaveConnectedMode =
true;
744 SwitchToState(CONNECTED_PHY_PROBLEM);
755 NS_FATAL_ERROR(
"unexpected event in state " <<
ToString(m_state));
761NrUeRrc::DoSetCsgWhiteList(uint32_t csgId)
763 NS_LOG_FUNCTION(
this << m_imsi << csgId);
764 m_csgWhiteList = csgId;
768NrUeRrc::DoStartCellSelection(uint32_t dlEarfcn)
770 NS_LOG_FUNCTION(
this << m_imsi << dlEarfcn);
771 NS_ASSERT_MSG(m_state == IDLE_START,
772 "cannot start cell selection from state " <<
ToString(m_state));
773 m_dlEarfcn = dlEarfcn;
775 SwitchToState(IDLE_CELL_SEARCH);
779NrUeRrc::DoForceCampedOnGnb(uint16_t cellId, uint32_t dlEarfcn)
781 NS_LOG_FUNCTION(
this << m_imsi << cellId << dlEarfcn);
787 m_dlEarfcn = dlEarfcn;
788 m_cphySapProvider.at(
GetPrimaryDlIndex())->SynchronizeWithGnb(m_cellId, m_dlEarfcn);
789 SwitchToState(IDLE_WAIT_MIB);
792 case IDLE_CELL_SEARCH:
793 case IDLE_WAIT_MIB_SIB1:
795 NS_FATAL_ERROR(
"cannot abort cell selection " <<
ToString(m_state));
799 NS_LOG_INFO(
"already forced to camp to cell " << m_cellId);
802 case IDLE_CAMPED_NORMALLY:
804 case IDLE_RANDOM_ACCESS:
805 case IDLE_CONNECTING:
806 NS_LOG_INFO(
"already camped to cell " << m_cellId);
809 case CONNECTED_NORMALLY:
810 case CONNECTED_HANDOVER:
811 case CONNECTED_PHY_PROBLEM:
812 case CONNECTED_REESTABLISHING:
813 NS_LOG_INFO(
"already connected to cell " << m_cellId);
817 NS_FATAL_ERROR(
"unexpected event in state " <<
ToString(m_state));
825 NS_LOG_FUNCTION(
this << m_imsi);
830 case IDLE_CELL_SEARCH:
831 case IDLE_WAIT_MIB_SIB1:
834 m_connectionPending =
true;
837 case IDLE_CAMPED_NORMALLY:
838 m_connectionPending =
true;
839 SwitchToState(IDLE_WAIT_SIB2);
843 case IDLE_RANDOM_ACCESS:
844 case IDLE_CONNECTING:
845 NS_LOG_INFO(
"already connecting");
848 case CONNECTED_NORMALLY:
849 case CONNECTED_REESTABLISHING:
850 case CONNECTED_HANDOVER:
851 NS_LOG_INFO(
"already connected");
855 NS_FATAL_ERROR(
"unexpected event in state " <<
ToString(m_state));
863NrUeRrc::DoRecvMasterInformationBlock(uint16_t cellId, NrRrcSap::MasterInformationBlock msg)
865 m_dlBandwidth = msg.dlBandwidth;
869 m_hasReceivedMib =
true;
870 m_mibReceivedTrace(m_imsi, m_cellId, m_rnti, cellId);
876 SwitchToState(IDLE_CAMPED_NORMALLY);
879 case IDLE_WAIT_MIB_SIB1:
881 SwitchToState(IDLE_WAIT_SIB1);
891NrUeRrc::DoRecvSystemInformationBlockType1(uint16_t cellId,
892 NrRrcSap::SystemInformationBlockType1 msg)
894 NS_LOG_FUNCTION(
this);
898 NS_ASSERT_MSG(cellId == msg.cellAccessRelatedInfo.cellIdentity,
899 "Cell identity in SIB1 does not match with the originating cell");
900 m_hasReceivedSib1 =
true;
902 m_sib1ReceivedTrace(m_imsi, m_cellId, m_rnti, cellId);
903 EvaluateCellForSelection();
906 case IDLE_CAMPED_NORMALLY:
907 case IDLE_RANDOM_ACCESS:
908 case IDLE_CONNECTING:
909 case CONNECTED_NORMALLY:
910 case CONNECTED_HANDOVER:
911 case CONNECTED_PHY_PROBLEM:
912 case CONNECTED_REESTABLISHING:
913 NS_ASSERT_MSG(cellId == msg.cellAccessRelatedInfo.cellIdentity,
914 "Cell identity in SIB1 does not match with the originating cell");
915 m_hasReceivedSib1 =
true;
917 m_sib1ReceivedTrace(m_imsi, m_cellId, m_rnti, cellId);
920 case IDLE_WAIT_MIB_SIB1:
930NrUeRrc::DoReportUeMeasurements(NrUeCphySapUser::UeMeasurementsParameters params)
932 NS_LOG_FUNCTION(
this);
935 bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
936 bool triggering =
true;
937 for (
auto newMeasIt = params.m_ueMeasurementsList.begin();
938 newMeasIt != params.m_ueMeasurementsList.end();
941 if (params.m_componentCarrierId != 0)
946 SaveUeMeasurements(newMeasIt->m_cellId,
950 params.m_componentCarrierId);
953 if (m_state == IDLE_CELL_SEARCH)
956 SynchronizeToStrongestCell();
962 for (
auto measIdIt = m_varMeasConfig.measIdList.begin();
963 measIdIt != m_varMeasConfig.measIdList.end();
966 MeasurementReportTriggering(measIdIt->first);
976NrUeRrc::DoCompleteSetup(NrUeRrcSapProvider::CompleteSetupParameters params)
978 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
979 m_srb0->m_rlc->SetNrRlcSapUser(params.srb0SapUser);
982 m_srb1->m_pdcp->SetNrPdcpSapUser(params.srb1SapUser);
987NrUeRrc::DoRecvSystemInformation(NrRrcSap::SystemInformation msg)
989 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
995 case IDLE_CAMPED_NORMALLY:
997 case IDLE_RANDOM_ACCESS:
998 case IDLE_CONNECTING:
999 case CONNECTED_NORMALLY:
1000 case CONNECTED_HANDOVER:
1001 case CONNECTED_PHY_PROBLEM:
1002 case CONNECTED_REESTABLISHING:
1003 m_hasReceivedSib2 =
true;
1004 m_ulBandwidth = msg.sib2.freqInfo.ulBandwidth;
1005 m_ulEarfcn = msg.sib2.freqInfo.ulCarrierFreq;
1006 m_sib2ReceivedTrace(m_imsi, m_cellId, m_rnti);
1007 NrUeCmacSapProvider::RachConfig rc;
1008 rc.numberOfRaPreambles = msg.sib2.radioResourceConfigCommon.rachConfigCommon
1009 .preambleInfo.numberOfRaPreambles;
1010 rc.preambleTransMax = msg.sib2.radioResourceConfigCommon.rachConfigCommon
1011 .raSupervisionInfo.preambleTransMax;
1012 rc.raResponseWindowSize = msg.sib2.radioResourceConfigCommon.rachConfigCommon
1013 .raSupervisionInfo.raResponseWindowSize;
1014 rc.connEstFailCount =
1015 msg.sib2.radioResourceConfigCommon.rachConfigCommon.txFailParam.connEstFailCount;
1016 m_connEstFailCountLimit = rc.connEstFailCount;
1017 NS_ASSERT_MSG(m_connEstFailCountLimit > 0 && m_connEstFailCountLimit < 5,
1018 "SIB2 msg contains wrong value " << m_connEstFailCountLimit
1019 <<
"of connEstFailCount");
1021 m_cphySapProvider.at(
GetPrimaryUlIndex())->ConfigureUplink(m_ulEarfcn, m_ulBandwidth);
1023 ->ConfigureUplink(m_ulEarfcn,
1028 ->ConfigureReferenceSignalPower(
1029 msg.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower);
1034 if (m_state == IDLE_WAIT_SIB2)
1036 NS_ASSERT(m_connectionPending);
1049NrUeRrc::DoRecvRrcConnectionSetup(NrRrcSap::RrcConnectionSetup msg)
1051 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
1054 case IDLE_CONNECTING: {
1055 ApplyRadioResourceConfigDedicated(msg.radioResourceConfigDedicated);
1056 m_connEstFailCount = 0;
1057 m_connectionTimeout.Cancel();
1058 SwitchToState(CONNECTED_NORMALLY);
1059 m_leaveConnectedMode =
false;
1060 NrRrcSap::RrcConnectionSetupCompleted msg2;
1061 msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
1065 m_connectionEstablishedTrace(m_imsi, m_cellId, m_rnti);
1066 NS_ABORT_MSG_IF(m_noOfSyncIndications > 0,
1067 "Sync indications should be zero "
1068 "when a new RRC connection is established. Current value = "
1069 << (uint16_t)m_noOfSyncIndications);
1074 NS_FATAL_ERROR(
"method unexpected in state " <<
ToString(m_state));
1080NrUeRrc::DoRecvRrcConnectionReconfiguration(NrRrcSap::RrcConnectionReconfiguration msg)
1082 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
1083 NS_LOG_INFO(
"DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:"
1084 << msg.haveNonCriticalExtension);
1087 case CONNECTED_NORMALLY:
1088 if (msg.haveMobilityControlInfo)
1090 NS_LOG_INFO(
"haveMobilityControlInfo == true");
1091 SwitchToState(CONNECTED_HANDOVER);
1092 if (m_radioLinkFailureDetected.IsPending())
1096 const NrRrcSap::MobilityControlInfo& mci = msg.mobilityControlInfo;
1097 m_handoverStartTrace(m_imsi, m_cellId, m_rnti, mci.targetPhysCellId);
1099 for (
auto cmacSapProvider : m_cmacSapProvider)
1101 cmacSapProvider->Reset();
1103 for (
auto cphySapProvider : m_cphySapProvider)
1105 cphySapProvider->Reset();
1107 m_ccmRrcSapProvider->
Reset();
1109 m_cellId = mci.targetPhysCellId;
1110 NS_ASSERT(mci.haveCarrierFreq);
1111 NS_ASSERT(mci.haveCarrierBandwidth);
1113 ->SynchronizeWithGnb(m_cellId, mci.carrierFreq.dlCarrierFreq);
1115 ->SetDlBandwidth(mci.carrierBandwidth.dlBandwidth);
1119 ->SetDlBandwidth(mci.carrierBandwidth.ulBandwidth);
1122 ->ConfigureUplink(mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
1123 m_rnti = msg.mobilityControlInfo.newUeIdentity;
1124 m_srb0->m_rlc->SetRnti(m_rnti);
1126 mci.haveRachConfigDedicated,
1127 "handover is only supported with non-contention-based random access procedure");
1129 ->StartNonContentionBasedRandomAccessProcedure(
1131 mci.rachConfigDedicated.raPreambleIndex,
1132 mci.rachConfigDedicated.raPrachMaskIndex);
1137 m_lastRrcTransactionIdentifier = msg.rrcTransactionIdentifier;
1138 NS_ASSERT(msg.haveRadioResourceConfigDedicated);
1145 Simulator::ScheduleNow(&NrUeRrc::DisposeOldSrb1,
this);
1150 ApplyRadioResourceConfigDedicated(msg.radioResourceConfigDedicated);
1151 if (msg.haveNonCriticalExtension)
1153 NS_LOG_DEBUG(
this <<
"RNTI " << m_rnti
1154 <<
" Handover. Configuring secondary carriers");
1155 ApplyRadioResourceConfigDedicatedSecondaryCarrier(msg.nonCriticalExtension);
1158 if (msg.haveMeasConfig)
1160 ApplyMeasConfig(msg.measConfig);
1167 NS_LOG_INFO(
"haveMobilityControlInfo == false");
1168 if (msg.haveNonCriticalExtension)
1170 ApplyRadioResourceConfigDedicatedSecondaryCarrier(msg.nonCriticalExtension);
1171 NS_LOG_DEBUG(
this <<
"RNTI " << m_rnti <<
" Configured for CA");
1173 if (msg.haveRadioResourceConfigDedicated)
1175 ApplyRadioResourceConfigDedicated(msg.radioResourceConfigDedicated);
1177 if (msg.haveMeasConfig)
1179 ApplyMeasConfig(msg.measConfig);
1181 NrRrcSap::RrcConnectionReconfigurationCompleted msg2;
1182 msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
1184 m_connectionReconfigurationTrace(m_imsi, m_cellId, m_rnti);
1189 NS_FATAL_ERROR(
"method unexpected in state " <<
ToString(m_state));
1195NrUeRrc::DoRecvRrcConnectionReestablishment(NrRrcSap::RrcConnectionReestablishment msg)
1197 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
1200 case CONNECTED_REESTABLISHING: {
1212 NS_FATAL_ERROR(
"method unexpected in state " <<
ToString(m_state));
1218NrUeRrc::DoRecvRrcConnectionReestablishmentReject(NrRrcSap::RrcConnectionReestablishmentReject msg)
1220 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
1223 case CONNECTED_REESTABLISHING: {
1233 NS_FATAL_ERROR(
"method unexpected in state " <<
ToString(m_state));
1239NrUeRrc::DoRecvRrcConnectionRelease(NrRrcSap::RrcConnectionRelease msg)
1241 NS_LOG_FUNCTION(
this <<
" RNTI " << m_rnti);
1244 m_lastRrcTransactionIdentifier = msg.rrcTransactionIdentifier;
1246 if (!m_leaveConnectedMode)
1248 m_leaveConnectedMode =
true;
1249 SwitchToState(CONNECTED_PHY_PROBLEM);
1256NrUeRrc::DoRecvRrcConnectionReject(NrRrcSap::RrcConnectionReject msg)
1258 NS_LOG_FUNCTION(
this);
1259 m_connectionTimeout.Cancel();
1262 m_cmacSapProvider.at(i)->Reset();
1264 m_hasReceivedSib2 =
false;
1265 SwitchToState(IDLE_CAMPED_NORMALLY);
1270NrUeRrc::DoSetNumberOfComponentCarriers(uint16_t noOfComponentCarriers)
1272 NS_LOG_FUNCTION(
this);
1277NrUeRrc::SynchronizeToStrongestCell()
1279 NS_LOG_FUNCTION(
this);
1280 NS_ASSERT(m_state == IDLE_CELL_SEARCH);
1282 uint16_t maxRsrpCellId = 0;
1283 double maxRsrp = -std::numeric_limits<double>::infinity();
1284 double minRsrp = -140.0;
1286 for (
auto it = m_storedMeasValues.begin(); it != m_storedMeasValues.end(); it++)
1292 if (maxRsrp < it->second.rsrp && it->second.rsrp > minRsrp)
1294 auto itCell = m_acceptableCell.find(it->first);
1295 if (itCell == m_acceptableCell.end())
1297 maxRsrpCellId = it->first;
1298 maxRsrp = it->second.rsrp;
1303 if (maxRsrpCellId == 0)
1305 NS_LOG_WARN(
this <<
" Cell search is unable to detect surrounding cell to attach to");
1309 NS_LOG_LOGIC(
this <<
" cell " << maxRsrpCellId
1310 <<
" is the strongest untried surrounding cell");
1311 m_cphySapProvider.at(
GetPrimaryDlIndex())->SynchronizeWithGnb(maxRsrpCellId, m_dlEarfcn);
1312 SwitchToState(IDLE_WAIT_MIB_SIB1);
1318NrUeRrc::EvaluateCellForSelection()
1320 NS_LOG_FUNCTION(
this);
1321 NS_ASSERT(m_state == IDLE_WAIT_SIB1);
1322 NS_ASSERT(m_hasReceivedMib);
1323 NS_ASSERT(m_hasReceivedSib1);
1328 bool isSuitableCell =
false;
1329 bool isAcceptableCell =
false;
1330 auto storedMeasIt = m_storedMeasValues.find(cellId);
1331 double qRxLevMeas = storedMeasIt->second.rsrp;
1334 NS_LOG_LOGIC(
this <<
" cell selection to cellId=" << cellId <<
" qrxlevmeas=" << qRxLevMeas
1336 <<
" qrxlevmin=" << qRxLevMin <<
" dBm");
1338 if (qRxLevMeas - qRxLevMin > 0)
1340 isAcceptableCell =
true;
1345 isSuitableCell = (!cellCsgIndication || cellCsgId == m_csgWhiteList);
1347 NS_LOG_LOGIC(
this <<
" csg(ue/cell/indication)=" << m_csgWhiteList <<
"/" << cellCsgId
1348 <<
"/" << cellCsgIndication);
1356 m_cphySapProvider.at(
GetPrimaryDlIndex())->SynchronizeWithGnb(cellId, m_dlEarfcn);
1358 m_initialCellSelectionEndOkTrace(m_imsi, cellId);
1368 if (!m_connectionPending)
1370 NS_LOG_DEBUG(
"Calling DoConnect in state = " <<
ToString(m_state));
1373 SwitchToState(IDLE_CAMPED_NORMALLY);
1378 m_hasReceivedMib =
false;
1379 m_hasReceivedSib1 =
false;
1381 m_initialCellSelectionEndErrorTrace(m_imsi, cellId);
1383 if (isAcceptableCell)
1389 m_acceptableCell.insert(cellId);
1392 SwitchToState(IDLE_CELL_SEARCH);
1393 SynchronizeToStrongestCell();
1399NrUeRrc::ApplyRadioResourceConfigDedicatedSecondaryCarrier(
1400 NrRrcSap::NonCriticalExtensionConfiguration nonCec)
1402 NS_LOG_FUNCTION(
this);
1404 m_sCellToAddModList = nonCec.sCellToAddModList;
1406 for (uint32_t sCellIndex : nonCec.sCellToReleaseList)
1408 m_cphySapProvider.at(sCellIndex)->Reset();
1409 m_cmacSapProvider.at(sCellIndex)->Reset();
1412 for (
auto& scell : nonCec.sCellToAddModList)
1414 uint8_t ccId = scell.sCellIndex;
1416 uint16_t physCellId = scell.cellIdentification.physCellId;
1418 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth;
1420 scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq;
1421 uint16_t dlBand = scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth;
1422 uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1423 uint8_t txMode = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1424 .antennaInfo.transmissionMode;
1425 uint16_t srsIndex = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1426 .soundingRsUlConfigDedicated.srsConfigIndex;
1428 m_cphySapProvider.at(ccId)->SynchronizeWithGnb(physCellId, dlEarfcn);
1429 m_cphySapProvider.at(ccId)->SetDlBandwidth(dlBand);
1430 m_cphySapProvider.at(ccId)->ConfigureUplink(ulEarfcn, ulBand);
1431 m_cphySapProvider.at(ccId)->ConfigureReferenceSignalPower(
1432 scell.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon
1433 .referenceSignalPower);
1434 m_cphySapProvider.at(ccId)->SetTransmissionMode(txMode);
1435 m_cphySapProvider.at(ccId)->SetRnti(m_rnti);
1436 m_cmacSapProvider.at(ccId)->SetRnti(m_rnti);
1438 NrRrcSap::PdschConfigDedicated pdschConfigDedicated =
1439 scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1440 .pdschConfigDedicated;
1442 m_cphySapProvider.at(ccId)->SetPa(paDouble);
1443 m_cphySapProvider.at(ccId)->SetSrsConfigurationIndex(srsIndex);
1446 m_sCarrierConfiguredTrace(
this, m_sCellToAddModList);
1450NrUeRrc::ApplyRadioResourceConfigDedicated(NrRrcSap::RadioResourceConfigDedicated rrcd)
1452 NS_LOG_FUNCTION(
this);
1453 const NrRrcSap::PhysicalConfigDedicated& pcd = rrcd.physicalConfigDedicated;
1455 if (pcd.haveAntennaInfoDedicated)
1458 ->SetTransmissionMode(pcd.antennaInfo.transmissionMode);
1460 if (pcd.haveSoundingRsUlConfigDedicated)
1463 ->SetSrsConfigurationIndex(pcd.soundingRsUlConfigDedicated.srsConfigIndex);
1466 if (pcd.havePdschConfigDedicated)
1469 m_pdschConfigDedicated = pcd.pdschConfigDedicated;
1474 auto stamIt = rrcd.srbToAddModList.begin();
1475 if (stamIt != rrcd.srbToAddModList.end())
1480 NS_ASSERT_MSG((m_state == IDLE_CONNECTING) || (m_state == CONNECTED_HANDOVER),
1481 "unexpected state " <<
ToString(m_state));
1482 NS_ASSERT_MSG(stamIt->srbIdentity == 1,
"only SRB1 supported");
1484 const uint8_t lcid = 1;
1486 Ptr<NrRlc> rlc = CreateObject<NrRlcAm>();
1487 rlc->SetNrMacSapProvider(m_macSapProvider);
1488 rlc->SetRnti(m_rnti);
1491 Ptr<NrPdcp> pdcp = CreateObject<NrPdcp>();
1492 pdcp->SetRnti(m_rnti);
1493 pdcp->SetLcId(lcid);
1494 pdcp->SetNrPdcpSapUser(m_drbPdcpSapUser);
1495 pdcp->SetNrRlcSapProvider(rlc->GetNrRlcSapProvider());
1496 rlc->SetNrRlcSapUser(pdcp->GetNrRlcSapUser());
1498 m_srb1 = CreateObject<NrSignalingRadioBearerInfo>();
1499 m_srb1->m_rlc = rlc;
1500 m_srb1->m_pdcp = pdcp;
1501 m_srb1->m_srbIdentity = 1;
1502 m_srb1CreatedTrace(m_imsi, m_cellId, m_rnti);
1504 m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1505 m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps =
1506 stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1507 m_srb1->m_logicalChannelConfig.bucketSizeDurationMs =
1508 stamIt->logicalChannelConfig.bucketSizeDurationMs;
1509 m_srb1->m_logicalChannelConfig.logicalChannelGroup =
1510 stamIt->logicalChannelConfig.logicalChannelGroup;
1512 NrUeCmacSapProvider::LogicalChannelConfig lcConfig;
1513 lcConfig.priority = stamIt->logicalChannelConfig.priority;
1514 lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1515 lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1516 lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1521 NS_ASSERT_MSG(stamIt == rrcd.srbToAddModList.end(),
"at most one SrbToAdd supported");
1523 NrUeRrcSapUser::SetupParameters ueParams;
1524 ueParams.srb0SapProvider = m_srb0->m_rlc->GetNrRlcSapProvider();
1525 ueParams.srb1SapProvider = m_srb1->m_pdcp->GetNrPdcpSapProvider();
1526 m_rrcSapUser->
Setup(ueParams);
1530 NS_LOG_INFO(
"request to modify SRB1 (skipping as currently not implemented)");
1535 for (
auto dtamIt = rrcd.drbToAddModList.begin(); dtamIt != rrcd.drbToAddModList.end(); ++dtamIt)
1537 NS_LOG_INFO(
this <<
" IMSI " << m_imsi <<
" adding/modifying DRBID "
1538 << (uint32_t)dtamIt->drbIdentity <<
" LC "
1539 << (uint32_t)dtamIt->logicalChannelIdentity);
1540 NS_ASSERT_MSG(dtamIt->logicalChannelIdentity > 2,
1541 "LCID value " << dtamIt->logicalChannelIdentity <<
" is reserved for SRBs");
1543 auto drbMapIt = m_drbMap.find(dtamIt->drbIdentity);
1544 if (drbMapIt == m_drbMap.end())
1546 NS_LOG_INFO(
"New Data Radio Bearer");
1555 switch (dtamIt->rlcConfig.choice)
1557 case NrRrcSap::RlcConfig::AM:
1561 case NrRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
1566 NS_FATAL_ERROR(
"unsupported RLC configuration");
1571 ObjectFactory rlcObjectFactory;
1572 rlcObjectFactory.SetTypeId(rlcTypeId);
1573 Ptr<NrRlc> rlc = rlcObjectFactory.Create()->GetObject<NrRlc>();
1574 rlc->SetNrMacSapProvider(m_macSapProvider);
1575 rlc->SetRnti(m_rnti);
1576 rlc->SetLcId(dtamIt->logicalChannelIdentity);
1581 Simulator::ScheduleNow(&NrRlcSm::Initialize, rlc);
1584 Ptr<NrDataRadioBearerInfo> drbInfo = CreateObject<NrDataRadioBearerInfo>();
1585 drbInfo->m_rlc = rlc;
1586 drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1587 drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1588 drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1594 Ptr<NrPdcp> pdcp = CreateObject<NrPdcp>();
1595 pdcp->SetRnti(m_rnti);
1596 pdcp->SetLcId(dtamIt->logicalChannelIdentity);
1597 pdcp->SetNrPdcpSapUser(m_drbPdcpSapUser);
1598 pdcp->SetNrRlcSapProvider(rlc->GetNrRlcSapProvider());
1599 rlc->SetNrRlcSapUser(pdcp->GetNrRlcSapUser());
1600 drbInfo->m_pdcp = pdcp;
1603 m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1606 std::pair<uint8_t, Ptr<NrDataRadioBearerInfo>>(dtamIt->drbIdentity, drbInfo));
1608 m_drbCreatedTrace(m_imsi, m_cellId, m_rnti, dtamIt->drbIdentity);
1610 NrUeCmacSapProvider::LogicalChannelConfig lcConfig;
1611 lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1612 lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1613 lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1614 lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1616 NS_LOG_DEBUG(
this <<
" UE RRC RNTI " << m_rnti <<
" Number Of Component Carriers "
1618 << (uint16_t)dtamIt->logicalChannelIdentity);
1620 std::vector<NrUeCcmRrcSapProvider::LcsConfig> lcOnCcMapping =
1621 m_ccmRrcSapProvider->
AddLc(dtamIt->logicalChannelIdentity,
1623 rlc->GetNrMacSapUser());
1625 NS_LOG_DEBUG(
"Size of lcOnCcMapping vector " << lcOnCcMapping.size());
1626 auto itLcOnCcMapping = lcOnCcMapping.begin();
1627 NS_ASSERT_MSG(itLcOnCcMapping != lcOnCcMapping.end(),
1628 "Component carrier manager failed to add LC for data radio bearer");
1630 for (itLcOnCcMapping = lcOnCcMapping.begin(); itLcOnCcMapping != lcOnCcMapping.end();
1633 NS_LOG_DEBUG(
"RNTI " << m_rnti <<
" LCG id "
1634 << (uint16_t)itLcOnCcMapping->lcConfig.logicalChannelGroup
1635 <<
" ComponentCarrierId "
1636 << (uint16_t)itLcOnCcMapping->componentCarrierId);
1637 uint8_t index = itLcOnCcMapping->componentCarrierId;
1638 NrUeCmacSapProvider::LogicalChannelConfig lcConfigFromCcm =
1639 itLcOnCcMapping->lcConfig;
1640 NrMacSapUser* msu = itLcOnCcMapping->msu;
1641 m_cmacSapProvider.at(index)->AddLc(dtamIt->logicalChannelIdentity,
1648 NS_LOG_INFO(
"request to modify existing DRBID");
1649 Ptr<NrDataRadioBearerInfo> drbInfo = drbMapIt->second;
1655 for (
auto dtdmIt = rrcd.drbToReleaseList.begin(); dtdmIt != rrcd.drbToReleaseList.end();
1658 uint8_t drbid = *dtdmIt;
1659 NS_LOG_INFO(
this <<
" IMSI " << m_imsi <<
" releasing DRB " << (uint32_t)drbid);
1660 auto it = m_drbMap.find(drbid);
1661 NS_ASSERT_MSG(it != m_drbMap.end(),
"could not find bearer with given lcid");
1663 m_bid2DrbidMap.erase(drbid);
1667 m_cmacSapProvider.at(i)->RemoveLc(drbid + 2);
1674NrUeRrc::ApplyMeasConfig(NrRrcSap::MeasConfig mc)
1676 NS_LOG_FUNCTION(
this);
1681 for (
auto it = mc.measObjectToRemoveList.begin(); it != mc.measObjectToRemoveList.end(); ++it)
1683 uint8_t measObjectId = *it;
1684 NS_LOG_LOGIC(
this <<
" deleting measObjectId " << (uint32_t)measObjectId);
1685 m_varMeasConfig.measObjectList.erase(measObjectId);
1686 auto measIdIt = m_varMeasConfig.measIdList.begin();
1687 while (measIdIt != m_varMeasConfig.measIdList.end())
1689 if (measIdIt->second.measObjectId == measObjectId)
1691 uint8_t measId = measIdIt->second.measId;
1692 NS_ASSERT(measId == measIdIt->first);
1693 NS_LOG_LOGIC(
this <<
" deleting measId " << (uint32_t)measId
1694 <<
" because referring to measObjectId "
1695 << (uint32_t)measObjectId);
1697 m_varMeasConfig.measIdList.erase(measIdIt++);
1698 VarMeasReportListClear(measId);
1708 for (
auto it = mc.measObjectToAddModList.begin(); it != mc.measObjectToAddModList.end(); ++it)
1711 NS_ASSERT_MSG(it->measObjectEutra.cellsToRemoveList.empty(),
1712 "cellsToRemoveList not supported");
1713 NS_ASSERT_MSG(it->measObjectEutra.cellsToAddModList.empty(),
1714 "cellsToAddModList not supported");
1715 NS_ASSERT_MSG(it->measObjectEutra.cellsToRemoveList.empty(),
1716 "blackCellsToRemoveList not supported");
1717 NS_ASSERT_MSG(it->measObjectEutra.blackCellsToAddModList.empty(),
1718 "blackCellsToAddModList not supported");
1719 NS_ASSERT_MSG(it->measObjectEutra.haveCellForWhichToReportCGI ==
false,
1720 "cellForWhichToReportCGI is not supported");
1722 uint8_t measObjectId = it->measObjectId;
1723 auto measObjectIt = m_varMeasConfig.measObjectList.find(measObjectId);
1724 if (measObjectIt != m_varMeasConfig.measObjectList.end())
1726 NS_LOG_LOGIC(
"measObjectId " << (uint32_t)measObjectId <<
" exists, updating entry");
1727 measObjectIt->second = *it;
1728 for (
auto measIdIt = m_varMeasConfig.measIdList.begin();
1729 measIdIt != m_varMeasConfig.measIdList.end();
1732 if (measIdIt->second.measObjectId == measObjectId)
1734 uint8_t measId = measIdIt->second.measId;
1735 NS_LOG_LOGIC(
this <<
" found measId " << (uint32_t)measId
1736 <<
" referring to measObjectId " << (uint32_t)measObjectId);
1737 VarMeasReportListClear(measId);
1743 NS_LOG_LOGIC(
"measObjectId " << (uint32_t)measObjectId <<
" is new, adding entry");
1744 m_varMeasConfig.measObjectList[measObjectId] = *it;
1749 for (
auto it = mc.reportConfigToRemoveList.begin(); it != mc.reportConfigToRemoveList.end();
1752 uint8_t reportConfigId = *it;
1753 NS_LOG_LOGIC(
this <<
" deleting reportConfigId " << (uint32_t)reportConfigId);
1754 m_varMeasConfig.reportConfigList.erase(reportConfigId);
1755 auto measIdIt = m_varMeasConfig.measIdList.begin();
1756 while (measIdIt != m_varMeasConfig.measIdList.end())
1758 if (measIdIt->second.reportConfigId == reportConfigId)
1760 uint8_t measId = measIdIt->second.measId;
1761 NS_ASSERT(measId == measIdIt->first);
1762 NS_LOG_LOGIC(
this <<
" deleting measId " << (uint32_t)measId
1763 <<
" because referring to reportConfigId "
1764 << (uint32_t)reportConfigId);
1766 m_varMeasConfig.measIdList.erase(measIdIt++);
1767 VarMeasReportListClear(measId);
1777 for (
auto it = mc.reportConfigToAddModList.begin(); it != mc.reportConfigToAddModList.end();
1782 "only trigger type EVENT is supported");
1784 uint8_t reportConfigId = it->reportConfigId;
1785 auto reportConfigIt = m_varMeasConfig.reportConfigList.find(reportConfigId);
1786 if (reportConfigIt != m_varMeasConfig.reportConfigList.end())
1788 NS_LOG_LOGIC(
"reportConfigId " << (uint32_t)reportConfigId
1789 <<
" exists, updating entry");
1790 m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1791 for (
auto measIdIt = m_varMeasConfig.measIdList.begin();
1792 measIdIt != m_varMeasConfig.measIdList.end();
1795 if (measIdIt->second.reportConfigId == reportConfigId)
1797 uint8_t measId = measIdIt->second.measId;
1798 NS_LOG_LOGIC(
this <<
" found measId " << (uint32_t)measId
1799 <<
" referring to reportConfigId "
1800 << (uint32_t)reportConfigId);
1801 VarMeasReportListClear(measId);
1807 NS_LOG_LOGIC(
"reportConfigId " << (uint32_t)reportConfigId <<
" is new, adding entry");
1808 m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1813 if (mc.haveQuantityConfig)
1815 NS_LOG_LOGIC(
this <<
" setting quantityConfig");
1816 m_varMeasConfig.quantityConfig = mc.quantityConfig;
1821 m_cphySapProvider.at(i)->SetRsrpFilterCoefficient(
1822 mc.quantityConfig.filterCoefficientRSRP);
1826 m_varMeasConfig.aRsrp = std::pow(0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1827 m_varMeasConfig.aRsrq = std::pow(0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1828 NS_LOG_LOGIC(
this <<
" new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp
1829 <<
", aRsrq=" << m_varMeasConfig.aRsrq);
1831 for (
auto measIdIt = m_varMeasConfig.measIdList.begin();
1832 measIdIt != m_varMeasConfig.measIdList.end();
1835 VarMeasReportListClear(measIdIt->second.measId);
1840 for (
auto it = mc.measIdToRemoveList.begin(); it != mc.measIdToRemoveList.end(); ++it)
1842 uint8_t measId = *it;
1843 NS_LOG_LOGIC(
this <<
" deleting measId " << (uint32_t)measId);
1844 m_varMeasConfig.measIdList.erase(measId);
1845 VarMeasReportListClear(measId);
1848 m_enteringTriggerQueue.erase(measId);
1849 m_leavingTriggerQueue.erase(measId);
1853 for (
auto it = mc.measIdToAddModList.begin(); it != mc.measIdToAddModList.end(); ++it)
1855 NS_LOG_LOGIC(
this <<
" measId " << (uint32_t)it->measId
1856 <<
" (measObjectId=" << (uint32_t)it->measObjectId
1857 <<
", reportConfigId=" << (uint32_t)it->reportConfigId <<
")");
1858 NS_ASSERT(m_varMeasConfig.measObjectList.find(it->measObjectId) !=
1859 m_varMeasConfig.measObjectList.end());
1860 NS_ASSERT(m_varMeasConfig.reportConfigList.find(it->reportConfigId) !=
1861 m_varMeasConfig.reportConfigList.end());
1862 m_varMeasConfig.measIdList[it->measId] = *it;
1863 auto measReportIt = m_varMeasReportList.find(it->measId);
1864 if (measReportIt != m_varMeasReportList.end())
1866 measReportIt->second.periodicReportTimer.Cancel();
1867 m_varMeasReportList.erase(measReportIt);
1869 NS_ASSERT(m_varMeasConfig.reportConfigList.find(it->reportConfigId)
1870 ->second.reportConfigEutra.triggerType !=
1874 std::list<PendingTrigger_t> s;
1875 m_enteringTriggerQueue[it->measId] = s;
1876 m_leavingTriggerQueue[it->measId] = s;
1879 if (mc.haveMeasGapConfig)
1881 NS_FATAL_ERROR(
"measurement gaps are currently not supported");
1884 if (mc.haveSmeasure)
1886 NS_FATAL_ERROR(
"s-measure is currently not supported");
1889 if (mc.haveSpeedStatePars)
1891 NS_FATAL_ERROR(
"SpeedStatePars are currently not supported");
1896NrUeRrc::SaveUeMeasurements(uint16_t cellId,
1899 bool useLayer3Filtering,
1900 uint8_t componentCarrierId)
1902 NS_LOG_FUNCTION(
this << cellId << +componentCarrierId << rsrp << rsrq << useLayer3Filtering);
1904 auto storedMeasIt = m_storedMeasValues.find(cellId);
1906 if (storedMeasIt != m_storedMeasValues.end())
1908 if (useLayer3Filtering)
1911 storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp +
1912 m_varMeasConfig.aRsrp * rsrp;
1914 if (std::isnan(storedMeasIt->second.rsrq))
1917 storedMeasIt->second.rsrq = rsrq;
1921 storedMeasIt->second.rsrq =
1922 (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq +
1923 m_varMeasConfig.aRsrq * rsrq;
1928 storedMeasIt->second.rsrp = rsrp;
1929 storedMeasIt->second.rsrq = rsrq;
1938 v.carrierFreq = m_cphySapProvider.at(componentCarrierId)->GetDlEarfcn();
1940 std::pair<uint16_t, MeasValues> val(cellId, v);
1941 auto ret = m_storedMeasValues.insert(val);
1942 NS_ASSERT_MSG(ret.second ==
true,
"element already existed");
1943 storedMeasIt = ret.first;
1946 NS_LOG_DEBUG(
this <<
" IMSI " << m_imsi <<
" state " <<
ToString(m_state) <<
", measured cell "
1947 << cellId <<
", carrier component Id " << componentCarrierId <<
", new RSRP "
1948 << rsrp <<
" stored " << storedMeasIt->second.rsrp <<
", new RSRQ " << rsrq
1949 <<
" stored " << storedMeasIt->second.rsrq);
1954NrUeRrc::MeasurementReportTriggering(uint8_t measId)
1956 NS_LOG_FUNCTION(
this << (uint16_t)measId);
1958 auto measIdIt = m_varMeasConfig.measIdList.find(measId);
1959 NS_ASSERT(measIdIt != m_varMeasConfig.measIdList.end());
1960 NS_ASSERT(measIdIt->first == measIdIt->second.measId);
1962 auto reportConfigIt = m_varMeasConfig.reportConfigList.find(measIdIt->second.reportConfigId);
1963 NS_ASSERT(reportConfigIt != m_varMeasConfig.reportConfigList.end());
1964 NrRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1966 auto measObjectIt = m_varMeasConfig.measObjectList.find(measIdIt->second.measObjectId);
1967 NS_ASSERT(measObjectIt != m_varMeasConfig.measObjectList.end());
1968 NrRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1970 auto measReportIt = m_varMeasReportList.find(measId);
1971 bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end());
1976 "only triggerType == event is supported");
1979 NS_LOG_LOGIC(
this <<
" considering measId " << (uint32_t)measId);
1980 bool eventEntryCondApplicable =
false;
1981 bool eventLeavingCondApplicable =
false;
1982 ConcernedCells_t concernedCellsEntry;
1983 ConcernedCells_t concernedCellsLeaving;
1992 uint16_t servingCellId = 0;
1993 for (
auto cphySapProvider : m_cphySapProvider)
1995 if (cphySapProvider->GetDlEarfcn() == measObjectEutra.carrierFreq)
1997 servingCellId = cphySapProvider->GetCellId();
2001 if (servingCellId == 0)
2006 switch (reportConfigEutra.eventId)
2020 switch (reportConfigEutra.triggerQuantity)
2023 ms = m_storedMeasValues[servingCellId].rsrp;
2025 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2031 ms = m_storedMeasValues[servingCellId].rsrq;
2032 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2037 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2042 bool entryCond = ms - hys > thresh;
2046 if (!isMeasIdInReportList)
2048 concernedCellsEntry.push_back(servingCellId);
2049 eventEntryCondApplicable =
true;
2057 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2058 measReportIt->second.cellsTriggeredList.end());
2061 else if (reportConfigEutra.timeToTrigger > 0)
2063 CancelEnteringTrigger(measId);
2067 bool leavingCond = ms + hys < thresh;
2071 if (isMeasIdInReportList)
2077 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(m_cellId) !=
2078 measReportIt->second.cellsTriggeredList.end());
2079 concernedCellsLeaving.push_back(m_cellId);
2080 eventLeavingCondApplicable =
true;
2083 else if (reportConfigEutra.timeToTrigger > 0)
2085 CancelLeavingTrigger(measId);
2088 NS_LOG_LOGIC(
this <<
" event A1: serving cell " << servingCellId <<
" ms=" << ms
2089 <<
" thresh=" << thresh <<
" entryCond=" << entryCond
2090 <<
" leavingCond=" << leavingCond);
2108 switch (reportConfigEutra.triggerQuantity)
2111 ms = m_storedMeasValues[servingCellId].rsrp;
2112 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2118 ms = m_storedMeasValues[servingCellId].rsrq;
2119 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2124 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2129 bool entryCond = ms + hys < thresh;
2133 if (!isMeasIdInReportList)
2135 concernedCellsEntry.push_back(servingCellId);
2136 eventEntryCondApplicable =
true;
2144 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2145 measReportIt->second.cellsTriggeredList.end());
2148 else if (reportConfigEutra.timeToTrigger > 0)
2150 CancelEnteringTrigger(measId);
2154 bool leavingCond = ms - hys > thresh;
2158 if (isMeasIdInReportList)
2164 NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2165 measReportIt->second.cellsTriggeredList.end());
2166 concernedCellsLeaving.push_back(servingCellId);
2167 eventLeavingCondApplicable =
true;
2170 else if (reportConfigEutra.timeToTrigger > 0)
2172 CancelLeavingTrigger(measId);
2175 NS_LOG_LOGIC(
this <<
" event A2: serving cell " << servingCellId <<
" ms=" << ms
2176 <<
" thresh=" << thresh <<
" entryCond=" << entryCond
2177 <<
" leavingCond=" << leavingCond);
2190 double ofn = measObjectEutra
2194 double ofp = measObjectEutra
2204 switch (reportConfigEutra.triggerQuantity)
2207 mp = m_storedMeasValues[m_cellId].rsrp;
2208 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2212 mp = m_storedMeasValues[m_cellId].rsrq;
2213 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2217 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2221 for (
auto storedMeasIt = m_storedMeasValues.begin();
2222 storedMeasIt != m_storedMeasValues.end();
2225 uint16_t cellId = storedMeasIt->first;
2226 if (cellId == m_cellId)
2233 if (m_storedMeasValues.at(cellId).carrierFreq != measObjectEutra.carrierFreq)
2238 switch (reportConfigEutra.triggerQuantity)
2241 mn = storedMeasIt->second.rsrp;
2244 mn = storedMeasIt->second.rsrq;
2247 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2252 isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2253 measReportIt->second.cellsTriggeredList.end());
2256 bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
2262 concernedCellsEntry.push_back(cellId);
2263 eventEntryCondApplicable =
true;
2266 else if (reportConfigEutra.timeToTrigger > 0)
2268 CancelEnteringTrigger(measId, cellId);
2272 bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2278 concernedCellsLeaving.push_back(cellId);
2279 eventLeavingCondApplicable =
true;
2282 else if (reportConfigEutra.timeToTrigger > 0)
2284 CancelLeavingTrigger(measId, cellId);
2287 NS_LOG_LOGIC(
this <<
" event A3: neighbor cell " << cellId <<
" mn=" << mn
2288 <<
" mp=" << mp <<
" offset=" << off <<
" entryCond=" << entryCond
2289 <<
" leavingCond=" << leavingCond);
2304 double ofn = measObjectEutra
2312 switch (reportConfigEutra.triggerQuantity)
2315 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2321 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2326 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2330 for (
auto storedMeasIt = m_storedMeasValues.begin();
2331 storedMeasIt != m_storedMeasValues.end();
2334 uint16_t cellId = storedMeasIt->first;
2335 if (cellId == m_cellId)
2340 switch (reportConfigEutra.triggerQuantity)
2343 mn = storedMeasIt->second.rsrp;
2346 mn = storedMeasIt->second.rsrq;
2349 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2354 isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2355 measReportIt->second.cellsTriggeredList.end());
2358 bool entryCond = mn + ofn + ocn - hys > thresh;
2364 concernedCellsEntry.push_back(cellId);
2365 eventEntryCondApplicable =
true;
2368 else if (reportConfigEutra.timeToTrigger > 0)
2370 CancelEnteringTrigger(measId, cellId);
2374 bool leavingCond = mn + ofn + ocn + hys < thresh;
2380 concernedCellsLeaving.push_back(cellId);
2381 eventLeavingCondApplicable =
true;
2384 else if (reportConfigEutra.timeToTrigger > 0)
2386 CancelLeavingTrigger(measId, cellId);
2389 NS_LOG_LOGIC(
this <<
" event A4: neighbor cell " << cellId <<
" mn=" << mn
2390 <<
" thresh=" << thresh <<
" entryCond=" << entryCond
2391 <<
" leavingCond=" << leavingCond);
2408 double ofn = measObjectEutra
2417 switch (reportConfigEutra.triggerQuantity)
2420 mp = m_storedMeasValues[m_cellId].rsrp;
2421 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2423 NS_ASSERT(reportConfigEutra.threshold2.choice ==
2431 mp = m_storedMeasValues[m_cellId].rsrq;
2432 NS_ASSERT(reportConfigEutra.threshold1.choice ==
2434 NS_ASSERT(reportConfigEutra.threshold2.choice ==
2442 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2447 bool entryCond = mp + hys < thresh1;
2451 for (
auto storedMeasIt = m_storedMeasValues.begin();
2452 storedMeasIt != m_storedMeasValues.end();
2455 uint16_t cellId = storedMeasIt->first;
2456 if (cellId == m_cellId)
2461 switch (reportConfigEutra.triggerQuantity)
2464 mn = storedMeasIt->second.rsrp;
2467 mn = storedMeasIt->second.rsrq;
2470 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2475 isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2476 measReportIt->second.cellsTriggeredList.end());
2480 entryCond = mn + ofn + ocn - hys > thresh2;
2486 concernedCellsEntry.push_back(cellId);
2487 eventEntryCondApplicable =
true;
2490 else if (reportConfigEutra.timeToTrigger > 0)
2492 CancelEnteringTrigger(measId, cellId);
2495 NS_LOG_LOGIC(
this <<
" event A5: neighbor cell " << cellId <<
" mn=" << mn
2496 <<
" mp=" << mp <<
" thresh2=" << thresh2
2497 <<
" thresh1=" << thresh1 <<
" entryCond=" << entryCond);
2504 NS_LOG_LOGIC(
this <<
" event A5: serving cell " << m_cellId <<
" mp=" << mp
2505 <<
" thresh1=" << thresh1 <<
" entryCond=" << entryCond);
2507 if (reportConfigEutra.timeToTrigger > 0)
2509 CancelEnteringTrigger(measId);
2513 if (isMeasIdInReportList)
2516 bool leavingCond = mp - hys > thresh1;
2520 if (reportConfigEutra.timeToTrigger == 0)
2524 for (
auto storedMeasIt = m_storedMeasValues.begin();
2525 storedMeasIt != m_storedMeasValues.end();
2528 uint16_t cellId = storedMeasIt->first;
2529 if (cellId == m_cellId)
2534 if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2535 measReportIt->second.cellsTriggeredList.end())
2537 concernedCellsLeaving.push_back(cellId);
2538 eventLeavingCondApplicable =
true;
2546 for (
auto storedMeasIt = m_storedMeasValues.begin();
2547 storedMeasIt != m_storedMeasValues.end();
2550 uint16_t cellId = storedMeasIt->first;
2551 if (cellId == m_cellId)
2556 if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2557 measReportIt->second.cellsTriggeredList.end())
2559 switch (reportConfigEutra.triggerQuantity)
2562 mn = storedMeasIt->second.rsrp;
2565 mn = storedMeasIt->second.rsrq;
2568 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2574 leavingCond = mn + ofn + ocn + hys < thresh2;
2578 CancelLeavingTrigger(measId, cellId);
2586 concernedCellsLeaving.push_back(cellId);
2587 eventLeavingCondApplicable =
true;
2589 NS_LOG_LOGIC(
this <<
" event A5: neighbor cell " << cellId
2590 <<
" mn=" << mn <<
" mp=" << mp
2591 <<
" thresh2=" << thresh2 <<
" thresh1=" << thresh1
2592 <<
" leavingCond=" << leavingCond);
2601 NS_LOG_LOGIC(
this <<
" event A5: serving cell " << m_cellId <<
" mp=" << mp
2602 <<
" thresh1=" << thresh1 <<
" leavingCond=" << leavingCond);
2607 if (reportConfigEutra.timeToTrigger > 0)
2609 CancelLeavingTrigger(measId);
2614 for (
auto storedMeasIt = m_storedMeasValues.begin();
2615 storedMeasIt != m_storedMeasValues.end();
2618 uint16_t cellId = storedMeasIt->first;
2619 if (cellId == m_cellId)
2624 if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2625 measReportIt->second.cellsTriggeredList.end())
2627 switch (reportConfigEutra.triggerQuantity)
2630 mn = storedMeasIt->second.rsrp;
2633 mn = storedMeasIt->second.rsrq;
2636 NS_FATAL_ERROR(
"unsupported triggerQuantity");
2641 leavingCond = mn + ofn + ocn + hys < thresh2;
2645 concernedCellsLeaving.push_back(cellId);
2646 eventLeavingCondApplicable =
true;
2649 NS_LOG_LOGIC(
this <<
" event A5: neighbor cell " << cellId <<
" mn=" << mn
2650 <<
" mp=" << mp <<
" thresh2=" << thresh2 <<
" thresh1="
2651 << thresh1 <<
" leavingCond=" << leavingCond);
2667 NS_FATAL_ERROR(
"unsupported eventId " << reportConfigEutra.eventId);
2672 NS_LOG_LOGIC(
this <<
" eventEntryCondApplicable=" << eventEntryCondApplicable
2673 <<
" eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2675 if (eventEntryCondApplicable)
2677 if (reportConfigEutra.timeToTrigger == 0)
2679 VarMeasReportListAdd(measId, concernedCellsEntry);
2685 t.concernedCells = concernedCellsEntry;
2686 t.timer = Simulator::Schedule(MilliSeconds(reportConfigEutra.timeToTrigger),
2687 &NrUeRrc::VarMeasReportListAdd,
2690 concernedCellsEntry);
2691 auto enteringTriggerIt = m_enteringTriggerQueue.find(measId);
2692 NS_ASSERT(enteringTriggerIt != m_enteringTriggerQueue.end());
2693 enteringTriggerIt->second.push_back(t);
2697 if (eventLeavingCondApplicable)
2701 reportConfigEutra.reportOnLeave;
2703 if (reportConfigEutra.timeToTrigger == 0)
2705 VarMeasReportListErase(measId, concernedCellsLeaving, reportOnLeave);
2711 t.concernedCells = concernedCellsLeaving;
2712 t.timer = Simulator::Schedule(MilliSeconds(reportConfigEutra.timeToTrigger),
2713 &NrUeRrc::VarMeasReportListErase,
2716 concernedCellsLeaving,
2718 auto leavingTriggerIt = m_leavingTriggerQueue.find(measId);
2719 NS_ASSERT(leavingTriggerIt != m_leavingTriggerQueue.end());
2720 leavingTriggerIt->second.push_back(t);
2727NrUeRrc::CancelEnteringTrigger(uint8_t measId)
2729 NS_LOG_FUNCTION(
this << (uint16_t)measId);
2731 auto it1 = m_enteringTriggerQueue.find(measId);
2732 NS_ASSERT(it1 != m_enteringTriggerQueue.end());
2734 if (!it1->second.empty())
2736 for (
auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
2738 NS_ASSERT(it2->measId == measId);
2739 NS_LOG_LOGIC(
this <<
" canceling entering time-to-trigger event at "
2740 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2741 Simulator::Cancel(it2->timer);
2744 it1->second.clear();
2749NrUeRrc::CancelEnteringTrigger(uint8_t measId, uint16_t cellId)
2751 NS_LOG_FUNCTION(
this << (uint16_t)measId << cellId);
2753 auto it1 = m_enteringTriggerQueue.find(measId);
2754 NS_ASSERT(it1 != m_enteringTriggerQueue.end());
2756 auto it2 = it1->second.begin();
2757 while (it2 != it1->second.end())
2759 NS_ASSERT(it2->measId == measId);
2761 for (
auto it3 = it2->concernedCells.begin(); it3 != it2->concernedCells.end(); ++it3)
2765 it3 = it2->concernedCells.erase(it3);
2769 if (it2->concernedCells.empty())
2771 NS_LOG_LOGIC(
this <<
" canceling entering time-to-trigger event at "
2772 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2773 Simulator::Cancel(it2->timer);
2774 it2 = it1->second.erase(it2);
2784NrUeRrc::CancelLeavingTrigger(uint8_t measId)
2786 NS_LOG_FUNCTION(
this << (uint16_t)measId);
2788 auto it1 = m_leavingTriggerQueue.find(measId);
2789 NS_ASSERT(it1 != m_leavingTriggerQueue.end());
2791 if (!it1->second.empty())
2793 for (
auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
2795 NS_ASSERT(it2->measId == measId);
2796 NS_LOG_LOGIC(
this <<
" canceling leaving time-to-trigger event at "
2797 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2798 Simulator::Cancel(it2->timer);
2801 it1->second.clear();
2806NrUeRrc::CancelLeavingTrigger(uint8_t measId, uint16_t cellId)
2808 NS_LOG_FUNCTION(
this << (uint16_t)measId << cellId);
2810 auto it1 = m_leavingTriggerQueue.find(measId);
2811 NS_ASSERT(it1 != m_leavingTriggerQueue.end());
2813 auto it2 = it1->second.begin();
2814 while (it2 != it1->second.end())
2816 NS_ASSERT(it2->measId == measId);
2818 for (
auto it3 = it2->concernedCells.begin(); it3 != it2->concernedCells.end(); ++it3)
2822 it3 = it2->concernedCells.erase(it3);
2826 if (it2->concernedCells.empty())
2828 NS_LOG_LOGIC(
this <<
" canceling leaving time-to-trigger event at "
2829 << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2830 Simulator::Cancel(it2->timer);
2831 it2 = it1->second.erase(it2);
2841NrUeRrc::VarMeasReportListAdd(uint8_t measId, ConcernedCells_t enteringCells)
2843 NS_LOG_FUNCTION(
this << (uint16_t)measId);
2844 NS_ASSERT(!enteringCells.empty());
2846 auto measReportIt = m_varMeasReportList.find(measId);
2848 if (measReportIt == m_varMeasReportList.end())
2852 std::pair<uint8_t, VarMeasReport> val(measId, r);
2853 auto ret = m_varMeasReportList.insert(val);
2854 NS_ASSERT_MSG(ret.second ==
true,
"element already existed");
2855 measReportIt = ret.first;
2858 NS_ASSERT(measReportIt != m_varMeasReportList.end());
2860 for (
auto it = enteringCells.begin(); it != enteringCells.end(); ++it)
2862 measReportIt->second.cellsTriggeredList.insert(*it);
2865 NS_ASSERT(!measReportIt->second.cellsTriggeredList.empty());
2868 if (!measReportIt->second.periodicReportTimer.IsPending())
2870 measReportIt->second.numberOfReportsSent = 0;
2871 measReportIt->second.periodicReportTimer =
2872 Simulator::Schedule(NR_UE_MEASUREMENT_REPORT_DELAY,
2873 &NrUeRrc::SendMeasurementReport,
2878 auto enteringTriggerIt = m_enteringTriggerQueue.find(measId);
2879 NS_ASSERT(enteringTriggerIt != m_enteringTriggerQueue.end());
2880 if (!enteringTriggerIt->second.empty())
2888 enteringTriggerIt->second.pop_front();
2890 if (!enteringTriggerIt->second.empty())
2897 for (
auto it = enteringCells.begin(); it != enteringCells.end(); ++it)
2899 CancelEnteringTrigger(measId, *it);
2908NrUeRrc::VarMeasReportListErase(uint8_t measId, ConcernedCells_t leavingCells,
bool reportOnLeave)
2910 NS_LOG_FUNCTION(
this << (uint16_t)measId);
2911 NS_ASSERT(!leavingCells.empty());
2913 auto measReportIt = m_varMeasReportList.find(measId);
2914 NS_ASSERT(measReportIt != m_varMeasReportList.end());
2916 for (
auto it = leavingCells.begin(); it != leavingCells.end(); ++it)
2918 measReportIt->second.cellsTriggeredList.erase(*it);
2924 SendMeasurementReport(measId);
2927 if (measReportIt->second.cellsTriggeredList.empty())
2929 measReportIt->second.periodicReportTimer.Cancel();
2930 m_varMeasReportList.erase(measReportIt);
2933 auto leavingTriggerIt = m_leavingTriggerQueue.find(measId);
2934 NS_ASSERT(leavingTriggerIt != m_leavingTriggerQueue.end());
2935 if (!leavingTriggerIt->second.empty())
2943 leavingTriggerIt->second.pop_front();
2945 if (!leavingTriggerIt->second.empty())
2952 for (
auto it = leavingCells.begin(); it != leavingCells.end(); ++it)
2954 CancelLeavingTrigger(measId, *it);
2963NrUeRrc::VarMeasReportListClear(uint8_t measId)
2965 NS_LOG_FUNCTION(
this << (uint16_t)measId);
2968 auto measReportIt = m_varMeasReportList.find(measId);
2969 if (measReportIt != m_varMeasReportList.end())
2971 NS_LOG_LOGIC(
this <<
" deleting existing report for measId " << (uint16_t)measId);
2972 measReportIt->second.periodicReportTimer.Cancel();
2973 m_varMeasReportList.erase(measReportIt);
2976 CancelEnteringTrigger(measId);
2977 CancelLeavingTrigger(measId);
2981NrUeRrc::SendMeasurementReport(uint8_t measId)
2983 NS_LOG_FUNCTION(
this << (uint16_t)measId);
2986 auto measIdIt = m_varMeasConfig.measIdList.find(measId);
2987 NS_ASSERT(measIdIt != m_varMeasConfig.measIdList.end());
2989 auto reportConfigIt = m_varMeasConfig.reportConfigList.find(measIdIt->second.reportConfigId);
2990 NS_ASSERT(reportConfigIt != m_varMeasConfig.reportConfigList.end());
2991 NrRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2993 NrRrcSap::MeasurementReport measurementReport;
2994 NrRrcSap::MeasResults& measResults = measurementReport.measResults;
2995 measResults.measId = measId;
2997 auto measReportIt = m_varMeasReportList.find(measId);
2998 if (measReportIt == m_varMeasReportList.end())
3000 NS_LOG_ERROR(
"no entry found in m_varMeasReportList for measId " << (uint32_t)measId);
3004 auto servingMeasIt = m_storedMeasValues.find(m_cellId);
3005 NS_ASSERT(servingMeasIt != m_storedMeasValues.end());
3006 measResults.measResultPCell.rsrpResult =
3008 measResults.measResultPCell.rsrqResult =
3010 NS_LOG_INFO(
this <<
" reporting serving cell "
3012 << +measResults.measResultPCell.rsrpResult <<
" ("
3013 << servingMeasIt->second.rsrp
3016 << +measResults.measResultPCell.rsrqResult <<
" ("
3017 << servingMeasIt->second.rsrq <<
" dB)");
3019 measResults.haveMeasResultServFreqList =
false;
3021 componentCarrierId++)
3023 const uint16_t cellId = m_cphySapProvider.at(componentCarrierId)->GetCellId();
3024 auto measValuesIt = m_storedMeasValues.find(cellId);
3025 if (measValuesIt != m_storedMeasValues.end())
3027 measResults.haveMeasResultServFreqList =
true;
3028 NrRrcSap::MeasResultServFreq measResultServFreq;
3029 measResultServFreq.servFreqId = componentCarrierId;
3030 measResultServFreq.haveMeasResultSCell =
true;
3031 measResultServFreq.measResultSCell.rsrpResult =
3033 measResultServFreq.measResultSCell.rsrqResult =
3035 measResultServFreq.haveMeasResultBestNeighCell =
false;
3036 measResults.measResultServFreqList.push_back(measResultServFreq);
3040 measResults.haveMeasResultNeighCells =
false;
3042 if (!(measReportIt->second.cellsTriggeredList.empty()))
3044 std::multimap<double, uint16_t> sortedNeighCells;
3045 for (
auto cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin();
3046 cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end();
3049 uint16_t cellId = *cellsTriggeredIt;
3050 if (cellId != m_cellId)
3052 auto neighborMeasIt = m_storedMeasValues.find(cellId);
3053 double triggerValue;
3054 switch (reportConfigEutra.triggerQuantity)
3057 triggerValue = neighborMeasIt->second.rsrp;
3060 triggerValue = neighborMeasIt->second.rsrq;
3063 NS_FATAL_ERROR(
"unsupported triggerQuantity");
3066 sortedNeighCells.insert(std::pair<double, uint16_t>(triggerValue, cellId));
3070 std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
3072 for (sortedNeighCellsIt = sortedNeighCells.rbegin(), count = 0;
3073 sortedNeighCellsIt != sortedNeighCells.rend() &&
3074 count < reportConfigEutra.maxReportCells;
3075 ++sortedNeighCellsIt, ++count)
3077 uint16_t cellId = sortedNeighCellsIt->second;
3078 auto neighborMeasIt = m_storedMeasValues.find(cellId);
3079 NS_ASSERT(neighborMeasIt != m_storedMeasValues.end());
3080 NrRrcSap::MeasResultEutra measResultEutra;
3081 measResultEutra.physCellId = cellId;
3082 measResultEutra.haveCgiInfo =
false;
3083 measResultEutra.haveRsrpResult =
true;
3084 measResultEutra.rsrpResult =
3086 measResultEutra.haveRsrqResult =
true;
3087 measResultEutra.rsrqResult =
3089 NS_LOG_INFO(
this <<
" reporting neighbor cell "
3090 << (uint32_t)measResultEutra.physCellId <<
" RSRP "
3091 << (uint32_t)measResultEutra.rsrpResult <<
" ("
3092 << neighborMeasIt->second.rsrp <<
" dBm)"
3093 <<
" RSRQ " << (uint32_t)measResultEutra.rsrqResult <<
" ("
3094 << neighborMeasIt->second.rsrq <<
" dB)");
3095 measResults.measResultListEutra.push_back(measResultEutra);
3096 measResults.haveMeasResultNeighCells =
true;
3101 NS_LOG_WARN(
this <<
" cellsTriggeredList is empty");
3109 measReportIt->second.numberOfReportsSent++;
3110 measReportIt->second.periodicReportTimer.Cancel();
3112 Time reportInterval;
3113 switch (reportConfigEutra.reportInterval)
3115 case NrRrcSap::ReportConfigEutra::MS120:
3116 reportInterval = MilliSeconds(120);
3118 case NrRrcSap::ReportConfigEutra::MS240:
3119 reportInterval = MilliSeconds(240);
3121 case NrRrcSap::ReportConfigEutra::MS480:
3122 reportInterval = MilliSeconds(480);
3124 case NrRrcSap::ReportConfigEutra::MS640:
3125 reportInterval = MilliSeconds(640);
3127 case NrRrcSap::ReportConfigEutra::MS1024:
3128 reportInterval = MilliSeconds(1024);
3130 case NrRrcSap::ReportConfigEutra::MS2048:
3131 reportInterval = MilliSeconds(2048);
3133 case NrRrcSap::ReportConfigEutra::MS5120:
3134 reportInterval = MilliSeconds(5120);
3136 case NrRrcSap::ReportConfigEutra::MS10240:
3137 reportInterval = MilliSeconds(10240);
3139 case NrRrcSap::ReportConfigEutra::MIN1:
3140 reportInterval = Seconds(60);
3142 case NrRrcSap::ReportConfigEutra::MIN6:
3143 reportInterval = Seconds(360);
3145 case NrRrcSap::ReportConfigEutra::MIN12:
3146 reportInterval = Seconds(720);
3148 case NrRrcSap::ReportConfigEutra::MIN30:
3149 reportInterval = Seconds(1800);
3151 case NrRrcSap::ReportConfigEutra::MIN60:
3152 reportInterval = Seconds(3600);
3155 NS_FATAL_ERROR(
"Unsupported reportInterval "
3156 << (uint16_t)reportConfigEutra.reportInterval);
3161 measReportIt->second.periodicReportTimer =
3162 Simulator::Schedule(reportInterval, &NrUeRrc::SendMeasurementReport,
this, measId);
3170NrUeRrc::StartConnection()
3172 NS_LOG_FUNCTION(
this << m_imsi);
3173 NS_ASSERT(m_hasReceivedMib);
3174 NS_ASSERT(m_hasReceivedSib2);
3175 m_connectionPending =
false;
3176 SwitchToState(IDLE_RANDOM_ACCESS);
3177 m_cmacSapProvider.at(
GetPrimaryUlIndex())->StartContentionBasedRandomAccessProcedure();
3181NrUeRrc::LeaveConnectedMode()
3183 NS_LOG_FUNCTION(
this << m_imsi);
3184 m_leaveConnectedMode =
true;
3185 m_storedMeasValues.clear();
3188 for (
auto measIdIt = m_varMeasConfig.measIdList.begin();
3189 measIdIt != m_varMeasConfig.measIdList.end();
3192 VarMeasReportListClear(measIdIt->second.measId);
3194 m_varMeasConfig.measIdList.clear();
3196 m_ccmRrcSapProvider->
Reset();
3200 m_cmacSapProvider.at(i)->Reset();
3204 m_bid2DrbidMap.clear();
3206 m_hasReceivedMib =
false;
3207 m_hasReceivedSib1 =
false;
3208 m_hasReceivedSib2 =
false;
3212 m_cphySapProvider.at(i)->ResetPhyAfterRlf();
3214 SwitchToState(IDLE_START);
3215 DoStartCellSelection(m_dlEarfcn);
3220 m_srb0->m_rlc->SetRnti(m_rnti);
3224NrUeRrc::ConnectionTimeout()
3226 NS_LOG_FUNCTION(
this << m_imsi);
3227 ++m_connEstFailCount;
3228 if (m_connEstFailCount >= m_connEstFailCountLimit)
3230 m_connectionTimeoutTrace(m_imsi, m_cellId, m_rnti, m_connEstFailCount);
3231 SwitchToState(CONNECTED_PHY_PROBLEM);
3237 m_connEstFailCount = 0;
3243 m_cmacSapProvider.at(i)->Reset();
3245 m_hasReceivedSib2 =
false;
3246 SwitchToState(IDLE_CAMPED_NORMALLY);
3247 m_connectionTimeoutTrace(m_imsi, m_cellId, m_rnti, m_connEstFailCount);
3255NrUeRrc::DisposeOldSrb1()
3257 NS_LOG_FUNCTION(
this);
3258 m_srb1Old =
nullptr;
3262NrUeRrc::Bid2Drbid(uint8_t bid)
3264 auto it = m_bid2DrbidMap.find(bid);
3266 if (it == m_bid2DrbidMap.end())
3277NrUeRrc::SwitchToState(State newState)
3279 NS_LOG_FUNCTION(
this <<
ToString(newState));
3280 State oldState = m_state;
3282 NS_LOG_INFO(
this <<
" IMSI " << m_imsi <<
" RNTI " << m_rnti <<
" UeRrc " <<
ToString(oldState)
3284 m_stateTransitionTrace(m_imsi, m_cellId, m_rnti, oldState, newState);
3289 if (m_leaveConnectedMode)
3291 NS_LOG_INFO(
"Starting initial cell selection after RLF");
3295 NS_FATAL_ERROR(
"cannot switch to an initial state");
3299 case IDLE_CELL_SEARCH:
3300 case IDLE_WAIT_MIB_SIB1:
3302 case IDLE_WAIT_SIB1:
3305 case IDLE_CAMPED_NORMALLY:
3306 if (m_connectionPending)
3308 SwitchToState(IDLE_WAIT_SIB2);
3312 case IDLE_WAIT_SIB2:
3313 if (m_hasReceivedSib2)
3315 NS_ASSERT(m_connectionPending);
3320 case IDLE_RANDOM_ACCESS:
3321 case IDLE_CONNECTING:
3322 case CONNECTED_NORMALLY:
3323 case CONNECTED_HANDOVER:
3324 case CONNECTED_PHY_PROBLEM:
3325 case CONNECTED_REESTABLISHING:
3332NrUeRrc::RadioLinkFailureDetected()
3334 NS_LOG_FUNCTION(
this << m_imsi << m_rnti);
3335 m_radioLinkFailureTrace(m_imsi, m_cellId, m_rnti);
3336 SwitchToState(CONNECTED_PHY_PROBLEM);
3342NrUeRrc::DoNotifyInSync()
3344 NS_LOG_FUNCTION(
this << m_imsi);
3345 m_noOfSyncIndications++;
3346 NS_LOG_INFO(
"noOfSyncIndications " << (uint16_t)m_noOfSyncIndications);
3347 m_phySyncDetectionTrace(m_imsi, m_rnti, m_cellId,
"Notify in sync", m_noOfSyncIndications);
3348 if (m_noOfSyncIndications == m_n311)
3355NrUeRrc::DoNotifyOutOfSync()
3357 NS_LOG_FUNCTION(
this << m_imsi);
3358 m_noOfSyncIndications++;
3359 NS_LOG_INFO(
this <<
" Total Number of Sync indications from PHY "
3360 << (uint16_t)m_noOfSyncIndications <<
"N310 value : " << (uint16_t)m_n310);
3361 m_phySyncDetectionTrace(m_imsi, m_rnti, m_cellId,
"Notify out of sync", m_noOfSyncIndications);
3362 if (m_noOfSyncIndications == m_n310)
3364 m_radioLinkFailureDetected =
3365 Simulator::Schedule(m_t310, &NrUeRrc::RadioLinkFailureDetected,
this);
3366 if (m_radioLinkFailureDetected.IsPending())
3368 NS_LOG_INFO(
"t310 started");
3371 m_noOfSyncIndications = 0;
3376NrUeRrc::DoResetSyncIndicationCounter()
3378 NS_LOG_FUNCTION(
this << m_imsi);
3380 NS_LOG_DEBUG(
"The number of sync indication received by RRC from PHY: "
3381 << (uint16_t)m_noOfSyncIndications);
3382 m_noOfSyncIndications = 0;
3386NrUeRrc::ResetRlfParams()
3388 NS_LOG_FUNCTION(
this << m_imsi);
3389 m_radioLinkFailureDetected.Cancel();
3390 m_noOfSyncIndications = 0;
3397 return g_ueRrcStateName[s];
virtual void NotifyConnectionSuccessful()=0
Notify the NAS that RRC Connection Establishment was successful.
virtual void NotifyConnectionReleased()=0
virtual void RecvData(Ptr< Packet > packet)=0
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
static TypeId GetTypeId()
Get the type ID.
void SetNrMacSapProvider(NrMacSapProvider *s)
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Service Access Point (SAP) offered by the UE component carrier manager to the UE RRC.
virtual NrMacSapUser * ConfigureSignalBearer(uint8_t lcid, NrUeCmacSapProvider::LogicalChannelConfig lcConfig, NrMacSapUser *msu)=0
Add the Signal Bearer for a specific Ue in NrUeComponenCarrierManager.
virtual std::vector< NrUeCcmRrcSapProvider::LcsConfig > AddLc(uint8_t lcId, NrUeCmacSapProvider::LogicalChannelConfig lcConfig, NrMacSapUser *msu)=0
virtual void Reset()=0
Reset LC maps.
Service Access Point (SAP) offered by the UE RRC to the UE CCM.
void SetNrUeCphySapProvider(NrUeCphySapProvider *s)
NrAsSapProvider * GetAsSapProvider()
void SetPrimaryUlIndex(uint16_t primaryIndex)
Sets the index of the UE PHY/MAC that will be used as the primary UL PHY/MAC.
friend class MemberNrUeRrcSapProvider< NrUeRrc >
allow MemberNrUeRrcSapProvider<NrUeRrc> class friend access
uint16_t GetPrimaryDlIndex() const
Returns the primary index.
uint8_t GetDlBandwidth() const
void SetNrCcmRrcSapProvider(NrUeCcmRrcSapProvider *s)
uint32_t GetDlEarfcn() const
uint16_t GetPrimaryUlIndex() const
Returns the primary index.
uint16_t GetPreviousCellId() const
Get the previous cell id.
void SetAsSapUser(NrAsSapUser *s)
void SetPrimaryDlIndex(uint16_t primaryIndex)
Sets the index of the UE PHY/MAC that will be used as the primary UL PHY/MAC.
NrUeCcmRrcSapUser * GetNrCcmRrcSapUser()
friend class MemberNrAsSapProvider< NrUeRrc >
allow MemberNrAsSapProvider<NrUeRrc> class friend access
void SetUseRlcSm(bool val)
friend class UeMemberNrUeCmacSapUser
allow UeMemberNrUeCmacSapUser class friend access
static TypeId GetTypeId()
Get the type ID.
void SetNrMacSapProvider(NrMacSapProvider *s)
static const std::string ToString(NrUeRrc::State s)
uint32_t GetUlEarfcn() const
void SetNrUeCmacSapProvider(NrUeCmacSapProvider *s)
This function is overloaded to maintain backward compatibility.
void SetImsi(uint64_t imsi)
bool IsServingCell(uint16_t cellId) const
NrUeCphySapUser * GetNrUeCphySapUser()
NrUeRrcSapProvider * GetNrUeRrcSapProvider()
void InitializeSap()
Initialize SAP.
uint8_t GetUlBandwidth() const
uint16_t m_numberOfComponentCarriers
void SetNrUeRrcSapUser(NrUeRrcSapUser *s)
friend class MemberNrUeCcmRrcSapUser< NrUeRrc >
allow MemberNrUeCcmRrcSapUser<NrUeRrc> class friend access
NrUeCmacSapUser * GetNrUeCmacSapUser()
This function is overloaded to maintain backward compatibility.
uint16_t GetCellId() const
friend class NrPdcpSpecificNrPdcpSapUser< NrUeRrc >
allow NrPdcpSpecificNrPdcpSapUser<NrUeRrc> class friend access
void InitializeSrb0()
Initialize the UE side of SRB0.
void StorePreviousCellId(uint16_t cellId)
Store the previous cell id.
Part of the RRC protocol. This Service Access Point (SAP) is used to let the UE RRC receive a message...
Part of the RRC protocol. This Service Access Point (SAP) is used by the UE RRC to send messages to t...
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
virtual void Setup(SetupParameters params)=0
Setup 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...
virtual void SendIdealUeContextRemoveRequest(uint16_t rnti)=0
Send UE context remove request function.
virtual void SendMeasurementReport(MeasurementReport msg)=0
Send a MeasurementReport message to the serving eNodeB during a measurement reporting procedure (Sect...
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
static double RsrqRange2Db(uint8_t range)
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
static double RsrpRange2Dbm(uint8_t range)
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
static uint8_t Dbm2RsrpRange(double dbm)
static uint8_t Db2RsrqRange(double db)
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
@ RSRP
Reference Signal Received Power.
@ RSRQ
Reference Signal Received Quality.
@ PERIODICAL
periodical report
@ EVENT_A2
Event A2: Serving becomes worse than absolute threshold.
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
@ EVENT_A4
Event A4: Neighbour becomes better than absolute threshold.
@ EVENT_A3
Event A3: Neighbour becomes amount of offset better than PCell.
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
@ THRESHOLD_RSRP
RSRP is used for the threshold.
LogicalChannelConfig structure.
uint16_t bucketSizeDurationMs
bucket size duration ms
uint8_t logicalChannelGroup
logical channel group
uint16_t prioritizedBitRateKbps
prioritize bit rate Kbps
SetupParameters structure.
NrRlcSapProvider * srb0SapProvider
SRB0 SAP provider.
NrPdcpSapProvider * srb1SapProvider
SRB1 SAP provider.