Commit 5b72232c authored by aligungr's avatar aligungr

PDU Session establishment improvement

parent 21d13917
...@@ -7,55 +7,117 @@ ...@@ -7,55 +7,117 @@
// //
#include "sm.hpp" #include "sm.hpp"
#include <algorithm>
#include <nas/proto_conf.hpp> #include <nas/proto_conf.hpp>
#include <nas/utils.hpp> #include <nas/utils.hpp>
#include <ue/app/task.hpp> #include <ue/app/task.hpp>
#include <ue/mm/mm.hpp>
namespace nr::ue namespace nr::ue
{ {
static nas::IE5gSmCapability MakeSmCapability()
{
nas::IE5gSmCapability cap{};
cap.rqos = nas::EReflectiveQoS::NOT_SUPPORTED;
cap.mh6pdu = nas::EMultiHomedIPv6PduSession::NOT_SUPPORTED;
return cap;
}
static nas::IEIntegrityProtectionMaximumDataRate MakeIntegrityMaxRate(const IntegrityMaxDataRateConfig &config)
{
nas::IEIntegrityProtectionMaximumDataRate res{};
res.maxRateDownlink = nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForDownlink::SIXTY_FOUR_KBPS;
res.maxRateUplink = nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForUplink::SIXTY_FOUR_KBPS;
if (config.downlinkFull)
res.maxRateDownlink = nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForDownlink::FULL_DATA_RATE;
if (config.uplinkFull)
res.maxRateUplink = nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForUplink::FULL_DATA_RATE;
return res;
}
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");
int psi = allocatePduSessionId(config); /* Control the protocol state */
if (psi == 0) if (!m_mm->isRegistered())
{ {
m_logger->err("PDU Session Establishment Request could not send"); m_logger->err("UE is not registered");
return; return;
} }
/* Control the received config */
if (config.type != nas::EPduSessionType::IPV4)
{
m_logger->err("PDU session type [%s] is not supported", nas::utils::EnumToString(config.type));
return;
}
if (m_mm->isRegisteredForEmergency() && !config.isEmergency)
{
m_logger->err("Non-emergency PDU session cannot be requested, UE is registered for emergency only");
return;
}
if (config.isEmergency && anyEmergencySession())
{
m_logger->err(
"Emergency PDU session cannot be requested, another emergency session already established or establishing");
return;
}
/* Allocate PSI */
int psi = allocatePduSessionId(config);
if (psi == 0)
return;
/* Allocate PTI */
int pti = allocateProcedureTransactionId(); int pti = allocateProcedureTransactionId();
if (pti == 0) if (pti == 0)
{ {
m_logger->err("PDU Session Establishment Request could not send");
freePduSessionId(psi); freePduSessionId(psi);
return; return;
} }
/* Set relevant fields of the PS description */
auto ps = m_pduSessions[psi];
ps->psState = EPsState::ACTIVE_PENDING;
ps->sessionType = config.type;
ps->apn = config.apn;
ps->sNssai = config.sNssai;
ps->isEmergency = config.isEmergency;
ps->authorizedQoSRules = {};
ps->sessionAmbr = {};
ps->authorizedQoSFlowDescriptions = {};
ps->pduAddress = {};
/* Make PCO */
nas::ProtocolConfigurationOptions opt{}; nas::ProtocolConfigurationOptions opt{};
opt.additionalParams.push_back(std::make_unique<nas::ProtocolConfigurationItem>( opt.additionalParams.push_back(std::make_unique<nas::ProtocolConfigurationItem>(
nas::EProtocolConfigId::CONT_ID_UP_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING, true, OctetString::Empty())); nas::EProtocolConfigId::CONT_ID_UP_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING, true, OctetString::Empty()));
opt.additionalParams.push_back(std::make_unique<nas::ProtocolConfigurationItem>( opt.additionalParams.push_back(std::make_unique<nas::ProtocolConfigurationItem>(
nas::EProtocolConfigId::CONT_ID_DOWN_DNS_SERVER_IPV4_ADDRESS, true, OctetString::Empty())); nas::EProtocolConfigId::CONT_ID_DOWN_DNS_SERVER_IPV4_ADDRESS, true, OctetString::Empty()));
nas::IEExtendedProtocolConfigurationOptions iePco{};
iePco.configurationProtocol = nas::EConfigurationProtocol::PPP;
iePco.extension = true;
iePco.options = opt.encode();
/* Prepare the establishment request message */
nas::PduSessionEstablishmentRequest req{}; nas::PduSessionEstablishmentRequest req{};
req.pti = pti; req.pti = pti;
req.pduSessionId = static_cast<nas::EPduSessionIdentity>(psi); req.pduSessionId = static_cast<nas::EPduSessionIdentity>(psi);
req.integrityProtectionMaximumDataRate.maxRateUplink = req.integrityProtectionMaximumDataRate = MakeIntegrityMaxRate(m_base->config->integrityMaxRate);
nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForUplink::FULL_DATA_RATE;
req.integrityProtectionMaximumDataRate.maxRateDownlink =
nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForDownlink::FULL_DATA_RATE;
req.pduSessionType = nas::IEPduSessionType{}; req.pduSessionType = nas::IEPduSessionType{};
req.pduSessionType->pduSessionType = nas::EPduSessionType::IPV4; req.pduSessionType->pduSessionType = nas::EPduSessionType::IPV4;
req.sscMode = nas::IESscMode{}; req.sscMode = nas::IESscMode{};
req.sscMode->sscMode = nas::ESscMode::SSC_MODE_1; req.sscMode->sscMode = nas::ESscMode::SSC_MODE_1;
req.extendedProtocolConfigurationOptions = nas::IEExtendedProtocolConfigurationOptions{}; req.extendedProtocolConfigurationOptions = std::move(iePco);
req.extendedProtocolConfigurationOptions->configurationProtocol = nas::EConfigurationProtocol::PPP; req.smCapability = MakeSmCapability();
req.extendedProtocolConfigurationOptions->extension = true;
req.extendedProtocolConfigurationOptions->options = opt.encode();
/* Start T3580 */
m_timers->t3580.start(); m_timers->t3580.start();
/* Send SM message */
sendSmMessage(psi, req); sendSmMessage(psi, req);
} }
...@@ -71,30 +133,34 @@ void NasSm::receivePduSessionEstablishmentAccept(const nas::PduSessionEstablishm ...@@ -71,30 +133,34 @@ void NasSm::receivePduSessionEstablishmentAccept(const nas::PduSessionEstablishm
freeProcedureTransactionId(msg.pti); freeProcedureTransactionId(msg.pti);
auto &pduSession = m_pduSessions[static_cast<int>(msg.pduSessionId)]; auto pduSession = m_pduSessions[static_cast<int>(msg.pduSessionId)];
if (pduSession.id == 0) if (pduSession->psState != EPsState::ACTIVE_PENDING)
m_logger->err("PDU session not found: %d", msg.pduSessionId); {
m_logger->err("PS establishment accept received without requested");
sendSmCause(nas::ESmCause::MESSAGE_TYPE_NOT_COMPATIBLE_WITH_THE_PROTOCOL_STATE, pduSession->psi);
return;
}
pduSession.isEstablished = true; pduSession->psState = EPsState::ACTIVE;
pduSession.authorizedQoSRules = nas::utils::DeepCopyIe(msg.authorizedQoSRules); pduSession->authorizedQoSRules = nas::utils::DeepCopyIe(msg.authorizedQoSRules);
pduSession.sessionAmbr = nas::utils::DeepCopyIe(msg.sessionAmbr); pduSession->sessionAmbr = nas::utils::DeepCopyIe(msg.sessionAmbr);
pduSession.sessionType = msg.selectedPduSessionType.pduSessionType; pduSession->sessionType = msg.selectedPduSessionType.pduSessionType;
if (msg.authorizedQoSFlowDescriptions.has_value()) if (msg.authorizedQoSFlowDescriptions.has_value())
pduSession.authorizedQoSFlowDescriptions = nas::utils::DeepCopyIe(*msg.authorizedQoSFlowDescriptions); pduSession->authorizedQoSFlowDescriptions = nas::utils::DeepCopyIe(*msg.authorizedQoSFlowDescriptions);
else else
pduSession.authorizedQoSFlowDescriptions = {}; pduSession->authorizedQoSFlowDescriptions = {};
if (msg.pduAddress.has_value()) if (msg.pduAddress.has_value())
pduSession.pduAddress = nas::utils::DeepCopyIe(*msg.pduAddress); pduSession->pduAddress = nas::utils::DeepCopyIe(*msg.pduAddress);
else else
pduSession.pduAddress = {}; pduSession->pduAddress = {};
auto *statusUpdate = new NwUeStatusUpdate(NwUeStatusUpdate::SESSION_ESTABLISHMENT); auto *statusUpdate = new NwUeStatusUpdate(NwUeStatusUpdate::SESSION_ESTABLISHMENT);
statusUpdate->pduSession = &pduSession; statusUpdate->pduSession = pduSession;
m_base->appTask->push(statusUpdate); m_base->appTask->push(statusUpdate);
m_logger->info("PDU Session establishment is successful PSI[%d]", pduSession.id); m_logger->info("PDU Session establishment is successful PSI[%d]", pduSession->psi);
} }
void NasSm::receivePduSessionEstablishmentReject(const nas::PduSessionEstablishmentReject &msg) void NasSm::receivePduSessionEstablishmentReject(const nas::PduSessionEstablishmentReject &msg)
......
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