Commit 182acb4d authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

First version for N1 Message Notify Procedure

parent ef5b7fa4
...@@ -874,6 +874,13 @@ void amf_app::add_promise( ...@@ -874,6 +874,13 @@ void amf_app::add_promise(
curl_handle_responses_n2_sm.emplace(id, p); curl_handle_responses_n2_sm.emplace(id, p);
} }
//---------------------------------------------------------------------------------------------
void amf_app::add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<nlohmann::json>>& p) {
std::unique_lock lock(m_curl_handle_responses_n11);
curl_handle_responses_n11.emplace(pid, p);
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void amf_app::trigger_process_response(uint32_t pid, std::string n2_sm) { void amf_app::trigger_process_response(uint32_t pid, std::string n2_sm) {
Logger::amf_app().debug( Logger::amf_app().debug(
...@@ -887,3 +894,18 @@ void amf_app::trigger_process_response(uint32_t pid, std::string n2_sm) { ...@@ -887,3 +894,18 @@ void amf_app::trigger_process_response(uint32_t pid, std::string n2_sm) {
curl_handle_responses_n2_sm.erase(pid); curl_handle_responses_n2_sm.erase(pid);
} }
} }
//------------------------------------------------------------------------------
void amf_app::trigger_process_response(
uint32_t pid, nlohmann::json& json_data) {
Logger::amf_app().debug(
"Trigger process response: Set promise with ID %u "
"to ready",
pid);
std::unique_lock lock(m_curl_handle_responses_n11);
if (curl_handle_responses_n11.count(pid) > 0) {
curl_handle_responses_n11[pid]->set_value(json_data);
// Remove this promise from list
curl_handle_responses_n11.erase(pid);
}
}
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "amf_module_from_config.hpp" #include "amf_module_from_config.hpp"
#include "amf_profile.hpp" #include "amf_profile.hpp"
#include "itti.hpp" #include "itti.hpp"
#include "itti_msg_n11.hpp"
#include "itti_msg_amf_app.hpp" #include "itti_msg_amf_app.hpp"
#include "ue_context.hpp" #include "ue_context.hpp"
#include "amf_subscription.hpp" #include "amf_subscription.hpp"
...@@ -268,11 +269,13 @@ class amf_app { ...@@ -268,11 +269,13 @@ class amf_app {
return util::uint_uid_generator<uint64_t>::get_instance().get_uid(); return util::uint_uid_generator<uint64_t>::get_instance().get_uid();
} }
void trigger_process_response(uint32_t pid, uint32_t http_code);
void add_promise( void add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<std::string>>& p); uint32_t pid, boost::shared_ptr<boost::promise<std::string>>& p);
void add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<nlohmann::json>>& p);
void trigger_process_response(uint32_t pid, uint32_t http_code);
void trigger_process_response(uint32_t pid, std::string n2_sm); void trigger_process_response(uint32_t pid, std::string n2_sm);
void trigger_process_response(uint32_t pid, nlohmann::json& json_data);
private: private:
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx; std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
...@@ -286,6 +289,10 @@ class amf_app { ...@@ -286,6 +289,10 @@ class amf_app {
mutable std::shared_mutex m_curl_handle_responses_n2_sm; mutable std::shared_mutex m_curl_handle_responses_n2_sm;
std::map<uint32_t, boost::shared_ptr<boost::promise<std::string>>> std::map<uint32_t, boost::shared_ptr<boost::promise<std::string>>>
curl_handle_responses_n2_sm; curl_handle_responses_n2_sm;
mutable std::shared_mutex m_curl_handle_responses_n11;
std::map<uint32_t, boost::shared_ptr<boost::promise<nlohmann::json>>>
curl_handle_responses_n11;
}; };
} // namespace amf_application } // namespace amf_application
......
...@@ -192,6 +192,12 @@ typedef struct { ...@@ -192,6 +192,12 @@ typedef struct {
std::string fqdn; std::string fqdn;
} smf_inst_t; } smf_inst_t;
typedef struct nf_addr_s {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nf_addr_t;
class amf_config { class amf_config {
public: public:
amf_config(); amf_config();
...@@ -228,7 +234,7 @@ class amf_config { ...@@ -228,7 +234,7 @@ class amf_config {
bool use_fqdn_dns; bool use_fqdn_dns;
bool use_http2; bool use_http2;
} support_features; } support_features;
/*
struct { struct {
struct in_addr ipv4_addr; struct in_addr ipv4_addr;
unsigned int port; unsigned int port;
...@@ -241,11 +247,22 @@ class amf_config { ...@@ -241,11 +247,22 @@ class amf_config {
std::string api_version; std::string api_version;
} ausf_addr; } ausf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} udm_addr;
struct { struct {
struct in_addr ipv4_addr; struct in_addr ipv4_addr;
unsigned int port; unsigned int port;
std::string api_version; std::string api_version;
} nssf_addr; } nssf_addr;
*/
nf_addr_t nrf_addr;
nf_addr_t ausf_addr;
nf_addr_t udm_addr;
nf_addr_t nssf_addr;
}; };
} // namespace config } // namespace config
......
...@@ -3740,15 +3740,75 @@ bool amf_n1::check_requested_nssai( ...@@ -3740,15 +3740,75 @@ bool amf_n1::check_requested_nssai(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
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 { const std::shared_ptr<nas_context>& nc, nssai_t& 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 = {};
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;
}
std::shared_ptr<itti_n11_slice_selection_subscription_data> itti_msg =
std::make_shared<itti_n11_slice_selection_subscription_data>(
TASK_AMF_N1, TASK_AMF_N11);
// Generate a promise and associate this promise to the ITTI message
uint32_t promise_id = amf_app_inst->generate_promise_id();
Logger::amf_n1().debug("Promise ID generated %d", promise_id);
boost::shared_ptr<boost::promise<nlohmann::json>> p =
boost::make_shared<boost::promise<nlohmann::json>>();
boost::shared_future<nlohmann::json> f = p->get_future();
amf_app_inst->add_promise(promise_id, p);
itti_msg->http_version = 1;
itti_msg->supi = uc.get()->supi;
itti_msg->plmn.mcc = uc.get()->cgi.mcc;
itti_msg->plmn.mnc = uc.get()->cgi.mnc;
itti_msg->promise_id = promise_id;
int ret = itti_inst->send_msg(itti_msg);
if (0 != ret) {
Logger::ngap().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
itti_msg->get_msg_name());
}
bool result = false;
boost::future_status status;
// wait for timeout or ready
status = f.wait_for(boost::chrono::milliseconds(FUTURE_STATUS_TIMEOUT_MS));
if (status == boost::future_status::ready) {
assert(f.is_ready());
assert(f.has_value());
assert(!f.has_exception());
// Wait for the result from APP and send reply to AMF
nlohmann::json nssai = f.get();
if (!nssai.empty()) {
Logger::ngap().debug("Got NSSAI from UDM", nssai.dump().c_str());
} else {
return false;
}
} else {
return false;
}
} else { } else {
// TODO: get from the conf file // TODO: get from the conf file
return get_slice_selection_subscription_data_from_conf_file(nc, nssai);
} }
return true; return true;
} }
//------------------------------------------------------------------------------
bool amf_n1::get_slice_selection_subscription_data_from_conf_file(
const std::shared_ptr<nas_context>& nc, nssai_t& nssai) {
// TODO:
return true;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool amf_n1::get_network_slice_selection( bool amf_n1::get_network_slice_selection(
const std::string& nf_instance_id, const std::string& nf_instance_id,
......
...@@ -221,12 +221,14 @@ class amf_n1 { ...@@ -221,12 +221,14 @@ 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; const std::shared_ptr<nas_context>& nc, nssai_t& nssai);
bool get_slice_selection_subscription_data_from_conf_file(
const std::shared_ptr<nas_context>& nc, nssai_t& 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, const nssai_t& nssai) const;
bool get_network_slice_selection( bool get_network_slice_selection(
const std::string& nf_instance_id, const std::string& nf_instance_id,
slice_info_fo_registration_t& slice_info, slice_info_for_registration_t& slice_info,
authorized_network_slice_info_t& authorized_network_slice_info) const; authorized_network_slice_info_t& authorized_network_slice_info) const;
void send_n1_message_notity( void send_n1_message_notity(
const std::shared_ptr<nas_context>& nc, const std::shared_ptr<nas_context>& nc,
......
...@@ -137,6 +137,15 @@ void amf_n11_task(void*) { ...@@ -137,6 +137,15 @@ void amf_n11_task(void*) {
dynamic_cast<itti_sbi_notify_subscribed_event*>(msg); dynamic_cast<itti_sbi_notify_subscribed_event*>(msg);
amf_n11_inst->handle_itti_message(ref(*m)); amf_n11_inst->handle_itti_message(ref(*m));
} break; } break;
case N11_SLICE_SELECTION_SUBSCRIPTION_DATA: {
Logger::amf_n11().info(
"Receive Slice Selection Subscription Data Retrieval Request, "
"handling ...");
itti_n11_slice_selection_subscription_data* m =
dynamic_cast<itti_n11_slice_selection_subscription_data*>(msg);
amf_n11_inst->handle_itti_message(ref(*m));
} break;
case TERMINATE: { case TERMINATE: {
if (itti_msg_terminate* terminate = if (itti_msg_terminate* terminate =
dynamic_cast<itti_msg_terminate*>(msg)) { dynamic_cast<itti_msg_terminate*>(msg)) {
...@@ -570,6 +579,91 @@ void amf_n11::handle_itti_message(itti_sbi_notify_subscribed_event& itti_msg) { ...@@ -570,6 +579,91 @@ void amf_n11::handle_itti_message(itti_sbi_notify_subscribed_event& itti_msg) {
return; return;
} }
//------------------------------------------------------------------------------
void amf_n11::handle_itti_message(
itti_n11_slice_selection_subscription_data& itti_msg) {
Logger::amf_n11().debug(
"Send Slice Selection Subscription Data Retrieval to UDM (HTTP version "
"%d)",
itti_msg.http_version);
std::string url =
std::string(inet_ntoa(*((struct in_addr*) &amf_cfg.udm_addr.ipv4_addr))) +
":" + std::to_string(amf_cfg.udm_addr.port) + "/nudm-sdm/" +
amf_cfg.udm_addr.api_version + "/" + itti_msg.supi + "/nssai";
nlohmann::json json_data = {};
json_data["plmn-id"]["mcc"] = itti_msg.plmn.mcc;
json_data["plmn-id"]["mnc"] = itti_msg.plmn.mnc;
std::string body = json_data.dump();
Logger::amf_n11().debug(
"Send Slice Selection Subscription Data Retrieval to UDM, URL %s",
url.c_str());
Logger::amf_n11().debug("MSG body: \n %s", body.c_str());
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl = curl_easy_init();
std::unique_ptr<std::string> httpData(new std::string());
nlohmann::json response_data = {};
if (curl) {
CURLcode res = {};
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, amf_cfg.n11.if_name.c_str());
if (itti_msg.http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
Logger::amf_n11().debug("Response from UDM, HTTP Code: %d", httpCode);
if (static_cast<http_response_codes_e>(httpCode) !=
http_response_codes_e::HTTP_RESPONSE_CODE_200_OK) {
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception& e) {
Logger::amf_n11().warn("Could not parse JSON from the UDM response");
}
} else {
Logger::amf_n11().warn("Could not get NSSAI from UDM");
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
// Notify to the result
if (itti_msg.promise_id > 0) {
amf_app_inst->trigger_process_response(itti_msg.promise_id, response_data);
return;
}
return;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool amf_n11::smf_selection_from_configuration( bool amf_n11::smf_selection_from_configuration(
std::string& smf_addr, std::string& smf_api_version) { std::string& smf_addr, std::string& smf_api_version) {
......
...@@ -59,6 +59,8 @@ class amf_n11 { ...@@ -59,6 +59,8 @@ class amf_n11 {
void handle_itti_message(itti_nsmf_pdusession_release_sm_context& itti_msg); void handle_itti_message(itti_nsmf_pdusession_release_sm_context& itti_msg);
void handle_itti_message(itti_pdu_session_resource_setup_response& itti_msg); void handle_itti_message(itti_pdu_session_resource_setup_response& itti_msg);
void handle_itti_message(itti_sbi_notify_subscribed_event& itti_msg); void handle_itti_message(itti_sbi_notify_subscribed_event& itti_msg);
void handle_itti_message(
itti_n11_slice_selection_subscription_data& itti_msg);
void send_pdu_session_update_sm_context_request( void send_pdu_session_update_sm_context_request(
std::string supi, std::shared_ptr<pdu_session_context> psc, std::string supi, std::shared_ptr<pdu_session_context> psc,
......
...@@ -205,6 +205,7 @@ class itti_n11_slice_selection_subscription_data : public itti_msg_n11 { ...@@ -205,6 +205,7 @@ class itti_n11_slice_selection_subscription_data : public itti_msg_n11 {
uint8_t http_version; uint8_t http_version;
std::string supi; std::string supi;
plmn_t plmn; plmn_t plmn;
uint32_t promise_id;
}; };
#endif #endif
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