diff --git a/src/gnb/ngap/management.cpp b/src/gnb/ngap/management.cpp index 8a33b54c9..f40abfba8 100644 --- a/src/gnb/ngap/management.cpp +++ b/src/gnb/ngap/management.cpp @@ -33,7 +33,7 @@ void NgapTask::createAmfContext(const GnbAmfConfig &conf) m_amfCtx[ctx->ctxId] = ctx; } -void NgapTask::createUeContext(int ueId) +void NgapTask::createUeContext(int ueId, const int32_t &requestedSliceType) { auto *ctx = new NgapUeContext(ueId); ctx->amfUeNgapId = -1; @@ -42,7 +42,7 @@ void NgapTask::createUeContext(int ueId) m_ueCtx[ctx->ctxId] = ctx; // Perform AMF selection - auto *amf = selectAmf(ueId); + auto *amf = selectAmf(ueId, requestedSliceType); if (amf == nullptr) m_logger->err("AMF selection for UE[%d] failed. Could not find a suitable AMF.", ueId); else diff --git a/src/gnb/ngap/nas.cpp b/src/gnb/ngap/nas.cpp index 38f44d674..4f8879201 100644 --- a/src/gnb/ngap/nas.cpp +++ b/src/gnb/ngap/nas.cpp @@ -20,13 +20,52 @@ #include #include #include +#include +#include "encode.hpp" +#include namespace nr::gnb { -void NgapTask::handleInitialNasTransport(int ueId, const OctetString &nasPdu, int64_t rrcEstablishmentCause, - const std::optional &sTmsi) +int32_t extractSliceInfoAndModifyPdu(OctetString &nasPdu) { + nas::RegistrationRequest *regRequest = nullptr; + int32_t requestedSliceType = -1; + auto m_data = nasPdu.getData(); + OctetView octetView(m_data.data(), m_data.size()); + auto nasMessage = nas::DecodeNasMessage(octetView); + if (nasMessage->epd == nas::EExtendedProtocolDiscriminator::MOBILITY_MANAGEMENT_MESSAGES) + { + nas::MmMessage *mmMessage = dynamic_cast(nasMessage.get()); + if (mmMessage) + { + nas::PlainMmMessage *plainMmMessage = dynamic_cast(mmMessage); + if (plainMmMessage) + { + regRequest = dynamic_cast(plainMmMessage); + if (regRequest) + { + auto sz = regRequest->requestedNSSAI->sNssais.size(); + if (sz > 0) { + requestedSliceType = static_cast(regRequest->requestedNSSAI->sNssais[0].sst.getValue()); + } + } + } + } + } + if (regRequest && regRequest->requestedNSSAI) + regRequest->requestedNSSAI = std::nullopt; + + OctetString modifiedNasPdu; + nas::EncodeNasMessage(*nasMessage, modifiedNasPdu); + nasPdu = std::move(modifiedNasPdu); + return requestedSliceType; +} + +void NgapTask::handleInitialNasTransport(int ueId, OctetString &nasPdu, int64_t rrcEstablishmentCause, + const std::optional &sTmsi) { + int32_t requestedSliceType = extractSliceInfoAndModifyPdu(nasPdu); + m_logger->debug("Initial NAS message received from UE[%d]", ueId); if (m_ueCtx.count(ueId)) @@ -35,7 +74,7 @@ void NgapTask::handleInitialNasTransport(int ueId, const OctetString &nasPdu, in return; } - createUeContext(ueId); + createUeContext(ueId, requestedSliceType); auto *ueCtx = findUeContext(ueId); if (ueCtx == nullptr) diff --git a/src/gnb/ngap/nnsf.cpp b/src/gnb/ngap/nnsf.cpp index bb2e78e06..0e1912f0b 100644 --- a/src/gnb/ngap/nnsf.cpp +++ b/src/gnb/ngap/nnsf.cpp @@ -11,11 +11,18 @@ namespace nr::gnb { -NgapAmfContext *NgapTask::selectAmf(int ueId) +NgapAmfContext *NgapTask::selectAmf(int ueId, const int32_t &requestedSliceType) { - // todo: - for (auto &amf : m_amfCtx) - return amf.second; // return the first one + for (auto &amf : m_amfCtx) { + for (const auto &PlmnSupport : amf.second->plmnSupportList) { + for (const auto &SingleSlice : PlmnSupport->sliceSupportList.slices) { + int32_t supportedSliceType = static_cast(SingleSlice.sst.getValue()); + if (supportedSliceType == requestedSliceType) { + return amf.second; + } + } + } + } return nullptr; } diff --git a/src/gnb/ngap/task.hpp b/src/gnb/ngap/task.hpp index ec0d613f9..4082ce0ac 100644 --- a/src/gnb/ngap/task.hpp +++ b/src/gnb/ngap/task.hpp @@ -71,7 +71,7 @@ class NgapTask : public NtsTask /* Utility functions */ void createAmfContext(const GnbAmfConfig &config); NgapAmfContext *findAmfContext(int ctxId); - void createUeContext(int ueId); + void createUeContext(int ueId, const int32_t &requestedSliceType); NgapUeContext *findUeContext(int ctxId); NgapUeContext *findUeByRanId(int64_t ranUeNgapId); NgapUeContext *findUeByAmfId(int64_t amfUeNgapId); @@ -98,7 +98,7 @@ class NgapTask : public NtsTask bool handleSctpStreamId(int amfId, int stream, const ASN_NGAP_NGAP_PDU &pdu); /* NAS transport */ - void handleInitialNasTransport(int ueId, const OctetString &nasPdu, int64_t rrcEstablishmentCause, + void handleInitialNasTransport(int ueId, OctetString &nasPdu, int64_t rrcEstablishmentCause, const std::optional &sTmsi); void handleUplinkNasTransport(int ueId, const OctetString &nasPdu); void receiveDownlinkNasTransport(int amfId, ASN_NGAP_DownlinkNASTransport *msg); @@ -118,7 +118,7 @@ class NgapTask : public NtsTask void sendContextRelease(int ueId, NgapCause cause); /* NAS Node Selection */ - NgapAmfContext *selectAmf(int ueId); + NgapAmfContext *selectAmf(int ueId, const int32_t &requestedSliceType); NgapAmfContext *selectNewAmfForReAllocation(int ueId, int initiatedAmfId, int amfSetId); /* Radio resource control */ diff --git a/src/ue/nas/mm/messaging.cpp b/src/ue/nas/mm/messaging.cpp index 3ac28070a..96ac9f4d3 100644 --- a/src/ue/nas/mm/messaging.cpp +++ b/src/ue/nas/mm/messaging.cpp @@ -73,7 +73,6 @@ static void RemoveCleartextIEs(nas::PlainMmMessage &msg, OctetString &&nasMsgCon regReq.micoIndication = std::nullopt; regReq.networkSlicingIndication = std::nullopt; regReq.mmCapability = std::nullopt; - regReq.requestedNSSAI = std::nullopt; regReq.requestedDrxParameters = std::nullopt; regReq.uesUsageSetting = std::nullopt; regReq.updateType = std::nullopt; diff --git a/src/utils/octet.hpp b/src/utils/octet.hpp index 2e9c2de37..0141f6872 100644 --- a/src/utils/octet.hpp +++ b/src/utils/octet.hpp @@ -25,6 +25,11 @@ struct octet { } + inline uint8_t getValue() const + { + return value; + } + /* no explicit */ octet(int32_t value) noexcept : value(static_cast(value & 0xFF)) { } diff --git a/src/utils/octet_string.hpp b/src/utils/octet_string.hpp index 59b380363..dc4e84678 100644 --- a/src/utils/octet_string.hpp +++ b/src/utils/octet_string.hpp @@ -25,6 +25,11 @@ class OctetString { } + const std::vector& getData() const + { + return m_data; + } + explicit OctetString(std::vector &&data) : m_data(std::move(data)) { }