Commit ecb9d6de authored by aligungr's avatar aligungr

Network initiated PDU session release impl.

parent 83a0128f
......@@ -41,6 +41,12 @@ void NasSm::abortProcedureByPti(int pti)
if (pt.state != EPtState::PENDING)
return;
if (pt.message == nullptr)
{
m_logger->err("Procedure abortion failure, stored SM message is null");
return;
}
auto msgType = pt.message->messageType;
int psi = m_procedureTransactions[pti].psi;
......
......@@ -7,9 +7,9 @@
//
#include "sm.hpp"
#include <algorithm>
#include <nas/proto_conf.hpp>
#include <nas/utils.hpp>
#include <optional>
#include <ue/app/task.hpp>
#include <ue/mm/mm.hpp>
......@@ -88,4 +88,74 @@ void NasSm::receiveReleaseReject(const nas::PduSessionReleaseReject &msg)
}
}
} // namespace nr::ue
\ No newline at end of file
void NasSm::receiveReleaseCommand(const nas::PduSessionReleaseCommand &msg)
{
m_logger->debug("PDU Session Release Command received");
int psi = msg.pduSessionId;
int pti = msg.pti;
/* Abnormal case handling 6.3.3.6/a */
if (m_pduSessions[msg.pduSessionId]->psState == EPsState::INACTIVE)
{
m_logger->err("PS[%d] is already in inactive state, ignoring release command", msg.pduSessionId);
sendSmCause(nas::ESmCause::INVALID_PDU_SESSION_IDENTITY, msg.pti, msg.pduSessionId);
return;
}
/* Abnormal case handling 6.4.1.6/c */
if (m_pduSessions[psi]->psState == EPsState::ACTIVE_PENDING)
{
m_logger->warn("PDU Session Release Command ignored for PSI[%d] due to collision with establishment procedure.",
psi);
return;
}
/* Handle reactivation case (take the fields before releasing the PS) */
std::optional<SessionConfig> reactivation{};
if (msg.smCause.value == nas::ESmCause::REACTIVATION_REQUESTED)
{
reactivation = SessionConfig{};
reactivation->type = m_pduSessions[psi]->sessionType;
reactivation->apn = m_pduSessions[psi]->apn;
reactivation->sNssai = m_pduSessions[psi]->sNssai;
}
/* Release PS and handle PT */
localReleaseSession(psi);
if (pti != 0)
{
auto &pt = m_procedureTransactions[pti];
if (pt.message == nullptr || pt.message->messageType != nas::EMessageType::PDU_SESSION_RELEASE_REQUEST)
{
m_logger->err("PTI mismatch occurred, received PTI[%d] has no PDU session release request", pti);
sendSmCause(nas::ESmCause::PTI_MISMATCH, msg.pti, msg.pduSessionId);
return;
}
// Warning: PS has been released, and the spec says that (6.3.3.3) this PTI should not be released immediately
// Therefore the PT does not hold a valid PSI after this point
pt.psi = 0;
// TODO: Let's immediately release the PT for now. See 6.3.3.3
freeProcedureTransactionId(pti);
}
/* Construct Release Complete message */
nas::PduSessionReleaseComplete resp{};
resp.pduSessionId = psi;
resp.pti = pti;
/* Send SM message */
sendSmMessage(psi, resp);
/* Handle reactivation */
if (reactivation.has_value())
{
m_logger->debug("Re-initiating a PDU session establishment procedure due to reactivation request");
sendEstablishmentRequest(*reactivation);
}
}
} // namespace nr::ue
......@@ -73,7 +73,8 @@ class NasSm
void receiveEstablishmentRoutingFailure(const nas::PduSessionEstablishmentRequest &msg);
/* Session Release */
void receiveReleaseReject(const nas::PduSessionReleaseReject& msg);
void receiveReleaseReject(const nas::PduSessionReleaseReject &msg);
void receiveReleaseCommand(const nas::PduSessionReleaseCommand &msg);
/* Timer */
std::unique_ptr<nas::NasTimer> newTransactionTimer(int code);
......
......@@ -56,6 +56,9 @@ void NasSm::receiveSmMessage(const nas::SmMessage &msg)
case nas::EMessageType::PDU_SESSION_RELEASE_REJECT:
receiveReleaseReject((const nas::PduSessionReleaseReject &)msg);
break;
case nas::EMessageType::PDU_SESSION_RELEASE_COMMAND:
receiveReleaseCommand((const nas::PduSessionReleaseCommand &)msg);
break;
case nas::EMessageType::FIVEG_SM_STATUS:
receiveSmStatus((const nas::FiveGSmStatus &)msg);
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