Commit 3cb309f6 authored by aligungr's avatar aligungr

Registration updating abnormal case handling

parent 28510561
...@@ -208,15 +208,25 @@ void NasMm::onSwitchCmState(ECmState oldState, ECmState newState) ...@@ -208,15 +208,25 @@ void NasMm::onSwitchCmState(ECmState oldState, ECmState newState)
// 5.5.1.2.7 Abnormal cases in the UE (in registration) // 5.5.1.2.7 Abnormal cases in the UE (in registration)
if (m_mmState == EMmState::MM_REGISTERED_INITIATED) if (m_mmState == EMmState::MM_REGISTERED_INITIATED)
{ {
// e) Lower layer failure or release of the NAS signalling connection received from lower layers before the // "Lower layer failure or release of the NAS signalling connection received from lower layers before the
// REGISTRATION ACCEPT or REGISTRATION REJECT message is received. The UE shall abort the registration // REGISTRATION ACCEPT or REGISTRATION REJECT message is received. The UE shall abort the registration
// procedure for initial registration and proceed as ... // procedure for initial registration and proceed as ..."
auto regType = m_lastRegistrationRequest->registrationType.registrationType;
if (regType == nas::ERegistrationType::INITIAL_REGISTRATION ||
regType == nas::ERegistrationType::EMERGENCY_REGISTRATION)
{
switchRmState(ERmState::RM_DEREGISTERED); switchRmState(ERmState::RM_DEREGISTERED);
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA); switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA);
switchUState(E5UState::U2_NOT_UPDATED); switchUState(E5UState::U2_NOT_UPDATED);
handleCommonAbnormalRegFailure(m_lastRegistrationRequest->registrationType.registrationType); handleAbnormalInitialRegFailure(regType);
}
else
{
handleAbnormalMobilityRegFailure(regType);
}
} }
// 5.5.2.2.6 Abnormal cases in the UE (in de-registration) // 5.5.2.2.6 Abnormal cases in the UE (in de-registration)
else if (m_mmState == EMmState::MM_DEREGISTERED_INITIATED) else if (m_mmState == EMmState::MM_DEREGISTERED_INITIATED)
......
...@@ -95,7 +95,8 @@ class NasMm ...@@ -95,7 +95,8 @@ class NasMm
void receiveRegistrationReject(const nas::RegistrationReject &msg); void receiveRegistrationReject(const nas::RegistrationReject &msg);
void receiveInitialRegistrationReject(const nas::RegistrationReject &msg); void receiveInitialRegistrationReject(const nas::RegistrationReject &msg);
void receiveMobilityRegistrationReject(const nas::RegistrationReject &msg); void receiveMobilityRegistrationReject(const nas::RegistrationReject &msg);
void handleCommonAbnormalRegFailure(nas::ERegistrationType regType); void handleAbnormalInitialRegFailure(nas::ERegistrationType regType);
void handleAbnormalMobilityRegFailure(nas::ERegistrationType regType);
private: /* Authentication */ private: /* Authentication */
void receiveAuthenticationRequest(const nas::AuthenticationRequest &msg); void receiveAuthenticationRequest(const nas::AuthenticationRequest &msg);
......
...@@ -109,10 +109,24 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) ...@@ -109,10 +109,24 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
return; return;
} }
m_logger->debug("Sending %s", // 5.5.1.3.7 Abnormal cases in the UE
nas::utils::EnumToString(updateCause == ERegUpdateCause::PERIODIC_REGISTRATION // a) Timer T3346 is running.
if (m_timers->t3346.isRunning())
{
bool allowed = m_cmState == ECmState::CM_CONNECTED || updateCause == ERegUpdateCause::PAGING_OR_NOTIFICATION ||
isHighPriority() || hasEmergency() || updateCause == ERegUpdateCause::CONFIGURATION_UPDATE;
if (!allowed)
{
m_logger->debug("Registration updating canceled, T3346 is running");
return;
}
}
m_logger->debug("Sending %s with update cause [%s]",
nas::utils::EnumToString(updateCause == ERegUpdateCause::T3512_EXPIRY
? nas::ERegistrationType::PERIODIC_REGISTRATION_UPDATING ? nas::ERegistrationType::PERIODIC_REGISTRATION_UPDATING
: nas::ERegistrationType::MOBILITY_REGISTRATION_UPDATING)); : nas::ERegistrationType::MOBILITY_REGISTRATION_UPDATING),
ToJson(updateCause).str().c_str());
// Switch state // Switch state
switchMmState(EMmState::MM_REGISTERED_INITIATED, EMmSubState::MM_REGISTERED_INITIATED_NA); switchMmState(EMmState::MM_REGISTERED_INITIATED, EMmSubState::MM_REGISTERED_INITIATED_NA);
...@@ -127,7 +141,7 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) ...@@ -127,7 +141,7 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
// Create registration request // Create registration request
auto request = std::make_unique<nas::RegistrationRequest>(); auto request = std::make_unique<nas::RegistrationRequest>();
request->registrationType = request->registrationType =
nas::IE5gsRegistrationType{followOn, updateCause == ERegUpdateCause::PERIODIC_REGISTRATION nas::IE5gsRegistrationType{followOn, updateCause == ERegUpdateCause::T3512_EXPIRY
? nas::ERegistrationType::PERIODIC_REGISTRATION_UPDATING ? nas::ERegistrationType::PERIODIC_REGISTRATION_UPDATING
: nas::ERegistrationType::MOBILITY_REGISTRATION_UPDATING}; : nas::ERegistrationType::MOBILITY_REGISTRATION_UPDATING};
...@@ -139,7 +153,7 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) ...@@ -139,7 +153,7 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
: nas::ENgRanRadioCapabilityUpdate::NOT_NEEDED; : nas::ENgRanRadioCapabilityUpdate::NOT_NEEDED;
// MM capability should be included if it is not a periodic registration // MM capability should be included if it is not a periodic registration
if (updateCause != ERegUpdateCause::PERIODIC_REGISTRATION) if (updateCause != ERegUpdateCause::T3512_EXPIRY)
{ {
request->mmCapability = nas::IE5gMmCapability{}; request->mmCapability = nas::IE5gMmCapability{};
request->mmCapability->s1Mode = nas::EEpcNasSupported::NOT_SUPPORTED; request->mmCapability->s1Mode = nas::EEpcNasSupported::NOT_SUPPORTED;
...@@ -452,7 +466,7 @@ void NasMm::receiveInitialRegistrationReject(const nas::RegistrationReject &msg) ...@@ -452,7 +466,7 @@ void NasMm::receiveInitialRegistrationReject(const nas::RegistrationReject &msg)
m_regCounter = 5; m_regCounter = 5;
} }
handleCommonAbnormalRegFailure(regType); handleAbnormalInitialRegFailure(regType);
}; };
if (regType == nas::ERegistrationType::INITIAL_REGISTRATION) if (regType == nas::ERegistrationType::INITIAL_REGISTRATION)
...@@ -568,7 +582,7 @@ void NasMm::receiveInitialRegistrationReject(const nas::RegistrationReject &msg) ...@@ -568,7 +582,7 @@ void NasMm::receiveInitialRegistrationReject(const nas::RegistrationReject &msg)
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NO_SUPI); switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NO_SUPI);
else else
{ {
// Spec perseveringly says that upper layers should be informed as well, for additional action for emergency // Spec says that upper layers should be informed as well, for additional action for emergency
// registration, but no need for now. // registration, but no need for now.
handleAbnormalCase(); handleAbnormalCase();
} }
...@@ -577,12 +591,165 @@ void NasMm::receiveInitialRegistrationReject(const nas::RegistrationReject &msg) ...@@ -577,12 +591,165 @@ void NasMm::receiveInitialRegistrationReject(const nas::RegistrationReject &msg)
void NasMm::receiveMobilityRegistrationReject(const nas::RegistrationReject &msg) void NasMm::receiveMobilityRegistrationReject(const nas::RegistrationReject &msg)
{ {
// TODO: auto cause = msg.mmCause.value;
auto regType = m_lastRegistrationRequest->registrationType.registrationType;
if (msg.eapMessage.has_value())
{
if (msg.eapMessage->eap->code == eap::ECode::FAILURE)
receiveEapFailureMessage(*msg.eapMessage->eap);
else
m_logger->warn("Network sent EAP with type of %s in RegistrationReject, ignoring EAP IE.",
nas::utils::EnumToString(msg.eapMessage->eap->code));
}
switchRmState(ERmState::RM_DEREGISTERED);
auto handleAbnormalCase = [this, regType, cause]() {
m_logger->debug("Handling Registration Reject abnormal case");
// Upon reception of the 5GMM causes #95, #96, #97, #99 and #111 the UE should set the registration attempt
// counter to 5.
int n = static_cast<int>(cause);
if (n == 95 || n == 96 || n == 97 || n == 99 || n == 111)
m_regCounter = 5;
handleAbnormalMobilityRegFailure(regType);
};
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME ||
cause == nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED || cause == nas::EMmCause::PLMN_NOT_ALLOWED ||
cause == nas::EMmCause::TA_NOT_ALLOWED || cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA ||
cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA || cause == nas::EMmCause::N1_MODE_NOT_ALLOWED)
{
switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
}
if (cause == nas::EMmCause::SERVING_NETWORK_NOT_AUTHORIZED ||
cause == nas::EMmCause::UE_IDENTITY_CANNOT_BE_DERIVED_FROM_NETWORK)
{
switchUState(E5UState::U2_NOT_UPDATED);
}
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME ||
cause == nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED || cause == nas::EMmCause::PLMN_NOT_ALLOWED ||
cause == nas::EMmCause::TA_NOT_ALLOWED || cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA ||
cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA || cause == nas::EMmCause::N1_MODE_NOT_ALLOWED ||
cause == nas::EMmCause::UE_IDENTITY_CANNOT_BE_DERIVED_FROM_NETWORK)
{
m_storage.m_storedGuti = {};
m_storage.m_lastVisitedRegisteredTai = {};
m_storage.m_taiList = {};
m_storage.m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {};
}
if (cause == nas::EMmCause::IMPLICITY_DEREGISTERED)
{
m_storage.m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {};
}
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME ||
cause == nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED)
{
m_storage.invalidateSim();
}
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME ||
cause == nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED ||
cause == nas::EMmCause::UE_IDENTITY_CANNOT_BE_DERIVED_FROM_NETWORK)
{
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA);
}
if (cause == nas::EMmCause::IMPLICITY_DEREGISTERED)
{
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NORMAL_SERVICE);
}
if (cause == nas::EMmCause::TA_NOT_ALLOWED || cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA ||
cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA)
{
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_LIMITED_SERVICE);
}
if (cause == nas::EMmCause::N1_MODE_NOT_ALLOWED)
{
switchMmState(EMmState::MM_NULL, EMmSubState::MM_NULL_NA);
setN1Capability(false);
}
if (cause == nas::EMmCause::PLMN_NOT_ALLOWED || cause == nas::EMmCause::SERVING_NETWORK_NOT_AUTHORIZED)
{
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_PLMN_SEARCH);
}
if (cause == nas::EMmCause::PLMN_NOT_ALLOWED || cause == nas::EMmCause::TA_NOT_ALLOWED ||
cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA || cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA ||
cause == nas::EMmCause::N1_MODE_NOT_ALLOWED || cause == nas::EMmCause::SERVING_NETWORK_NOT_AUTHORIZED)
{
m_regCounter = 0;
}
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME ||
cause == nas::EMmCause::PLMN_NOT_ALLOWED || cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA)
{
m_storage.m_equivalentPlmnList = {};
}
if (cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA || cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA)
{
// TODO add to forbidden tai
}
if (cause == nas::EMmCause::PLMN_NOT_ALLOWED || cause == nas::EMmCause::SERVING_NETWORK_NOT_AUTHORIZED)
{
nas::utils::AddToPlmnList(m_storage.m_forbiddenPlmnList, nas::utils::PlmnFrom(m_storage.m_currentPlmn));
}
if (cause == nas::EMmCause::CONGESTION)
{
if (msg.t3346value.has_value() && nas::utils::HasValue(*msg.t3346value))
{
if (!hasEmergency())
{
switchUState(E5UState::U2_NOT_UPDATED);
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_ATTEMPTING_REGISTRATION);
}
m_timers->t3346.stop();
if (msg.sht != nas::ESecurityHeaderType::NOT_PROTECTED)
m_timers->t3346.start(*msg.t3346value);
else
m_timers->t3346.start(nas::IEGprsTimer2{5});
}
else
{
handleAbnormalCase();
}
}
if (cause != nas::EMmCause::ILLEGAL_UE && cause != nas::EMmCause::ILLEGAL_ME &&
cause != nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED && cause != nas::EMmCause::PLMN_NOT_ALLOWED &&
cause != nas::EMmCause::TA_NOT_ALLOWED && cause != nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA &&
cause != nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA && cause != nas::EMmCause::CONGESTION &&
cause != nas::EMmCause::N1_MODE_NOT_ALLOWED && cause != nas::EMmCause::SERVING_NETWORK_NOT_AUTHORIZED &&
cause != nas::EMmCause::IMPLICITY_DEREGISTERED &&
cause != nas::EMmCause::UE_IDENTITY_CANNOT_BE_DERIVED_FROM_NETWORK)
{
handleAbnormalCase();
}
// todo handleCommonAbnormalRegFailure ikisi için de ortak mı diye özellikle bakılacak if (hasEmergency())
{
// Spec says that upper layers should be informed as well, for additional action for emergency
// registration, but no need for now.
handleAbnormalCase();
}
} }
void NasMm::handleCommonAbnormalRegFailure(nas::ERegistrationType regType) void NasMm::handleAbnormalInitialRegFailure(nas::ERegistrationType regType)
{ {
// Timer T3510 shall be stopped if still running // Timer T3510 shall be stopped if still running
m_timers->t3510.stop(); m_timers->t3510.stop();
...@@ -626,4 +793,54 @@ void NasMm::handleCommonAbnormalRegFailure(nas::ERegistrationType regType) ...@@ -626,4 +793,54 @@ void NasMm::handleCommonAbnormalRegFailure(nas::ERegistrationType regType)
} }
} }
void NasMm::handleAbnormalMobilityRegFailure(nas::ERegistrationType regType)
{
// "Timer T3510 shall be stopped if still running"
m_timers->t3510.stop();
// "The registration attempt counter shall be incremented, unless it was already set to 5."
if (m_regCounter != 5)
m_regCounter++;
// "If the registration attempt counter is less than 5:"
if (m_regCounter < 5)
{
bool includedInTaiList = false; // TODO
// "If the TAI of the current serving cell is not included in the TAI list or the 5GS update status is different
// to 5U1 UPDATED"
if (!includedInTaiList || m_storage.m_uState != E5UState::U1_UPDATED)
{
// "The UE shall start timer T3511, shall set the 5GS update status to 5U2 NOT UPDATED and change to state
// 5GMM-REGISTERED.ATTEMPTING-REGISTRATION-UPDATE. When timer T3511 expires and the registration update
// procedure is triggered again"
m_timers->t3511.start(); // todo
switchUState(E5UState::U2_NOT_UPDATED);
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_ATTEMPTING_REGISTRATION_UPDATE);
}
// "If the TAI of the current serving cell is included in the TAI list, the 5GS update status is equal to 5U1
// UPDATED, and the UE is not performing the registration procedure after an inter-system change from S1 mode to
// N1 mode"
if (includedInTaiList && m_storage.m_uState == E5UState::U1_UPDATED)
{
// "The UE shall keep the 5GS update status to 5U1 UPDATED and enter state 5GMM-REGISTERED.NORMAL-SERVICE."
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NORMAL_SERVICE);
// "The UE shall start timer T3511"
m_timers->t3511.start();
}
}
else
{
// "The UE shall start timer T3502, shall set the 5GS update status to 5U2 NOT UPDATED."
m_timers->t3502.start();
switchUState(E5UState::U2_NOT_UPDATED);
// "The UE shall delete the list of equivalent PLMNs and shall change to state
// 5GMM-REGISTERED.ATTEMPTING-REGISTRATION-UPDATE UPDATE"
m_storage.m_equivalentPlmnList = {};
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_ATTEMPTING_REGISTRATION_UPDATE);
}
}
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
...@@ -34,12 +34,17 @@ void NasMm::onTimerExpire(nas::NasTimer &timer) ...@@ -34,12 +34,17 @@ void NasMm::onTimerExpire(nas::NasTimer &timer)
break; break;
} }
case 3510: { case 3510: {
// The UE shall abort the registration procedure for initial registration and the NAS signalling connection, if if (m_mmState == EMmState::MM_REGISTERED_INITIATED)
// any, shall be released locally if the initial registration request is not for emergency services..
if (m_mmState == EMmState::MM_REGISTERED_INITIATED && m_lastRegistrationRequest)
{ {
logExpired(); logExpired();
auto regType = m_lastRegistrationRequest->registrationType.registrationType;
if (regType == nas::ERegistrationType::INITIAL_REGISTRATION ||
regType == nas::ERegistrationType::EMERGENCY_REGISTRATION)
{
// The UE shall abort the registration procedure for initial registration and the NAS signalling
// connection, if any, shall be released locally if the initial registration request is not for
// emergency services..
switchRmState(ERmState::RM_DEREGISTERED); switchRmState(ERmState::RM_DEREGISTERED);
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA); switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA);
switchUState(E5UState::U2_NOT_UPDATED); switchUState(E5UState::U2_NOT_UPDATED);
...@@ -50,16 +55,26 @@ void NasMm::onTimerExpire(nas::NasTimer &timer) ...@@ -50,16 +55,26 @@ void NasMm::onTimerExpire(nas::NasTimer &timer)
localReleaseConnection(); localReleaseConnection();
} }
handleCommonAbnormalRegFailure(m_lastRegistrationRequest->registrationType.registrationType); handleAbnormalInitialRegFailure(regType);
} }
else if (regType == nas::ERegistrationType::MOBILITY_REGISTRATION_UPDATING ||
regType == nas::ERegistrationType::PERIODIC_REGISTRATION_UPDATING)
{
localReleaseConnection();
handleAbnormalMobilityRegFailure(regType);
}
}
break;
}
case 3511: {
// TODO
break; break;
} }
case 3512: { case 3512: {
if (m_mmState == EMmState::MM_REGISTERED && m_cmState == ECmState::CM_CONNECTED) if (m_mmState == EMmState::MM_REGISTERED && m_cmState == ECmState::CM_CONNECTED)
{ {
logExpired(); logExpired();
sendMobilityRegistration(ERegUpdateCause::PERIODIC_REGISTRATION); sendMobilityRegistration(ERegUpdateCause::T3512_EXPIRY);
} }
break; break;
} }
......
...@@ -157,4 +157,51 @@ Json ToJson(const E5UState &state) ...@@ -157,4 +157,51 @@ Json ToJson(const E5UState &state)
} }
} }
Json ToJson(const ERegUpdateCause &v)
{
switch (v)
{
case ERegUpdateCause::UNSPECIFIED:
return "UNSPECIFIED";
case ERegUpdateCause::ENTER_UNLISTED_TRACKING_AREA:
return "ENTER_UNLISTED_TRACKING_AREA";
case ERegUpdateCause::T3512_EXPIRY:
return "T3512_EXPIRY";
case ERegUpdateCause::CONFIGURATION_UPDATE:
return "CONFIGURATION_UPDATE";
case ERegUpdateCause::PAGING_OR_NOTIFICATION:
return "PAGING_OR_NOTIFICATION";
case ERegUpdateCause::INTER_SYSTEM_CHANGE_S1_TO_N1:
return "INTER_SYSTEM_CHANGE_S1_TO_N1";
case ERegUpdateCause::CONNECTION_RECOVERY:
return "CONNECTION_RECOVERY";
case ERegUpdateCause::MM_OR_S1_CAPABILITY_CHANGE:
return "MM_OR_S1_CAPABILITY_CHANGE";
case ERegUpdateCause::USAGE_SETTING_CHANGE:
return "USAGE_SETTING_CHANGE";
case ERegUpdateCause::SLICE_CHANGE:
return "SLICE_CHANGE";
case ERegUpdateCause::DRX_CHANGE:
return "DRX_CHANGE";
case ERegUpdateCause::EMERGENCY_CASE:
return "EMERGENCY_CASE";
case ERegUpdateCause::SMS_OVER_NAS_CHANGE:
return "SMS_OVER_NAS_CHANGE";
case ERegUpdateCause::PS_STATUS_INFORM:
return "PS_STATUS_INFORM";
case ERegUpdateCause::RADIO_CAP_CHANGE:
return "RADIO_CAP_CHANGE";
case ERegUpdateCause::NEW_LADN_NEEDED:
return "NEW_LADN_NEEDED";
case ERegUpdateCause::MICO_MODE_CHANGE:
return "MICO_MODE_CHANGE";
case ERegUpdateCause::ENTER_EQUIVALENT_PLMN_CELL:
return "ENTER_EQUIVALENT_PLMN_CELL";
case ERegUpdateCause::RESTRICTED_SERVICE_AREA:
return "RESTRICTED_SERVICE_AREA";
default:
return "?";
}
}
} // namespace nr::ue } // namespace nr::ue
...@@ -368,9 +368,56 @@ struct UePduSessionInfo ...@@ -368,9 +368,56 @@ struct UePduSessionInfo
enum class ERegUpdateCause enum class ERegUpdateCause
{ {
// unspecified cause
UNSPECIFIED, UNSPECIFIED,
PERIODIC_REGISTRATION, // when the UE detects entering a tracking area that is not in the list of tracking areas that the UE previously
RADIO_CAP_CHANGE // registered in the AMF
ENTER_UNLISTED_TRACKING_AREA,
// when the periodic registration updating timer T3512 expires
T3512_EXPIRY,
// when the UE receives a CONFIGURATION UPDATE COMMAND message indicating "registration requested" in the
// Configuration update indication IE as specified in subclauses 5.4.4.3;
CONFIGURATION_UPDATE,
// when the UE in state 5GMM-REGISTERED.ATTEMPTING-REGISTRATION-UPDATE either receives a paging or the UE receives a
// NOTIFICATION message with access type indicating 3GPP access over the non-3GPP access for PDU sessions associated
// with 3GPP access
PAGING_OR_NOTIFICATION,
// upon inter-system change from S1 mode to N1 mode
INTER_SYSTEM_CHANGE_S1_TO_N1,
// when the UE receives an indication of "RRC Connection failure" from the lower layers and does not have signalling
// pending (i.e. when the lower layer requests NAS signalling connection recovery) except for the case specified in
// subclause 5.3.1.4;
// when the UE receives a fallback indication from the lower layers and does not have signalling pending (i.e. when
// the lower layer requests NAS signalling connection recovery, see subclauses 5.3.1.4 and 5.3.1.2);
CONNECTION_RECOVERY,
// when the UE changes the 5GMM capability or the S1 UE network capability or both
MM_OR_S1_CAPABILITY_CHANGE,
// when the UE's usage setting changes
USAGE_SETTING_CHANGE,
// when the UE needs to change the slice(s) it is currently registered to
SLICE_CHANGE,
// when the UE changes the UE specific DRX parameters
DRX_CHANGE,
// when the UE in state 5GMM-REGISTERED.ATTEMPTING-REGISTRATION-UPDATE receives a request from the upper layers to
// establish an emergency PDU session or perform emergency services fallback
EMERGENCY_CASE,
// when the UE needs to register for SMS over NAS, indicate a change in the requirements to use SMS over NAS, or
// de-register from SMS over NAS;
SMS_OVER_NAS_CHANGE,
// when the UE needs to indicate PDU session status to the network after performing a local release of PDU
// session(s) as specified in subclauses 6.4.1.5 and 6.4.3.5;
PS_STATUS_INFORM,
// when the UE in 5GMM-IDLE mode changes the radio capability for NG-RAN
RADIO_CAP_CHANGE,
// when the UE needs to request new LADN information
NEW_LADN_NEEDED,
// when the UE needs to request the use of MICO mode or needs to stop the use of MICO mode
MICO_MODE_CHANGE,
// when the UE in 5GMM-CONNECTED mode with RRC inactive indication enters a cell in the current registration area
// belonging to an equivalent PLMN of the registered PLMN and not belonging to the registered PLMN;
ENTER_EQUIVALENT_PLMN_CELL,
// when the UE receives a SERVICE REJECT message with the 5GMM cause value set to #28 "Restricted service area".
RESTRICTED_SERVICE_AREA
}; };
Json ToJson(const ECmState &state); Json ToJson(const ECmState &state);
...@@ -380,5 +427,6 @@ Json ToJson(const EMmSubState &state); ...@@ -380,5 +427,6 @@ Json ToJson(const EMmSubState &state);
Json ToJson(const E5UState &state); Json ToJson(const E5UState &state);
Json ToJson(const UeConfig &v); Json ToJson(const UeConfig &v);
Json ToJson(const UeTimers &v); Json ToJson(const UeTimers &v);
Json ToJson(const ERegUpdateCause &v);
} // namespace nr::ue } // namespace nr::ue
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment