Commit b276eeb1 authored by aligungr's avatar aligungr

Service request initiation

parent 22e8cecc
......@@ -25,7 +25,7 @@ bool NasMm::hasEmergency()
m_lastRegistrationRequest->registrationType.registrationType == nas::ERegistrationType::EMERGENCY_REGISTRATION)
return true;
// TODO: Other case which is an emergency PDU session is established, or need to be established (and wanted to be
// TODO: Other case which is an emergency PDU session need to be established (and wanted to be
// established soon)
if (m_sm->anyEmergencySession())
return true;
......@@ -43,4 +43,27 @@ void NasMm::setN1Capability(bool enabled)
// TODO
}
bool NasMm::isInNonAllowedArea()
{
if (!m_usim->isValid())
return false;
if (!m_usim->m_currentPlmn.has_value())
return false;
auto &plmn = *m_usim->m_currentPlmn;
if (nas::utils::ServiceAreaListForbidsPlmn(m_usim->m_serviceAreaList, nas::utils::PlmnFrom(plmn)))
return true;
if (m_usim->m_servingCell.has_value())
{
if (nas::utils::ServiceAreaListForbidsTai(
m_usim->m_serviceAreaList,
nas::VTrackingAreaIdentity{nas::utils::PlmnFrom(plmn), octet3{m_usim->m_servingCell->tac}}))
return true;
}
return false;
}
} // namespace nr::ue
......@@ -40,6 +40,8 @@ class NasMm
std::unique_ptr<nas::RegistrationRequest> m_lastRegistrationRequest{};
// Most recent de-registration request
std::unique_ptr<nas::DeRegistrationRequestUeOriginating> m_lastDeregistrationRequest{};
// Most recent service request
std::unique_ptr<nas::ServiceRequest> m_lastServiceRequest{};
// Indicates the last de-registration cause
EDeregCause m_lastDeregCause{};
// Last time PLMN search is triggered
......@@ -133,6 +135,7 @@ class NasMm
nas::IE5gsMobileIdentity getOrGeneratePreferredId();
private: /* Service */
void sendServiceRequest(EServiceReqCause reqCause);
void receiveServiceAccept(const nas::ServiceAccept &msg);
void receiveServiceReject(const nas::ServiceReject &msg);
......@@ -152,6 +155,7 @@ class NasMm
bool isHighPriority();
bool hasEmergency();
void setN1Capability(bool enabled);
bool isInNonAllowedArea();
private: /* eCall */
bool startECallInactivityIfNeeded();
......
......@@ -7,10 +7,108 @@
//
#include "mm.hpp"
#include <ue/nas/sm/sm.hpp>
namespace nr::ue
{
void NasMm::sendServiceRequest(EServiceReqCause reqCause)
{
auto request = std::make_unique<nas::ServiceRequest>();
if (reqCause == EServiceReqCause::IDLE_PAGING)
{
if (m_sm->anyUplinkDataPending())
{
request->uplinkDataStatus = nas::IEUplinkDataStatus{};
request->uplinkDataStatus->psi = m_sm->getUplinkDataStatus();
}
request->serviceType.serviceType = nas::EServiceType::MOBILE_TERMINATED_SERVICES;
}
else if (reqCause == EServiceReqCause::CONNECTED_3GPP_NOTIFICATION_N3GPP)
{
// TODO: This case not handled since the non-3gpp access is not supported
m_logger->err("Unhandled case in ServiceRequest");
}
else if (reqCause == EServiceReqCause::IDLE_UPLINK_SIGNAL_PENDING)
{
if (isHighPriority())
request->serviceType.serviceType = nas::EServiceType::HIGH_PRIORITY_ACCESS;
else if (hasEmergency())
request->serviceType.serviceType = nas::EServiceType::EMERGENCY_SERVICES;
else
request->serviceType.serviceType = nas::EServiceType::SIGNALLING;
if (isInNonAllowedArea())
{
// TODO: This case not handled since PS data off not supported
m_logger->err("Unhandled case in ServiceRequest");
}
}
else if (reqCause == EServiceReqCause::IDLE_UPLINK_DATA_PENDING ||
reqCause == EServiceReqCause::CONNECTED_UPLINK_DATA_PENDING)
{
request->uplinkDataStatus = nas::IEUplinkDataStatus{};
request->uplinkDataStatus->psi = m_sm->getUplinkDataStatus();
if (isHighPriority())
request->serviceType.serviceType = nas::EServiceType::HIGH_PRIORITY_ACCESS;
else if (m_sm->anyEmergencyUplinkDataPending())
request->serviceType.serviceType = nas::EServiceType::EMERGENCY_SERVICES;
else
request->serviceType.serviceType = nas::EServiceType::DATA;
}
else if (reqCause == EServiceReqCause::NON_3GPP_AS_ESTABLISHED)
{
// TODO: This case not handled since the non-3gpp access is not supported
m_logger->err("Unhandled case found in ServiceRequest");
}
else if (reqCause == EServiceReqCause::IDLE_3GPP_NOTIFICATION_N3GPP)
{
// TODO: This case not handled since the non-3gpp access is not supported
m_logger->err("Unhandled case occurred in ServiceRequest");
}
else if (reqCause == EServiceReqCause::EMERGENCY_FALLBACK)
{
request->serviceType.serviceType = nas::EServiceType::EMERGENCY_SERVICES_FALLBACK;
}
else if (reqCause == EServiceReqCause::FALLBACK_INDICATION)
{
if (isHighPriority())
request->serviceType.serviceType = nas::EServiceType::HIGH_PRIORITY_ACCESS;
else
{
// TODO: fallback indication not supported yet
}
}
// Assign ngKSI
if (m_usim->m_currentNsCtx)
{
request->ngKSI.tsc = m_usim->m_currentNsCtx->tsc;
request->ngKSI.ksi = m_usim->m_currentNsCtx->ngKsi;
}
// Assign TMSI (TMSI is a part of GUTI)
request->tmsi = m_usim->m_storedGuti;
if (request->tmsi.type != nas::EIdentityType::NO_IDENTITY)
{
request->tmsi.type = nas::EIdentityType::TMSI;
request->tmsi.gutiOrTmsi.plmn = {};
request->tmsi.gutiOrTmsi.amfRegionId = {};
}
// Assign PDU session status
request->pduSessionStatus = nas::IEPduSessionStatus{};
request->pduSessionStatus->psi = m_sm->getPduSessionStatus();
// Send the message and process the timers
sendNasMessage(*request);
m_lastServiceRequest = std::move(request);
m_timers->t3517.start();
switchMmState(EMmState::MM_SERVICE_REQUEST_INITIATED, EMmSubState::MM_SERVICE_REQUEST_INITIATED_NA);
}
void NasMm::receiveServiceAccept(const nas::ServiceAccept &msg)
{
if (msg.eapMessage.has_value())
......
......@@ -48,6 +48,15 @@ bool NasSm::anyUplinkDataPending()
return false;
}
bool NasSm::anyEmergencyUplinkDataPending()
{
auto status = getUplinkDataStatus();
for (int i = 1; i < 16; i++)
if (status[i] && m_pduSessions[i]->isEmergency)
return true;
return false;
}
std::bitset<16> NasSm::getUplinkDataStatus()
{
std::bitset<16> res{};
......@@ -57,4 +66,13 @@ std::bitset<16> NasSm::getUplinkDataStatus()
return res;
}
std::bitset<16> NasSm::getPduSessionStatus()
{
std::bitset<16> res{};
for (int i = 1; i < 16; i++)
if (m_pduSessions[i]->psState == EPsState::ACTIVE)
res[i] = true;
return res;
}
} // namespace nr::ue
......@@ -52,7 +52,9 @@ class NasSm
bool anyEmergencySession();
void handleUplinkStatusChange(int psi, bool isPending);
bool anyUplinkDataPending();
bool anyEmergencyUplinkDataPending();
std::bitset<16> getUplinkDataStatus();
std::bitset<16> getPduSessionStatus();
/* Session Release */
void sendReleaseRequest(int psi);
......
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