Commit 98aa771b authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Fix issue for NF Update (Heartbeat)

parent 1e932480
......@@ -595,5 +595,18 @@ class itti_n11_update_nf_instance_request : public itti_n11_msg {
std::string smf_instance_id;
};
//-----------------------------------------------------------------------------
class itti_n11_update_nf_instance_response : public itti_n11_msg {
public:
itti_n11_update_nf_instance_response(const task_id_t orig,
const task_id_t dest)
: itti_n11_msg(N11_UPDATE_NF_INSTANCE_RESPONSE, orig, dest),
http_version(1) {}
const char *get_msg_name() { return "N11_UPDATE_NF_INSTANCE_RESPONSE"; };
uint8_t http_version;
std::string smf_instance_id;
uint8_t http_response_code;
};
#endif /* ITTI_MSG_N11_HPP_INCLUDED_ */
......@@ -119,6 +119,7 @@ typedef enum {
N11_REGISTER_NF_INSTANCE_REQUEST,
N11_REGISTER_NF_INSTANCE_RESPONSE,
N11_UPDATE_NF_INSTANCE_REQUEST,
N11_UPDATE_NF_INSTANCE_RESPONSE,
NX_TRIGGER_SESSION_MODIFICATION,
SBI_EVENT_EXPOSURE_REQUEST,
UDP_INIT,
......
......@@ -29,11 +29,11 @@
#include "smf_app.hpp"
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "3gpp_24.007.h"
#include "3gpp_24.501.h"
......@@ -261,6 +261,13 @@ void smf_app_task(void *) {
}
break;
case N11_UPDATE_NF_INSTANCE_RESPONSE:
if (itti_n11_update_nf_instance_response *m =
dynamic_cast<itti_n11_update_nf_instance_response *>(msg)) {
smf_app_inst->handle_itti_msg(std::ref(*m));
}
break;
case TIME_OUT:
if (itti_msg_timeout *to = dynamic_cast<itti_msg_timeout *>(msg)) {
Logger::smf_app().info("TIME-OUT event timer id %d", to->timer_id);
......@@ -269,7 +276,8 @@ void smf_app_task(void *) {
smf_app_inst->timer_t3591_timeout(to->timer_id, to->arg2_user);
break;
case TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT:
smf_app_inst->timer_nrf_heartbeat_timeout(to->timer_id, to->arg2_user);
smf_app_inst->timer_nrf_heartbeat_timeout(to->timer_id,
to->arg2_user);
break;
default:;
}
......@@ -330,7 +338,7 @@ smf_app::smf_app(const std::string &config_file)
start_upf_association(*it);
}
//Register to NRF
// Register to NRF
register_to_nrf();
Logger::smf_app().startup("Started");
......@@ -562,15 +570,34 @@ 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");
//Set heartbeat timer
timer_nrf_heartbeat = itti_inst->timer_setup(
r.profile.get_nf_heartBeat_timer(), 0, TASK_SMF_APP, TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT,
0); //TODO arg2_user
// TODO: Update profile if necessary
nf_profile = r.profile;
// Set heartbeat timer
Logger::smf_app().debug("Set NRF Heartbeat timer (%d)",
r.profile.get_nf_heartBeat_timer());
timer_nrf_heartbeat =
itti_inst->timer_setup(r.profile.get_nf_heartBeat_timer(), 0,
TASK_SMF_APP, TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT,
0); // TODO arg2_user
}
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(itti_n11_update_nf_instance_response &u) {
Logger::smf_app().debug("NF Update NF response");
Logger::smf_app().debug("Set NRF Heartbeat timer (%d)",
nf_profile.get_nf_heartBeat_timer());
// Set 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, 0); //TODO arg2_user
}
//------------------------------------------------------------------------------
void smf_app::handle_pdu_session_create_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_request> smreq) {
......@@ -614,7 +641,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
return;
}
//Fill the mandatory IEs
// Fill the mandatory IEs
smreq->req.set_epd(decoded_nas_msg.header.extended_protocol_discriminator);
pdu_session_id_t pdu_session_id =
decoded_nas_msg.plain.sm.header.pdu_session_identity;
......@@ -759,7 +786,8 @@ void smf_app::handle_pdu_session_create_sm_context_request(
Logger::smf_app().warn("Invalid request type (request type = %s)",
request_type.c_str());
//"Existing PDU Session", AMF should use PDUSession_UpdateSMContext instead
//(see step 3, section 4.3.2.2.1 @ 3GPP TS 23.502 v16.0.0) ignore the message
//(see step 3, section 4.3.2.2.1 @ 3GPP TS 23.502 v16.0.0) ignore the
//message
return;
}
......@@ -1402,10 +1430,10 @@ void smf_app::timer_nrf_heartbeat_timeout(timer_id_t timer_id,
TASK_SMF_N11);
oai::smf_server::model::PatchItem patch_item = {};
//{"op":"replace","path":"/nfInstanceName", "value": "OAI-SMF"}
//{"op":"replace","path":"/nfStatus", "value": "REGISTERED"}
patch_item.setOp("replace");
patch_item.setPath("/nfInstanceName");
patch_item.setValue("OAI-SMF");
patch_item.setPath("/nfStatus");
patch_item.setValue("REGISTERED");
itti_msg->patch_items.push_back(patch_item);
itti_msg->smf_instance_id = smf_instance_id;
......@@ -1414,6 +1442,21 @@ void smf_app::timer_nrf_heartbeat_timeout(timer_id_t timer_id,
Logger::smf_app().error(
"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
timer_nrf_heartbeat =
itti_inst->timer_setup(nf_profile.get_nf_heartBeat_timer(), 0,
TASK_SMF_APP, TASK_SMF_APP_TIMEOUT_NRF_HEARTBEAT,
0); // TODO arg2_user
}
}
......@@ -1472,7 +1515,8 @@ bool smf_app::get_session_management_subscription_data(
dnn_configuration->_5g_qos_profile._5qi =
smf_cfg.session_management_subscription[i].default_qos._5qi;
dnn_configuration->_5g_qos_profile.arp.priority_level =
smf_cfg.session_management_subscription[i].default_qos.arp.priority_level;
smf_cfg.session_management_subscription[i]
.default_qos.arp.priority_level;
dnn_configuration->_5g_qos_profile.arp.preempt_cap =
smf_cfg.session_management_subscription[i]
.default_qos.arp.preempt_cap;
......@@ -1480,8 +1524,7 @@ bool smf_app::get_session_management_subscription_data(
smf_cfg.session_management_subscription[i]
.default_qos.arp.preempt_vuln;
dnn_configuration->_5g_qos_profile.priority_level =
smf_cfg.session_management_subscription[i]
.default_qos.priority_level;
smf_cfg.session_management_subscription[i].default_qos.priority_level;
// session_ambr
dnn_configuration->session_ambr.uplink =
......@@ -1735,8 +1778,15 @@ void smf_app::generate_smf_profile() {
nf_profile.set_nf_priority(1);
nf_profile.set_nf_capacity(100);
nf_profile.add_nf_ipv4_addresses(smf_cfg.sbi.addr4);
// custom info
// TODO: custom info
int i = 0;
for (auto s : smf_cfg.session_management_subscription) {
if (i < smf_cfg.num_session_management_subscription)
i++;
else
break;
// SNSSAIS
snssai_t snssai = {};
snssai.sD = s.single_nssai.sD;
......@@ -1751,6 +1801,9 @@ void smf_app::generate_smf_profile() {
smf_info_item.snssai.sST = s.single_nssai.sST;
nf_profile.add_smf_info_item(smf_info_item);
}
// Display the profile
nf_profile.display();
}
//---------------------------------------------------------------------------------------------
......
......@@ -353,6 +353,13 @@ class smf_app {
*/
void handle_itti_msg(itti_n11_register_nf_instance_response &r);
/*
* Handle ITTI message from N11 (NFUpdate Response)
* @param [itti_n11_update_nf_instance_response&] u
* @return void
*/
void handle_itti_msg(itti_n11_update_nf_instance_response &u);
/*
* Restore a N4 Session
* @param [const seid_t &] seid: Session ID to be restored
......
......@@ -671,7 +671,7 @@ 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 %s)",
Logger::smf_n11().debug("Send NF Instance Registration to NRF, msg body: \n %s",
body.c_str());
curl_global_init(CURL_GLOBAL_ALL);
......@@ -707,19 +707,17 @@ void smf_n11::register_nf_instance(
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
Logger::smf_n11().debug("Response from AMF, Http Code: %d", 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_CREATED) {
Logger::smf_n11().debug("Got successful response from NRF");
json response_data = {};
try {
response_data = json::parse(*httpData.get());
} catch (json::exception &e) {
Logger::smf_n11().warn("Could not parse json from the NRF response");
}
Logger::smf_n11().debug("Response from NRF, Http Code: %d", httpCode);
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 =
......@@ -727,6 +725,7 @@ void smf_n11::register_nf_instance(
TASK_SMF_N11, TASK_SMF_APP);
itti_msg->http_response_code = httpCode;
itti_msg->http_version = msg->http_version;
Logger::smf_app().debug("Registered SMF profile (from NRF)");
itti_msg->profile.from_json(response_data);
int ret = itti_inst->send_msg(itti_msg);
......@@ -749,7 +748,7 @@ 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 Instance Registration to NRF (HTTP version %d)",
"Send NF Update to NRF (HTTP version %d)",
msg->http_version);
nlohmann::json json_data = nlohmann::json::array();
......@@ -759,7 +758,7 @@ void smf_n11::update_nf_instance(
json_data.push_back(item);
}
std::string body = json_data.dump();
Logger::smf_n11().debug("Send NF Instance Registration to NRF (Msg body %s)",
Logger::smf_n11().debug("Send NF Update to NRF (Msg body %s)",
body.c_str());
std::string url =
......@@ -804,6 +803,31 @@ void smf_n11::update_nf_instance(
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");
//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);
}
......
......@@ -147,9 +147,7 @@ void smf_profile::set_custom_info(const nlohmann::json &c) { custom_info = c; }
void smf_profile::get_custom_info(nlohmann::json &c) const { c = custom_info; }
//------------------------------------------------------------------------------
void smf_profile::set_smf_info(const smf_info_t &s) {
smf_info = s;
}
void smf_profile::set_smf_info(const smf_info_t &s) { smf_info = s; }
//------------------------------------------------------------------------------
void smf_profile::add_smf_info_item(const snssai_smf_info_item_t &s) {
......@@ -157,9 +155,7 @@ void smf_profile::add_smf_info_item(const snssai_smf_info_item_t &s) {
}
//------------------------------------------------------------------------------
void smf_profile::get_smf_info(smf_info_t &s) const {
s = smf_info;
}
void smf_profile::get_smf_info(smf_info_t &s) const { s = smf_info; }
//------------------------------------------------------------------------------
void smf_profile::display() {
......@@ -174,18 +170,37 @@ void smf_profile::display() {
Logger::smf_app().debug("\tPriority: %d", priority);
Logger::smf_app().debug("\tCapacity: %d", capacity);
// SNSSAIs
if (snssais.size() > 0) {
Logger::smf_app().debug("\tSNSSAI:");
}
for (auto s : snssais) {
Logger::smf_app().debug("\tNNSSAI(SST, SD): %d, %s", s.sST, s.sD.c_str());
Logger::smf_app().debug("\t\t SST, SD: %d, %s", s.sST, s.sD.c_str());
}
// IPv4 Addresses
if (ipv4_addresses.size() > 0) {
Logger::smf_app().debug("\tIPv4 Addr:");
}
for (auto address : ipv4_addresses) {
Logger::smf_app().debug("\tIPv4 Addr: %s", inet_ntoa(address));
Logger::smf_app().debug("\t\t %s", inet_ntoa(address));
}
if (!custom_info.empty()) {
Logger::smf_app().debug("\tCustom info: %s", custom_info.dump().c_str());
}
// SMF info
if (smf_info.snssai_smf_info_list.size() > 0) {
Logger::smf_app().debug("\tSMF Info:");
}
for (auto s : smf_info.snssai_smf_info_list) {
Logger::smf_app().debug("\t\tParameters supported by the SMF:");
Logger::smf_app().debug("\t\t\tSNSSAI (SST %d, SD %s)", s.snssai.sST,
s.snssai.sD.c_str());
for (auto d : s.dnn_smf_info_list) {
Logger::smf_app().debug("\t\t\tDNN %s", d.dnn.c_str());
}
}
}
//------------------------------------------------------------------------------
......@@ -214,11 +229,28 @@ void smf_profile::to_json(nlohmann::json &data) const {
data["priority"] = priority;
data["capacity"] = capacity;
data["custom_info"] = custom_info;
// SMF info
data["smfInfo"] = {};
data["smfInfo"]["sNssaiSmfInfoList"] = nlohmann::json::array();
for (auto s : smf_info.snssai_smf_info_list) {
nlohmann::json tmp = {};
tmp["sNssai"]["sst"] = s.snssai.sST;
tmp["sNssai"]["sd"] = s.snssai.sD;
tmp["dnnSmfInfoList"] = nlohmann::json::array();
for (auto d : s.dnn_smf_info_list) {
nlohmann::json dnn_json = {};
dnn_json["dnn"] = d.dnn;
tmp["dnnSmfInfoList"].push_back(dnn_json);
}
data["smfInfo"]["sNssaiSmfInfoList"].push_back(tmp);
}
Logger::smf_app().debug("SMF profile to json:\n %s", data.dump().c_str());
}
//------------------------------------------------------------------------------
void smf_profile::from_json(const nlohmann::json &data) {
if (data.find("nfInstanceId") != data.end()) {
nf_instance_id = data["nfInstanceId"].get<std::string>();
}
......@@ -235,17 +267,61 @@ void smf_profile::from_json(const nlohmann::json &data) {
nf_status = data["nfStatus"].get<std::string>();
}
if (data.find("heartBeatTimer") != data.end()) {
heartBeat_timer = data["heartBeatTimer"].get<int>();
}
// sNssais
if (data.find("sNssais") != data.end()) {
for (auto it : data["sNssais"]) {
snssai_t s = {};
s.sST = it["sst"].get<int>();
s.sD = it["sd"].get<std::string>();
snssais.push_back(s);
// Logger::smf_app().debug("Added SNSSAI (SST %d, SD %s)", s.sST,
// s.sD.c_str());
}
}
if (data.find("ipv4Addresses") != data.end()) {
nlohmann::json addresses = data["ipv4Addresses"];
for (auto it : addresses) {
struct in_addr addr4 = {};
std::string address = it.get<std::string>();
unsigned char buf_in_addr[sizeof(struct in_addr)];
if (inet_pton(AF_INET, util::trim(address).c_str(), buf_in_addr) == 1) {
memcpy(&addr4, buf_in_addr, sizeof(struct in_addr));
} else {
Logger::smf_app().warn("Address conversion: Bad value %s",
util::trim(address).c_str());
}
// Logger::smf_app().debug("\tIPv4 Addr: %s", address.c_str());
add_nf_ipv4_addresses(addr4);
}
}
if (data.find("priority") != data.end()) {
priority = data["priority"].get<int>();
}
if (data.find("capacity") != data.end()) {
capacity = data["capacity"].get<int>();
}
// TODO: custom_info;
// SMF info
if (data.find("smfInfo") != data.end()) {
nlohmann::json info = data["smfInfo"];
dnn_smf_info_item_t dnn_item = {};
snssai_smf_info_item_t smf_info_item = {};
if (info.find("sNssaiSmfInfoList") != info.end()) {
nlohmann::json snssai_smf_info_list =
data["smfInfo"]["sNssaiSmfInfoList"];
for (auto it : snssai_smf_info_list) {
snssai_smf_info_item_t smf_info_item = {};
if (it.find("sNssai") != it.end()) {
if (it["sNssai"].find("sst") != it["sNssai"].end())
smf_info_item.snssai.sST = it["sNssai"]["sst"].get<int>();
......@@ -254,44 +330,18 @@ void smf_profile::from_json(const nlohmann::json &data) {
}
if (it.find("dnnSmfInfoList") != it.end()) {
for (auto d : it["dnnSmfInfoList"]) {
if (it.find("dnn") != it.end()) {
if (d.find("dnn") != d.end()) {
dnn_item.dnn = d["dnn"].get<std::string>();
smf_info_item.dnn_smf_info_list.push_back(dnn_item);
}
}
}
smf_info.snssai_smf_info_list.push_back(smf_info_item);
}
}
}
if (data.find("ipv4Addresses") != data.end()) {
nlohmann::json ipv4_addresses = data["ipv4Addresses"];
for (auto it : ipv4_addresses) {
struct in_addr addr4 = {};
std::string address = it.get<std::string>();
unsigned char buf_in_addr[sizeof(struct in_addr)];
if (inet_pton(AF_INET, util::trim(address).c_str(),
buf_in_addr) == 1) {
memcpy(&addr4, buf_in_addr, sizeof(struct in_addr));
} else {
Logger::smf_app().warn("Address conversion: Bad value %s",
util::trim(address).c_str());
}
Logger::smf_app().debug("\tIPv4 Addr: %s", address.c_str());
add_nf_ipv4_addresses(addr4);
}
}
if (data.find("priority") != data.end()) {
priority = data["priority"].get<int>();
}
if (data.find("capacity") != data.end()) {
capacity = data["capacity"].get<int>();
}
//TODO: custom_info;
display();
}
//------------------------------------------------------------------------------
......
......@@ -41,7 +41,6 @@
#include "logger.hpp"
#include "smf.h"
#include "smf_event.hpp"
namespace smf {
......@@ -56,7 +55,6 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
ipv4_addresses(),
priority(0),
capacity(0)
// event_sub(smf_event::get_instance())
{
nf_instance_name = "";
nf_status = "";
......@@ -71,7 +69,6 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
priority(0),
capacity(0),
nf_type("NF_TYPE_UNKNOWN")
// event_sub(smf_event::get_instance())
{
nf_instance_name = "";
nf_status = "";
......@@ -79,7 +76,6 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
}
smf_profile &operator=(const smf_profile &s) {
nf_instance_id = s.nf_instance_id;
heartBeat_timer = s.heartBeat_timer;
snssais = s.snssais;
......@@ -87,13 +83,12 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
priority = s.priority;
capacity = s.capacity;
nf_type = s.nf_type;
// event_sub = s.event_sub;
nf_instance_name = s.nf_instance_name;
nf_status = s.nf_status;
custom_info = s.custom_info;
smf_info = s.smf_info;
}
//smf_profile(smf_profile &b) = delete;
// smf_profile(smf_profile &b) = delete;
virtual ~smf_profile() {
Logger::smf_app().debug("Delete SMF Profile instance...");
......@@ -294,7 +289,6 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
*/
void get_custom_info(nlohmann::json &c) const;
/*
* Set smf info
* @param [smf_info_t &] s: smf info
......@@ -316,7 +310,6 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
*/
void get_smf_info(smf_info_t &s) const;
/*
* Print related-information for NF profile
* @param void
......@@ -346,8 +339,6 @@ class smf_profile : public std::enable_shared_from_this<smf_profile> {
void handle_heartbeart_timeout(uint64_t ms);
protected:
// for Event Handling
//smf_event &event_sub;
// From NFProfile (Section 6.1.6.2.2@3GPP TS 29.510 V16.0.0 (2019-06))
std::string nf_instance_id;
std::string nf_instance_name;
......
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