Commit 99751933 authored by aligungr's avatar aligungr

UE initiated PDU session release impl.

parent f6d45224
...@@ -83,9 +83,11 @@ class NasMm ...@@ -83,9 +83,11 @@ class NasMm
void receiveMmCause(const nas::IE5gMmCause &msg); void receiveMmCause(const nas::IE5gMmCause &msg);
void sendMmStatus(nas::EMmCause cause); void sendMmStatus(nas::EMmCause cause);
public: /* Registration */
void sendMobilityRegistration(ERegUpdateCause updateCause);
private: /* Registration */ private: /* Registration */
void sendInitialRegistration(bool isEmergencyReg, bool dueToDereg); void sendInitialRegistration(bool isEmergencyReg, bool dueToDereg);
void 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);
......
...@@ -38,7 +38,7 @@ static nas::IEIntegrityProtectionMaximumDataRate MakeIntegrityMaxRate(const Inte ...@@ -38,7 +38,7 @@ static nas::IEIntegrityProtectionMaximumDataRate MakeIntegrityMaxRate(const Inte
void NasSm::sendEstablishmentRequest(const SessionConfig &config) void NasSm::sendEstablishmentRequest(const SessionConfig &config)
{ {
m_logger->debug("Sending PDU session establishment request"); m_logger->debug("Sending PDU Session Establishment Request");
/* Control the protocol state */ /* Control the protocol state */
if (!m_mm->isRegistered()) if (!m_mm->isRegistered())
...@@ -190,6 +190,7 @@ void NasSm::receiveEstablishmentReject(const nas::PduSessionEstablishmentReject ...@@ -190,6 +190,7 @@ void NasSm::receiveEstablishmentReject(const nas::PduSessionEstablishmentReject
freeProcedureTransactionId(msg.pti); freeProcedureTransactionId(msg.pti);
auto &pduSession = m_pduSessions[msg.pduSessionId]; auto &pduSession = m_pduSessions[msg.pduSessionId];
if (pduSession->psState != EPsState::ACTIVE_PENDING) if (pduSession->psState != EPsState::ACTIVE_PENDING)
{ {
m_logger->err("PS establishment reject received without being requested"); m_logger->err("PS establishment reject received without being requested");
...@@ -198,6 +199,7 @@ void NasSm::receiveEstablishmentReject(const nas::PduSessionEstablishmentReject ...@@ -198,6 +199,7 @@ void NasSm::receiveEstablishmentReject(const nas::PduSessionEstablishmentReject
} }
pduSession->psState = EPsState::INACTIVE; pduSession->psState = EPsState::INACTIVE;
if (pduSession->isEmergency) if (pduSession->isEmergency)
{ {
// This not much important and no need for now // This not much important and no need for now
......
...@@ -41,17 +41,25 @@ void NasSm::abortProcedureByPti(int pti) ...@@ -41,17 +41,25 @@ void NasSm::abortProcedureByPti(int pti)
if (pt.state != EPtState::PENDING) if (pt.state != EPtState::PENDING)
return; return;
auto msgType = pt.message->messageType;
int psi = m_procedureTransactions[pti].psi; int psi = m_procedureTransactions[pti].psi;
auto &ps = m_pduSessions[psi]; auto &ps = m_pduSessions[psi];
m_logger->debug("Aborting SM procedure for PTI[%d], PSI[%d]", pti, psi); m_logger->debug("Aborting SM procedure for PTI[%d], PSI[%d]", pti, psi);
if (msgType == nas::EMessageType::PDU_SESSION_ESTABLISHMENT_REQUEST)
{
freeProcedureTransactionId(pti); freeProcedureTransactionId(pti);
if (ps->psState == EPsState::ACTIVE_PENDING)
freePduSessionId(psi); freePduSessionId(psi);
if (ps->psState == EPsState::INACTIVE_PENDING || ps->psState == EPsState::MODIFICATION_PENDING) }
ps->psState = EPsState::ACTIVE; else if (msgType == nas::EMessageType::PDU_SESSION_RELEASE_REQUEST)
{
freeProcedureTransactionId(pti);
localReleaseSession(psi);
}
// todo: others
} }
void NasSm::abortProcedureByPtiOrPsi(int pti, int psi) void NasSm::abortProcedureByPtiOrPsi(int pti, int psi)
......
//
// 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 "sm.hpp"
#include <algorithm>
#include <nas/proto_conf.hpp>
#include <nas/utils.hpp>
#include <ue/app/task.hpp>
#include <ue/mm/mm.hpp>
namespace nr::ue
{
void NasSm::sendReleaseRequest(int psi)
{
m_logger->debug("Sending PDU Session Release Request");
/* Control the PDU session state */
auto &ps = m_pduSessions[psi];
if (ps->psState != EPsState::ACTIVE)
{
m_logger->warn("PDU session release procedure could not start: PS[%d] is not active", psi);
return;
}
/* Allocate PTI */
int pti = allocateProcedureTransactionId();
if (pti == 0)
return;
/* Construct the message */
auto req = std::make_unique<nas::PduSessionReleaseRequest>();
req->pti = pti;
req->pduSessionId = psi;
req->smCause = nas::IE5gSmCause{};
req->smCause->value = nas::ESmCause::REGULAR_DEACTIVATION;
/* Set relevant fields of the PT, and start T3582 */
auto &pt = m_procedureTransactions[pti];
pt.state = EPtState::PENDING;
pt.timer = newTransactionTimer(3582);
pt.message = std::move(req);
pt.psi = psi;
/* Send SM message */
sendSmMessage(psi, *pt.message);
}
void NasSm::receiveReleaseReject(const nas::PduSessionReleaseReject &msg)
{
auto cause = msg.smCause.value;
m_logger->err("PDU Session Release Reject received [%s]", nas::utils::EnumToString(cause));
if (!checkPtiAndPsi(msg))
return;
freeProcedureTransactionId(msg.pti);
if (cause != nas::ESmCause::PTI_ALREADY_IN_USE && cause != nas::ESmCause::INVALID_PDU_SESSION_IDENTITY)
{
auto &pduSession = m_pduSessions[msg.pduSessionId];
if (pduSession->psState != EPsState::INACTIVE_PENDING)
{
m_logger->err("PS release reject received without being requested");
sendSmCause(nas::ESmCause::MESSAGE_TYPE_NOT_COMPATIBLE_WITH_THE_PROTOCOL_STATE, msg.pti, msg.pduSessionId);
return;
}
pduSession->psState = EPsState::ACTIVE;
}
else
{
localReleaseSession(msg.pduSessionId);
}
}
} // namespace nr::ue
\ No newline at end of file
...@@ -68,6 +68,10 @@ class NasSm ...@@ -68,6 +68,10 @@ class NasSm
void receiveEstablishmentReject(const nas::PduSessionEstablishmentReject &msg); void receiveEstablishmentReject(const nas::PduSessionEstablishmentReject &msg);
void receiveEstablishmentRoutingFailure(const nas::PduSessionEstablishmentRequest &msg); void receiveEstablishmentRoutingFailure(const nas::PduSessionEstablishmentRequest &msg);
/* Session Release */
void sendReleaseRequest(int psi);
void receiveReleaseReject(const nas::PduSessionReleaseReject& msg);
/* Timer */ /* Timer */
std::unique_ptr<nas::NasTimer> newTransactionTimer(int code); std::unique_ptr<nas::NasTimer> newTransactionTimer(int code);
void onTimerExpire(nas::NasTimer &timer); void onTimerExpire(nas::NasTimer &timer);
......
...@@ -62,11 +62,27 @@ void NasSm::onTransactionTimerExpire(int pti) ...@@ -62,11 +62,27 @@ void NasSm::onTransactionTimerExpire(int pti)
} }
else else
{ {
m_logger->err("PDU Session Establishment Procedure failure, no response from the network after 5 attempts"); m_logger->err("PDU Session Establishment procedure failure, no response from the network after 5 attempts");
abortProcedureByPti(pti); abortProcedureByPti(pti);
} }
break; break;
} }
case 3582: {
if (pt.timer->getExpiryCount() < 5)
{
m_logger->warn("Retransmitting PDU Session Release Request due to T3582 expiry");
sendSmMessage(pt.psi, *pt.message);
pt.timer->start(false);
}
else
{
m_logger->err("PDU Session Release procedure failure, no response from the network after 5 attempts");
abortProcedureByPti(pti);
m_mm->sendMobilityRegistration(ERegUpdateCause::PS_STATUS_INFORM);
}
break;
}
} }
} }
......
...@@ -53,6 +53,9 @@ void NasSm::receiveSmMessage(const nas::SmMessage &msg) ...@@ -53,6 +53,9 @@ void NasSm::receiveSmMessage(const nas::SmMessage &msg)
case nas::EMessageType::PDU_SESSION_ESTABLISHMENT_REQUEST: case nas::EMessageType::PDU_SESSION_ESTABLISHMENT_REQUEST:
receiveEstablishmentRoutingFailure((const nas::PduSessionEstablishmentRequest &)msg); receiveEstablishmentRoutingFailure((const nas::PduSessionEstablishmentRequest &)msg);
break; break;
case nas::EMessageType::PDU_SESSION_RELEASE_REJECT:
receiveReleaseReject((const nas::PduSessionReleaseReject &)msg);
break;
case nas::EMessageType::FIVEG_SM_STATUS: case nas::EMessageType::FIVEG_SM_STATUS:
receiveSmStatus((const nas::FiveGSmStatus &)msg); receiveSmStatus((const nas::FiveGSmStatus &)msg);
break; break;
......
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