Commit 878f7629 authored by aligungr's avatar aligungr

Network initiated PDU session release impl.

parent ecb9d6de
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include "task.hpp" #include "task.hpp"
#include <asn/ngap/ASN_NGAP_QosFlowSetupRequestItem.h> #include <asn/ngap/ASN_NGAP_QosFlowSetupRequestItem.h>
#include <gnb/mr/task.hpp>
#include <gnb/gtp/proto.hpp> #include <gnb/gtp/proto.hpp>
#include <gnb/mr/task.hpp>
#include <utils/constants.hpp> #include <utils/constants.hpp>
#include <utils/libc_error.hpp> #include <utils/libc_error.hpp>
...@@ -61,12 +61,16 @@ void GtpTask::onLoop() ...@@ -61,12 +61,16 @@ void GtpTask::onLoop()
handleUeContextUpdate(*w->update); handleUeContextUpdate(*w->update);
break; break;
} }
case NwGnbNgapToGtp::UE_CONTEXT_RELEASE: {
handleUeContextDelete(w->ueId);
break;
}
case NwGnbNgapToGtp::SESSION_CREATE: { case NwGnbNgapToGtp::SESSION_CREATE: {
handleSessionCreate(w->resource); handleSessionCreate(w->resource);
break; break;
} }
case NwGnbNgapToGtp::UE_CONTEXT_RELEASE: { case NwGnbNgapToGtp::SESSION_RELEASE: {
handleUeContextDelete(w->ueId); handleSessionRelease(w->ueId, w->psi);
break; break;
} }
} }
...@@ -122,6 +126,28 @@ void GtpTask::handleSessionCreate(PduSessionResource *session) ...@@ -122,6 +126,28 @@ void GtpTask::handleSessionCreate(PduSessionResource *session)
updateAmbrForSession(sessionInd); updateAmbrForSession(sessionInd);
} }
void GtpTask::handleSessionRelease(int ueId, int psi)
{
if (!m_ueContexts.count(ueId))
{
m_logger->err("PDU session resource could not be released, UE context with ID[%d] not found", ueId);
return;
}
uint64_t sessionInd = MakeSessionResInd(ueId, psi);
// Remove all session information from rate limiter
m_rateLimiter->updateSessionUplinkLimit(sessionInd, 0);
m_rateLimiter->updateUeDownlinkLimit(sessionInd, 0);
// And remove from PDU session table
int teid = m_pduSessions[sessionInd]->downTunnel.teid;
m_pduSessions.erase(sessionInd);
// And remove from the tree
m_sessionTree.remove(sessionInd, teid);
}
void GtpTask::handleUeContextDelete(int ueId) void GtpTask::handleUeContextDelete(int ueId)
{ {
// Find PDU sessions of the UE // Find PDU sessions of the UE
......
...@@ -48,6 +48,7 @@ class GtpTask : public NtsTask ...@@ -48,6 +48,7 @@ class GtpTask : public NtsTask
void handleUdpReceive(const udp::NwUdpServerReceive &msg); void handleUdpReceive(const udp::NwUdpServerReceive &msg);
void handleUeContextUpdate(const GtpUeContextUpdate &msg); void handleUeContextUpdate(const GtpUeContextUpdate &msg);
void handleSessionCreate(PduSessionResource *session); void handleSessionCreate(PduSessionResource *session);
void handleSessionRelease(int ueId, int psi);
void handleUeContextDelete(int ueId); void handleUeContextDelete(int ueId);
void handleUplinkData(int ueId, int psi, OctetString &&data); void handleUplinkData(int ueId, int psi, OctetString &&data);
......
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
#include <asn/ngap/ASN_NGAP_AssociatedQosFlowList.h> #include <asn/ngap/ASN_NGAP_AssociatedQosFlowList.h>
#include <asn/ngap/ASN_NGAP_GTPTunnel.h> #include <asn/ngap/ASN_NGAP_GTPTunnel.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceFailedToSetupItemSURes.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceFailedToSetupItemSURes.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceReleaseCommand.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceReleaseResponse.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceReleaseResponseTransfer.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceReleasedItemRelRes.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupItemSUReq.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupItemSUReq.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupItemSURes.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupItemSURes.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupRequest.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupRequest.h>
...@@ -21,12 +25,14 @@ ...@@ -21,12 +25,14 @@
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupResponse.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupResponse.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupResponseTransfer.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupResponseTransfer.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer.h> #include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceToReleaseItemRelCmd.h>
#include <asn/ngap/ASN_NGAP_ProtocolIE-Field.h> #include <asn/ngap/ASN_NGAP_ProtocolIE-Field.h>
#include <asn/ngap/ASN_NGAP_QosFlowPerTNLInformationItem.h> #include <asn/ngap/ASN_NGAP_QosFlowPerTNLInformationItem.h>
#include <asn/ngap/ASN_NGAP_QosFlowPerTNLInformationList.h> #include <asn/ngap/ASN_NGAP_QosFlowPerTNLInformationList.h>
#include <asn/ngap/ASN_NGAP_QosFlowSetupRequestItem.h> #include <asn/ngap/ASN_NGAP_QosFlowSetupRequestItem.h>
#include <asn/ngap/ASN_NGAP_QosFlowSetupRequestList.h> #include <asn/ngap/ASN_NGAP_QosFlowSetupRequestList.h>
#include <gnb/gtp/task.hpp> #include <gnb/gtp/task.hpp>
#include <set>
#include <stdexcept> #include <stdexcept>
namespace nr::gnb namespace nr::gnb
...@@ -193,12 +199,14 @@ void NgapTask::receiveSessionResourceSetupRequest(int amfId, ASN_NGAP_PDUSession ...@@ -193,12 +199,14 @@ void NgapTask::receiveSessionResourceSetupRequest(int amfId, ASN_NGAP_PDUSession
sendNgapUeAssociated(ue->ctxId, respPdu); sendNgapUeAssociated(ue->ctxId, respPdu);
if (failedList.empty()) if (failedList.empty())
m_logger->info("PDU session resource is setup for UE[%d] count[%d]", ue->ctxId, successList.size()); m_logger->info("PDU session resource is setup for UE[%d] count[%d]", ue->ctxId,
static_cast<int>(successList.size()));
else if (successList.empty()) else if (successList.empty())
m_logger->err("PDU session resource setup was failed for UE[%d] count[%d]", ue->ctxId, failedList.size()); m_logger->err("PDU session resource setup was failed for UE[%d] count[%d]", ue->ctxId,
static_cast<int>(failedList.size()));
else else
m_logger->err("PDU session establishment is partially successful for UE[%d], success[%d], failed[%d]", m_logger->err("PDU session establishment is partially successful for UE[%d], success[%d], failed[%d]",
successList.size(), failedList.size()); static_cast<int>(successList.size()), static_cast<int>(failedList.size()));
} }
std::optional<NgapCause> NgapTask::setupPduSessionResource(PduSessionResource *resource) std::optional<NgapCause> NgapTask::setupPduSessionResource(PduSessionResource *resource)
...@@ -231,4 +239,68 @@ std::optional<NgapCause> NgapTask::setupPduSessionResource(PduSessionResource *r ...@@ -231,4 +239,68 @@ std::optional<NgapCause> NgapTask::setupPduSessionResource(PduSessionResource *r
return {}; return {};
} }
void NgapTask::receiveSessionResourceReleaseCommand(int amfId, ASN_NGAP_PDUSessionResourceReleaseCommand *msg)
{
auto *ue = findUeByNgapIdPair(amfId, ngap_utils::FindNgapIdPair(msg));
if (ue == nullptr)
return;
std::set<int> psIds{};
auto *ieReq = asn::ngap::GetProtocolIe(msg, ASN_NGAP_ProtocolIE_ID_id_PDUSessionResourceToReleaseListRelCmd);
if (ieReq)
{
auto &list = ieReq->PDUSessionResourceToReleaseListRelCmd.list;
for (int i = 0; i < list.count; i++)
{
auto &item = list.array[i];
if (item)
psIds.insert(static_cast<int>(item->pDUSessionID));
}
}
ieReq = asn::ngap::GetProtocolIe(msg, ASN_NGAP_ProtocolIE_ID_id_NAS_PDU);
if (ieReq)
deliverDownlinkNas(ue->ctxId, asn::GetOctetString(ieReq->NAS_PDU));
auto *ieResp = asn::New<ASN_NGAP_PDUSessionResourceReleaseResponseIEs>();
ieResp->id = ASN_NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
ieResp->criticality = ASN_NGAP_Criticality_ignore;
ieResp->value.present =
ASN_NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
// Perform release
for (auto &psi : psIds)
{
auto *w = new NwGnbNgapToGtp(NwGnbNgapToGtp::SESSION_RELEASE);
w->ueId = ue->ctxId;
w->psi = psi;
m_base->gtpTask->push(w);
}
for (auto &psi : psIds)
{
auto *tr = asn::New<ASN_NGAP_PDUSessionResourceReleaseResponseTransfer>();
OctetString encodedTr = ngap_encode::EncodeS(asn_DEF_ASN_NGAP_PDUSessionResourceReleaseResponseTransfer, tr);
if (encodedTr.length() == 0)
throw std::runtime_error("PDUSessionResourceReleaseResponseTransfer encoding failed");
asn::Free(asn_DEF_ASN_NGAP_PDUSessionResourceReleaseResponseTransfer, tr);
auto *item = asn::New<ASN_NGAP_PDUSessionResourceReleasedItemRelRes>();
item->pDUSessionID = static_cast<ASN_NGAP_PDUSessionID_t>(psi);
asn::SetOctetString(item->pDUSessionResourceReleaseResponseTransfer, encodedTr);
asn::SequenceAdd(ieResp->value.choice.PDUSessionResourceReleasedListRelRes, item);
}
auto *respPdu = asn::ngap::NewMessagePdu<ASN_NGAP_PDUSessionResourceReleaseResponse>({ieResp});
sendNgapUeAssociated(ue->ctxId, respPdu);
m_logger->info("PDU session resource(s) released for UE[%d] count[%d]", ue->ctxId, static_cast<int>(psIds.size()));
}
} // namespace nr::gnb } // namespace nr::gnb
\ No newline at end of file
...@@ -30,6 +30,7 @@ extern "C" struct ASN_NGAP_UEContextModificationRequest; ...@@ -30,6 +30,7 @@ extern "C" struct ASN_NGAP_UEContextModificationRequest;
extern "C" struct ASN_NGAP_AMFConfigurationUpdate; extern "C" struct ASN_NGAP_AMFConfigurationUpdate;
extern "C" struct ASN_NGAP_OverloadStart; extern "C" struct ASN_NGAP_OverloadStart;
extern "C" struct ASN_NGAP_OverloadStop; extern "C" struct ASN_NGAP_OverloadStop;
extern "C" struct ASN_NGAP_PDUSessionResourceReleaseCommand;
namespace nr::gnb namespace nr::gnb
{ {
...@@ -102,6 +103,7 @@ class NgapTask : public NtsTask ...@@ -102,6 +103,7 @@ class NgapTask : public NtsTask
/* PDU session management */ /* PDU session management */
void receiveSessionResourceSetupRequest(int amfId, ASN_NGAP_PDUSessionResourceSetupRequest *msg); void receiveSessionResourceSetupRequest(int amfId, ASN_NGAP_PDUSessionResourceSetupRequest *msg);
void receiveSessionResourceReleaseCommand(int amfId, ASN_NGAP_PDUSessionResourceReleaseCommand *msg);
std::optional<NgapCause> setupPduSessionResource(PduSessionResource *resource); std::optional<NgapCause> setupPduSessionResource(PduSessionResource *resource);
/* UE context management */ /* UE context management */
......
...@@ -230,6 +230,9 @@ void NgapTask::handleSctpMessage(int amfId, uint16_t stream, const UniqueBuffer ...@@ -230,6 +230,9 @@ void NgapTask::handleSctpMessage(int amfId, uint16_t stream, const UniqueBuffer
case ASN_NGAP_InitiatingMessage__value_PR_OverloadStop: case ASN_NGAP_InitiatingMessage__value_PR_OverloadStop:
receiveOverloadStop(amf->ctxId, &value.choice.OverloadStop); receiveOverloadStop(amf->ctxId, &value.choice.OverloadStop);
break; break;
case ASN_NGAP_InitiatingMessage__value_PR_PDUSessionResourceReleaseCommand:
receiveSessionResourceReleaseCommand(amf->ctxId, &value.choice.PDUSessionResourceReleaseCommand);
break;
default: default:
m_logger->err("Unhandled NGAP initiating-message received (%d)", value.present); m_logger->err("Unhandled NGAP initiating-message received (%d)", value.present);
break; break;
......
...@@ -119,8 +119,9 @@ struct NwGnbNgapToGtp : NtsMessage ...@@ -119,8 +119,9 @@ struct NwGnbNgapToGtp : NtsMessage
enum PR enum PR
{ {
UE_CONTEXT_UPDATE, UE_CONTEXT_UPDATE,
SESSION_CREATE,
UE_CONTEXT_RELEASE, UE_CONTEXT_RELEASE,
SESSION_CREATE,
SESSION_RELEASE,
} present; } present;
// UE_CONTEXT_UPDATE // UE_CONTEXT_UPDATE
...@@ -130,8 +131,12 @@ struct NwGnbNgapToGtp : NtsMessage ...@@ -130,8 +131,12 @@ struct NwGnbNgapToGtp : NtsMessage
PduSessionResource *resource{}; PduSessionResource *resource{};
// UE_CONTEXT_RELEASE // UE_CONTEXT_RELEASE
// SESSION_RELEASE
int ueId{}; int ueId{};
// SESSION_RELEASE
int psi{};
explicit NwGnbNgapToGtp(PR present) : NtsMessage(NtsMessageType::GNB_NGAP_TO_GTP), present(present) explicit NwGnbNgapToGtp(PR present) : NtsMessage(NtsMessageType::GNB_NGAP_TO_GTP), present(present)
{ {
} }
......
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