Commit 3efaf373 authored by aligungr's avatar aligungr

MM refactor

parent a6b060dd
...@@ -109,10 +109,10 @@ void UeCmdHandler::handleCmdImpl(NwUeCliCommand &msg) ...@@ -109,10 +109,10 @@ void UeCmdHandler::handleCmdImpl(NwUeCliCommand &msg)
{"cm-state", ToJson(m_base->nasTask->mm->m_cmState)}, {"cm-state", ToJson(m_base->nasTask->mm->m_cmState)},
{"rm-state", ToJson(m_base->nasTask->mm->m_rmState)}, {"rm-state", ToJson(m_base->nasTask->mm->m_rmState)},
{"mm-state", ToJson(m_base->nasTask->mm->m_mmSubState)}, {"mm-state", ToJson(m_base->nasTask->mm->m_mmSubState)},
{"5u-state", ToJson(m_base->nasTask->mm->m_storage.m_uState)}, {"5u-state", ToJson(m_base->nasTask->mm->m_usim->m_uState)},
{"sim-inserted", m_base->nasTask->mm->m_storage.isSimValid()}, {"sim-inserted", m_base->nasTask->mm->m_usim->isValid()},
{"stored-suci", ToJson(m_base->nasTask->mm->m_storage.m_storedSuci)}, {"stored-suci", ToJson(m_base->nasTask->mm->m_usim->m_storedSuci)},
{"stored-guti", ToJson(m_base->nasTask->mm->m_storage.m_storedGuti)}, {"stored-guti", ToJson(m_base->nasTask->mm->m_usim->m_storedGuti)},
{"has-emergency", ::ToJson(m_base->nasTask->mm->hasEmergency())}, {"has-emergency", ::ToJson(m_base->nasTask->mm->hasEmergency())},
{"pdu-sessions", Json::Arr(std::move(pduSessions))}, {"pdu-sessions", Json::Arr(std::move(pduSessions))},
}); });
......
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <nas/utils.hpp> #include <nas/utils.hpp>
#include <ue/app/task.hpp> #include <ue/app/task.hpp>
#include <ue/nas/task.hpp> #include <ue/nas/task.hpp>
#include <ue/nas/usim.hpp>
#include <ue/rrc/task.hpp> #include <ue/rrc/task.hpp>
#include <utils/common.hpp> #include <utils/common.hpp>
...@@ -25,15 +26,12 @@ NasMm::NasMm(TaskBase *base, UeTimers *timers) : m_base{base}, m_timers{timers}, ...@@ -25,15 +26,12 @@ 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_storage.m_uState = E5UState::U1_UPDATED;
m_storage.initialize(base->config->supi.has_value(), base->config->initials);
m_storage.m_currentPlmn = base->config->hplmn; // TODO: normally assigned after plmn search
} }
void NasMm::onStart(NasSm *sm) void NasMm::onStart(NasSm *sm, Usim *usim)
{ {
m_sm = sm; m_sm = sm;
m_usim = usim;
triggerMmCycle(); triggerMmCycle();
} }
...@@ -57,7 +55,7 @@ void NasMm::performMmCycle() ...@@ -57,7 +55,7 @@ void NasMm::performMmCycle()
if (switchToECallInactivityIfNeeded()) if (switchToECallInactivityIfNeeded())
return; return;
if (m_storage.isSimValid()) if (m_usim->isValid())
{ {
if (m_cmState == ECmState::CM_IDLE) if (m_cmState == ECmState::CM_IDLE)
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_PLMN_SEARCH); switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_PLMN_SEARCH);
...@@ -162,15 +160,15 @@ void NasMm::switchCmState(ECmState state) ...@@ -162,15 +160,15 @@ void NasMm::switchCmState(ECmState state)
void NasMm::switchUState(E5UState state) void NasMm::switchUState(E5UState state)
{ {
E5UState oldState = m_storage.m_uState; E5UState oldState = m_usim->m_uState;
m_storage.m_uState = state; m_usim->m_uState = state;
onSwitchUState(oldState, m_storage.m_uState); onSwitchUState(oldState, m_usim->m_uState);
if (m_base->nodeListener) if (m_base->nodeListener)
{ {
m_base->nodeListener->onSwitch(app::NodeType::UE, m_base->config->getNodeName(), app::StateType::U5, m_base->nodeListener->onSwitch(app::NodeType::UE, m_base->config->getNodeName(), app::StateType::U5,
ToJson(oldState).str(), ToJson(m_storage.m_uState).str()); ToJson(oldState).str(), ToJson(m_usim->m_uState).str());
} }
if (state != oldState) if (state != oldState)
...@@ -186,12 +184,12 @@ void NasMm::onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState ol ...@@ -186,12 +184,12 @@ void NasMm::onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState ol
// 5GMM-DEREGISTERED for any other state except 5GMM-NULL. // 5GMM-DEREGISTERED for any other state except 5GMM-NULL.
if (oldState == EMmState::MM_DEREGISTERED && newState != EMmState::MM_DEREGISTERED && newState != EMmState::MM_NULL) if (oldState == EMmState::MM_DEREGISTERED && newState != EMmState::MM_DEREGISTERED && newState != EMmState::MM_NULL)
{ {
if (m_storage.m_currentNsCtx || m_storage.m_nonCurrentNsCtx) if (m_usim->m_currentNsCtx || m_usim->m_nonCurrentNsCtx)
{ {
m_logger->debug("Deleting NAS security context"); m_logger->debug("Deleting NAS security context");
m_storage.m_currentNsCtx = {}; m_usim->m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {}; m_usim->m_nonCurrentNsCtx = {};
} }
} }
} }
......
...@@ -26,8 +26,8 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -26,8 +26,8 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if (msg.guti.has_value() && msg.guti->type == nas::EIdentityType::GUTI) if (msg.guti.has_value() && msg.guti->type == nas::EIdentityType::GUTI)
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.m_storedSuci = {}; m_usim->m_storedSuci = {};
m_storage.m_storedGuti = *msg.guti; m_usim->m_storedGuti = *msg.guti;
m_timers->t3519.stop(); m_timers->t3519.stop();
} }
...@@ -36,7 +36,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -36,7 +36,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if (msg.taiList.has_value()) if (msg.taiList.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.m_taiList = *msg.taiList; m_usim->m_taiList = *msg.taiList;
} }
// "If the UE receives a new service area list in the CONFIGURATION UPDATE COMMAND message, the UE shall consider // "If the UE receives a new service area list in the CONFIGURATION UPDATE COMMAND message, the UE shall consider
...@@ -46,7 +46,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -46,7 +46,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if (msg.serviceAreaList.has_value()) if (msg.serviceAreaList.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.m_serviceAreaList = *msg.serviceAreaList; m_usim->m_serviceAreaList = *msg.serviceAreaList;
} }
// "If the UE receives new NITZ information in the CONFIGURATION UPDATE COMMAND message, the UE considers the new // "If the UE receives new NITZ information in the CONFIGURATION UPDATE COMMAND message, the UE considers the new
...@@ -55,27 +55,27 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -55,27 +55,27 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if (msg.networkFullName.has_value()) if (msg.networkFullName.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.networkFullName = nas::utils::DeepCopyIe(*msg.networkFullName); m_usim->m_networkFullName = nas::utils::DeepCopyIe(*msg.networkFullName);
} }
if (msg.networkShortName.has_value()) if (msg.networkShortName.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.networkShortName = nas::utils::DeepCopyIe(*msg.networkShortName); m_usim->m_networkShortName = nas::utils::DeepCopyIe(*msg.networkShortName);
} }
if (msg.localTimeZone.has_value()) if (msg.localTimeZone.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.localTimeZone = *msg.localTimeZone; m_usim->m_localTimeZone = *msg.localTimeZone;
} }
if (msg.universalTimeAndLocalTimeZone.has_value()) if (msg.universalTimeAndLocalTimeZone.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.universalTimeAndLocalTimeZone = *msg.universalTimeAndLocalTimeZone; m_usim->m_universalTimeAndLocalTimeZone = *msg.universalTimeAndLocalTimeZone;
} }
if (msg.networkDaylightSavingTime.has_value()) if (msg.networkDaylightSavingTime.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.networkDaylightSavingTime = *msg.networkDaylightSavingTime; m_usim->m_networkDaylightSavingTime = *msg.networkDaylightSavingTime;
} }
// "If the UE receives a new allowed NSSAI for the associated access type in the CONFIGURATION UPDATE COMMAND // "If the UE receives a new allowed NSSAI for the associated access type in the CONFIGURATION UPDATE COMMAND
...@@ -86,7 +86,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -86,7 +86,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if (msg.allowedNssai.has_value()) if (msg.allowedNssai.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.m_allowedNssai = nas::utils::NssaiTo(*msg.allowedNssai); m_usim->m_allowedNssai = nas::utils::NssaiTo(*msg.allowedNssai);
} }
// "If the UE receives a new configured NSSAI in the CONFIGURATION UPDATE COMMAND message, the UE shall consider the // "If the UE receives a new configured NSSAI in the CONFIGURATION UPDATE COMMAND message, the UE shall consider the
...@@ -96,7 +96,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -96,7 +96,7 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if (msg.configuredNssai.has_value()) if (msg.configuredNssai.has_value())
{ {
hasNewConfig = true; hasNewConfig = true;
m_storage.m_configuredNssai = nas::utils::NssaiTo(*msg.configuredNssai); m_usim->m_configuredNssai = nas::utils::NssaiTo(*msg.configuredNssai);
} }
// "If the UE receives the Network slicing indication IE in the CONFIGURATION UPDATE COMMAND message with the // "If the UE receives the Network slicing indication IE in the CONFIGURATION UPDATE COMMAND message with the
...@@ -121,8 +121,8 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms ...@@ -121,8 +121,8 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
slice.sst = rejectedSlice.sst; slice.sst = rejectedSlice.sst;
slice.sd = rejectedSlice.sd; slice.sd = rejectedSlice.sd;
auto &list = rejectedSlice.cause == nas::ERejectedSNssaiCause::NA_IN_PLMN ? m_storage.m_rejectedNssaiInPlmn auto &list = rejectedSlice.cause == nas::ERejectedSNssaiCause::NA_IN_PLMN ? m_usim->m_rejectedNssaiInPlmn
: m_storage.m_rejectedNssaiInTa; : m_usim->m_rejectedNssaiInTa;
list.addIfNotExists(slice); list.addIfNotExists(slice);
} }
} }
......
...@@ -38,10 +38,10 @@ void NasMm::sendDeregistration(EDeregCause deregCause) ...@@ -38,10 +38,10 @@ void NasMm::sendDeregistration(EDeregCause deregCause)
auto request = std::make_unique<nas::DeRegistrationRequestUeOriginating>(); auto request = std::make_unique<nas::DeRegistrationRequestUeOriginating>();
request->deRegistrationType = MakeDeRegistrationType(deregCause); request->deRegistrationType = MakeDeRegistrationType(deregCause);
if (m_storage.m_currentNsCtx) if (m_usim->m_currentNsCtx)
{ {
request->ngKSI.tsc = m_storage.m_currentNsCtx->tsc; request->ngKSI.tsc = m_usim->m_currentNsCtx->tsc;
request->ngKSI.ksi = m_storage.m_currentNsCtx->ngKsi; request->ngKSI.ksi = m_usim->m_currentNsCtx->ngKsi;
} }
else else
{ {
...@@ -68,7 +68,7 @@ void NasMm::sendDeregistration(EDeregCause deregCause) ...@@ -68,7 +68,7 @@ void NasMm::sendDeregistration(EDeregCause deregCause)
else if (deregCause == EDeregCause::USIM_REMOVAL) else if (deregCause == EDeregCause::USIM_REMOVAL)
{ {
m_logger->info("SIM card has been invalidated"); m_logger->info("SIM card has been invalidated");
m_storage.invalidateSim(); m_usim->invalidate();
} }
m_sm->localReleaseAllSessions(); m_sm->localReleaseAllSessions();
...@@ -96,7 +96,7 @@ void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOrigina ...@@ -96,7 +96,7 @@ void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOrigina
m_timers->t3521.stop(); m_timers->t3521.stop();
m_timers->t3519.stop(); m_timers->t3519.stop();
m_storage.m_storedSuci = {}; m_usim->m_storedSuci = {};
m_sm->localReleaseAllSessions(); m_sm->localReleaseAllSessions();
...@@ -178,8 +178,8 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi ...@@ -178,8 +178,8 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
// "Upon sending a DEREGISTRATION ACCEPT message, the UE shall delete the rejected NSSAI as specified in // "Upon sending a DEREGISTRATION ACCEPT message, the UE shall delete the rejected NSSAI as specified in
// subclause 4.6.2.2." // subclause 4.6.2.2."
m_storage.m_rejectedNssaiInTa = {}; m_usim->m_rejectedNssaiInTa = {};
m_storage.m_rejectedNssaiInPlmn = {}; m_usim->m_rejectedNssaiInPlmn = {};
// Handle 5.5.2.3.4 Abnormal cases in the UE, item b) // Handle 5.5.2.3.4 Abnormal cases in the UE, item b)
auto handleAbnormal = [this]() { auto handleAbnormal = [this]() {
...@@ -187,12 +187,12 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi ...@@ -187,12 +187,12 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
// set the 5GS update status to 5U2 NOT UPDATED and shall start timer T3502. A UE not supporting S1 mode may // set the 5GS update status to 5U2 NOT UPDATED and shall start timer T3502. A UE not supporting S1 mode may
// enter the state 5GMM-DEREGISTERED.PLMN-SEARCH in order to perform a PLMN selection according to 3GPP // enter the state 5GMM-DEREGISTERED.PLMN-SEARCH in order to perform a PLMN selection according to 3GPP
// TS 23.122 [5]; otherwise the UE shall enter the state 5GMM-DEREGISTERED.ATTEMPTING-REGISTRATION." // TS 23.122 [5]; otherwise the UE shall enter the state 5GMM-DEREGISTERED.ATTEMPTING-REGISTRATION."
m_storage.m_storedGuti = {}; m_usim->m_storedGuti = {};
m_storage.m_taiList = {}; m_usim->m_taiList = {};
m_storage.m_lastVisitedRegisteredTai = {}; m_usim->m_lastVisitedRegisteredTai = {};
m_storage.m_equivalentPlmnList = {}; m_usim->m_equivalentPlmnList = {};
m_storage.m_currentNsCtx = {}; m_usim->m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {}; m_usim->m_nonCurrentNsCtx = {};
switchUState(E5UState::U2_NOT_UPDATED); switchUState(E5UState::U2_NOT_UPDATED);
m_timers->t3502.start(); m_timers->t3502.start();
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_PLMN_SEARCH); switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_PLMN_SEARCH);
...@@ -210,21 +210,21 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi ...@@ -210,21 +210,21 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA || cause == nas::EMmCause::N1_MODE_NOT_ALLOWED) cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA || cause == nas::EMmCause::N1_MODE_NOT_ALLOWED)
{ {
switchUState(E5UState::U3_ROAMING_NOT_ALLOWED); switchUState(E5UState::U3_ROAMING_NOT_ALLOWED);
m_storage.m_storedGuti = {}; m_usim->m_storedGuti = {};
m_storage.m_lastVisitedRegisteredTai = {}; m_usim->m_lastVisitedRegisteredTai = {};
m_storage.m_taiList = {}; m_usim->m_taiList = {};
m_storage.m_currentNsCtx = {}; m_usim->m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {}; m_usim->m_nonCurrentNsCtx = {};
} }
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME || if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME ||
cause == nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED) cause == nas::EMmCause::FIVEG_SERVICES_NOT_ALLOWED)
m_storage.invalidateSim(); m_usim->invalidate();
if (cause == nas::EMmCause::ILLEGAL_UE || cause == nas::EMmCause::ILLEGAL_ME || 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::FIVEG_SERVICES_NOT_ALLOWED || cause == nas::EMmCause::PLMN_NOT_ALLOWED ||
cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA) cause == nas::EMmCause::ROAMING_NOT_ALLOWED_IN_TA)
m_storage.m_equivalentPlmnList = {}; m_usim->m_equivalentPlmnList = {};
if (cause == nas::EMmCause::PLMN_NOT_ALLOWED || cause == nas::EMmCause::TA_NOT_ALLOWED || 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::ROAMING_NOT_ALLOWED_IN_TA || cause == nas::EMmCause::NO_SUITIBLE_CELLS_IN_TA ||
......
...@@ -23,7 +23,7 @@ bool NasMm::startECallInactivityIfNeeded() ...@@ -23,7 +23,7 @@ bool NasMm::startECallInactivityIfNeeded()
// "The eCall inactivity procedure is performed only in 3GPP access and applicable only to a UE configured for eCall // "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]. // only mode as specified in 3GPP TS 31.102 [22].
if (!m_storage.isECallOnly) if (!m_usim->m_isECallOnly)
return false; return false;
// The procedure shall be started when // The procedure shall be started when
...@@ -72,7 +72,7 @@ bool NasMm::startECallInactivityIfNeeded() ...@@ -72,7 +72,7 @@ bool NasMm::startECallInactivityIfNeeded()
bool NasMm::switchToECallInactivityIfNeeded() bool NasMm::switchToECallInactivityIfNeeded()
{ {
if (!m_storage.isECallOnly) if (!m_usim->m_isECallOnly)
return false; return false;
if (m_mmState != EMmState::MM_DEREGISTERED) if (m_mmState != EMmState::MM_DEREGISTERED)
...@@ -86,12 +86,12 @@ bool NasMm::switchToECallInactivityIfNeeded() ...@@ -86,12 +86,12 @@ bool NasMm::switchToECallInactivityIfNeeded()
return false; return false;
// Perform item c) in 5.5.3 // Perform item c) in 5.5.3
m_storage.m_storedGuti = {}; m_usim->m_storedGuti = {};
m_storage.m_taiList = {}; m_usim->m_taiList = {};
m_storage.m_lastVisitedRegisteredTai = {}; m_usim->m_lastVisitedRegisteredTai = {};
m_storage.m_equivalentPlmnList = {}; m_usim->m_equivalentPlmnList = {};
m_storage.m_currentNsCtx = {}; m_usim->m_currentNsCtx = {};
m_storage.m_nonCurrentNsCtx = {}; m_usim->m_nonCurrentNsCtx = {};
// Perform item d) in 5.5.3 // Perform item d) in 5.5.3
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_ECALL_INACTIVE); switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_ECALL_INACTIVE);
......
...@@ -42,21 +42,21 @@ void NasMm::receiveIdentityRequest(const nas::IdentityRequest &msg) ...@@ -42,21 +42,21 @@ void NasMm::receiveIdentityRequest(const nas::IdentityRequest &msg)
nas::IE5gsMobileIdentity NasMm::getOrGenerateSuci() nas::IE5gsMobileIdentity NasMm::getOrGenerateSuci()
{ {
if (m_timers->t3519.isRunning() && m_storage.m_storedSuci.type != nas::EIdentityType::NO_IDENTITY) if (m_timers->t3519.isRunning() && m_usim->m_storedSuci.type != nas::EIdentityType::NO_IDENTITY)
return m_storage.m_storedSuci; return m_usim->m_storedSuci;
m_storage.m_storedSuci = generateSuci(); m_usim->m_storedSuci = generateSuci();
m_timers->t3519.start(); m_timers->t3519.start();
if (m_storage.m_storedSuci.type == nas::EIdentityType::NO_IDENTITY) if (m_usim->m_storedSuci.type == nas::EIdentityType::NO_IDENTITY)
return {}; return {};
return m_storage.m_storedSuci; return m_usim->m_storedSuci;
} }
nas::IE5gsMobileIdentity NasMm::generateSuci() nas::IE5gsMobileIdentity NasMm::generateSuci()
{ {
auto &supi = m_base->config->supi; auto &supi = m_base->config->supi;
auto &plmn = m_storage.m_currentPlmn; auto &plmn = m_usim->m_currentPlmn;
if (!supi.has_value()) if (!supi.has_value())
return {}; return {};
...@@ -84,8 +84,8 @@ nas::IE5gsMobileIdentity NasMm::generateSuci() ...@@ -84,8 +84,8 @@ nas::IE5gsMobileIdentity NasMm::generateSuci()
nas::IE5gsMobileIdentity NasMm::getOrGeneratePreferredId() nas::IE5gsMobileIdentity NasMm::getOrGeneratePreferredId()
{ {
if (m_storage.m_storedGuti.type != nas::EIdentityType::NO_IDENTITY) if (m_usim->m_storedGuti.type != nas::EIdentityType::NO_IDENTITY)
return m_storage.m_storedGuti; return m_usim->m_storedGuti;
auto suci = getOrGenerateSuci(); auto suci = getOrGenerateSuci();
if (suci.type != nas::EIdentityType::NO_IDENTITY) if (suci.type != nas::EIdentityType::NO_IDENTITY)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <crypt/milenage.hpp> #include <crypt/milenage.hpp>
#include <nas/nas.hpp> #include <nas/nas.hpp>
#include <nas/timer.hpp> #include <nas/timer.hpp>
#include <ue/nas/storage.hpp> #include <ue/nas/usim.hpp>
#include <ue/nts.hpp> #include <ue/nts.hpp>
#include <ue/types.hpp> #include <ue/types.hpp>
#include <utils/nts.hpp> #include <utils/nts.hpp>
...@@ -29,7 +29,7 @@ class NasMm ...@@ -29,7 +29,7 @@ class NasMm
UeTimers *m_timers; UeTimers *m_timers;
std::unique_ptr<Logger> m_logger; std::unique_ptr<Logger> m_logger;
NasSm *m_sm; NasSm *m_sm;
MobileStorage m_storage{}; Usim *m_usim{};
ERmState m_rmState; ERmState m_rmState;
ECmState m_cmState; ECmState m_cmState;
...@@ -59,7 +59,7 @@ class NasMm ...@@ -59,7 +59,7 @@ class NasMm
NasMm(TaskBase *base, UeTimers *timers); NasMm(TaskBase *base, UeTimers *timers);
public: /* Base */ public: /* Base */
void onStart(NasSm *sm); void onStart(NasSm *sm, Usim *usim);
void onQuit(); void onQuit();
private: /* Base */ private: /* Base */
......
This diff is collapsed.
...@@ -56,7 +56,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -56,7 +56,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
// TODO // TODO
} }
int whichCtx = FindSecurityContext(msg.ngKsi.ksi, m_storage.m_currentNsCtx, m_storage.m_nonCurrentNsCtx); int whichCtx = FindSecurityContext(msg.ngKsi.ksi, m_usim->m_currentNsCtx, m_usim->m_nonCurrentNsCtx);
if (whichCtx == -1) if (whichCtx == -1)
{ {
m_logger->err("Security context with ngKSI[%d] not found", msg.ngKsi.ksi); m_logger->err("Security context with ngKSI[%d] not found", msg.ngKsi.ksi);
...@@ -64,7 +64,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -64,7 +64,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
return; return;
} }
auto &nsCtx = whichCtx == 0 ? m_storage.m_currentNsCtx : m_storage.m_nonCurrentNsCtx; auto &nsCtx = whichCtx == 0 ? m_usim->m_currentNsCtx : m_usim->m_nonCurrentNsCtx;
// ======================== Check the integrity with new security context ======================== // ======================== Check the integrity with new security context ========================
...@@ -129,7 +129,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -129,7 +129,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
// Set the new NAS Security Context as current one. (If it is not already the current one) // Set the new NAS Security Context as current one. (If it is not already the current one)
if (whichCtx == 1) if (whichCtx == 1)
m_storage.m_currentNsCtx = std::make_unique<NasSecurityContext>(nsCtx->deepCopy()); m_usim->m_currentNsCtx = std::make_unique<NasSecurityContext>(nsCtx->deepCopy());
// ============================ Handle EAP-Success message if any. ============================ // ============================ Handle EAP-Success message if any. ============================
......
...@@ -43,25 +43,25 @@ NetworkSlice NasMm::makeRequestedNssai(bool &isDefaultNssai) const ...@@ -43,25 +43,25 @@ NetworkSlice NasMm::makeRequestedNssai(bool &isDefaultNssai) const
NetworkSlice res{}; NetworkSlice res{};
if (!m_storage.m_allowedNssai.slices.empty() || !m_storage.m_configuredNssai.slices.empty()) if (!m_usim->m_allowedNssai.slices.empty() || !m_usim->m_configuredNssai.slices.empty())
{ {
if (!m_storage.m_allowedNssai.slices.empty()) if (!m_usim->m_allowedNssai.slices.empty())
{ {
AppendSubset(m_storage.m_allowedNssai, res, m_storage.m_rejectedNssaiInPlmn, m_storage.m_rejectedNssaiInTa, AppendSubset(m_usim->m_allowedNssai, res, m_usim->m_rejectedNssaiInPlmn, m_usim->m_rejectedNssaiInTa,
8); 8);
AppendSubset(m_storage.m_configuredNssai, res, m_storage.m_rejectedNssaiInPlmn, AppendSubset(m_usim->m_configuredNssai, res, m_usim->m_rejectedNssaiInPlmn,
m_storage.m_rejectedNssaiInTa, static_cast<size_t>(8) - res.slices.size()); m_usim->m_rejectedNssaiInTa, static_cast<size_t>(8) - res.slices.size());
} }
else else
{ {
AppendSubset(m_storage.m_configuredNssai, res, m_storage.m_rejectedNssaiInPlmn, AppendSubset(m_usim->m_configuredNssai, res, m_usim->m_rejectedNssaiInPlmn,
m_storage.m_rejectedNssaiInTa, 8); m_usim->m_rejectedNssaiInTa, 8);
} }
} }
else if (!m_storage.m_defConfiguredNssai.slices.empty()) else if (!m_usim->m_defConfiguredNssai.slices.empty())
{ {
AppendSubset(m_storage.m_defConfiguredNssai, res, m_storage.m_rejectedNssaiInPlmn, AppendSubset(m_usim->m_defConfiguredNssai, res, m_usim->m_rejectedNssaiInPlmn,
m_storage.m_rejectedNssaiInTa, 8); m_usim->m_rejectedNssaiInTa, 8);
isDefaultNssai = true; isDefaultNssai = true;
} }
......
...@@ -88,7 +88,7 @@ void NasMm::onTimerExpire(nas::NasTimer &timer) ...@@ -88,7 +88,7 @@ void NasMm::onTimerExpire(nas::NasTimer &timer)
break; break;
} }
case 3519: { case 3519: {
m_storage.m_storedSuci = {}; m_usim->m_storedSuci = {};
break; break;
} }
case 3521: { case 3521: {
......
...@@ -21,11 +21,11 @@ void NasMm::sendNasMessage(const nas::PlainMmMessage &msg) ...@@ -21,11 +21,11 @@ void NasMm::sendNasMessage(const nas::PlainMmMessage &msg)
// TODO trigger on send // TODO trigger on send
OctetString pdu{}; OctetString pdu{};
if (m_storage.m_currentNsCtx && if (m_usim->m_currentNsCtx &&
(m_storage.m_currentNsCtx->integrity != nas::ETypeOfIntegrityProtectionAlgorithm::IA0 || (m_usim->m_currentNsCtx->integrity != nas::ETypeOfIntegrityProtectionAlgorithm::IA0 ||
m_storage.m_currentNsCtx->ciphering != nas::ETypeOfCipheringAlgorithm::EA0)) m_usim->m_currentNsCtx->ciphering != nas::ETypeOfCipheringAlgorithm::EA0))
{ {
auto secured = nas_enc::Encrypt(*m_storage.m_currentNsCtx, msg); auto secured = nas_enc::Encrypt(*m_usim->m_currentNsCtx, msg);
nas::EncodeNasMessage(*secured, pdu); nas::EncodeNasMessage(*secured, pdu);
} }
else else
...@@ -63,7 +63,7 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg) ...@@ -63,7 +63,7 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg)
{ {
// If any NAS signalling message is received as not integrity protected even though the secure exchange of NAS // If any NAS signalling message is received as not integrity protected even though the secure exchange of NAS
// messages has been established by the network, then the NAS shall discard this message // messages has been established by the network, then the NAS shall discard this message
if (m_storage.m_currentNsCtx) if (m_usim->m_currentNsCtx)
{ {
m_logger->err( m_logger->err(
"Not integrity protected NAS message received after security establishment. Ignoring received " "Not integrity protected NAS message received after security establishment. Ignoring received "
...@@ -101,14 +101,14 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg) ...@@ -101,14 +101,14 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg)
return; return;
} }
if (!m_storage.m_currentNsCtx) if (!m_usim->m_currentNsCtx)
{ {
m_logger->warn("Secured NAS message received while no security context"); m_logger->warn("Secured NAS message received while no security context");
sendMmStatus(nas::EMmCause::MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE); sendMmStatus(nas::EMmCause::MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE);
return; return;
} }
auto decrypted = nas_enc::Decrypt(*m_storage.m_currentNsCtx, securedMm); auto decrypted = nas_enc::Decrypt(*m_usim->m_currentNsCtx, securedMm);
if (decrypted == nullptr) if (decrypted == nullptr)
{ {
m_logger->err("MAC mismatch in NAS encryption. Ignoring received NAS Message."); m_logger->err("MAC mismatch in NAS encryption. Ignoring received NAS Message.");
......
//
// 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 "storage.hpp"
namespace nr::ue
{
} // namespace nr::ue
//
// 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 <nas/nas.hpp>
#include <ue/types.hpp>
#pragma once
namespace nr::ue
{
class MobileStorage
{
private:
bool m_simIsValid{};
public:
// Location related
nas::IE5gsMobileIdentity m_storedGuti{};
std::optional<nas::IE5gsTrackingAreaIdentity> m_lastVisitedRegisteredTai{};
E5UState m_uState{};
// Identity related
nas::IE5gsMobileIdentity m_storedSuci{};
// Plmn related
Plmn m_currentPlmn{};
nas::IE5gsTrackingAreaIdentityList m_taiList{};
nas::IE5gsTrackingAreaIdentityList m_forbiddenTaiList{};
nas::IEPlmnList m_equivalentPlmnList{};
nas::IEPlmnList m_forbiddenPlmnList{};
nas::IEServiceAreaList m_serviceAreaList{};
// Security related
std::unique_ptr<NasSecurityContext> m_currentNsCtx{};
std::unique_ptr<NasSecurityContext> m_nonCurrentNsCtx{};
OctetString m_sqn{};
// NSSAI related
NetworkSlice m_defConfiguredNssai{};
NetworkSlice m_configuredNssai{};
NetworkSlice m_allowedNssai{};
NetworkSlice m_rejectedNssaiInPlmn{};
NetworkSlice m_rejectedNssaiInTa{};
// NITZ related
std::optional<nas::IENetworkName> networkFullName{};
std::optional<nas::IENetworkName> networkShortName{};
std::optional<nas::IETimeZone> localTimeZone{};
std::optional<nas::IETimeZoneAndTime> universalTimeAndLocalTimeZone{};
std::optional<nas::IEDaylightSavingTime> networkDaylightSavingTime{};
// eCall related
bool isECallOnly{};
public:
void initialize(bool hasSupi, const UeConfig::Initials &initials)
{
m_simIsValid = hasSupi;
m_defConfiguredNssai = initials.defaultConfiguredNssai;
m_configuredNssai = initials.configuredNssai;
}
void invalidateSim()
{
m_simIsValid = false;
}
[[nodiscard]] bool isSimValid() const
{
return m_simIsValid;
}
};
} // namespace nr::ue
\ No newline at end of file
...@@ -23,14 +23,18 @@ NasTask::NasTask(TaskBase *base) : base{base}, timers{} ...@@ -23,14 +23,18 @@ NasTask::NasTask(TaskBase *base) : base{base}, timers{}
mm = new NasMm(base, &timers); mm = new NasMm(base, &timers);
sm = new NasSm(base, &timers); sm = new NasSm(base, &timers);
usim = new Usim();
} }
void NasTask::onStart() void NasTask::onStart()
{ {
logger->debug("NAS layer started"); logger->debug("NAS layer started");
usim->initialize(base->config->supi.has_value(), base->config->initials);
usim->m_currentPlmn = base->config->hplmn; // TODO: normally assigned after plmn search
sm->onStart(mm); sm->onStart(mm);
mm->onStart(sm); mm->onStart(sm, usim);
setTimer(NTS_TIMER_ID_NAS_TIMER_CYCLE, NTS_TIMER_INTERVAL_NAS_TIMER_CYCLE); setTimer(NTS_TIMER_ID_NAS_TIMER_CYCLE, NTS_TIMER_INTERVAL_NAS_TIMER_CYCLE);
setTimer(NTS_TIMER_ID_MM_CYCLE, NTS_TIMER_INTERVAL_MM_CYCLE); setTimer(NTS_TIMER_ID_MM_CYCLE, NTS_TIMER_INTERVAL_MM_CYCLE);
...@@ -43,6 +47,8 @@ void NasTask::onQuit() ...@@ -43,6 +47,8 @@ void NasTask::onQuit()
delete mm; delete mm;
delete sm; delete sm;
delete usim;
} }
void NasTask::onLoop() void NasTask::onLoop()
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#pragma once #pragma once
#include "usim.hpp"
#include <crypt/milenage.hpp> #include <crypt/milenage.hpp>
#include <nas/nas.hpp> #include <nas/nas.hpp>
#include <nas/timer.hpp> #include <nas/timer.hpp>
...@@ -29,6 +30,7 @@ class NasTask : public NtsTask ...@@ -29,6 +30,7 @@ class NasTask : public NtsTask
UeTimers timers; UeTimers timers;
NasMm *mm; NasMm *mm;
NasSm *sm; NasSm *sm;
Usim *usim;
friend class UeCmdHandler; friend class UeCmdHandler;
......
...@@ -6,7 +6,29 @@ ...@@ -6,7 +6,29 @@
// and subject to the terms and conditions defined in LICENSE file. // and subject to the terms and conditions defined in LICENSE file.
// //
#include "usim.hpp"
namespace nr::ue namespace nr::ue
{ {
} void ue::Usim::initialize(bool hasSupi, const UeConfig::Initials &initials)
\ No newline at end of file {
m_isValid = hasSupi;
m_uState = E5UState::U1_UPDATED;
m_defConfiguredNssai = initials.defaultConfiguredNssai;
m_configuredNssai = initials.configuredNssai;
}
bool Usim::isValid()
{
return m_isValid;
}
void Usim::invalidate()
{
m_isValid = false;
}
} // namespace nr::ue
...@@ -6,13 +6,66 @@ ...@@ -6,13 +6,66 @@
// and subject to the terms and conditions defined in LICENSE file. // and subject to the terms and conditions defined in LICENSE file.
// //
#pragma once
#include <memory>
#include <nas/msg.hpp>
#include <optional>
#include <ue/types.hpp>
#include <utils/common_types.hpp>
#include <utils/octet_string.hpp>
namespace nr::ue namespace nr::ue
{ {
class Usim class Usim
{ {
private:
bool m_isValid{};
}; public:
// Location related
nas::IE5gsMobileIdentity m_storedGuti{};
std::optional<nas::IE5gsTrackingAreaIdentity> m_lastVisitedRegisteredTai{};
E5UState m_uState{};
// Identity related
nas::IE5gsMobileIdentity m_storedSuci{};
// Plmn related
Plmn m_currentPlmn{};
nas::IE5gsTrackingAreaIdentityList m_taiList{};
nas::IE5gsTrackingAreaIdentityList m_forbiddenTaiList{};
nas::IEPlmnList m_equivalentPlmnList{};
nas::IEPlmnList m_forbiddenPlmnList{};
nas::IEServiceAreaList m_serviceAreaList{};
// Security related
std::unique_ptr<NasSecurityContext> m_currentNsCtx{};
std::unique_ptr<NasSecurityContext> m_nonCurrentNsCtx{};
OctetString m_sqn{};
// NSSAI related
NetworkSlice m_defConfiguredNssai{};
NetworkSlice m_configuredNssai{};
NetworkSlice m_allowedNssai{};
NetworkSlice m_rejectedNssaiInPlmn{};
NetworkSlice m_rejectedNssaiInTa{};
// NITZ related
std::optional<nas::IENetworkName> m_networkFullName{};
std::optional<nas::IENetworkName> m_networkShortName{};
std::optional<nas::IETimeZone> m_localTimeZone{};
std::optional<nas::IETimeZoneAndTime> m_universalTimeAndLocalTimeZone{};
std::optional<nas::IEDaylightSavingTime> m_networkDaylightSavingTime{};
// eCall related
bool m_isECallOnly{};
public:
void initialize(bool hasSupi, const UeConfig::Initials &initials);
bool isValid();
void invalidate();
};
} } // namespace nr::ue
\ No newline at end of file \ No newline at end of file
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