Commit 8a310228 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Validate NSSAIs

parent 13c9b4e5
...@@ -73,7 +73,7 @@ extern "C" { ...@@ -73,7 +73,7 @@ extern "C" {
#include "dynamic_memory_check.h" #include "dynamic_memory_check.h"
} }
using namespace oai::amf::model; // using namespace oai::amf::model;
using namespace nas; using namespace nas;
using namespace amf_application; using namespace amf_application;
using namespace config; using namespace config;
...@@ -1436,8 +1436,9 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) { ...@@ -1436,8 +1436,9 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) {
} }
nc.get()->ngKsi = ngksi; nc.get()->ngKsi = ngksi;
} }
// TODO: If AMF can't handle this UE, reroute the Registration Request to a
// new AMF Get UE's slice selection subscription from UDM if not available // If current AMF can't handle this UE, reroute the Registration Request to
// a target AMF
if (reroute_registration_request(nc)) { if (reroute_registration_request(nc)) {
return; return;
} }
...@@ -3708,30 +3709,58 @@ bool amf_n1::reroute_registration_request(std::shared_ptr<nas_context>& nc) { ...@@ -3708,30 +3709,58 @@ bool amf_n1::reroute_registration_request(std::shared_ptr<nas_context>& nc) {
Logger::amf_n1().debug( Logger::amf_n1().debug(
"Registration with AMF re-allocation, Reroute Registration Request to " "Registration with AMF re-allocation, Reroute Registration Request to "
"the target AMF"); "the target AMF");
nssai_t nssai = {};
// Get NSSAI from UDM // Get NSSAI from UDM
oai::amf::model::Nssai nssai = {};
if (!get_slice_selection_subscription_data(nc, nssai)) { if (!get_slice_selection_subscription_data(nc, nssai)) {
Logger::amf_n1().debug(
"Could not get the Slice Selection Subscription Data from UDM");
return false; return false;
} }
// Check that AMF can process the Requested NSSAIs or not // Check that AMF can process the Requested NSSAIs or not
if (check_requested_nssai(nc, nssai)) { if (check_requested_nssai(nc, nssai)) {
Logger::amf_n1().debug(
"Current AMF can handle all the Subscribed NSSAIs, do not need to "
"perform AMF Re-allocation procedure");
return false; return false;
} }
// Process NS selection to select the appropriate AMF // Process NS selection to select the appropriate AMF
oai::amf::model::SliceInfoForRegistration slice_info = {}; oai::amf::model::SliceInfoForRegistration slice_info = {};
oai::amf::model::AuthorizedNetworkSliceInfo authorized_network_slice_info = oai::amf::model::AuthorizedNetworkSliceInfo authorized_network_slice_info =
{}; {};
std::vector<SubscribedSnssai> subscribed_snssais;
for (auto n : nssai.getDefaultSingleNssais()) {
SubscribedSnssai subscribed_snssai = {};
subscribed_snssai.setSubscribedSnssai(n);
subscribed_snssai.setDefaultIndication(true);
subscribed_snssais.push_back(subscribed_snssai);
}
slice_info.setSubscribedNssai(subscribed_snssais);
// TODO: To be verified
// slice_info.setRequestedNssai(nssai.getDefaultSingleNssais());
if (!get_network_slice_selection( if (!get_network_slice_selection(
nc, amf_app_inst->get_nf_instance(), slice_info, nc, amf_app_inst->get_nf_instance(), slice_info,
authorized_network_slice_info)) { authorized_network_slice_info)) {
Logger::amf_n1().debug(
"Could not get the Network Slice Selection information from NSSF");
return false; return false;
} }
// if get_target_amf();
// Find the appropriate target AMF
std::string target_amf = {}; std::string target_amf = {};
if (get_target_amf(nc, target_amf, authorized_network_slice_info)) { if (get_target_amf(nc, target_amf, authorized_network_slice_info)) {
Logger::amf_n1().debug("Target AMF %s", target_amf.c_str());
// Send N1MessageNotify to the Target AMF // Send N1MessageNotify to the Target AMF
send_n1_message_notity(nc, target_amf); send_n1_message_notity(nc, target_amf);
return true;
} else {
Logger::amf_n1().debug(
"Could not find an appropriate target AMF to handle UE");
return false;
} }
return true; return true;
...@@ -3739,15 +3768,64 @@ bool amf_n1::reroute_registration_request(std::shared_ptr<nas_context>& nc) { ...@@ -3739,15 +3768,64 @@ bool amf_n1::reroute_registration_request(std::shared_ptr<nas_context>& nc) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool amf_n1::check_requested_nssai( bool amf_n1::check_requested_nssai(
const std::shared_ptr<nas_context>& nc, const nssai_t& nssai) const { const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai) {
// TODO // Check if the AMF can serve all the subscribed S-NSSAIs
return true; std::shared_ptr<ue_context> uc = {};
if (!find_ue_context(
nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id, uc)) {
Logger::amf_n1().warn("Cannot find the UE context");
return false;
}
bool result = false;
for (auto p : amf_cfg.plmn_list) {
// Check PLMN/TAC
if ((uc.get()->tai.mcc.compare(p.mcc) != 0) or
(uc.get()->tai.mnc.compare(p.mnc) != 0) or
(uc.get()->tai.tac != p.tac)) {
continue;
}
result = true;
// Each S-NSSAI in the Default Single NSSAIs must be in the AMF's Slice List
for (auto n : nssai.getDefaultSingleNssais()) {
bool found_nssai = false;
for (auto s : p.slice_list) {
uint8_t sst = 0;
try {
sst = std::stoi(s.sST);
} catch (const std::exception& err) {
Logger::amf_n1().warn("Invalid SST");
continue;
}
if (sst == n.getSst()) {
if ((n.sdIsSet() and (n.getSd().compare(s.sD) == 0)) or
(!n.sdIsSet() and s.sD.empty())) {
found_nssai = true;
Logger::amf_n1().debug(
"Found S-NSSAI (SST %d, SD %s)", sst, n.getSd().c_str());
break;
}
}
}
if (!found_nssai) {
result = false;
break;
}
}
}
return result;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool amf_n1::get_slice_selection_subscription_data( bool amf_n1::get_slice_selection_subscription_data(
const std::shared_ptr<nas_context>& nc, nssai_t& nssai) { const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai) {
// TODO: UDM selection (from NRF or configuration file) // TODO: UDM selection (from NRF or configuration file)
if (amf_cfg.support_features.enable_external_udm) { if (amf_cfg.support_features.enable_external_udm) {
std::shared_ptr<ue_context> uc = {}; std::shared_ptr<ue_context> uc = {};
...@@ -3792,9 +3870,12 @@ bool amf_n1::get_slice_selection_subscription_data( ...@@ -3792,9 +3870,12 @@ bool amf_n1::get_slice_selection_subscription_data(
assert(f.has_value()); assert(f.has_value());
assert(!f.has_exception()); assert(!f.has_exception());
// Wait for the result from UDM // Wait for the result from UDM
nlohmann::json nssai = f.get(); nlohmann::json nssai_json = f.get();
if (!nssai.empty()) { if (!nssai_json.empty()) {
Logger::ngap().debug("Got NSSAI from UDM: %s", nssai.dump().c_str()); Logger::ngap().debug(
"Got NSSAI from UDM: %s", nssai_json.dump().c_str());
from_json(nssai_json, nssai);
return true;
} else { } else {
return false; return false;
} }
...@@ -3812,7 +3893,7 @@ bool amf_n1::get_slice_selection_subscription_data( ...@@ -3812,7 +3893,7 @@ bool amf_n1::get_slice_selection_subscription_data(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool amf_n1::get_slice_selection_subscription_data_from_conf_file( bool amf_n1::get_slice_selection_subscription_data_from_conf_file(
const std::shared_ptr<nas_context>& nc, nssai_t& nssai) { const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai) {
// TODO: // TODO:
return true; return true;
} }
...@@ -3911,6 +3992,11 @@ bool amf_n1::get_target_amf( ...@@ -3911,6 +3992,11 @@ bool amf_n1::get_target_amf(
const oai::amf::model::AuthorizedNetworkSliceInfo& const oai::amf::model::AuthorizedNetworkSliceInfo&
authorized_network_slice_info) { authorized_network_slice_info) {
// Get Target AMF from AuthorizedNetworkSliceInfo // Get Target AMF from AuthorizedNetworkSliceInfo
std::string target_amf_set = {};
if (authorized_network_slice_info.targetAmfSetIsSet()) {
target_amf_set = authorized_network_slice_info.getTargetAmfSet();
}
return true; return true;
} }
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include "3gpp_ts24501.hpp" #include "3gpp_ts24501.hpp"
#include "3gpp_29.503.h" #include "3gpp_29.503.h"
#include "3gpp_29.531.h"
#include "amf.hpp" #include "amf.hpp"
#include "amf_statistics.hpp" #include "amf_statistics.hpp"
#include "bstrlib.h" #include "bstrlib.h"
...@@ -52,6 +51,7 @@ ...@@ -52,6 +51,7 @@
#include "itti.hpp" #include "itti.hpp"
#include "SliceInfoForRegistration.h" #include "SliceInfoForRegistration.h"
#include "AuthorizedNetworkSliceInfo.h" #include "AuthorizedNetworkSliceInfo.h"
#include "Nssai.h"
namespace amf_application { namespace amf_application {
...@@ -223,11 +223,11 @@ class amf_n1 { ...@@ -223,11 +223,11 @@ class amf_n1 {
bool reroute_registration_request(std::shared_ptr<nas_context>& nc); bool reroute_registration_request(std::shared_ptr<nas_context>& nc);
bool get_slice_selection_subscription_data( bool get_slice_selection_subscription_data(
const std::shared_ptr<nas_context>& nc, nssai_t& nssai); const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai);
bool get_slice_selection_subscription_data_from_conf_file( bool get_slice_selection_subscription_data_from_conf_file(
const std::shared_ptr<nas_context>& nc, nssai_t& nssai); const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai);
bool check_requested_nssai( bool check_requested_nssai(
const std::shared_ptr<nas_context>& nc, const nssai_t& nssai) const; const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai);
bool get_network_slice_selection( bool get_network_slice_selection(
const std::shared_ptr<nas_context>& nc, const std::string& nf_instance_id, const std::shared_ptr<nas_context>& nc, const std::string& nf_instance_id,
const oai::amf::model::SliceInfoForRegistration& slice_info, const oai::amf::model::SliceInfoForRegistration& slice_info,
......
...@@ -1411,8 +1411,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) { ...@@ -1411,8 +1411,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
GlobalgNBId* TargetGlobalgNBId = new GlobalgNBId(); GlobalgNBId* TargetGlobalgNBId = new GlobalgNBId();
itti_msg.handoverReq->getGlobalRanNodeId(TargetGlobalgNBId); itti_msg.handoverReq->getGlobalRanNodeId(TargetGlobalgNBId);
PlmnId* plmn = new PlmnId(); ngap::PlmnId* plmn = new ngap::PlmnId();
GNB_ID* gnbid = new GNB_ID(); GNB_ID* gnbid = new GNB_ID();
TargetGlobalgNBId->getGlobalgNBId(plmn, gnbid); TargetGlobalgNBId->getGlobalgNBId(plmn, gnbid);
std::string mcc = {}; std::string mcc = {};
std::string mnc = {}; std::string mnc = {};
...@@ -1426,8 +1426,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) { ...@@ -1426,8 +1426,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
TAI* tai = new TAI(); TAI* tai = new TAI();
itti_msg.handoverReq->getTAI(tai); itti_msg.handoverReq->getTAI(tai);
PlmnId* plmnOfTAI = new PlmnId(); ngap::PlmnId* plmnOfTAI = new ngap::PlmnId();
TAC* tac = new TAC(); TAC* tac = new TAC();
tai->getTAI(plmnOfTAI, tac); tai->getTAI(plmnOfTAI, tac);
string mccOfselectTAI = {}; string mccOfselectTAI = {};
string mncOfselectTAI = {}; string mncOfselectTAI = {};
...@@ -1478,7 +1478,7 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) { ...@@ -1478,7 +1478,7 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
guami.regionID = amf_cfg.guami.regionID; guami.regionID = amf_cfg.guami.regionID;
guami.AmfSetID = amf_cfg.guami.AmfSetID; guami.AmfSetID = amf_cfg.guami.AmfSetID;
guami.AmfPointer = amf_cfg.guami.AmfPointer; guami.AmfPointer = amf_cfg.guami.AmfPointer;
PlmnId* m_plmnId = new PlmnId(); ngap::PlmnId* m_plmnId = new ngap::PlmnId();
AMFRegionID* m_aMFRegionID = new AMFRegionID(); AMFRegionID* m_aMFRegionID = new AMFRegionID();
AMFSetID* m_aMFSetID = new AMFSetID(); AMFSetID* m_aMFSetID = new AMFSetID();
AMFPointer* m_aMFPointer = new AMFPointer(); AMFPointer* m_aMFPointer = new AMFPointer();
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "amf_profile.hpp" #include "amf_profile.hpp"
#include "bstrlib.h" #include "bstrlib.h"
#include "itti_msg.hpp" #include "itti_msg.hpp"
#include "3gpp_29.531.h"
#include "SliceInfoForRegistration.h" #include "SliceInfoForRegistration.h"
class itti_msg_n11 : public itti_msg { class itti_msg_n11 : public itti_msg {
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/**
* Nudm_SDM
* Nudm Subscriber Data Management Service. � 2019, 3GPP Organizational Partners
* (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
#include "Nssai.h"
namespace oai {
namespace amf {
namespace model {
Nssai::Nssai() {
m_SupportedFeatures = "";
m_SupportedFeaturesIsSet = false;
m_SingleNssaisIsSet = false;
}
Nssai::~Nssai() {}
void Nssai::validate() {
// TODO: implement validation
}
void to_json(nlohmann::json& j, const Nssai& o) {
j = nlohmann::json();
if (o.supportedFeaturesIsSet())
j["supportedFeatures"] = o.m_SupportedFeatures;
j["defaultSingleNssais"] = o.m_DefaultSingleNssais;
if (o.singleNssaisIsSet()) j["singleNssais"] = o.m_SingleNssais;
}
void from_json(const nlohmann::json& j, Nssai& o) {
if (j.find("supportedFeatures") != j.end()) {
j.at("supportedFeatures").get_to(o.m_SupportedFeatures);
o.m_SupportedFeaturesIsSet = true;
}
j.at("defaultSingleNssais").get_to(o.m_DefaultSingleNssais);
if (j.find("singleNssais") != j.end()) {
j.at("singleNssais").get_to(o.m_SingleNssais);
o.m_SingleNssaisIsSet = true;
}
}
std::string Nssai::getSupportedFeatures() const {
return m_SupportedFeatures;
}
void Nssai::setSupportedFeatures(std::string const& value) {
m_SupportedFeatures = value;
m_SupportedFeaturesIsSet = true;
}
bool Nssai::supportedFeaturesIsSet() const {
return m_SupportedFeaturesIsSet;
}
void Nssai::unsetSupportedFeatures() {
m_SupportedFeaturesIsSet = false;
}
std::vector<Snssai>& Nssai::getDefaultSingleNssais() {
return m_DefaultSingleNssais;
}
std::vector<Snssai>& Nssai::getSingleNssais() {
return m_SingleNssais;
}
bool Nssai::singleNssaisIsSet() const {
return m_SingleNssaisIsSet;
}
void Nssai::unsetSingleNssais() {
m_SingleNssaisIsSet = false;
}
} // namespace model
} // namespace amf
} // namespace oai
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this * the OAI Public License, Version 1.1 (the "License"); you may not use this
*file except in compliance with the License. You may obtain a copy of the * file except in compliance with the License. You may obtain a copy of the
*License at * License at
* *
* http://www.openairinterface.org/?page_id=698 * http://www.openairinterface.org/?page_id=698
* *
...@@ -18,78 +18,84 @@ ...@@ -18,78 +18,84 @@
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/**
/*! \file 3gpp_29.531.h * Nudm_SDM
\brief * Nudm Subscriber Data Management Service. � 2019, 3GPP Organizational Partners
\author Tien Thinh NGUYEN * (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
\company Eurecom *
\email: tien-thinh.nguyen@eurecom.fr * The version of the OpenAPI document: 2.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
/*
* Nssai.h
*
*
*/ */
#ifndef FILE_3GPP_29_531_SEEN
#define FILE_3GPP_29_531_SEEN
#include <stdint.h> #ifndef Nssai_H_
#define Nssai_H_
#include <nlohmann/json.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
#include "3gpp_23.003.h"
typedef struct subscribed_snssai_s { #include "Snssai.h"
snssai_t subscribed_snssai;
} subscribed_snssai_t; using namespace oai::amf::model;
namespace oai {
namespace amf {
namespace model {
typedef struct nsi_information_s { /// <summary>
std::string nrf_id; ///
// TODO: nsiId /// </summary>
// TODO: nrfNfMgtUri class Nssai {
// TODO: nrfAccessTokenUri public:
} nsi_information_t; Nssai();
virtual ~Nssai();
typedef struct allowed_snssai_s { void validate();
snssai_t allowed_snssai;
std::vector<nsi_information_t> nsi_information_list;
snssai_t mapped_home_snssai;
} allowed_snssai_t;
typedef struct allowed_nssai_s { /////////////////////////////////////////////
std::vector<allowed_snssai_t> allowed_snssai_list; /// Nssai members
std::string access_type;
} allowed_nssai_t;
typedef struct mapping_of_snssai_s { /// <summary>
snssai_t serving_snssai; ///
snssai_t home_snssai; /// </summary>
} mapping_of_snssai_t; std::string getSupportedFeatures() const;
void setSupportedFeatures(std::string const& value);
bool supportedFeaturesIsSet() const;
void unsetSupportedFeatures();
/// <summary>
///
/// </summary>
std::vector<Snssai>& getDefaultSingleNssais();
/// <summary>
///
/// </summary>
std::vector<Snssai>& getSingleNssais();
bool singleNssaisIsSet() const;
void unsetSingleNssais();
typedef struct slice_info_for_registration_s { friend void to_json(nlohmann::json& j, const Nssai& o);
std::vector<subscribed_snssai_t> subscribed_nssai; friend void from_json(const nlohmann::json& j, Nssai& o);
std::vector<allowed_nssai_t> allowed_nssai_current_access;
// allowed_nssai_other_access
std::vector<snssai_t> sNssai_for_mapping;
std::vector<snssai_t> requested_nssai;
bool default_configured_snssai_ind;
std::vector<mapping_of_snssai_t> mapping_of_nssai;
bool request_mapping;
} slice_info_for_registration_t;
typedef struct configured_snssai_s { protected:
snssai_t configured_snssai; std::string m_SupportedFeatures;
snssai_t mapped_home_snssai; bool m_SupportedFeaturesIsSet;
} configured_snssai_t; std::vector<Snssai> m_DefaultSingleNssais;
typedef struct authorized_network_slice_info_s { std::vector<Snssai> m_SingleNssais;
std::vector<allowed_nssai_t> allowed_nssai_list; bool m_SingleNssaisIsSet;
std::vector<configured_snssai_t> configured_nssai; };
std::string target_amf_set;
std::vector<std::string> candidate_amf_list;
std::vector<snssai_t> rejected_nssai_in_plmn;
std::vector<snssai_t> rejected_nssai_in_ta;
nsi_information_t nsi_information;
// SupportedFeatures
std::string nrf_amf_set;
std::string nrf_amf_set_nf_mgt_uri;
std::string nrf_amf_set_access_token_uri;
} authorized_network_slice_info_t; } // namespace model
} // namespace amf
} // namespace oai
#endif #endif /* Nssai_H_ */
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "3gpp_29.518.h" #include "3gpp_29.518.h"
using namespace amf_application; using namespace amf_application;
using namespace oai::amf::model; // using namespace oai::amf::model;
namespace xgpp_conv { namespace xgpp_conv {
/* /*
......
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