Commit aec399ec authored by aligungr's avatar aligungr

L3 RRC/NAS developments

parent ce6ff2e4
...@@ -105,6 +105,12 @@ static void RemoveCleartextIEs(nas::PlainMmMessage &msg, OctetString &&nasMsgCon ...@@ -105,6 +105,12 @@ static void RemoveCleartextIEs(nas::PlainMmMessage &msg, OctetString &&nasMsgCon
EProcRc NasMm::sendNasMessage(const nas::PlainMmMessage &msg) EProcRc NasMm::sendNasMessage(const nas::PlainMmMessage &msg)
{ {
if (!m_base->shCtx.hasActiveCell())
{
m_logger->debug("NAS Transport aborted, no active cell");
return EProcRc::STAY;
}
if (m_cmState == ECmState::CM_IDLE && !IsInitialNasMessage(msg)) if (m_cmState == ECmState::CM_IDLE && !IsInitialNasMessage(msg))
{ {
m_logger->warn("NAS Transport aborted, Service Request is needed for uplink signalling"); m_logger->warn("NAS Transport aborted, Service Request is needed for uplink signalling");
......
...@@ -104,8 +104,8 @@ class NasMm ...@@ -104,8 +104,8 @@ class NasMm
void deliverUlTransport(const nas::UlNasTransport &msg); void deliverUlTransport(const nas::UlNasTransport &msg);
private: /* Registration */ private: /* Registration */
void sendMobilityRegistration(ERegUpdateCause updateCause);
EProcRc sendInitialRegistration(EInitialRegCause regCause); EProcRc sendInitialRegistration(EInitialRegCause regCause);
EProcRc sendMobilityRegistration(ERegUpdateCause updateCause);
void receiveRegistrationAccept(const nas::RegistrationAccept &msg); void receiveRegistrationAccept(const nas::RegistrationAccept &msg);
void receiveInitialRegistrationAccept(const nas::RegistrationAccept &msg); void receiveInitialRegistrationAccept(const nas::RegistrationAccept &msg);
void receiveMobilityRegistrationAccept(const nas::RegistrationAccept &msg); void receiveMobilityRegistrationAccept(const nas::RegistrationAccept &msg);
...@@ -149,7 +149,7 @@ class NasMm ...@@ -149,7 +149,7 @@ class NasMm
nas::IE5gsMobileIdentity getOrGeneratePreferredId(); nas::IE5gsMobileIdentity getOrGeneratePreferredId();
private: /* Service */ private: /* Service */
void sendServiceRequest(EServiceReqCause reqCause); EProcRc sendServiceRequest(EServiceReqCause reqCause);
void receiveServiceAccept(const nas::ServiceAccept &msg); void receiveServiceAccept(const nas::ServiceAccept &msg);
void receiveServiceReject(const nas::ServiceReject &msg); void receiveServiceReject(const nas::ServiceReject &msg);
......
...@@ -102,7 +102,11 @@ void NasMm::deregistrationRequired(EDeregCause cause) ...@@ -102,7 +102,11 @@ void NasMm::deregistrationRequired(EDeregCause cause)
void NasMm::invokeProcedures() void NasMm::invokeProcedures()
{ {
if (m_procCtl.deregistration) auto activeCell = m_base->shCtx.currentCell.get();
bool hasActiveCell = activeCell.hasValue();
if (hasActiveCell && m_procCtl.deregistration)
{ {
EProcRc rc = sendDeregistration(*m_procCtl.deregistration); EProcRc rc = sendDeregistration(*m_procCtl.deregistration);
if (rc == EProcRc::OK) if (rc == EProcRc::OK)
...@@ -119,7 +123,7 @@ void NasMm::invokeProcedures() ...@@ -119,7 +123,7 @@ void NasMm::invokeProcedures()
return; return;
} }
if (m_procCtl.initialRegistration) if (hasActiveCell && m_procCtl.initialRegistration)
{ {
EProcRc rc = sendInitialRegistration(*m_procCtl.initialRegistration); EProcRc rc = sendInitialRegistration(*m_procCtl.initialRegistration);
if (rc == EProcRc::OK) if (rc == EProcRc::OK)
...@@ -127,17 +131,41 @@ void NasMm::invokeProcedures() ...@@ -127,17 +131,41 @@ void NasMm::invokeProcedures()
m_procCtl.initialRegistration = std::nullopt; m_procCtl.initialRegistration = std::nullopt;
m_procCtl.mobilityRegistration = std::nullopt; m_procCtl.mobilityRegistration = std::nullopt;
m_procCtl.serviceRequest = std::nullopt; m_procCtl.serviceRequest = std::nullopt;
return;
} }
else if (rc == EProcRc::CANCEL) else if (rc == EProcRc::CANCEL)
{ {
m_procCtl.initialRegistration = std::nullopt; m_procCtl.initialRegistration = std::nullopt;
return;
}
}
if (hasActiveCell && m_procCtl.mobilityRegistration)
{
EProcRc rc = sendMobilityRegistration(*m_procCtl.mobilityRegistration);
if (rc == EProcRc::OK)
{
m_procCtl.mobilityRegistration = std::nullopt;
m_procCtl.serviceRequest = std::nullopt;
return;
}
else if (rc == EProcRc::CANCEL)
{
m_procCtl.mobilityRegistration = std::nullopt;
return;
} }
return; return;
} }
// note1: if (hasActiveCell && m_procCtl.serviceRequest)
// TODO: "the periodic registration update procedure is delayed until the UE returns to {
// 5GMM-REGISTERED.NORMAL-SERVICE over 3GPP access." See 5.3.7 EProcRc rc = sendServiceRequest(*m_procCtl.serviceRequest);
if (rc == EProcRc::OK || rc == EProcRc::CANCEL)
{
m_procCtl.serviceRequest = std::nullopt;
return;
}
}
} }
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
...@@ -115,21 +115,21 @@ EProcRc NasMm::sendInitialRegistration(EInitialRegCause regCause) ...@@ -115,21 +115,21 @@ EProcRc NasMm::sendInitialRegistration(EInitialRegCause regCause)
return EProcRc::OK; return EProcRc::OK;
} }
void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) EProcRc NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
{ {
if (m_rmState == ERmState::RM_DEREGISTERED) if (m_rmState == ERmState::RM_DEREGISTERED)
{ {
m_logger->warn("Mobility updating could not be triggered. UE is in RM-DEREGISTERED state."); m_logger->warn("Mobility updating could not be triggered. UE is in RM-DEREGISTERED state.");
return; return EProcRc::CANCEL;
} }
if (m_mmSubState == EMmSubState::MM_REGISTERED_NON_ALLOWED_SERVICE) if (m_mmState == EMmState::MM_DEREGISTERED_INITIATED)
return EProcRc::STAY;
if (updateCause == ERegUpdateCause::T3512_EXPIRY && m_mmSubState == EMmSubState::MM_REGISTERED_NON_ALLOWED_SERVICE)
{ {
if (!isHighPriority() && !hasEmergency()) if (!isHighPriority() && !hasEmergency())
{ return EProcRc::STAY;
m_logger->debug("Mobility updating canceled, registered in non allowed service");
return;
}
} }
// 5.5.1.3.7 Abnormal cases in the UE // 5.5.1.3.7 Abnormal cases in the UE
...@@ -141,7 +141,7 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) ...@@ -141,7 +141,7 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
if (!allowed) if (!allowed)
{ {
m_logger->debug("Mobility updating canceled, T3346 is running"); m_logger->debug("Mobility updating canceled, T3346 is running");
return; return EProcRc::STAY;
} }
} }
...@@ -163,9 +163,6 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) ...@@ -163,9 +163,6 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
// lower layers with the 5G-S-TMSI or the registered GUAMI; " // lower layers with the 5G-S-TMSI or the registered GUAMI; "
updateProvidedGuti(updateCause != ERegUpdateCause::CONFIGURATION_UPDATE); updateProvidedGuti(updateCause != ERegUpdateCause::CONFIGURATION_UPDATE);
// Switch state
switchMmState(EMmSubState::MM_REGISTERED_INITIATED_PS);
// Prepare FOR pending field // Prepare FOR pending field
nas::EFollowOnRequest followOn = nas::EFollowOnRequest::FOR_PENDING; nas::EFollowOnRequest followOn = nas::EFollowOnRequest::FOR_PENDING;
...@@ -211,14 +208,21 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause) ...@@ -211,14 +208,21 @@ void NasMm::sendMobilityRegistration(ERegUpdateCause updateCause)
// : nas::EDefaultConfiguredNssaiIndication::NOT_CREATED_FROM_DEFAULT_CONFIGURED_NSSAI; // : nas::EDefaultConfiguredNssaiIndication::NOT_CREATED_FROM_DEFAULT_CONFIGURED_NSSAI;
// Send the message // Send the message
sendNasMessage(*request); auto rc = sendNasMessage(*request);
if (rc != EProcRc::OK)
return rc;
m_lastRegistrationRequest = std::move(request); m_lastRegistrationRequest = std::move(request);
m_lastRegWithoutNsc = m_usim->m_currentNsCtx == nullptr; m_lastRegWithoutNsc = m_usim->m_currentNsCtx == nullptr;
// Switch state
switchMmState(EMmSubState::MM_REGISTERED_INITIATED_PS);
// Process timers // Process timers
m_timers->t3510.start(); m_timers->t3510.start();
m_timers->t3502.stop(); m_timers->t3502.stop();
m_timers->t3511.stop(); m_timers->t3511.stop();
return EProcRc::OK;
} }
void NasMm::receiveRegistrationAccept(const nas::RegistrationAccept &msg) void NasMm::receiveRegistrationAccept(const nas::RegistrationAccept &msg)
......
...@@ -14,36 +14,34 @@ ...@@ -14,36 +14,34 @@
namespace nr::ue namespace nr::ue
{ {
void NasMm::sendServiceRequest(EServiceReqCause reqCause) EProcRc NasMm::sendServiceRequest(EServiceReqCause reqCause)
{ {
m_logger->debug("Sending Service Request due to [%s]", ToJson(reqCause).str().c_str());
// "The procedure shall only be initiated by the UE when the following conditions are fulfilled ..." // "The procedure shall only be initiated by the UE when the following conditions are fulfilled ..."
if (m_mmState == EMmState::MM_REGISTERED_INITIATED || m_mmState == EMmState::MM_DEREGISTERED_INITIATED) if (m_mmState == EMmState::MM_REGISTERED_INITIATED || m_mmState == EMmState::MM_DEREGISTERED_INITIATED)
{ {
m_logger->warn("Service Request canceled, MM specific procedure is ongoing"); m_logger->warn("Service Request canceled, MM specific procedure is ongoing");
return; return EProcRc::STAY;
} }
if (m_mmState == EMmState::MM_SERVICE_REQUEST_INITIATED) if (m_mmState == EMmState::MM_SERVICE_REQUEST_INITIATED)
{ {
m_logger->debug("Service Request canceled, already in 5GMM-SERVICE-REQUEST-INITIATED"); m_logger->debug("Service Request canceled, already in 5GMM-SERVICE-REQUEST-INITIATED");
return; return EProcRc::CANCEL;
} }
if (m_storage->uState->get() != E5UState::U1_UPDATED) if (m_storage->uState->get() != E5UState::U1_UPDATED)
{ {
m_logger->err("Service Request canceled, UE not in 5U1 UPDATED state"); m_logger->err("Service Request canceled, UE not in 5U1 UPDATED state");
return; return EProcRc::STAY;
} }
Tai currentTai = m_base->shCtx.getCurrentTai(); Tai currentTai = m_base->shCtx.getCurrentTai();
if (!currentTai.hasValue()) if (!currentTai.hasValue())
{ {
m_logger->err("Service Request canceled, no active cell exists"); m_logger->err("Service Request canceled, no active cell exists");
return; return EProcRc::STAY;
} }
if (!nas::utils::TaiListContains(m_storage->taiList->get(), nas::VTrackingAreaIdentity{currentTai})) if (!nas::utils::TaiListContains(m_storage->taiList->get(), nas::VTrackingAreaIdentity{currentTai}))
{ {
m_logger->err("Service Request canceled, current TAI is not in the TAI list"); m_logger->err("Service Request canceled, current TAI is not in the TAI list");
return; return EProcRc::CANCEL;
} }
if (m_mmSubState == EMmSubState::MM_REGISTERED_NON_ALLOWED_SERVICE) if (m_mmSubState == EMmSubState::MM_REGISTERED_NON_ALLOWED_SERVICE)
...@@ -53,7 +51,7 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause) ...@@ -53,7 +51,7 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause)
reqCause != EServiceReqCause::IDLE_3GPP_NOTIFICATION_N3GPP && !isHighPriority() && !hasEmergency()) reqCause != EServiceReqCause::IDLE_3GPP_NOTIFICATION_N3GPP && !isHighPriority() && !hasEmergency())
{ {
m_logger->debug("Service Request canceled, registered in non allowed service"); m_logger->debug("Service Request canceled, registered in non allowed service");
return; return EProcRc::CANCEL;
} }
} }
...@@ -67,7 +65,7 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause) ...@@ -67,7 +65,7 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause)
reqCause != EServiceReqCause::EMERGENCY_FALLBACK && !isHighPriority() && !hasEmergency()) reqCause != EServiceReqCause::EMERGENCY_FALLBACK && !isHighPriority() && !hasEmergency())
{ {
m_logger->debug("Service Request canceled, T3346 is running"); m_logger->debug("Service Request canceled, T3346 is running");
return; return EProcRc::STAY;
} }
} }
// c) Timer T3346 is running. // c) Timer T3346 is running.
...@@ -79,10 +77,12 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause) ...@@ -79,10 +77,12 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause)
reqCause != EServiceReqCause::EMERGENCY_FALLBACK) reqCause != EServiceReqCause::EMERGENCY_FALLBACK)
{ {
m_logger->debug("Service Request canceled, T3346 is running"); m_logger->debug("Service Request canceled, T3346 is running");
return; return EProcRc::STAY;
} }
} }
m_logger->debug("Sending Service Request due to [%s]", ToJson(reqCause).str().c_str());
updateProvidedGuti(); updateProvidedGuti();
auto request = std::make_unique<nas::ServiceRequest>(); auto request = std::make_unique<nas::ServiceRequest>();
...@@ -174,10 +174,13 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause) ...@@ -174,10 +174,13 @@ void NasMm::sendServiceRequest(EServiceReqCause reqCause)
request->pduSessionStatus->psi = m_sm->getPduSessionStatus(); request->pduSessionStatus->psi = m_sm->getPduSessionStatus();
// Send the message and process the timers // Send the message and process the timers
sendNasMessage(*request); auto rc = sendNasMessage(*request);
if (rc != EProcRc::OK)
return rc;
m_lastServiceRequest = std::move(request); m_lastServiceRequest = std::move(request);
m_lastServiceReqCause = reqCause; m_lastServiceReqCause = reqCause;
m_timers->t3517.start(); m_timers->t3517.start();
switchMmState(EMmSubState::MM_SERVICE_REQUEST_INITIATED_PS); switchMmState(EMmSubState::MM_SERVICE_REQUEST_INITIATED_PS);
} }
......
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