Commit 5b72232c authored by aligungr's avatar aligungr

PDU Session establishment improvement

parent 21d13917
......@@ -7,55 +7,117 @@
//
#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
{
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)
{
m_logger->debug("Sending PDU session establishment request");
int psi = allocatePduSessionId(config);
if (psi == 0)
/* Control the protocol state */
if (!m_mm->isRegistered())
{
m_logger->err("PDU Session Establishment Request could not send");
m_logger->err("UE is not registered");
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();
if (pti == 0)
{
m_logger->err("PDU Session Establishment Request could not send");
freePduSessionId(psi);
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{};
opt.additionalParams.push_back(std::make_unique<nas::ProtocolConfigurationItem>(
nas::EProtocolConfigId::CONT_ID_UP_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING, true, OctetString::Empty()));
opt.additionalParams.push_back(std::make_unique<nas::ProtocolConfigurationItem>(
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{};
req.pti = pti;
req.pduSessionId = static_cast<nas::EPduSessionIdentity>(psi);
req.integrityProtectionMaximumDataRate.maxRateUplink =
nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForUplink::FULL_DATA_RATE;
req.integrityProtectionMaximumDataRate.maxRateDownlink =
nas::EMaximumDataRatePerUeForUserPlaneIntegrityProtectionForDownlink::FULL_DATA_RATE;
req.integrityProtectionMaximumDataRate = MakeIntegrityMaxRate(m_base->config->integrityMaxRate);
req.pduSessionType = nas::IEPduSessionType{};
req.pduSessionType->pduSessionType = nas::EPduSessionType::IPV4;
req.sscMode = nas::IESscMode{};
req.sscMode->sscMode = nas::ESscMode::SSC_MODE_1;
req.extendedProtocolConfigurationOptions = nas::IEExtendedProtocolConfigurationOptions{};
req.extendedProtocolConfigurationOptions->configurationProtocol = nas::EConfigurationProtocol::PPP;
req.extendedProtocolConfigurationOptions->extension = true;
req.extendedProtocolConfigurationOptions->options = opt.encode();
req.extendedProtocolConfigurationOptions = std::move(iePco);
req.smCapability = MakeSmCapability();
/* Start T3580 */
m_timers->t3580.start();
/* Send SM message */
sendSmMessage(psi, req);
}
......@@ -71,30 +133,34 @@ void NasSm::receivePduSessionEstablishmentAccept(const nas::PduSessionEstablishm
freeProcedureTransactionId(msg.pti);
auto &pduSession = m_pduSessions[static_cast<int>(msg.pduSessionId)];
if (pduSession.id == 0)
m_logger->err("PDU session not found: %d", msg.pduSessionId);
auto pduSession = m_pduSessions[static_cast<int>(msg.pduSessionId)];
if (pduSession->psState != EPsState::ACTIVE_PENDING)
{
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.authorizedQoSRules = nas::utils::DeepCopyIe(msg.authorizedQoSRules);
pduSession.sessionAmbr = nas::utils::DeepCopyIe(msg.sessionAmbr);
pduSession.sessionType = msg.selectedPduSessionType.pduSessionType;
pduSession->psState = EPsState::ACTIVE;
pduSession->authorizedQoSRules = nas::utils::DeepCopyIe(msg.authorizedQoSRules);
pduSession->sessionAmbr = nas::utils::DeepCopyIe(msg.sessionAmbr);
pduSession->sessionType = msg.selectedPduSessionType.pduSessionType;
if (msg.authorizedQoSFlowDescriptions.has_value())
pduSession.authorizedQoSFlowDescriptions = nas::utils::DeepCopyIe(*msg.authorizedQoSFlowDescriptions);
pduSession->authorizedQoSFlowDescriptions = nas::utils::DeepCopyIe(*msg.authorizedQoSFlowDescriptions);
else
pduSession.authorizedQoSFlowDescriptions = {};
pduSession->authorizedQoSFlowDescriptions = {};
if (msg.pduAddress.has_value())
pduSession.pduAddress = nas::utils::DeepCopyIe(*msg.pduAddress);
pduSession->pduAddress = nas::utils::DeepCopyIe(*msg.pduAddress);
else
pduSession.pduAddress = {};
pduSession->pduAddress = {};
auto *statusUpdate = new NwUeStatusUpdate(NwUeStatusUpdate::SESSION_ESTABLISHMENT);
statusUpdate->pduSession = &pduSession;
statusUpdate->pduSession = pduSession;
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)
......
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