Commit d88f7ed4 authored by kharade's avatar kharade

Basic NF registration completed

parent b4eb847f
......@@ -366,12 +366,21 @@ check_install_udr_deps() {
if [[ $OS_DISTRO == "ubuntu" ]]; then
case "$(get_distribution_release)" in
"ubuntu18.04")
# Currently Ubuntu18.04 has boost 1.65 as the latest
# We need at least 1.66
# PPA has 1.67
$SUDO add-apt-repository ppa:mhier/libboost-latest --yes
$SUDO $INSTALLER update
specific_packages="libconfig++-dev"
;;
*)
specific_packages="libconfig++-dev libasio-dev libboost-all-dev"
;;
esac
# removed libspdlog-dev
PACKAGE_LIST="\
$specific_packages \
libboost1.67-dev \
guile-2.0-dev \
libcurl4-gnutls-dev \
libevent-dev \
......
......@@ -68,6 +68,7 @@ RUN apt-get update && \
libnettle6 \
libnghttp2-14 \
libhogweed4 \
perl \
libconfig++9v5 && \
rm -rf /var/lib/apt/lists/*
......@@ -82,7 +83,8 @@ COPY --from=oai-udr-builder \
COPY --from=oai-udr-builder \
/usr/local/lib/libpistache.so \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 \
/usr/lib/libboost_system.so.1.67.0 \
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 \
/usr/local/lib/
RUN ldconfig && \
......
......@@ -38,6 +38,7 @@ RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
psmisc \
software-properties-common \
git && \
rm -rf /var/lib/apt/lists/*
......@@ -84,6 +85,7 @@ RUN apt-get update && \
libnettle6 \
libnghttp2-14 \
libhogweed4 \
perl \
libconfig++9v5 && \
rm -rf /var/lib/apt/lists/*
......@@ -98,7 +100,8 @@ COPY --from=oai-udr-builder \
COPY --from=oai-udr-builder \
/usr/local/lib/libpistache.so \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 \
/usr/lib/libboost_system.so.1.67.0 \
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 \
/usr/local/lib/
RUN ldconfig && \
......
......@@ -2,7 +2,15 @@ UDR =
{
INSTANCE_ID = @INSTANCE@; # 0 is the default
PID_DIRECTORY = "@PID_DIRECTORY@"; # /var/run is the default
SUPPORT_FEATURES:{
# STRING, {"yes", "no"},
USE_FQDN_DNS = "@USE_FQDN_DNS@"; # Set to yes if AUSF will relying on a DNS to resolve UDM's FQDN
REGISTER_NRF = "@REGISTER_NRF@"; # Set to 'yes' if AUSF resgisters to an NRF
USE_HTTP2 = "@USE_HTTP2@"; # Set to yes to enable HTTP2 for AUSF server
}
INTERFACES:
{
# NUDR Interface (SBI)
......@@ -13,10 +21,17 @@ UDR =
PORT = @UDR_INTERFACE_PORT_FOR_NUDR@; # YOUR NETWORK CONFIG HERE
HTTP2_PORT = @UDR_INTERFACE_HTTP2_PORT_FOR_NUDR@; # YOUR NETWORK CONFIG HERE
API_VERSION = "@UDR_API_VERSION@"; # YOUR NUDR API VERSION CONFIG HERE
};
};
NRF:
{
IPV4_ADDRESS = "@NRF_IPV4_ADDRESS@"; # YOUR NRF CONFIG HERE
PORT = @NRF_PORT@; # YOUR NRF CONFIG HERE (default: 80)
API_VERSION = "@NRF_API_VERSION@"; # YOUR NRF API VERSION HERE
FQDN = "@NRF_FQDN@";
};
MYSQL:
{
# MySQL options
......
......@@ -5,6 +5,13 @@ set -euo pipefail
CONFIG_DIR="/openair-udr/etc"
UDR_INTERFACE_PORT_FOR_NUDR=${UDR_INTERFACE_PORT_FOR_NUDR:-80}
UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=${UDR_INTERFACE_HTTP2_PORT_FOR_NUDR:-8080}
USE_HTTP2=${USE_HTTP2:-no}
USE_FQDN_DNS=${USE_FQDN_DNS:-no}
REGISTER_NRF=${REGISTER_NRF:-no}
NRF_IPV4_ADDRESS=${NRF_IPV4_ADDRESS:-0.0.0.0}
NRF_PORT=${NRF_PORT:-80}
NRF_API_VERSION=${NRF_API_VERSION:-v1}
NRF_FQDN=${NRF_FQDN:-oai-nrf}
for c in ${CONFIG_DIR}/*.conf; do
# grep variable names (format: ${VAR}) from template to be rendered
......
/*
* 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
*/
#ifndef FILE_3GPP_29_510_nssf_SEEN
#define FILE_3GPP_29_510_nssf_SEEN
#include <nlohmann/json.hpp>
#include <vector>
// Section 28.4, TS23.003
typedef struct s_nssai {
uint8_t sST;
std::string sD;
s_nssai(const uint8_t &sst, const std::string sd) : sST(sst), sD(sd) {}
s_nssai() : sST(), sD() {}
s_nssai(const s_nssai &p) : sST(p.sST), sD(p.sD) {}
bool operator==(const struct s_nssai &s) const {
if ((s.sST == this->sST) && (s.sD.compare(this->sD) == 0)) {
return true;
} else {
return false;
}
}
s_nssai &operator=(const s_nssai &s) {
sST = s.sST;
sD = s.sD;
return *this;
}
} snssai_t;
typedef struct dnai_s {
} dnai_t;
typedef struct patch_item_s {
std::string op;
std::string path;
// std::string from;
std::string value;
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["op"] = op;
json_data["path"] = path;
json_data["value"] = value;
return json_data;
}
} patch_item_t;
#define UDR_CURL_TIMEOUT_MS 100L
#define NNRF_NFM_BASE "/nnrf-nfm/"
#define UDR_NF_REGISTER_URL "/nf-instances/"
#endif
\ No newline at end of file
......@@ -30,6 +30,7 @@ add_library(3GPP_COMMON_TYPES STATIC
${CMAKE_CURRENT_SOURCE_DIR}/pid_file.cpp
${CMAKE_CURRENT_SOURCE_DIR}/if.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fqdn.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
*/
#include "fqdn.hpp"
#include "logger.hpp"
#include <boost/asio.hpp>
#include <iostream>
bool fqdn::resolve(const std::string &host_name, std::string &address,
uint32_t &port, uint8_t &addr_type,
const std::string &protocol) {
try {
Logger::udr_app().debug("Resolving DNS:- %s", host_name.c_str());
boost::asio::io_context io_context = {};
boost::asio::ip::tcp::resolver resolver{io_context};
boost::asio::ip::tcp::resolver::results_type endpoints =
resolver.resolve(host_name, protocol);
addr_type = 0; // IPv4 by default
for (auto it = endpoints.cbegin(); it != endpoints.cend(); it++) {
// get the first Endpoint
boost::asio::ip::tcp::endpoint endpoint = *it;
address = endpoint.address().to_string();
port = endpoint.port();
Logger::udr_app().debug(
"Resolve a DNS (name %s, protocol %s): Ip Addr %s, port %u",
host_name.c_str(), protocol.c_str(), address.c_str(), port);
if (endpoint.address().is_v4())
addr_type = 0;
else
addr_type = 1;
return true;
}
} catch (std::exception &e) {
throw std::runtime_error("Cannot resolve a DNS name " +
std::string(e.what()));
return false;
}
return false;
}
/*
* 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 fqdn.hpp
\brief
\author
\company Eurecom
\email:
*/
#ifndef FILE_FQDN_HPP_SEEN
#define FILE_FQDN_HPP_SEEN
#include <string>
class fqdn {
public:
/*
* Resolve a DNS name to get host's IP Addr
* @param [const std::string &] host_name: host's name/url
* @param [const std::string &] protocol: protocol
* @param [uint8_t &] addr_type: addr_type (Ipv4/v6)
* @return void
*/
static bool resolve(const std::string &host_name, std::string &address,
uint32_t &port, uint8_t &addr_type,
const std::string &protocol = "http");
};
#endif /* FILE_FQDN_HPP_SEEN */
......@@ -70,6 +70,7 @@ void Logger::_init(const char *app, const bool log_stdout,
m_config = new _Logger("configurations", m_sinks, ss.str().c_str());
m_udr_server = new _Logger("udr_server", m_sinks, ss.str().c_str());
m_udr_app = new _Logger("udr_app", m_sinks, ss.str().c_str());
m_udr_nrf = new _Logger("udr_nrf", m_sinks, ss.str().c_str());
}
//------------------------------------------------------------------------------
......
......@@ -85,6 +85,7 @@ public:
static _Logger &system() { return *singleton().m_system; }
static _Logger &config() { return *singleton().m_config; }
static _Logger &udr_server() { return *singleton().m_udr_server; }
static _Logger &udr_nrf() { return *singleton().m_udr_nrf; }
private:
static Logger *m_singleton;
......@@ -107,6 +108,7 @@ private:
_Logger *m_config;
_Logger *m_system;
_Logger *m_udr_server;
_Logger *m_udr_nrf;
};
#endif
......@@ -32,4 +32,34 @@
#define NUDR_DR_SMF_REG "smf-registrations"
#define NUDR_DR_SMF_SELECT "smf-selection-subscription-data"
#define NF_CURL_TIMEOUT_MS 1000L
typedef struct identity_range_s {
std::string start;
std::string end;
std::string pattern;
} identity_range_t;
typedef struct identity_range_udr_info_item_s {
identity_range_t identity_range;
} identity_range_udr_info_item_t;
typedef struct supi_range_s {
std::string start;
std::string end;
std::string pattern;
} supi_range_t;
typedef struct supi_range_udr_info_item_s {
supi_range_t supi_range;
} supi_range_udr_info_item_t;
typedef struct udr_info_s {
std::string groupid;
std::vector<supi_range_udr_info_item_t> supi_ranges;
std::vector<identity_range_udr_info_item_t> gpsi_ranges;
std::vector<identity_range_udr_info_item_t> ext_grp_id_ranges;
std::vector<std::string> data_set_id;
} udr_info_t;
#endif
......@@ -29,6 +29,9 @@ include_directories(${SRC_TOP_DIR}/common/)
add_library (UDR STATIC
udr_app.cpp
udr_config.cpp
udr_profile.cpp
udr_nrf.cpp
udr_client.cpp
)
......@@ -38,6 +38,7 @@
#include "SequenceNumber.h"
#include "logger.hpp"
#include "udr_config.hpp"
#include "udr_nrf.hpp"
using namespace oai::udr::app;
using namespace oai::udr::model;
......@@ -45,6 +46,7 @@ using namespace oai::udr::config;
extern udr_app *udr_app_inst;
extern udr_config udr_cfg;
udr_nrf *udr_nrf_inst = nullptr;
//------------------------------------------------------------------------------
udr_app::udr_app(const std::string &config_file) {
......@@ -65,7 +67,17 @@ udr_app::udr_app(const std::string &config_file) {
throw std::runtime_error("Cannot connect to MySQL DB");
}
// TODO: Register to NRF
// Register to NRF
if (udr_cfg.register_nrf) {
try {
udr_nrf_inst = new udr_nrf();
udr_nrf_inst->register_to_nrf();
Logger::udr_app().info("NRF TASK Created ");
} catch (std::exception &e) {
Logger::udr_app().error("Cannot create NRF TASK: %s", e.what());
throw;
}
}
Logger::udr_app().startup("Started");
}
......
/*
* 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_client.cpp
\brief
\author Jian Yang, Fengjiao He, Hongxin Wang, Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email:
*/
#include "udr_client.hpp"
#include "3gpp_29.500.h"
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <pistache/http.h>
#include <pistache/mime.h>
#include <stdexcept>
#include "logger.hpp"
#include "udr.h"
using namespace Pistache::Http;
using namespace Pistache::Http::Mime;
using namespace oai::udr::app;
using namespace oai::udr::config;
using json = nlohmann::json;
extern udr_client *udr_client_inst;
extern udr_config udr_cfg;
//------------------------------------------------------------------------------
// To read content of the response from NF
static std::size_t callback(const char *in, std::size_t size, std::size_t num,
std::string *out) {
const std::size_t totalBytes(size * num);
out->append(in, totalBytes);
return totalBytes;
}
//------------------------------------------------------------------------------
udr_client::udr_client() {}
//------------------------------------------------------------------------------
udr_client::~udr_client() {
Logger::udr_app().debug("Delete UDR Client instance...");
}
//------------------------------------------------------------------------------
void udr_client::curl_http_client(std::string remoteUri, std::string method,
std::string msgBody, std::string &response) {
Logger::udr_app().info("Send HTTP message with body %s", msgBody.c_str());
uint32_t str_len = msgBody.length();
char *body_data = (char *)malloc(str_len + 1);
memset(body_data, 0, str_len + 1);
memcpy((void *)body_data, (void *)msgBody.c_str(), str_len);
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
uint8_t http_version = 1;
if (udr_cfg.use_http2)
http_version = 2;
if (curl) {
CURLcode res = {};
struct curl_slist *headers = nullptr;
if ((method.compare("POST") == 0) or (method.compare("PUT") == 0) or
(method.compare("PATCH") == 0)) {
std::string content_type = "Content-Type: application/json";
headers = curl_slist_append(headers, content_type.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
}
curl_easy_setopt(curl, CURLOPT_URL, remoteUri.c_str());
if (method.compare("POST") == 0)
curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1);
else if (method.compare("PUT") == 0)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
else if (method.compare("DELETE") == 0)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
else if (method.compare("PATCH") == 0)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
else
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, NF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
curl_easy_setopt(curl, CURLOPT_INTERFACE, udr_cfg.nudr.if_name.c_str());
if (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());
std::unique_ptr<std::string> httpHeaderData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_HEADERDATA, httpHeaderData.get());
if ((method.compare("POST") == 0) or (method.compare("PUT") == 0) or
(method.compare("PATCH") == 0)) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, msgBody.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body_data);
}
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
// Process the response
response = *httpData.get();
bool is_response_ok = true;
Logger::udr_app().info("Get response with HTTP code (%d)", httpCode);
if (httpCode == 0) {
Logger::udr_app().info("Cannot get response when calling %s",
remoteUri.c_str());
// free curl before returning
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return;
}
nlohmann::json response_data = {};
if (httpCode != HTTP_STATUS_CODE_200_OK &&
httpCode != HTTP_STATUS_CODE_201_CREATED &&
httpCode != HTTP_STATUS_CODE_204_NO_CONTENT) {
is_response_ok = false;
if (response.size() < 1) {
Logger::udr_app().info("There's no content in the response");
// TODO: send context response error
return;
}
Logger::udr_app().warn("Receive response with HTTP code %d", httpCode);
return;
}
if (!is_response_ok) {
try {
response_data = nlohmann::json::parse(response);
} catch (nlohmann::json::exception &e) {
Logger::udr_app().info("Could not get JSON content from the response");
// Set the default Cause
response_data["error"]["cause"] = "504 Gateway Timeout";
}
Logger::udr_app().info("Get response with jsonData: %s",
response.c_str());
std::string cause = response_data["error"]["cause"];
Logger::udr_app().info("Call Network Function services failure");
Logger::udr_app().info("Cause value: %s", cause.c_str());
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
if (body_data) {
free(body_data);
body_data = NULL;
}
return;
}
/*
* 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_client.hpp
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email:
*/
#ifndef FILE_UDR_CLIENT_HPP_SEEN
#define FILE_UDR_CLIENT_HPP_SEEN
#include <map>
#include <thread>
#include <curl/curl.h>
#include "logger.hpp"
#include "udr_config.hpp"
namespace oai {
namespace udr {
namespace app {
class udr_client {
private:
public:
udr_client();
virtual ~udr_client();
udr_client(udr_client const &) = delete;
void curl_http_client(std::string remoteUri, std::string method,
std::string msgBody, std::string &response);
};
} // namespace app
} // namespace udr
} // namespace oai
#endif /* FILE_UDR_CLIENT_HPP_SEEN */
......@@ -29,6 +29,7 @@
#include <boost/algorithm/string/split.hpp>
#include "common_defs.h"
#include "fqdn.hpp"
#include "if.hpp"
#include "logger.hpp"
#include "string.hpp"
......@@ -104,6 +105,98 @@ int udr_config::load(const std ::string &config_file) {
return RETURNerror;
}
// Support features
try {
const Setting &support_features =
udr_cfg[UDR_CONFIG_STRING_SUPPORT_FEATURES];
std::string opt = {};
support_features.lookupValue(
UDR_CONFIG_STRING_SUPPORT_FEATURES_USE_FQDN_DNS, opt);
if (boost::iequals(opt, "yes")) {
use_fqdn_dns = true;
} else {
use_fqdn_dns = false;
}
support_features.lookupValue(
UDR_CONFIG_STRING_SUPPORTED_FEATURES_REGISTER_NRF, opt);
if (boost::iequals(opt, "yes")) {
register_nrf = true;
} else {
register_nrf = false;
}
support_features.lookupValue(UDM_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2,
opt);
if (boost::iequals(opt, "yes")) {
use_http2 = true;
} else {
use_http2 = false;
}
} catch (const SettingNotFoundException &nfex) {
Logger::udr_app().error("%s : %s, using defaults", nfex.what(),
nfex.getPath());
return RETURNerror;
}
// NRF
if (register_nrf) {
try {
std::string astring = {};
const Setting &nrf_cfg = udr_cfg[UDR_CONFIG_STRING_NRF];
struct in_addr nrf_ipv4_addr = {};
unsigned int nrf_port = 0;
std::string nrf_api_version = {};
if (!use_fqdn_dns) {
nrf_cfg.lookupValue(UDR_CONFIG_STRING_NRF_IPV4_ADDRESS, astring);
IPV4_STR_ADDR_TO_INADDR(util::trim(astring).c_str(), nrf_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR NRF !");
nrf_addr.ipv4_addr = nrf_ipv4_addr;
if (!(nrf_cfg.lookupValue(UDR_CONFIG_STRING_NRF_PORT, nrf_port))) {
Logger::udr_app().error(UDR_CONFIG_STRING_NRF_PORT "failed");
throw(UDR_CONFIG_STRING_NRF_PORT "failed");
}
nrf_addr.port = nrf_port;
if (!(nrf_cfg.lookupValue(UDR_CONFIG_STRING_API_VERSION,
nrf_api_version))) {
Logger::udr_app().error(UDR_CONFIG_STRING_API_VERSION "failed");
throw(UDR_CONFIG_STRING_API_VERSION "failed");
}
nrf_addr.api_version = nrf_api_version;
} else {
nrf_cfg.lookupValue(UDR_CONFIG_STRING_FQDN_DNS, astring);
uint8_t addr_type = {0};
std::string address = {};
fqdn::resolve(astring, address, nrf_port, addr_type);
if (addr_type != 0) { // IPv6
// TODO:
throw("DO NOT SUPPORT IPV6 ADDR FOR NRF!");
} else { // IPv4
IPV4_STR_ADDR_TO_INADDR(util::trim(address).c_str(), nrf_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR NRF !");
nrf_addr.ipv4_addr = nrf_ipv4_addr;
// We hardcode amf port from config for the moment
if (!(nrf_cfg.lookupValue(UDR_CONFIG_STRING_NRF_PORT, nrf_port))) {
Logger::udr_app().error(UDR_CONFIG_STRING_NRF_PORT "failed");
throw(UDR_CONFIG_STRING_NRF_PORT "failed");
}
nrf_addr.port = nrf_port;
nrf_addr.api_version = "v1"; // TODO: to get API version from DNS
nrf_addr.fqdn = astring;
}
}
} catch (const SettingNotFoundException &nfex) {
Logger::udr_app().error("%s : %s", nfex.what(), nfex.getPath());
return RETURNerror;
}
}
// MySQL
try {
const Setting &mysql_cfg = udr_cfg[UDR_CONFIG_STRING_MYSQL];
mysql_cfg.lookupValue(UDR_CONFIG_STRING_MYSQL_SERVER, mysql.mysql_server);
......@@ -191,7 +284,22 @@ void udr_config::display() {
Logger::config().info(" HTTP2 port ..........: %d", nudr_http2_port);
Logger::config().info(" API version..........: %s",
nudr.api_version.c_str());
Logger::config().info("- Supported Features:");
Logger::config().info(" Register NRF ..........: %s",
register_nrf ? "Yes" : "No");
Logger::config().info(" Use FQDN ..............: %s",
use_fqdn_dns ? "Yes" : "No");
Logger::config().info(" Use HTTP2 .............: %s",
use_http2 ? "Yes" : "No");
Logger::config().info("- NRF:");
Logger::config().info(" IPv4 Addr ............: %s",
inet_ntoa(*((struct in_addr *)&nrf_addr.ipv4_addr)));
Logger::config().info(" Port .................: %lu ", nrf_addr.port);
Logger::config().info(" API version ..........: %s",
nrf_addr.api_version.c_str());
if (use_fqdn_dns)
Logger::config().info(" FQDN .................: %s",
nrf_addr.fqdn.c_str());
Logger::config().info(
"- MYSQL Server Addr...................................: %s",
mysql.mysql_server.c_str());
......
......@@ -38,6 +38,16 @@
#define UDR_CONFIG_STRING_HTTP2_PORT "HTTP2_PORT"
#define UDR_CONFIG_STRING_API_VERSION "API_VERSION"
#define UDR_CONFIG_STRING_NRF "NRF"
#define UDR_CONFIG_STRING_NRF_IPV4_ADDRESS "IPV4_ADDRESS"
#define UDR_CONFIG_STRING_NRF_PORT "PORT"
#define UDR_CONFIG_STRING_SUPPORT_FEATURES "SUPPORT_FEATURES"
#define UDR_CONFIG_STRING_SUPPORT_FEATURES_USE_FQDN_DNS "USE_FQDN_DNS"
#define UDR_CONFIG_STRING_SUPPORTED_FEATURES_REGISTER_NRF "REGISTER_NRF"
#define UDM_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2 "USE_HTTP2"
#define UDR_CONFIG_STRING_FQDN_DNS "FQDN"
#define UDR_CONFIG_STRING_MYSQL "MYSQL"
#define UDR_CONFIG_STRING_MYSQL_SERVER "MYSQL_SERVER"
#define UDR_CONFIG_STRING_MYSQL_USER "MYSQL_USER"
......@@ -80,6 +90,17 @@ public:
interface_cfg_t nudr;
unsigned int nudr_http2_port;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
std::string fqdn;
} nrf_addr;
bool register_nrf;
bool use_fqdn_dns;
bool use_http2;
mysql_conf_t mysql;
};
} // namespace oai::udr::config
......
/*
* 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_nrf.cpp
\brief
\author Jian Yang, Fengjiao He, Hongxin Wang, Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email:
*/
#include "udr_nrf.hpp"
#include "udr_app.hpp"
#include "udr_client.hpp"
#include "udr_profile.hpp"
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <pistache/http.h>
#include <pistache/mime.h>
#include <stdexcept>
#include "logger.hpp"
#include "udr.h"
using namespace oai::udr::config;
// using namespace udr;
using namespace oai::udr::app;
using json = nlohmann::json;
extern udr_config udr_cfg;
extern udr_nrf *udr_nrf_inst;
udr_client *udr_client_instance = nullptr;
//------------------------------------------------------------------------------
udr_nrf::udr_nrf() {}
//---------------------------------------------------------------------------------------------
void udr_nrf::get_udr_api_root(std::string &api_root) {
api_root =
std::string(inet_ntoa(*((struct in_addr *)&udr_cfg.nrf_addr.ipv4_addr))) +
":" + std::to_string(udr_cfg.nrf_addr.port) + NNRF_NFM_BASE +
udr_cfg.nrf_addr.api_version;
}
//---------------------------------------------------------------------------------------------
void udr_nrf::generate_udr_profile(udr_profile &udr_nf_profile,
std::string &udr_instance_id) {
// TODO: remove hardcoded values
udr_nf_profile.set_nf_instance_id(udr_instance_id);
udr_nf_profile.set_nf_instance_name("OAI-UDR");
udr_nf_profile.set_nf_type("UDR");
udr_nf_profile.set_nf_status("REGISTERED");
udr_nf_profile.set_nf_heartBeat_timer(50);
udr_nf_profile.set_nf_priority(1);
udr_nf_profile.set_nf_capacity(100);
// udr_nf_profile.set_fqdn(udr_cfg.fqdn);
udr_nf_profile.add_nf_ipv4_addresses(udr_cfg.nudr.addr4);
// UDR info (Hardcoded for now)
// ToDo:-If none of these parameters are provided, the UDR can serve any
// external group and any SUPI or GPSI managed by the PLMN of the UDR
// instance. If "supiRanges", "gpsiRanges" and
// "externalGroupIdentifiersRanges" attributes are absent, and "groupId" is
// present, the SUPIs / GPSIs / ExternalGroups served by this UDR instance is
// determined by the NRF (see 3GPP TS 23.501 [2], clause 6.2.6.2).
udr_info_t udr_info_item;
supi_range_udr_info_item_t supi_ranges;
udr_info_item.groupid = "oai-udr-testgroupid";
udr_info_item.data_set_id.push_back("0210");
udr_info_item.data_set_id.push_back("9876");
supi_ranges.supi_range.start = "208950000000031";
supi_ranges.supi_range.pattern = "^imsi-20895[31-131]{6}$";
supi_ranges.supi_range.start = "208950000000131";
udr_info_item.supi_ranges.push_back(supi_ranges);
identity_range_udr_info_item_t gpsi_ranges;
gpsi_ranges.identity_range.start = "752740000";
gpsi_ranges.identity_range.pattern = "^gpsi-75274[0-9]{4}$";
gpsi_ranges.identity_range.end = "752749999";
udr_info_item.gpsi_ranges.push_back(gpsi_ranges);
udr_nf_profile.set_udr_info(udr_info_item);
// ToDo:- Add remaining fields
// UDR info item end
udr_nf_profile.display();
}
//---------------------------------------------------------------------------------------------
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 = {};
// Generate NF Profile
udr_profile udr_nf_profile;
generate_udr_profile(udr_nf_profile, udr_instance_id);
// Send NF registeration request
std::string udr_api_root = {};
std::string response = {};
std::string method = {"PUT"};
get_udr_api_root(udr_api_root);
std::string remoteUri = udr_api_root + UDR_NF_REGISTER_URL + udr_instance_id;
nlohmann::json json_data = {};
udr_nf_profile.to_json(json_data);
Logger::udr_nrf().info("Sending NF registeration request");
udr_client_instance->curl_http_client(remoteUri, method,
json_data.dump().c_str(), response);
try {
response_data = nlohmann::json::parse(response);
if (response_data["nfStatus"].dump().c_str() == "REGISTERED") {
// ToDo Trigger NF heartbeats
}
} catch (nlohmann::json::exception &e) {
Logger::udr_nrf().info("NF registeration procedure failed");
}
}
//---------------------------------------------------------------------------------------------
/*
* 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_client.hpp
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email:
*/
#ifndef FILE_UDR_NRF_SEEN
#define FILE_UDR_NRF_SEEN
#include <map>
#include <thread>
#include <curl/curl.h>
#include "logger.hpp"
#include "udr_config.hpp"
#include "udr_profile.hpp"
namespace oai {
namespace udr {
namespace app {
class udr_nrf {
private:
public:
udr_profile udr_nf_profile; // UDR profile
std::string udr_instance_id; // UDR instance id
// timer_id_t timer_udr_heartbeat;
udr_nrf();
udr_nrf(udr_nrf const &) = delete;
void operator=(udr_nrf const &) = delete;
void generate_uuid();
/*
* Generate a UDR profile for this instance
* @param [void]
* @return void
*/
void generate_udr_profile(udr_profile &udr_nf_profile,
std::string &udr_instance_id);
/*
* Trigger NF instance registration to NRF
* @param [void]
* @return void
*/
void register_to_nrf();
/*
* Get udr API Root
* @param [std::string& ] api_root: udr's API Root
* @return void
*/
void get_udr_api_root(std::string &api_root);
};
} // namespace app
} // namespace udr
} // namespace oai
#endif /* FILE_UDR_NRF_SEEN */
This diff is collapsed.
/*
* 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_profile.hpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2021
\email: Tien-Thinh.Nguyen@eurecom.fr
*/
#ifndef FILE_UDR_PROFILE_HPP_SEEN
#define FILE_UDR_PROFILE_HPP_SEEN
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nlohmann/json.hpp>
#include <shared_mutex>
#include <vector>
#include "3gpp_29.510.h"
#include "logger.hpp"
#include "udr.h"
namespace oai {
namespace udr {
namespace app {
class udr_profile : public std::enable_shared_from_this<udr_profile> {
public:
udr_profile()
: nf_type("NF_TYPE_UNKNOWN"), heartBeat_timer(0), snssais(), fqdn(),
ipv4_addresses(), priority(0), capacity(0) {
nf_instance_name = {};
nf_status = {};
}
udr_profile(const std::string &id)
: nf_instance_id(id), heartBeat_timer(0), snssais(), fqdn(),
ipv4_addresses(), priority(0), capacity(0), nf_type("NF_TYPE_UNKNOWN") {
nf_instance_name = {};
nf_status = {};
}
udr_profile &operator=(const udr_profile &s) {
nf_instance_id = s.nf_instance_id;
heartBeat_timer = s.heartBeat_timer;
snssais = s.snssais;
fqdn = s.fqdn;
ipv4_addresses = s.ipv4_addresses;
priority = s.priority;
capacity = s.capacity;
nf_type = s.nf_type;
nf_instance_name = s.nf_instance_name;
nf_status = s.nf_status;
udr_info = s.udr_info;
return *this;
}
// udr_profile(udr_profile &b) = delete;
virtual ~udr_profile() {
// Logger::udr_app().debug("Delete udr Profile instance...");
}
/*
* Set NF instance ID
* @param [const std::string &] instance_id: instance id
* @return void
*/
void set_nf_instance_id(const std::string &instance_id);
/*
* Get NF instance ID
* @param [std::string &] instance_id: store instance id
* @return void:
*/
void get_nf_instance_id(std::string &instance_id) const;
/*
* Get NF instance ID
* @param [std::string &] instance_id: store instance id
* @return void:
*/
std::string get_nf_instance_id() const;
/*
* Set NF instance name
* @param [const std::string &] instance_name: instance name
* @return void
*/
void set_nf_instance_name(const std::string &instance_name);
/*
* Get NF instance ID
* @param [std::string &] instance_name: store instance name
* @return void:
*/
void get_nf_instance_name(std::string &instance_name) const;
/*
* Get NF instance name
* @param
* @return [std::string] instance name
*/
std::string get_nf_instance_name() const;
/*
* Set NF instance status
* @param [const std::string &] status: instance status
* @return void
*/
void set_nf_status(const std::string &status);
/*
* Get NF instance status
* @param [std::string &] status: store instance status
* @return void:
*/
void get_nf_status(std::string &status) const;
/*
* Get NF status
* @param
* @return [std::string] instance status
*/
std::string get_nf_status() const;
/*
* Get NF type
* @param
* @return [std::string] nf type
*/
std::string get_nf_type() const;
/*
* Set NF type
* @param [const nf_type_t &] type: nf type
* @return void
*/
void set_nf_type(const std::string &type);
/*
* Set NF instance heartBeat_timer
* @param [const std::string &] timer: heartBeat_timer
* @return void
*/
void set_nf_heartBeat_timer(const int32_t &timer);
/*
* Get NF instance heartBeat_timer
* @param [std::string &] timer: store heartBeat_timer
* @return void:
*/
void get_nf_heartBeat_timer(int32_t &timer) const;
/*
* Get NF heartBeat_timer
* @param void
* @return heartBeat_timer
*/
int32_t get_nf_heartBeat_timer() const;
/*
* Set NF instance priority
* @param [const uint16_t] p: instance priority
* @return void
*/
void set_nf_priority(const uint16_t &p);
/*
* Get NF instance priority
* @param [uint16_t] p: store instance priority
* @return void:
*/
void get_nf_priority(uint16_t &p) const;
/*
* Get NF instance priority
* @param void
* @return [uint16_t] instance priority
*/
uint16_t get_nf_priority() const;
/*
* Set NF instance capacity
* @param [const uint16_t] c: instance capacity
* @return void
*/
void set_nf_capacity(const uint16_t &c);
/*
* Get NF instance priority
* @param [uint16_t ] c: store instance capacity
* @return void:
*/
void get_nf_capacity(uint16_t &c) const;
/*
* Get NF instance priority
* @param void
* @return [uint16_t ] instance capacity
*/
uint16_t get_nf_capacity() const;
/*
* Set NF instance SNSSAIs
* @param [std::vector<snssai_t> &] s: SNSSAIs
* @return void
*/
void set_nf_snssais(const std::vector<snssai_t> &s);
/*
* Add SNSSAI
* @param [snssai_t &] s: SNSSAI
* @return void
*/
void add_snssai(const snssai_t &s);
/*
* Get NF instance SNSSAIs
* @param [std::vector<snssai_t> &] s: store instance's SNSSAIs
* @return void:
*/
void get_nf_snssais(std::vector<snssai_t> &s) const;
/*
* Get NF fqdn
* @param
* @return [std::string] nf fqdn
*/
std::string get_fqdn() const;
/*
* Set NF fqdn
* @param [const fqdn_t &] fqdn: nf fqdn
* @return void
*/
void set_fqdn(const std::string &fqdn);
/*
* Set NF instance ipv4_addresses
* @param [std::vector<struct in_addr> &] a: ipv4_addresses
* @return void
*/
void set_nf_ipv4_addresses(const std::vector<struct in_addr> &a);
/*
* Add an IPv4 address to the list of addresses
* @param [const struct in_addr &] a: ipv4_address
* @return void
*/
void add_nf_ipv4_addresses(const struct in_addr &a);
/*
* Get NF instance ipv4_addresses
* @param [std::vector<struct in_addr> &] a: store instance's ipv4_addresses
* @return void:
*/
void get_nf_ipv4_addresses(std::vector<struct in_addr> &a) const;
/*
* Set udr info
* @param [udr_info_t &] s: udr info
* @return void
*/
void set_udr_info(const udr_info_t &s);
/*
* Get NF instance udr info
* @param [udr_info_t &] s: store instance's udr info
* @return void:
*/
void get_udr_info(udr_info_t &s) const;
/*
* Print related-information for NF profile
* @param void
* @return void:
*/
void display() const;
/*
* Represent NF profile as json object
* @param [nlohmann::json &] data: Json data
* @return void
*/
void to_json(nlohmann::json &data) const;
/*
* Covert from a json represetation to udr profile
* @param [nlohmann::json &] data: Json data
* @return void
*/
void from_json(const nlohmann::json &data);
/*
* Handle heartbeart timeout event
* @param [uint64_t] ms: current time
* @return void
*/
void handle_heartbeart_timeout(uint64_t ms);
protected:
// 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;
std::string nf_type;
std::string nf_status;
int32_t heartBeat_timer;
std::vector<snssai_t> snssais;
std::string fqdn;
std::vector<struct in_addr> ipv4_addresses;
uint16_t priority;
uint16_t capacity;
udr_info_t udr_info;
};
} // namespace app
} // namespace udr
} // namespace oai
#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