Commit 0031283d authored by aligungr's avatar aligungr

eCall inactivity implementation

parent 6f565a5f
...@@ -53,6 +53,9 @@ void NasMm::performMmCycle() ...@@ -53,6 +53,9 @@ void NasMm::performMmCycle()
if (m_mmSubState == EMmSubState::MM_DEREGISTERED_NA) if (m_mmSubState == EMmSubState::MM_DEREGISTERED_NA)
{ {
if (switchToECallInactivityIfNeeded())
return;
if (m_storage.isSimValid()) if (m_storage.isSimValid())
{ {
if (m_cmState == ECmState::CM_IDLE) if (m_cmState == ECmState::CM_IDLE)
...@@ -87,16 +90,11 @@ void NasMm::performMmCycle() ...@@ -87,16 +90,11 @@ void NasMm::performMmCycle()
return; return;
} }
if (m_mmState == EMmState::MM_REGISTERED_INITIATED) if (m_mmState == EMmState::MM_REGISTERED)
return; {
if (m_mmSubState == EMmSubState::MM_REGISTERED_NORMAL_SERVICE) if (startECallInactivityIfNeeded())
return; return;
if (m_mmState == EMmState::MM_DEREGISTERED_INITIATED) }
return;
if (m_mmSubState == EMmSubState::MM_DEREGISTERED_NA)
return;
if (m_mmSubState == EMmSubState::MM_DEREGISTERED_NO_SUPI)
return;
} }
void NasMm::switchMmState(EMmState state, EMmSubState subState) void NasMm::switchMmState(EMmState state, EMmSubState subState)
......
//
// This file is a part of UERANSIM open source project.
// Copyright (c) 2021 ALİ GÜNGÖR.
//
// The software and all associated files are licensed under GPL-3.0
// and subject to the terms and conditions defined in LICENSE file.
//
#include "mm.hpp"
#include <nas/utils.hpp>
#include <stdexcept>
#include <ue/app/task.hpp>
#include <ue/nas/task.hpp>
#include <ue/rrc/task.hpp>
namespace nr::ue
{
bool NasMm::startECallInactivityIfNeeded()
{
// 5.5.3 eCall inactivity procedure
// "The eCall inactivity procedure is performed only in 3GPP access and applicable only to a UE configured for eCall
// only mode as specified in 3GPP TS 31.102 [22].
if (!m_storage.isECallOnly)
return false;
// The procedure shall be started when
// a) the UE is in any 5GMM-REGISTERED substate except substates 5GMM-REGISTERED.PLMN-SEARCH or
// 5GMM-REGISTERED.NO-CELL-AVAILABLE;"
if (m_mmState != EMmState::MM_REGISTERED)
return false;
if (m_mmSubState == EMmSubState::MM_REGISTERED_PLMN_SEARCH ||
m_mmSubState == EMmSubState::MM_REGISTERED_NO_CELL_AVAILABLE)
return false;
// "b) the UE is in 5GMM-IDLE mode; and"
if (m_cmState != ECmState::CM_IDLE)
return false;
// c) one of the following conditions applies:
// 1) timer T3444 expires or is found to have already expired and timer T3445 is not running;
// 2) timer T3445 expires or is found to have already expired and timer T3444 is not running; or
// 3) timers T3444 and T3445 expire or are found to have already expired.
if (!(!m_timers->t3444.isRunning() && m_timers->t3445.isRunning()) ||
(!m_timers->t3445.isRunning() && m_timers->t3444.isRunning()) ||
(!m_timers->t3444.isRunning() && !m_timers->t3445.isRunning()))
return false;
// "The UE shall then perform the following actions:
// a) stop other running timers (e.g. T3511, T3512);
// b) if the UE is currently registered to the network for 5GS services, perform a de-registration procedure;
// c) delete any 5G-GUTI, TAI list, last visited registered TAI, list of equivalent PLMNs, and ngKSI; and
// d) enter 5GMM-DEREGISTERED.eCALL-INACTIVE state."
// TODO: Spec says 'other running timers' in item a), what are those timers other than 3511 and 3512?
m_timers->t3511.stop();
m_timers->t3512.stop();
// Spec says if the UE is currently registered to the network for 5GS services, but it also says procedure shall
// be started if ... and 5GMM-REGISTERED ....
if (m_rmState != ERmState::RM_REGISTERED)
{
// Therefore just assert that the UE is registered
throw std::runtime_error("UE MM eCall - MM and RM state inconsistent");
}
// And perform de-registration.
// NOTE: The items c) and d) is performed after de-registration by the other function, therefore we are just
// performing de-registration for now.
sendDeregistration(EDeregCause::ECALL_INACTIVITY);
return true;
}
bool NasMm::switchToECallInactivityIfNeeded()
{
if (!m_storage.isECallOnly)
return false;
if (m_mmState != EMmState::MM_DEREGISTERED)
return false;
if (m_cmState != ECmState::CM_IDLE)
return false;
if (!(!m_timers->t3444.isRunning() && m_timers->t3445.isRunning()) ||
(!m_timers->t3445.isRunning() && m_timers->t3444.isRunning()) ||
(!m_timers->t3444.isRunning() && !m_timers->t3445.isRunning()))
return false;
// Perform item c) in 5.5.3
m_storage.m_storedGuti = {};
m_storage.m_taiList = {};
m_storage.m_lastVisitedRegisteredTai = {};
m_storage.m_equivalentPlmnList = {};
m_storage.m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {};
// Perform item d) in 5.5.3
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_ECALL_INACTIVE);
return true;
}
} // namespace nr::ue
...@@ -154,6 +154,10 @@ class NasMm ...@@ -154,6 +154,10 @@ class NasMm
bool isHighPriority(); bool isHighPriority();
bool hasEmergency(); bool hasEmergency();
private: /* eCall */
bool startECallInactivityIfNeeded();
bool switchToECallInactivityIfNeeded();
public: /* Timer */ public: /* Timer */
void onTimerExpire(nas::NasTimer &timer); void onTimerExpire(nas::NasTimer &timer);
}; };
......
...@@ -55,6 +55,9 @@ class MobileStorage ...@@ -55,6 +55,9 @@ class MobileStorage
std::optional<nas::IETimeZoneAndTime> universalTimeAndLocalTimeZone{}; std::optional<nas::IETimeZoneAndTime> universalTimeAndLocalTimeZone{};
std::optional<nas::IEDaylightSavingTime> networkDaylightSavingTime{}; std::optional<nas::IEDaylightSavingTime> networkDaylightSavingTime{};
// eCall related
bool isECallOnly{};
public: public:
void initialize(bool hasSupi, const UeConfig::Initials &initials) void initialize(bool hasSupi, const UeConfig::Initials &initials)
{ {
......
...@@ -67,6 +67,8 @@ Json ToJson(const EDeregCause &v) ...@@ -67,6 +67,8 @@ Json ToJson(const EDeregCause &v)
return "USIM-REMOVAL"; return "USIM-REMOVAL";
case EDeregCause::DISABLE_5G: case EDeregCause::DISABLE_5G:
return "DISABLE-5G"; return "DISABLE-5G";
case EDeregCause::ECALL_INACTIVITY:
return "ECALL-INACTIVITY";
default: default:
return "?"; return "?";
} }
......
...@@ -116,6 +116,7 @@ enum class EDeregCause ...@@ -116,6 +116,7 @@ enum class EDeregCause
SWITCH_OFF, SWITCH_OFF,
USIM_REMOVAL, USIM_REMOVAL,
DISABLE_5G, DISABLE_5G,
ECALL_INACTIVITY,
}; };
Json ToJson(const Supi &v); Json ToJson(const Supi &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