Commit 878f7629 authored by aligungr's avatar aligungr

Network initiated PDU session release impl.

parent ecb9d6de
......@@ -9,8 +9,8 @@
#include "task.hpp"
#include <asn/ngap/ASN_NGAP_QosFlowSetupRequestItem.h>
#include <gnb/mr/task.hpp>
#include <gnb/gtp/proto.hpp>
#include <gnb/mr/task.hpp>
#include <utils/constants.hpp>
#include <utils/libc_error.hpp>
......@@ -61,12 +61,16 @@ void GtpTask::onLoop()
handleUeContextUpdate(*w->update);
break;
}
case NwGnbNgapToGtp::UE_CONTEXT_RELEASE: {
handleUeContextDelete(w->ueId);
break;
}
case NwGnbNgapToGtp::SESSION_CREATE: {
handleSessionCreate(w->resource);
break;
}
case NwGnbNgapToGtp::UE_CONTEXT_RELEASE: {
handleUeContextDelete(w->ueId);
case NwGnbNgapToGtp::SESSION_RELEASE: {
handleSessionRelease(w->ueId, w->psi);
break;
}
}
......@@ -122,6 +126,28 @@ void GtpTask::handleSessionCreate(PduSessionResource *session)
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)
{
// Find PDU sessions of the UE
......
......@@ -48,6 +48,7 @@ class GtpTask : public NtsTask
void handleUdpReceive(const udp::NwUdpServerReceive &msg);
void handleUeContextUpdate(const GtpUeContextUpdate &msg);
void handleSessionCreate(PduSessionResource *session);
void handleSessionRelease(int ueId, int psi);
void handleUeContextDelete(int ueId);
void handleUplinkData(int ueId, int psi, OctetString &&data);
......
......@@ -14,6 +14,10 @@
#include <asn/ngap/ASN_NGAP_AssociatedQosFlowList.h>
#include <asn/ngap/ASN_NGAP_GTPTunnel.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_PDUSessionResourceSetupItemSURes.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupRequest.h>
......@@ -21,12 +25,14 @@
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupResponse.h>
#include <asn/ngap/ASN_NGAP_PDUSessionResourceSetupResponseTransfer.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_QosFlowPerTNLInformationItem.h>
#include <asn/ngap/ASN_NGAP_QosFlowPerTNLInformationList.h>
#include <asn/ngap/ASN_NGAP_QosFlowSetupRequestItem.h>
#include <asn/ngap/ASN_NGAP_QosFlowSetupRequestList.h>
#include <gnb/gtp/task.hpp>
#include <set>
#include <stdexcept>
namespace nr::gnb
......@@ -193,12 +199,14 @@ void NgapTask::receiveSessionResourceSetupRequest(int amfId, ASN_NGAP_PDUSession
sendNgapUeAssociated(ue->ctxId, respPdu);
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())
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
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)
......@@ -231,4 +239,68 @@ std::optional<NgapCause> NgapTask::setupPduSessionResource(PduSessionResource *r
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
\ No newline at end of file
......@@ -30,6 +30,7 @@ extern "C" struct ASN_NGAP_UEContextModificationRequest;
extern "C" struct ASN_NGAP_AMFConfigurationUpdate;
extern "C" struct ASN_NGAP_OverloadStart;
extern "C" struct ASN_NGAP_OverloadStop;
extern "C" struct ASN_NGAP_PDUSessionResourceReleaseCommand;
namespace nr::gnb
{
......@@ -102,6 +103,7 @@ class NgapTask : public NtsTask
/* PDU session management */
void receiveSessionResourceSetupRequest(int amfId, ASN_NGAP_PDUSessionResourceSetupRequest *msg);
void receiveSessionResourceReleaseCommand(int amfId, ASN_NGAP_PDUSessionResourceReleaseCommand *msg);
std::optional<NgapCause> setupPduSessionResource(PduSessionResource *resource);
/* UE context management */
......
......@@ -230,6 +230,9 @@ void NgapTask::handleSctpMessage(int amfId, uint16_t stream, const UniqueBuffer
case ASN_NGAP_InitiatingMessage__value_PR_OverloadStop:
receiveOverloadStop(amf->ctxId, &value.choice.OverloadStop);
break;
case ASN_NGAP_InitiatingMessage__value_PR_PDUSessionResourceReleaseCommand:
receiveSessionResourceReleaseCommand(amf->ctxId, &value.choice.PDUSessionResourceReleaseCommand);
break;
default:
m_logger->err("Unhandled NGAP initiating-message received (%d)", value.present);
break;
......
......@@ -119,8 +119,9 @@ struct NwGnbNgapToGtp : NtsMessage
enum PR
{
UE_CONTEXT_UPDATE,
SESSION_CREATE,
UE_CONTEXT_RELEASE,
SESSION_CREATE,
SESSION_RELEASE,
} present;
// UE_CONTEXT_UPDATE
......@@ -130,8 +131,12 @@ struct NwGnbNgapToGtp : NtsMessage
PduSessionResource *resource{};
// UE_CONTEXT_RELEASE
// SESSION_RELEASE
int ueId{};
// SESSION_RELEASE
int psi{};
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