Unverified Commit b902581e authored by kharade's avatar kharade

nf_heartbeat procedure added

parent b6d908d6
......@@ -22,6 +22,13 @@
#ifndef FILE_UDR_SEEN
#define FILE_UDR_SEEN
#define HEART_BEAT_TIMER 10
#define _unused(x) ((void)(x))
#define NNRF_NFM_BASE "/nnrf-nfm/"
#define UDR_NF_REGISTER_URL "/nf-instances/"
#define NUDR_DR_BASE "/nudr-dr/"
#define NUDR_DR_AUTH_STATUS "authentication-status"
#define NUDR_DR_AUTH_SUBS "authentication-subscription"
......
......@@ -84,12 +84,19 @@ int main(int argc, char **argv) {
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
// Event subsystem
udr_event ev;
// Config
udr_cfg.load(Options::getlibconfigConfig());
udr_cfg.display();
// UDR application layer
udr_app_inst = new udr_app(Options::getlibconfigConfig());
udr_app_inst = new udr_app(Options::getlibconfigConfig(), ev);
// Task Manager
task_manager tm(ev);
std::thread task_manager_thread(&task_manager::run, &tm);
// PID file
// Currently hard-coded value. TODO: add as config option.
......
......@@ -31,6 +31,8 @@ add_library (UDR STATIC
udr_config.cpp
udr_profile.cpp
udr_nrf.cpp
udr_event.cpp
task_manager.cpp
udr_client.cpp
)
......
/*
* 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
*/
/*! \file task_manager.cpp
\brief
\author
\company Eurecom
\date 2020
\email: Tien-Thinh.Nguyen@eurecom.fr
*/
#include "task_manager.hpp"
#include <iostream>
#include <thread>
#include <unistd.h>
#include "logger.hpp"
using namespace oai::udr::app;
//------------------------------------------------------------------------------
task_manager::task_manager(udr_event &ev) : event_sub_(ev) {
struct itimerspec its;
sfd = timerfd_create(CLOCK_MONOTONIC, 0);
/* Start the timer */
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 1000 * 1000;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
if (timerfd_settime(sfd, TFD_TIMER_ABSTIME, &its, NULL) == -1) {
Logger::udr_app().error("Failed to set timer for task manager");
}
}
//------------------------------------------------------------------------------
void task_manager::run() { manage_tasks(); }
//------------------------------------------------------------------------------
void task_manager::manage_tasks() {
// starting from current time
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
while (1) {
event_sub_.task_tick(t);
t++;
wait_for_cycle();
}
}
//------------------------------------------------------------------------------
void task_manager::wait_for_cycle() {
uint64_t exp;
ssize_t res;
if (sfd > 0) {
res = read(sfd, &exp, sizeof(exp));
if ((res < 0) || (res != sizeof(exp))) {
Logger::udr_app().error("Failed in task manager timer wait");
}
}
}
/*
* 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
*/
/*! \file task_manager.hpp
\brief
\author
\company Eurecom
\date 2020
\email: Tien-Thinh.Nguyen@eurecom.fr
*/
#ifndef TASK_MANAGER_H_
#define TASK_MANAGER_H_
#include "udr_event.hpp"
#include <linux/types.h>
#include <sys/timerfd.h>
namespace oai {
namespace udr {
namespace app {
class udr_event;
class task_manager {
public:
task_manager(udr_event &ev);
/*
* Manage the tasks
* @param [void]
* @return void
*/
void manage_tasks();
/*
* Run the tasks (for the moment, simply call function manage_tasks)
* @param [void]
* @return void
*/
void run();
private:
/*
* Make sure that the task tick run every 1ms
* @param [void]
* @return void
*/
void wait_for_cycle();
udr_event &event_sub_;
int sfd;
};
} // namespace app
} // namespace udr
} // namespace oai
#endif
......@@ -49,7 +49,8 @@ extern udr_config udr_cfg;
udr_nrf *udr_nrf_inst = nullptr;
//------------------------------------------------------------------------------
udr_app::udr_app(const std::string &config_file) {
udr_app::udr_app(const std::string &config_file, udr_event &ev)
: event_sub(ev) {
Logger::udr_app().startup("Starting...");
if (!mysql_init(&mysql)) {
......@@ -70,7 +71,7 @@ udr_app::udr_app(const std::string &config_file) {
// Register to NRF
if (udr_cfg.register_nrf) {
try {
udr_nrf_inst = new udr_nrf();
udr_nrf_inst = new udr_nrf(ev);
udr_nrf_inst->register_to_nrf();
Logger::udr_app().info("NRF TASK Created ");
} catch (std::exception &e) {
......
......@@ -33,6 +33,7 @@
#include <mysql/mysql.h>
#include <pistache/http.h>
#include "udr_event.hpp"
#include <nlohmann/json.hpp>
#include <string>
......@@ -50,7 +51,7 @@ namespace app {
class udr_app {
public:
explicit udr_app(const std::string &config_file);
explicit udr_app(const std::string &config_file, udr_event &ev);
udr_app(udr_app const &) = delete;
void operator=(udr_app const &) = delete;
......@@ -306,6 +307,7 @@ public:
private:
MYSQL mysql;
udr_event &event_sub;
};
} // namespace app
} // namespace udr
......
/*
* 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
*/
/*! \file udr_event.cpp
\brief
\author Tien-Thinh NGUYEN (EURECOM)
\company
\date 2022
\email: contact@openairinterface.org
*/
#include "udr_event.hpp"
using namespace oai::udr::app;
bs2::connection
udr_event::subscribe_task_nf_heartbeat(const task_sig_t::slot_type &sig,
uint64_t period, uint64_t start) {
/* Wrap the actual callback in a lambda. The latter checks whether the
* current time is after start time, and ensures that the callback is only
* called every X ms with X being the period time. This way, it is possible
* to register to be notified every X ms instead of every ms, which provides
* greater freedom to implementations. */
auto f = [period, start, sig](uint64_t t) {
if (t >= start && (t - start) % period == 0)
sig(t);
};
return task_tick.connect(f);
}
/*
* 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
*/
/*! \file udr_event.hpp
\brief
\author Tien-Thinh NGUYEN (EURECOM)
\company
\date 2022
\email: contact@openairinterface.org
*/
#ifndef FILE_UDR_EVENT_HPP_SEEN
#define FILE_UDR_EVENT_HPP_SEEN
#include <boost/signals2.hpp>
namespace bs2 = boost::signals2;
#include "task_manager.hpp"
#include "udr.h"
#include "udr_event_sig.hpp"
namespace oai::udr::app {
class task_manager;
class udr_event {
public:
udr_event(){};
udr_event(udr_event const &) = delete;
void operator=(udr_event const &) = delete;
static udr_event &get_instance() {
static udr_event instance;
return instance;
}
// class register/handle event
friend class udr_app;
friend class udr_nrf;
friend class task_manager;
//------------------------------------------------------------------------------
/*
* Subscribe to the task tick event
* @param [const task_sig_t::slot_type &] sig
* @param [uint64_t] period: interval between two events
* @param [uint64_t] start:
* @return void
*/
bs2::connection subscribe_task_nf_heartbeat(const task_sig_t::slot_type &sig,
uint64_t period,
uint64_t start = 0);
private:
task_sig_t task_tick;
};
} // namespace oai::udr::app
#endif
/*
* 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
*/
/*! \file udr_event_sig.hpp
\brief
\author Tien-Thinh NGUYEN (EURECOM)
\company
\date 2022
\email: contact@openairinterface.org
*/
#ifndef FILE_UDR_EVENT_SIG_HPP_SEEN
#define FILE_UDR_EVENT_SIG_HPP_SEEN
#include <boost/signals2.hpp>
#include <string>
namespace bs2 = boost::signals2;
namespace oai::udr::app {
typedef bs2::signal_type<void(uint64_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
task_sig_t;
} // namespace oai::udr::app
#endif
......@@ -54,7 +54,7 @@ extern udr_nrf *udr_nrf_inst;
udr_client *udr_client_instance = nullptr;
//------------------------------------------------------------------------------
udr_nrf::udr_nrf() {}
udr_nrf::udr_nrf(udr_event &ev) : m_event_sub(ev) {}
//---------------------------------------------------------------------------------------------
void udr_nrf::get_udr_api_root(std::string &api_root) {
api_root =
......@@ -107,7 +107,6 @@ void udr_nrf::generate_udr_profile(udr_profile &udr_nf_profile,
//---------------------------------------------------------------------------------------------
void udr_nrf::register_to_nrf() {
// generate UUID
std::string udr_instance_id; // UDR instance id
udr_instance_id = to_string(boost::uuids::random_generator()());
nlohmann::json response_data = {};
......@@ -130,11 +129,56 @@ void udr_nrf::register_to_nrf() {
try {
response_data = nlohmann::json::parse(response);
if (response_data["nfStatus"].dump().c_str() == "REGISTERED") {
// ToDo Trigger NF heartbeats
if (response.find("REGISTERED") != 0) {
start_event_nf_heartbeat(remoteUri);
}
} catch (nlohmann::json::exception &e) {
Logger::udr_nrf().info("NF registeration procedure failed");
}
}
//---------------------------------------------------------------------------------------------
void udr_nrf::start_event_nf_heartbeat(std::string &remoteURI) {
// get current time
uint64_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
struct itimerspec its;
its.it_value.tv_sec = HEART_BEAT_TIMER; // seconds
its.it_value.tv_nsec = 0; // 100 * 1000 * 1000; //100ms
const uint64_t interval =
its.it_value.tv_sec * 1000 +
its.it_value.tv_nsec / 1000000; // convert sec, nsec to msec
task_connection = m_event_sub.subscribe_task_nf_heartbeat(
boost::bind(&udr_nrf::trigger_nf_heartbeat_procedure, this, _1), interval,
ms + interval);
}
//---------------------------------------------------------------------------------------------
void udr_nrf::trigger_nf_heartbeat_procedure(uint64_t ms) {
_unused(ms);
oai::udr::model::PatchItem patch_item = {};
std::vector<oai::udr::model::PatchItem> patch_items;
//{"op":"replace","path":"/nfStatus", "value": "REGISTERED"}
patch_item.setOp("replace");
patch_item.setPath("/nfStatus");
patch_item.setValue("REGISTERED");
patch_items.push_back(patch_item);
Logger::udr_nrf().info("Sending NF heartbeat request");
std::string response = {};
std::string method = {"PATCH"};
nlohmann::json json_data = nlohmann::json::array();
for (auto i : patch_items) {
nlohmann::json item = {};
to_json(item, i);
json_data.push_back(item);
}
std::string udr_api_root = {};
get_udr_api_root(udr_api_root);
std::string remoteUri = udr_api_root + UDR_NF_REGISTER_URL + udr_instance_id;
udr_client_instance->curl_http_client(remoteUri, method,
json_data.dump().c_str(), response);
if (!response.empty())
task_connection.disconnect();
}
\ No newline at end of file
......@@ -36,6 +36,7 @@
#include "logger.hpp"
#include "udr_config.hpp"
#include "udr_event.hpp"
#include "udr_profile.hpp"
namespace oai {
......@@ -49,12 +50,25 @@ public:
std::string udr_instance_id; // UDR instance id
// timer_id_t timer_udr_heartbeat;
udr_nrf();
udr_nrf(udr_event &ev);
udr_nrf(udr_nrf const &) = delete;
void operator=(udr_nrf const &) = delete;
void generate_uuid();
/*
* Start event nf heartbeat procedure
* @param [void]
* @return void
*/
void start_event_nf_heartbeat(std::string &remoteURI);
/*
* Trigger NF heartbeat procedure
* @param [void]
* @return void
*/
void trigger_nf_heartbeat_procedure(uint64_t ms);
/*
* Generate a UDR profile for this instance
* @param [void]
......@@ -75,6 +89,10 @@ public:
* @return void
*/
void get_udr_api_root(std::string &api_root);
private:
udr_event &m_event_sub;
bs2::connection task_connection;
};
} // namespace app
} // namespace udr
......
......@@ -182,27 +182,28 @@ void udr_profile::display() const {
}
Logger::udr_app().debug("\tUDR Info");
Logger::udr_app().debug("\t\tGroupId: %s", udr_info.groupid);
Logger::udr_app().debug("\t\tGroupId: %s", udr_info.groupid.c_str());
for (auto supi : udr_info.supi_ranges) {
Logger::udr_app().debug(
"\t\t SupiRanges: Start - %s, End - %s, Pattern - %s",
supi.supi_range.start, supi.supi_range.end, supi.supi_range.pattern);
supi.supi_range.start.c_str(), supi.supi_range.end.c_str(),
supi.supi_range.pattern.c_str());
}
for (auto gpsi : udr_info.gpsi_ranges) {
Logger::udr_app().debug(
"\t\t GpsiRanges: Start - %s, End - %s, Pattern - %s",
gpsi.identity_range.start, gpsi.identity_range.end,
gpsi.identity_range.pattern);
gpsi.identity_range.start.c_str(), gpsi.identity_range.end.c_str(),
gpsi.identity_range.pattern.c_str());
}
for (auto ext_grp_id : udr_info.ext_grp_id_ranges) {
Logger::udr_app().debug("\t\t externalGroupIdentifiersRanges: Start - %s, "
"End - %s, Pattern - %s",
ext_grp_id.identity_range.start,
ext_grp_id.identity_range.end,
ext_grp_id.identity_range.pattern);
ext_grp_id.identity_range.start.c_str(),
ext_grp_id.identity_range.end.c_str(),
ext_grp_id.identity_range.pattern.c_str());
}
for (auto data_set_Id : udr_info.data_set_id) {
Logger::udr_app().debug("\t\t Data Set Id: %s", data_set_Id);
Logger::udr_app().debug("\t\t Data Set Id: %s", data_set_Id.c_str());
}
}
......
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