diff --git a/src/gnb/ngap/management.cpp b/src/gnb/ngap/management.cpp index 8a33b54c9..2b0ec9416 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, 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..6bd6beb88 100644 --- a/src/gnb/ngap/nas.cpp +++ b/src/gnb/ngap/nas.cpp @@ -20,13 +20,53 @@ #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; + const uint8_t *m_data = nasPdu.data(); + size_t m_dataLength = nasPdu.length(); + OctetView octetView(m_data, m_dataLength); + 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); + } + } + } + } + } + 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 +75,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..84ae61548 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, 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); + if (supportedSliceType == requestedSliceType) { + return amf.second; + } + } + } + } return nullptr; } diff --git a/src/gnb/ngap/task.hpp b/src/gnb/ngap/task.hpp index ec0d613f9..14ea9563a 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, 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, 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;