Commit f1442d1c authored by aligungr's avatar aligungr

Service reject handling

parent 4540dd43
......@@ -137,7 +137,7 @@ enum class EMmCause
SEC_MODE_REJECTED_UNSPECIFIED = 0b00011000,
NON_5G_AUTHENTICATION_UNACCEPTABLE = 0b00011010,
N1_MODE_NOT_ALLOWED = 0b00011011,
RESTRICTED_NOT_SERVICE_AREA = 0b00011100,
RESTRICTED_SERVICE_AREA = 0b00011100,
LADN_NOT_AVAILABLE = 0b00101011,
MAX_PDU_SESSIONS_REACHED = 0b01000001,
INSUFFICIENT_RESOURCES_FOR_SLICE_AND_DNN = 0b01000011,
......@@ -646,6 +646,7 @@ enum class EServiceType
EMERGENCY_SERVICES = 0b0011,
EMERGENCY_SERVICES_FALLBACK = 0b0100,
HIGH_PRIORITY_ACCESS = 0b0101,
ELEVATED_SIGNALLING = 0b0110,
UNUSED_SIGNALLING_1 = 0b0110,
UNUSED_SIGNALLING_2 = 0b0111,
UNUSED_SIGNALLING_3 = 0b1000,
......
......@@ -95,8 +95,8 @@ const char *EnumToString(EMmCause v)
return "NON_5G_AUTHENTICATION_UNACCEPTABLE";
case EMmCause::N1_MODE_NOT_ALLOWED:
return "N1_MODE_NOT_ALLOWED";
case EMmCause::RESTRICTED_NOT_SERVICE_AREA:
return "RESTRICTED_NOT_SERVICE_AREA";
case EMmCause::RESTRICTED_SERVICE_AREA:
return "RESTRICTED_SERVICE_AREA";
case EMmCause::LADN_NOT_AVAILABLE:
return "LADN_NOT_AVAILABLE";
case EMmCause::MAX_PDU_SESSIONS_REACHED:
......
......@@ -170,7 +170,7 @@ void NasMm::receiveServiceAccept(const nas::ServiceAccept &msg)
void NasMm::receiveServiceReject(const nas::ServiceReject &msg)
{
if (m_mmState != EMmState::MM_SERVICE_REQUEST_INITIATED)
if (m_mmState != EMmState::MM_SERVICE_REQUEST_INITIATED || !m_lastServiceRequest)
{
m_logger->warn("Service Reject ignored since the MM state is not MM_SERVICE_REQUEST_INITIATED");
sendMmStatus(nas::EMmCause::MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE);
......@@ -192,6 +192,11 @@ void NasMm::receiveServiceReject(const nas::ServiceReject &msg)
auto cause = msg.mmCause.value;
m_logger->err("Service Request failed [%s]", nas::utils::EnumToString(cause));
auto handleAbnormalCase = [this, cause]() {
m_logger->debug("Handling Service Reject abnormal case");
// TODO
};
// Handle PDU session status
if (msg.pduSessionStatus.has_value() && msg.sht != nas::ESecurityHeaderType::NOT_PROTECTED)
{
......@@ -269,7 +274,8 @@ void NasMm::receiveServiceReject(const nas::ServiceReject &msg)
}
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)
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);
switchRmState(ERmState::RM_DEREGISTERED);
......@@ -317,6 +323,56 @@ void NasMm::receiveServiceReject(const nas::ServiceReject &msg)
{
setN1Capability(false);
}
if (cause == nas::EMmCause::UE_IDENTITY_CANNOT_BE_DERIVED_FROM_NETWORK)
{
if (m_lastServiceReqCause != EServiceReqCause::EMERGENCY_FALLBACK)
{
// TODO: new initial registration
}
}
if (cause == nas::EMmCause::IMPLICITY_DEREGISTERED)
{
if (hasEmergency())
{
// TODO: new initial registration
}
}
if (cause == nas::EMmCause::CONGESTION)
{
if (msg.t3346Value.has_value() && nas::utils::HasValue(*msg.t3346Value))
{
if (!hasEmergency())
{
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NA);
switchRmState(ERmState::RM_REGISTERED);
m_timers->t3517.stop();
}
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::RESTRICTED_SERVICE_AREA)
{
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NON_ALLOWED_SERVICE);
switchRmState(ERmState::RM_REGISTERED);
if (m_lastServiceRequest->serviceType.serviceType != nas::EServiceType::ELEVATED_SIGNALLING)
sendMobilityRegistration(ERegUpdateCause::RESTRICTED_SERVICE_AREA);
}
}
} // namespace nr::ue
......@@ -185,6 +185,8 @@ Json ToJson(const ERegUpdateCause &v)
return "INTER_SYSTEM_CHANGE_S1_TO_N1";
case ERegUpdateCause::CONNECTION_RECOVERY:
return "CONNECTION_RECOVERY";
case ERegUpdateCause::FALLBACK_INDICATION:
return "FALLBACK_INDICATION";
case ERegUpdateCause::MM_OR_S1_CAPABILITY_CHANGE:
return "MM_OR_S1_CAPABILITY_CHANGE";
case ERegUpdateCause::USAGE_SETTING_CHANGE:
......
......@@ -420,9 +420,10 @@ enum class ERegUpdateCause
// 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;
CONNECTION_RECOVERY,
// 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,
FALLBACK_INDICATION,
// 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
......
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