Commit f8572110 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Add NFDeregister operation

parent 98aa771b
......@@ -609,4 +609,18 @@ class itti_n11_update_nf_instance_response : public itti_n11_msg {
uint8_t http_response_code;
};
//-----------------------------------------------------------------------------
class itti_n11_deregister_nf_instance : public itti_n11_msg {
public:
itti_n11_deregister_nf_instance(const task_id_t orig,
const task_id_t dest)
: itti_n11_msg(N11_DEREGISTER_NF_INSTANCE, orig, dest),
http_version(1) {}
const char *get_msg_name() { return "N11_DEREGISTER_NF_INSTANCE"; };
uint8_t http_version;
std::string smf_instance_id;
};
#endif /* ITTI_MSG_N11_HPP_INCLUDED_ */
......@@ -206,6 +206,7 @@ typedef struct qos_profile_s {
//NRF
#define NNRF_NFM_BASE "/nnrf-nfm/"
#define NNRF_NF_REGISTER_URL "/nf-instances/"
#define NRF_CURL_TIMEOUT_MS 100L
//for CURL
#define AMF_CURL_TIMEOUT_MS 100L
......
......@@ -120,6 +120,7 @@ typedef enum {
N11_REGISTER_NF_INSTANCE_RESPONSE,
N11_UPDATE_NF_INSTANCE_REQUEST,
N11_UPDATE_NF_INSTANCE_RESPONSE,
N11_DEREGISTER_NF_INSTANCE,
NX_TRIGGER_SESSION_MODIFICATION,
SBI_EVENT_EXPOSURE_REQUEST,
UDP_INIT,
......
......@@ -279,6 +279,10 @@ void smf_app_task(void *) {
smf_app_inst->timer_nrf_heartbeat_timeout(to->timer_id,
to->arg2_user);
break;
case TASK_SMF_APP_TIMEOUT_NRF_DEREGISTRATION:
smf_app_inst->timer_nrf_deregistration(to->timer_id,
to->arg2_user);
break;
default:;
}
}
......@@ -574,7 +578,6 @@ void smf_app::handle_itti_msg(itti_n11_release_sm_context_response &m) {
void smf_app::handle_itti_msg(itti_n11_register_nf_instance_response &r) {
Logger::smf_app().debug("NF Instance Registration response");
// TODO: Update profile if necessary
nf_profile = r.profile;
// Set heartbeat timer
Logger::smf_app().debug("Set NRF Heartbeat timer (%d)",
......@@ -583,6 +586,12 @@ void smf_app::handle_itti_msg(itti_n11_register_nf_instance_response &r) {
itti_inst->timer_setup(r.profile.get_nf_heartBeat_timer(), 0,
TASK_SMF_APP, TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT,
0); // TODO arg2_user
//Set timer to send NF Deregistration (for testing purpose)
/* itti_inst->timer_setup(50, 0,
TASK_SMF_APP, TASK_SMF_APP_TIMEOUT_NRF_DEREGISTRATION,
0); // TODO arg2_user
*/
}
//------------------------------------------------------------------------------
......@@ -1422,7 +1431,6 @@ void smf_app::timer_t3591_timeout(timer_id_t timer_id, uint64_t arg2_user) {
//---------------------------------------------------------------------------------------------
void smf_app::timer_nrf_heartbeat_timeout(timer_id_t timer_id,
uint64_t arg2_user) {
// TODO: send Heatbeat to NRF
Logger::smf_app().debug("Send ITTI msg to N11 task to trigger NRF Heartbeat");
std::shared_ptr<itti_n11_update_nf_instance_request> itti_msg =
......@@ -1443,16 +1451,8 @@ void smf_app::timer_nrf_heartbeat_timeout(timer_id_t timer_id,
"Could not send ITTI message %s to task TASK_SMF_N11",
itti_msg->get_msg_name());
} else {
uint64_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
Logger::smf_app().debug(
"Subscribe to task tick to be noticed when the Heartbearttimer (%d) "
"expires (after NF update) %ld, %d",
10, ms, ms % (10 * 1000));
// Set heartbeat timer
Logger::smf_app().debug("Set a timer to the next Heart-beat (%d)",
nf_profile.get_nf_heartBeat_timer());
timer_nrf_heartbeat =
itti_inst->timer_setup(nf_profile.get_nf_heartBeat_timer(), 0,
TASK_SMF_APP, TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT,
......@@ -1460,6 +1460,14 @@ void smf_app::timer_nrf_heartbeat_timeout(timer_id_t timer_id,
}
}
//---------------------------------------------------------------------------------------------
void smf_app::timer_nrf_deregistration(timer_id_t timer_id,
uint64_t arg2_user) {
Logger::smf_app().debug("Send ITTI msg to N11 task to trigger NRF Deregistratino");
trigger_nf_deregistration();
}
//---------------------------------------------------------------------------------------------
n2_sm_info_type_e smf_app::n2_sm_info_type_str2e(
const std::string &n2_info_type) const {
......@@ -1835,3 +1843,21 @@ void smf_app::trigger_nf_registration_request() {
itti_msg->get_msg_name());
}
}
//------------------------------------------------------------------------------
void smf_app::trigger_nf_deregistration() {
Logger::smf_app().debug(
"Send ITTI msg to N11 task to trigger the deregistration request to NRF");
std::shared_ptr<itti_n11_deregister_nf_instance> itti_msg =
std::make_shared<itti_n11_deregister_nf_instance>(TASK_SMF_APP,
TASK_SMF_N11);
itti_msg->smf_instance_id = smf_instance_id;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
itti_msg->get_msg_name());
}
}
......@@ -61,6 +61,7 @@ namespace smf {
#define TASK_SMF_APP_TRIGGER_T3592 (2)
#define TASK_SMF_APP_TIMEOUT_T3592 (3)
#define TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT (4)
#define TASK_SMF_APP_TIMEOUT_NRF_DEREGISTRATION (5)
// Table 10.3.2 @3GPP TS 24.501 V16.1.0 (2019-06)
#define T3591_TIMER_VALUE_SEC 16
......@@ -193,6 +194,14 @@ class smf_app {
public:
explicit smf_app(const std::string &config_file);
smf_app(smf_app const &) = delete;
virtual ~smf_app() {
Logger::smf_app().debug("Delete SMF_APP instance...");
//TODO: disconnect connections
//Unregister NRF
}
void operator=(smf_app const &) = delete;
/*
......@@ -631,6 +640,7 @@ class smf_app {
*/
void timer_nrf_heartbeat_timeout(timer_id_t timer_id, uint64_t arg2_user);
void timer_nrf_deregistration(timer_id_t timer_id, uint64_t arg2_user);
/*
* To start an association with a UPF (SMF-initiated association)
* @param [const pfcp::node_id_t] node_id: UPF Node ID
......@@ -806,6 +816,14 @@ class smf_app {
* @return void
*/
void trigger_nf_registration_request();
/*
* Send request to N11 task to trigger NF instance deregistration to NRF
* @param [void]
* @return void
*/
void trigger_nf_deregistration();
};
}
#include "smf_config.hpp"
......
......@@ -118,6 +118,12 @@ void smf_n11_task(void *args_p) {
shared_msg));
break;
case N11_DEREGISTER_NF_INSTANCE:
smf_n11_inst->deregister_nf_instance(
std::static_pointer_cast<itti_n11_deregister_nf_instance>(
shared_msg));
break;
case TERMINATE:
if (itti_msg_terminate *terminate =
dynamic_cast<itti_msg_terminate *>(msg)) {
......@@ -671,8 +677,8 @@ void smf_n11::register_nf_instance(
url.c_str());
std::string body = json_data.dump();
Logger::smf_n11().debug("Send NF Instance Registration to NRF, msg body: \n %s",
body.c_str());
Logger::smf_n11().debug(
"Send NF Instance Registration to NRF, msg body: \n %s", body.c_str());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
......@@ -686,7 +692,7 @@ void smf_n11::register_nf_instance(
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NRF_CURL_TIMEOUT_MS);
if (msg->http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
......@@ -717,7 +723,8 @@ void smf_n11::register_nf_instance(
} catch (json::exception &e) {
Logger::smf_n11().warn("Could not parse json from the NRF response");
}
Logger::smf_n11().debug("Response from NRF, Json data: \n %s", response_data.dump().c_str());
Logger::smf_n11().debug("Response from NRF, Json data: \n %s",
response_data.dump().c_str());
// send response to APP to process
std::shared_ptr<itti_n11_register_nf_instance_response> itti_msg =
......@@ -747,9 +754,8 @@ void smf_n11::register_nf_instance(
//-----------------------------------------------------------------------------------------------------
void smf_n11::update_nf_instance(
std::shared_ptr<itti_n11_update_nf_instance_request> msg) {
Logger::smf_n11().debug(
"Send NF Update to NRF (HTTP version %d)",
msg->http_version);
Logger::smf_n11().debug("Send NF Update to NRF (HTTP version %d)",
msg->http_version);
nlohmann::json json_data = nlohmann::json::array();
for (auto i : msg->patch_items) {
......@@ -758,8 +764,7 @@ void smf_n11::update_nf_instance(
json_data.push_back(item);
}
std::string body = json_data.dump();
Logger::smf_n11().debug("Send NF Update to NRF (Msg body %s)",
body.c_str());
Logger::smf_n11().debug("Send NF Update to NRF (Msg body %s)", body.c_str());
std::string url =
std::string(inet_ntoa(*((struct in_addr *)&smf_cfg.nrf_addr.ipv4_addr))) +
......@@ -781,7 +786,7 @@ void smf_n11::update_nf_instance(
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NRF_CURL_TIMEOUT_MS);
if (msg->http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
......@@ -805,28 +810,93 @@ void smf_n11::update_nf_instance(
Logger::smf_n11().debug("Response from NRF, Http Code: %d", httpCode);
if ((static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_OK) or (static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_NO_CONTENT)) {
Logger::smf_n11().debug("Got successful response from NRF");
//TODO: in case of response containing NF profile
// send response to APP to process
std::shared_ptr<itti_n11_update_nf_instance_response> itti_msg =
std::make_shared<itti_n11_update_nf_instance_response>(
TASK_SMF_N11, TASK_SMF_APP);
itti_msg->http_response_code = httpCode;
itti_msg->http_version = msg->http_version;
itti_msg->smf_instance_id = msg->smf_instance_id;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_n11().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
} else {
Logger::smf_n11().warn("Could not get response from NRF");
http_response_codes_e::HTTP_RESPONSE_CODE_OK) or
(static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_NO_CONTENT)) {
Logger::smf_n11().debug("Got successful response from NRF");
// TODO: in case of response containing NF profile
// send response to APP to process
std::shared_ptr<itti_n11_update_nf_instance_response> itti_msg =
std::make_shared<itti_n11_update_nf_instance_response>(TASK_SMF_N11,
TASK_SMF_APP);
itti_msg->http_response_code = httpCode;
itti_msg->http_version = msg->http_version;
itti_msg->smf_instance_id = msg->smf_instance_id;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_n11().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
} else {
Logger::smf_n11().warn("Could not get response from NRF");
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
//-----------------------------------------------------------------------------------------------------
void smf_n11::deregister_nf_instance(
std::shared_ptr<itti_n11_deregister_nf_instance> msg) {
Logger::smf_n11().debug("Send NF De-register to NRF (HTTP version %d)",
msg->http_version);
std::string url =
std::string(inet_ntoa(*((struct in_addr *)&smf_cfg.nrf_addr.ipv4_addr))) +
":" + std::to_string(smf_cfg.nrf_addr.port) + NNRF_NFM_BASE +
smf_cfg.nrf_addr.api_version + NNRF_NF_REGISTER_URL +
msg->smf_instance_id;
Logger::smf_n11().debug("Send NF De-register to NRF (NRF URL %s)",
url.c_str());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
if (curl) {
CURLcode res = {};
struct curl_slist *headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
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_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NRF_CURL_TIMEOUT_MS);
if (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());
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
Logger::smf_n11().debug("Response from NRF, Http Code: %d", httpCode);
if ((static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_OK) or
(static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_NO_CONTENT)) {
Logger::smf_n11().debug("Got successful response from NRF");
} else {
Logger::smf_n11().warn("Could not get response from NRF");
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
......
......@@ -115,6 +115,14 @@ class smf_n11 {
void update_nf_instance(
std::shared_ptr<itti_n11_update_nf_instance_request> msg);
/*
* Send NF deregister to NRF
* @param [std::shared_ptr<itti_n11_deregister_nf_instance>] msg: Content
* of message to be sent
* @return void
*/
void deregister_nf_instance(
std::shared_ptr<itti_n11_deregister_nf_instance> msg);
/*
* Create Curl handle for multi curl
* @param [event_notification&] ev_notif: content of the event notification
......
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