Commit 06aa099c authored by aligungr's avatar aligungr

Network-initiated de-registration improvement

parent c9ea3b37
...@@ -35,6 +35,7 @@ enum class StateType ...@@ -35,6 +35,7 @@ enum class StateType
MM_SUB, MM_SUB,
RM, RM,
CM, CM,
U5,
}; };
class INodeListener class INodeListener
......
...@@ -25,6 +25,7 @@ NasMm::NasMm(TaskBase *base, UeTimers *timers) : m_base{base}, m_timers{timers}, ...@@ -25,6 +25,7 @@ NasMm::NasMm(TaskBase *base, UeTimers *timers) : m_base{base}, m_timers{timers},
m_cmState = ECmState::CM_IDLE; m_cmState = ECmState::CM_IDLE;
m_mmState = EMmState::MM_DEREGISTERED; m_mmState = EMmState::MM_DEREGISTERED;
m_mmSubState = EMmSubState::MM_DEREGISTERED_NA; m_mmSubState = EMmSubState::MM_DEREGISTERED_NA;
m_uState = E5UState::U1_UPDATED;
m_autoBehaviour = base->config->autoBehaviour; m_autoBehaviour = base->config->autoBehaviour;
m_validSim = base->config->supi.has_value(); m_validSim = base->config->supi.has_value();
} }
...@@ -165,6 +166,25 @@ void NasMm::switchCmState(ECmState state) ...@@ -165,6 +166,25 @@ void NasMm::switchCmState(ECmState state)
triggerMmCycle(); triggerMmCycle();
} }
void NasMm::switchUState(E5UState state)
{
E5UState oldState = m_uState;
m_uState = state;
onSwitchUState(oldState, m_uState);
if (m_base->nodeListener)
{
m_base->nodeListener->onSwitch(app::NodeType::UE, m_base->config->getNodeName(), app::StateType::U5,
ToJson(oldState).str(), ToJson(m_uState).str());
}
if (state != oldState)
m_logger->info("UE switches to state: %s", ToJson(state).str().c_str());
triggerMmCycle();
}
void NasMm::onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState oldSubState, EMmSubState newSubSate) void NasMm::onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState oldSubState, EMmSubState newSubSate)
{ {
// The UE shall mark the 5G NAS security context on the USIM or in the non-volatile memory as invalid when the UE // The UE shall mark the 5G NAS security context on the USIM or in the non-volatile memory as invalid when the UE
...@@ -210,6 +230,10 @@ void NasMm::onSwitchCmState(ECmState oldState, ECmState newState) ...@@ -210,6 +230,10 @@ void NasMm::onSwitchCmState(ECmState oldState, ECmState newState)
} }
} }
void NasMm::onSwitchUState(E5UState oldState, E5UState newState)
{
}
void NasMm::receivePlmnSearchResponse(const std::string &gnbName) void NasMm::receivePlmnSearchResponse(const std::string &gnbName)
{ {
if (m_base->nodeListener) if (m_base->nodeListener)
...@@ -284,4 +308,20 @@ void NasMm::onTimerExpire(nas::NasTimer &timer) ...@@ -284,4 +308,20 @@ void NasMm::onTimerExpire(nas::NasTimer &timer)
} }
} }
void NasMm::invalidateAcquiredParams()
{
m_storedGuti = {};
m_lastVisitedRegisteredTai = {};
m_taiList = {};
m_currentNsCtx = {};
m_nonCurrentNsCtx = {};
}
void NasMm::invalidateSim()
{
m_logger->warn("USIM is removed or invalidated");
m_validSim = false;
invalidateAcquiredParams();
}
} // namespace nr::ue } // namespace nr::ue
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
// //
#include "mm.hpp" #include "mm.hpp"
#include <nas/utils.hpp>
#include <ue/sm/sm.hpp> #include <ue/sm/sm.hpp>
namespace nr::ue namespace nr::ue
...@@ -20,6 +21,9 @@ void NasMm::sendDeregistration(nas::ESwitchOff switchOff, bool dueToDisable5g) ...@@ -20,6 +21,9 @@ void NasMm::sendDeregistration(nas::ESwitchOff switchOff, bool dueToDisable5g)
return; return;
} }
m_logger->debug("Starting de-registration procedure. switch-off[%d] disable-5g[%d]",
switchOff == nas::ESwitchOff::SWITCH_OFF ? 1 : 0, (int)dueToDisable5g);
auto request = std::make_unique<nas::DeRegistrationRequestUeOriginating>(); auto request = std::make_unique<nas::DeRegistrationRequestUeOriginating>();
request->deRegistrationType.accessType = nas::EDeRegistrationAccessType::THREEGPP_ACCESS; request->deRegistrationType.accessType = nas::EDeRegistrationAccessType::THREEGPP_ACCESS;
request->deRegistrationType.reRegistrationRequired = nas::EReRegistrationRequired::NOT_REQUIRED; request->deRegistrationType.reRegistrationRequired = nas::EReRegistrationRequired::NOT_REQUIRED;
...@@ -57,6 +61,8 @@ void NasMm::sendDeregistration(nas::ESwitchOff switchOff, bool dueToDisable5g) ...@@ -57,6 +61,8 @@ void NasMm::sendDeregistration(nas::ESwitchOff switchOff, bool dueToDisable5g)
void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOriginating &msg) void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOriginating &msg)
{ {
m_logger->debug("De-registration accept received");
if (m_mmSubState != EMmSubState::MM_DEREGISTERED_INITIATED_NA) if (m_mmSubState != EMmSubState::MM_DEREGISTERED_INITIATED_NA)
{ {
m_logger->warn("De-registration accept message ignored. UE is not in MM_DEREGISTERED_INITIATED"); m_logger->warn("De-registration accept message ignored. UE is not in MM_DEREGISTERED_INITIATED");
...@@ -84,7 +90,22 @@ void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOrigina ...@@ -84,7 +90,22 @@ void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOrigina
void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTerminated &msg) void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTerminated &msg)
{ {
bool forceIgnoreReregistration = false; // todo use this if (m_rmState != ERmState::RM_REGISTERED)
{
m_logger->warn("De-registration message ignored. UE is already de-registered");
return;
}
if (msg.deRegistrationType.accessType == nas::EDeRegistrationAccessType::NON_THREEGPP_ACCESS)
{
m_logger->warn("De-registration message ignored. Access type mismatch");
sendMmStatus(nas::EMmCause::SEMANTICALLY_INCORRECT_MESSAGE);
return;
}
m_logger->debug("Network initiated de-registration request received");
bool forceIgnoreReregistration = false;
// 5.5.2.2.6 Abnormal cases in the UE (de-registration collision) // 5.5.2.2.6 Abnormal cases in the UE (de-registration collision)
if (m_mmState == EMmState::MM_DEREGISTERED_INITIATED) if (m_mmState == EMmState::MM_DEREGISTERED_INITIATED)
...@@ -111,9 +132,13 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi ...@@ -111,9 +132,13 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
return; return;
} }
// TODO: this function is not complete bool reRegistrationRequired =
msg.deRegistrationType.reRegistrationRequired == nas::EReRegistrationRequired::REQUIRED &&
!forceIgnoreReregistration;
if (msg.deRegistrationType.reRegistrationRequired == nas::EReRegistrationRequired::REQUIRED) // todo local release of pdu sessions
if (reRegistrationRequired)
{ {
m_timers->t3346.stop(); m_timers->t3346.stop();
m_timers->t3396.stop(); m_timers->t3396.stop();
...@@ -122,8 +147,63 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi ...@@ -122,8 +147,63 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
} }
sendNasMessage(nas::DeRegistrationAcceptUeTerminated{}); sendNasMessage(nas::DeRegistrationAcceptUeTerminated{});
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA);
switchRmState(ERmState::RM_DEREGISTERED); switchRmState(ERmState::RM_DEREGISTERED);
// If the de-registration type indicates "re-registration not required", the UE shall take the actions depending on
// the received 5GMM cause value. Otherwise ignore the 5GMM cause value.
if (msg.deRegistrationType.reRegistrationRequired == nas::EReRegistrationRequired::NOT_REQUIRED)
{
if (msg.mmCause.has_value())
{
switch (msg.mmCause->value)
{
case nas::EMmCause::ILLEGAL_UE:
case nas::EMmCause::ILLEGAL_ME:
case nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED: {
switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
invalidateSim();
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA);
break;
}
// case nas::EMmCause::PLMN_NOT_ALLOWED: {
// switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
// invalidateAcquiredParams();
// // TODO: add to forbidden plmn list, otherwise endless plmn search may occur.
// switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_PLMN_SEARCH);
// break;
//}
case nas::EMmCause::TA_NOT_ALLOWED: {
switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
invalidateAcquiredParams();
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_LIMITED_SERVICE);
break;
}
case nas::EMmCause::N1_MODE_NOT_ALLOWED: {
switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
invalidateAcquiredParams();
switchMmState(EMmState::MM_NULL, EMmSubState::MM_NULL_NA);
break;
}
case nas::EMmCause::CONGESTION: {
switchUState(E5UState::U2_NOT_UPDATED);
m_timers->t3346.stop();
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_ATTEMPTING_REGISTRATION);
if (msg.t3346Value.has_value() && msg.t3346Value->value != 0)
m_timers->t3346.start(*msg.t3346Value);
break;
}
default: {
m_logger->err("Unhandled network-initiated de-registration cause[%s]",
nas::utils::EnumToString(msg.mmCause->value));
switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
invalidateSim();
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NA);
break;
}
}
}
}
} }
} // namespace nr::ue } // namespace nr::ue
...@@ -33,6 +33,7 @@ class NasMm ...@@ -33,6 +33,7 @@ class NasMm
ECmState m_cmState; ECmState m_cmState;
EMmState m_mmState; EMmState m_mmState;
EMmSubState m_mmSubState; EMmSubState m_mmSubState;
E5UState m_uState;
nas::IE5gsMobileIdentity m_storedSuci{}; nas::IE5gsMobileIdentity m_storedSuci{};
nas::IE5gsMobileIdentity m_storedGuti{}; nas::IE5gsMobileIdentity m_storedGuti{};
...@@ -78,9 +79,13 @@ class NasMm ...@@ -78,9 +79,13 @@ class NasMm
void switchMmState(EMmState state, EMmSubState subState); void switchMmState(EMmState state, EMmSubState subState);
void switchRmState(ERmState state); void switchRmState(ERmState state);
void switchCmState(ECmState state); void switchCmState(ECmState state);
void switchUState(E5UState state);
void onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState oldSubState, EMmSubState newSubSate); void onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState oldSubState, EMmSubState newSubSate);
void onSwitchRmState(ERmState oldState, ERmState newState); void onSwitchRmState(ERmState oldState, ERmState newState);
void onSwitchCmState(ECmState oldState, ECmState newState); void onSwitchCmState(ECmState oldState, ECmState newState);
void onSwitchUState(E5UState oldState, E5UState newState);
void invalidateAcquiredParams();
void invalidateSim();
/* Transport */ /* Transport */
void sendMmStatus(nas::EMmCause cause); void sendMmStatus(nas::EMmCause cause);
......
...@@ -134,14 +134,28 @@ Json ToJson(const UeConfig &v) ...@@ -134,14 +134,28 @@ Json ToJson(const UeConfig &v)
Json ToJson(const UeTimers &v) Json ToJson(const UeTimers &v)
{ {
return Json::Obj({ return Json::Obj({
{"T3346", ToJson(v.t3346)}, {"T3396", ToJson(v.t3396)}, {"T3444", ToJson(v.t3444)}, {"T3346", ToJson(v.t3346)}, {"T3396", ToJson(v.t3396)}, {"T3444", ToJson(v.t3444)}, {"T3445", ToJson(v.t3445)},
{"T3445", ToJson(v.t3445)}, {"T3502", ToJson(v.t3502)}, {"T3510", ToJson(v.t3510)}, {"T3502", ToJson(v.t3502)}, {"T3510", ToJson(v.t3510)}, {"T3511", ToJson(v.t3511)}, {"T3512", ToJson(v.t3512)},
{"T3511", ToJson(v.t3511)}, {"T3512", ToJson(v.t3512)}, {"T3516", ToJson(v.t3516)}, {"T3516", ToJson(v.t3516)}, {"T3517", ToJson(v.t3517)}, {"T3519", ToJson(v.t3519)}, {"T3520", ToJson(v.t3520)},
{"T3517", ToJson(v.t3517)}, {"T3519", ToJson(v.t3519)}, {"T3520", ToJson(v.t3520)}, {"T3521", ToJson(v.t3521)}, {"T3525", ToJson(v.t3525)}, {"T3540", ToJson(v.t3540)}, {"T3580", ToJson(v.t3580)},
{"T3521", ToJson(v.t3521)}, {"T3525", ToJson(v.t3525)}, {"T3540", ToJson(v.t3540)}, {"T3581", ToJson(v.t3581)}, {"T3582", ToJson(v.t3582)}, {"T3583", ToJson(v.t3583)}, {"T3584", ToJson(v.t3584)},
{"T3580", ToJson(v.t3580)}, {"T3581", ToJson(v.t3581)}, {"T3582", ToJson(v.t3582)}, {"T3585", ToJson(v.t3585)},
{"T3583", ToJson(v.t3583)}, {"T3584", ToJson(v.t3584)}, {"T3585", ToJson(v.t3585)},
}); });
} }
Json ToJson(const E5UState &state)
{
switch (state)
{
case E5UState::U1_UPDATED:
return "5U1-UPDATED";
case E5UState::U2_NOT_UPDATED:
return "5U2-NOT-UPDATED";
case E5UState::U3_ROAMING_NOT_ALLOWED:
return "5U3-ROAMING-NOT-ALLOWED";
default:
return "?";
}
}
} // namespace nr::ue } // namespace nr::ue
...@@ -363,6 +363,7 @@ Json ToJson(const ECmState &state); ...@@ -363,6 +363,7 @@ Json ToJson(const ECmState &state);
Json ToJson(const ERmState &state); Json ToJson(const ERmState &state);
Json ToJson(const EMmState &state); Json ToJson(const EMmState &state);
Json ToJson(const EMmSubState &state); Json ToJson(const EMmSubState &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);
......
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