Commit 7b7c4a22 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge branch 'nf_heartbeat' into 'develop'

nf_heartbeat procedure added

See merge request oai/cn5g/oai-cn5g-ausf!20
parents 936b74a6 334742dd
#
# Copyright (c) 2015, EURECOM (www.eurecom.fr)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of the FreeBSD Project.
#
# see https://clang.llvm.org/docs/ClangFormatStyleOptions.html for explanation
# of style options
BasedOnStyle: Google
Language: Cpp
IndentWidth: 2
ColumnLimit: 80
IncludeBlocks: Preserve
SortIncludes: false
# alignment
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
DerivePointerAlignment: false
PointerAlignment: Left
# function style
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortFunctionsOnASingleLine: Inline
AlwaysBreakAfterReturnType: None
IndentWrappedFunctionNames: false
# template style
AlwaysBreakTemplateDeclarations: Yes
# preprocessor style
IndentPPDirectives: None
# block style
AllowShortBlocksOnASingleLine: false
KeepEmptyLinesAtTheStartOfBlocks: false
# break style
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: false
BreakStringLiterals: true
CompactNamespaces: false
ContinuationIndentWidth: 4
MaxEmptyLinesToKeep: 1
ReflowComments: true
# spacing style
UseTab: Never
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
# class style
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
# case statements
IndentCaseLabels: true
# cpp
Cpp11BracedListStyle: true
FixNamespaceComments: true
NamespaceIndentation: None
SortUsingDeclarations: true
# todo
# AlwaysBreakBeforeMultilineStrings: bool
# PenaltyBreakAssignment (unsigned)
# PenaltyBreakBeforeFirstCallParameter (unsigned)
# PenaltyBreakComment (unsigned)
# PenaltyBreakFirstLessLess (unsigned)
# PenaltyBreakString (unsigned)
# PenaltyBreakTemplateDeclaration (unsigned)
# PenaltyExcessCharacter (unsigned)
# PenaltyReturnTypeOnItsOwnLine (unsigned)
/*
* 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
*/
/**
* Nausf_DataRepository API OpenAPI file
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB,
* ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
#include "PatchItem.h"
#include <iostream>
using namespace std;
namespace oai {
namespace ausf_server {
namespace model {
PatchItem::PatchItem() {
m_Path = "";
m_From = "";
m_Value = "";
m_FromIsSet = false;
m_ValueIsSet = false;
}
PatchItem::~PatchItem() {}
void PatchItem::validate() {
// TODO: implement validation
}
void to_json(nlohmann::json &j, const PatchItem &o) {
j = nlohmann::json();
j["op"] = o.m_Op;
j["path"] = o.m_Path;
if (o.fromIsSet())
j["from"] = o.m_From;
if (o.valueIsSet())
j["value"] = o.m_Value;
}
void from_json(const nlohmann::json &j, PatchItem &o) {
j.at("op").get_to(o.m_Op);
j.at("path").get_to(o.m_Path);
if (j.find("from") != j.end()) {
j.at("from").get_to(o.m_From);
o.m_FromIsSet = true;
}
if (j.find("value") != j.end()) {
j.at("value").get_to(o.m_Value);
o.m_ValueIsSet = true;
}
}
std::string PatchItem::getOp() const { return m_Op; }
void PatchItem::setOp(std::string const &value) { m_Op = value; }
std::string PatchItem::getPath() const { return m_Path; }
void PatchItem::setPath(std::string const &value) { m_Path = value; }
std::string PatchItem::getFrom() const { return m_From; }
void PatchItem::setFrom(std::string const &value) {
m_From = value;
m_FromIsSet = true;
}
bool PatchItem::fromIsSet() const { return m_FromIsSet; }
void PatchItem::unsetFrom() { m_FromIsSet = false; }
std::string PatchItem::getValue() const { return m_Value; }
void PatchItem::setValue(std::string const &value) {
m_Value = value;
m_ValueIsSet = true;
}
bool PatchItem::valueIsSet() const { return m_ValueIsSet; }
void PatchItem::unsetValue() { m_ValueIsSet = false; }
} // namespace model
} // namespace ausf_server
} // namespace oai
/*
* 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
*/
/**
* Nausf_DataRepository API OpenAPI file
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB,
* ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
/*
* PatchItem.h
*
*
*/
#ifndef PatchItem_H_
#define PatchItem_H_
#include <string>
#include "PatchOperation.h"
//#include "AnyType.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace ausf_server {
namespace model {
/// <summary>
///
/// </summary>
class PatchItem {
public:
PatchItem();
virtual ~PatchItem();
void validate();
/////////////////////////////////////////////
/// PatchItem members
/// <summary>
///
/// </summary>
std::string getOp() const;
void setOp(std::string const &value);
/// <summary>
///
/// </summary>
std::string getPath() const;
void setPath(std::string const &value);
/// <summary>
///
/// </summary>
std::string getFrom() const;
void setFrom(std::string const &value);
bool fromIsSet() const;
void unsetFrom();
/// <summary>
///
/// </summary>
std::string getValue() const;
void setValue(std::string const &value);
bool valueIsSet() const;
void unsetValue();
friend void to_json(nlohmann::json &j, const PatchItem &o);
friend void from_json(const nlohmann::json &j, PatchItem &o);
protected:
std::string m_Op;
std::string m_Path;
std::string m_From;
bool m_FromIsSet;
std::string m_Value;
bool m_ValueIsSet;
};
} // namespace model
} // namespace ausf_server
} // namespace oai
#endif /* PatchItem_H_ */
/*
* 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
*/
/**
* Nausf_DataRepository API OpenAPI file
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB,
* ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
#include "PatchOperation.h"
namespace oai {
namespace ausf_server {
namespace model {
PatchOperation::PatchOperation() {}
PatchOperation::~PatchOperation() {}
void PatchOperation::validate() {
// TODO: implement validation
}
void to_json(nlohmann::json &j, const PatchOperation &o) {
j = nlohmann::json();
}
void from_json(const nlohmann::json &j, PatchOperation &o) {}
} // namespace model
} // namespace ausf_server
} // namespace oai
/*
* 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
*/
/**
* NUDR_DataRepository API OpenAPI file
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB,
* ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
/*
* PatchOperation.h
*
*
*/
#ifndef PatchOperation_H_
#define PatchOperation_H_
#include <nlohmann/json.hpp>
#define PATCH_OPERATION_ADD "add"
#define PATCH_OPERATION_COPY "copy"
#define PATCH_OPERATION_MOVE "move"
#define PATCH_OPERATION_REMOVE "remove"
#define PATCH_OPERATION_REPLACE "replace"
namespace oai {
namespace ausf_server {
namespace model {
/// <summary>
///
/// </summary>
class PatchOperation {
public:
PatchOperation();
virtual ~PatchOperation();
void validate();
/////////////////////////////////////////////
/// PatchOperation members
friend void to_json(nlohmann::json &j, const PatchOperation &o);
friend void from_json(const nlohmann::json &j, PatchOperation &o);
protected:
};
} // namespace model
} // namespace ausf_server
} // namespace oai
#endif /* PatchOperation_H_ */
......@@ -31,6 +31,8 @@ add_library (AUSF STATIC
ausf_app.cpp
ausf_client.cpp
ausf_config.cpp
task_manager.cpp
ausf_event.cpp
ausf_profile.cpp
ausf_nrf.cpp
)
......@@ -30,50 +30,49 @@
#include "ausf_app.hpp"
#include "ausf_nrf.hpp"
#include <unistd.h>
#include "logger.hpp"
#include "ausf_client.hpp"
#include "ProblemDetails.h"
#include "ausf_client.hpp"
#include "logger.hpp"
#include <unistd.h>
#include "conversions.hpp"
#include "sha256.hpp"
#include "UEAuthenticationCtx.h"
#include "ConfirmationDataResponse.h"
#include "AuthenticationInfo.h"
#include "ConfirmationDataResponse.h"
#include "UEAuthenticationCtx.h"
#include "authentication_algorithms_with_5gaka.hpp"
#include <string>
#include "conversions.hpp"
#include "iostream"
#include "sha256.hpp"
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
using namespace oai::ausf::app;
extern ausf_app* ausf_app_inst;
ausf_client* ausf_client_inst = nullptr;
extern ausf_app *ausf_app_inst;
ausf_client *ausf_client_inst = nullptr;
using namespace config;
extern ausf_config ausf_cfg;
ausf_nrf* ausf_nrf_inst = nullptr;
ausf_nrf *ausf_nrf_inst = nullptr;
//------------------------------------------------------------------------------
ausf_app::ausf_app(const std::string& config_file)
: contextId2security_context(),
supi2security_context(),
ausf_app::ausf_app(const std::string &config_file, ausf_event &ev)
: event_sub(ev), contextId2security_context(), supi2security_context(),
imsi2security_context() {
Logger::ausf_app().startup("Starting...");
try {
ausf_client_inst = new ausf_client();
} catch (std::exception& e) {
} catch (std::exception &e) {
Logger::ausf_app().error("Cannot create AUSF APP: %s", e.what());
throw;
}
// Register to NRF
if (ausf_cfg.register_nrf) {
try {
ausf_nrf_inst = new ausf_nrf();
ausf_nrf_inst = new ausf_nrf(ev);
ausf_nrf_inst->register_to_nrf();
Logger::ausf_app().info("NRF TASK Created ");
} catch (std::exception& e) {
} catch (std::exception &e) {
Logger::ausf_app().error("Cannot create NRF TASK: %s", e.what());
throw;
}
......@@ -87,54 +86,54 @@ ausf_app::~ausf_app() {
}
//------------------------------------------------------------------------------
bool ausf_app::is_supi_2_security_context(const std::string& supi) const {
bool ausf_app::is_supi_2_security_context(const std::string &supi) const {
std::shared_lock lock(m_supi2security_context);
return bool{supi2security_context.count(supi) > 0};
}
//------------------------------------------------------------------------------
std::shared_ptr<security_context> ausf_app::supi_2_security_context(
const std::string& supi) const {
std::shared_ptr<security_context>
ausf_app::supi_2_security_context(const std::string &supi) const {
std::shared_lock lock(m_supi2security_context);
return supi2security_context.at(supi);
}
//------------------------------------------------------------------------------
void ausf_app::set_supi_2_security_context(
const std::string& supi, std::shared_ptr<security_context> sc) {
const std::string &supi, std::shared_ptr<security_context> sc) {
std::unique_lock lock(m_supi2security_context);
supi2security_context[supi] = sc;
}
//------------------------------------------------------------------------------
bool ausf_app::is_contextId_2_security_context(
const std::string& contextId) const {
const std::string &contextId) const {
std::shared_lock lock(m_contextId2security_context);
return bool{contextId2security_context.count(contextId) > 0};
}
//------------------------------------------------------------------------------
std::shared_ptr<security_context> ausf_app::contextId_2_security_context(
const std::string& contextId) const {
std::shared_ptr<security_context>
ausf_app::contextId_2_security_context(const std::string &contextId) const {
std::shared_lock lock(m_contextId2security_context);
return contextId2security_context.at(contextId);
}
//------------------------------------------------------------------------------
void ausf_app::set_contextId_2_security_context(
const std::string& contextId, std::shared_ptr<security_context> sc) {
const std::string &contextId, std::shared_ptr<security_context> sc) {
std::unique_lock lock(m_contextId2security_context);
contextId2security_context[contextId] = sc;
}
//------------------------------------------------------------------------------
void ausf_app::handle_ue_authentications(
const AuthenticationInfo& authenticationInfo, nlohmann::json& json_data,
std::string& location, Pistache::Http::Code& code, uint8_t http_version) {
const AuthenticationInfo &authenticationInfo, nlohmann::json &json_data,
std::string &location, Pistache::Http::Code &code, uint8_t http_version) {
Logger::ausf_app().info("Handle UE Authentication Request");
std::string snn =
authenticationInfo.getServingNetworkName(); // serving network name
std::string supi = authenticationInfo.getSupiOrSuci(); // supi
authenticationInfo.getServingNetworkName(); // serving network name
std::string supi = authenticationInfo.getSupiOrSuci(); // supi
// TODO: supi64_t supi64 = {};
Logger::ausf_app().info("ServingNetworkName %s", snn.c_str());
......@@ -142,12 +141,12 @@ void ausf_app::handle_ue_authentications(
// 5g he av from udm
// get authentication related info
std::string udm_uri = {};
std::string method = "POST";
std::string udm_uri = {};
std::string method = "POST";
std::string response = {};
udm_uri = "http://" +
udm_uri = "http://" +
std::string(
inet_ntoa(*((struct in_addr*) &ausf_cfg.udm_addr.ipv4_addr))) +
inet_ntoa(*((struct in_addr *)&ausf_cfg.udm_addr.ipv4_addr))) +
":" + std::to_string(ausf_cfg.udm_addr.port) + "/nudm-ueau/" +
ausf_cfg.udm_addr.api_version + "/" + supi +
"/security-information/generate-auth-data";
......@@ -155,14 +154,14 @@ void ausf_app::handle_ue_authentications(
// Create AuthInfo to send to UDM
nlohmann::json AuthInfo =
{}; // model AuthenticationInfo do not have ausfInstanceId field
{}; // model AuthenticationInfo do not have ausfInstanceId field
AuthInfo["servingNetworkName"] = snn;
AuthInfo["ausfInstanceId"] =
"400346f4-087e-40b1-a4cd-00566953999d"; // TODO: need to be generated
// automatically
"400346f4-087e-40b1-a4cd-00566953999d"; // TODO: need to be generated
// automatically
if (authenticationInfo
.resynchronizationInfoIsSet()) // set ResynchronizationInfo
.resynchronizationInfoIsSet()) // set ResynchronizationInfo
{
ResynchronizationInfo resynInfo =
authenticationInfo.getResynchronizationInfo();
......@@ -177,8 +176,8 @@ void ausf_app::handle_ue_authentications(
}
// Send request to UDM
ausf_client_inst->curl_http_client(
udm_uri, method, AuthInfo.dump(), response);
ausf_client_inst->curl_http_client(udm_uri, method, AuthInfo.dump(),
response);
Logger::ausf_app().info("Response from UDM: %s", response.c_str());
......@@ -186,30 +185,30 @@ void ausf_app::handle_ue_authentications(
nlohmann::json problemDetails_json = {};
nlohmann::json response_data = {};
std::string authType_udm = {};
std::string autn_udm = {};
std::string avType_udm = {};
std::string kausf_udm = {};
std::string rand_udm = {};
std::string xresStar_udm = {};
std::string authType_udm = {};
std::string autn_udm = {};
std::string avType_udm = {};
std::string kausf_udm = {};
std::string rand_udm = {};
std::string xresStar_udm = {};
try {
response_data = nlohmann::json::parse(response.c_str());
// Get security context
authType_udm = response_data.at("authType"); // AuthType
authType_udm = response_data.at("authType"); // AuthType
Logger::ausf_app().debug("authType %s", authType_udm.c_str());
autn_udm = response_data["authenticationVector"].at("autn"); // autn
autn_udm = response_data["authenticationVector"].at("autn"); // autn
Logger::ausf_app().debug("autn_udm %s", autn_udm.c_str());
avType_udm = response_data["authenticationVector"].at("avType"); // avType
avType_udm = response_data["authenticationVector"].at("avType"); // avType
Logger::ausf_app().debug("avType_udm %s", avType_udm.c_str());
kausf_udm = response_data["authenticationVector"].at("kausf"); // kausf
kausf_udm = response_data["authenticationVector"].at("kausf"); // kausf
Logger::ausf_app().debug("kausf_udm %s", kausf_udm.c_str());
rand_udm = response_data["authenticationVector"].at("rand"); // rand
rand_udm = response_data["authenticationVector"].at("rand"); // rand
Logger::ausf_app().debug("rand_udm %s", rand_udm.c_str());
xresStar_udm =
response_data["authenticationVector"].at("xresStar"); // xres*
response_data["authenticationVector"].at("xresStar"); // xres*
Logger::ausf_app().debug("xres*_udm %s", xresStar_udm.c_str());
} catch (nlohmann::json::exception& e) {
} catch (nlohmann::json::exception &e) {
// TODO: Catch parse_error exception
// TODO: Catch out_of_range exception
Logger::ausf_app().info("Could not Parse JSON content from UDM response");
......@@ -217,28 +216,28 @@ void ausf_app::handle_ue_authentications(
// TODO: error handling
problemDetails.setCause("CONTEXT_NOT_FOUND");
problemDetails.setStatus(404);
problemDetails.setDetail(
"Resource corresponding to User " + supi + " not found");
problemDetails.setDetail("Resource corresponding to User " + supi +
" not found");
to_json(problemDetails_json, problemDetails);
Logger::ausf_app().error(
"Resource corresponding to User %s not found", supi.c_str());
Logger::ausf_app().error("Resource corresponding to User %s not found",
supi.c_str());
Logger::ausf_app().info("Send 404 Not_Found response");
code = Pistache::Http::Code::Not_Found;
code = Pistache::Http::Code::Not_Found;
json_data = problemDetails_json;
return;
}
// 5G HE AV
uint8_t autn[16] = {0};
uint8_t rand[16] = {0};
uint8_t autn[16] = {0};
uint8_t rand[16] = {0};
uint8_t xresStar[16] = {0};
uint8_t kausf[32] = {0};
uint8_t kausf[32] = {0};
conv::hex_str_to_uint8(autn_udm.c_str(), autn); // autn
conv::hex_str_to_uint8(rand_udm.c_str(), rand); // rand
conv::hex_str_to_uint8(xresStar_udm.c_str(), xresStar); // xres*
conv::hex_str_to_uint8(kausf_udm.c_str(), kausf); // kausf
conv::hex_str_to_uint8(autn_udm.c_str(), autn); // autn
conv::hex_str_to_uint8(rand_udm.c_str(), rand); // rand
conv::hex_str_to_uint8(xresStar_udm.c_str(), xresStar); // xres*
conv::hex_str_to_uint8(kausf_udm.c_str(), kausf); // kausf
// Generating 5G AV from 5G HE AV
// HXRES* <-- XRES*
......@@ -249,88 +248,85 @@ void ausf_app::handle_ue_authentications(
Logger::ausf_app().debug("Generating 5G AV");
// Generating hxres*
uint8_t rand_ausf[16] = {0};
uint8_t autn_ausf[16] = {0};
uint8_t rand_ausf[16] = {0};
uint8_t autn_ausf[16] = {0};
uint8_t xresStar_ausf[16] = {0};
uint8_t kausf_ausf[32] = {0};
uint8_t hxresStar[16] = {0};
uint8_t kausf_ausf[32] = {0};
uint8_t hxresStar[16] = {0};
// Getting params from UDM 5G HE AV
std::copy(
std::begin(xresStar), std::end(xresStar), std::begin(xresStar_ausf));
std::copy(std::begin(xresStar), std::end(xresStar),
std::begin(xresStar_ausf));
std::copy(std::begin(rand), std::end(rand), std::begin(rand_ausf));
std::copy(std::begin(autn), std::end(autn), std::begin(autn_ausf));
std::copy(std::begin(kausf), std::end(kausf), std::begin(kausf_ausf));
// Generate_Hxres*
Authentication_5gaka::generate_Hxres(rand_ausf, xresStar_ausf, hxresStar);
Logger::ausf_app().debug(
"HXresStar calculated:\n %s",
(conv::uint8_to_hex_string(hxresStar, 16)).c_str());
Logger::ausf_app().debug("HXresStar calculated:\n %s",
(conv::uint8_to_hex_string(hxresStar, 16)).c_str());
uint8_t kseaf[32] = {0};
Authentication_5gaka::derive_kseaf(snn, kausf, kseaf);
Logger::ausf_app().debug(
"Kseaf calculated:\n %s", (conv::uint8_to_hex_string(kseaf, 32)).c_str());
Logger::ausf_app().debug("Kseaf calculated:\n %s",
(conv::uint8_to_hex_string(kseaf, 32)).c_str());
// Store the security context
std::shared_ptr<security_context> sc = {};
if (is_supi_2_security_context(supi)) {
Logger::ausf_app().debug(
"Update security context with SUPI: ", supi.c_str());
Logger::ausf_app().debug("Update security context with SUPI: ",
supi.c_str());
sc = supi_2_security_context(supi);
} else {
Logger::ausf_app().debug(
"Create a new security context with SUPI ", supi.c_str());
Logger::ausf_app().debug("Create a new security context with SUPI ",
supi.c_str());
sc = std::make_shared<security_context>();
set_supi_2_security_context(supi, sc);
}
// Update information
sc->supi_ausf = supi; // TODO: setter/getter
std::copy(
std::begin(rand_ausf), std::end(rand_ausf),
std::begin(sc->ausf_av_s.rand));
std::copy(
std::begin(autn_ausf), std::end(autn_ausf),
std::begin(sc->ausf_av_s.autn));
std::copy(
std::begin(hxresStar), std::end(hxresStar),
std::begin(sc->ausf_av_s.hxresStar));
std::copy(
std::begin(kseaf), std::end(kseaf), std::begin(sc->ausf_av_s.kseaf));
sc->supi_ausf = supi; // TODO: setter/getter
std::copy(std::begin(rand_ausf), std::end(rand_ausf),
std::begin(sc->ausf_av_s.rand));
std::copy(std::begin(autn_ausf), std::end(autn_ausf),
std::begin(sc->ausf_av_s.autn));
std::copy(std::begin(hxresStar), std::end(hxresStar),
std::begin(sc->ausf_av_s.hxresStar));
std::copy(std::begin(kseaf), std::end(kseaf),
std::begin(sc->ausf_av_s.kseaf));
// store xres* in ausf
std::copy(
std::begin(xresStar), std::end(xresStar), std::begin(sc->xres_star));
std::copy(std::begin(xresStar), std::end(xresStar),
std::begin(sc->xres_star));
sc->supi_ausf = authenticationInfo.getSupiOrSuci(); // store supi in ausf
sc->serving_nn = snn; // store snn in ausf
sc->auth_type = authType_udm; // store authType in ausf
sc->supi_ausf = authenticationInfo.getSupiOrSuci(); // store supi in ausf
sc->serving_nn = snn; // store snn in ausf
sc->auth_type = authType_udm; // store authType in ausf
sc->kausf_tmp =
conv::uint8_to_hex_string(kausf_ausf, 32); // store kausf_tmp in ausf
conv::uint8_to_hex_string(kausf_ausf, 32); // store kausf_tmp in ausf
// Send authentication context to SEAF (AUSF->SEAF)
UEAuthenticationCtx UEAuthCtx;
string rand_s = conv::uint8_to_hex_string(rand_ausf, 16);
string autn_s = conv::uint8_to_hex_string(autn_ausf, 16);
string rand_s = conv::uint8_to_hex_string(rand_ausf, 16);
string autn_s = conv::uint8_to_hex_string(autn_ausf, 16);
string hxresStar_s = conv::uint8_to_hex_string(hxresStar, 16);
UEAuthCtx.setAuthType(authType_udm); // authType(string)
UEAuthCtx.setAuthType(authType_udm); // authType(string)
std::map<std::string, LinksValueSchema> ausf_links; // links(std::map)
std::map<std::string, LinksValueSchema> ausf_links; // links(std::map)
LinksValueSchema ausf_Href;
std::string resourceURI;
std::string authCtxId_s;
authCtxId_s = autn_s; // authCtxId = autn
authCtxId_s = autn_s; // authCtxId = autn
// Store the security context
set_contextId_2_security_context(authCtxId_s, sc);
std::string ausf_port = std::to_string(ausf_cfg.sbi.port);
if (http_version == 2) ausf_port = std::to_string(ausf_cfg.sbi_http2_port);
if (http_version == 2)
ausf_port = std::to_string(ausf_cfg.sbi_http2_port);
resourceURI =
"http://" +
std::string(inet_ntoa(*((struct in_addr*) &ausf_cfg.sbi.addr4))) + ":" +
std::string(inet_ntoa(*((struct in_addr *)&ausf_cfg.sbi.addr4))) + ":" +
ausf_port + "/nausf-auth/v1/ue-authentications/" + authCtxId_s +
"/5g-aka-confirmation";
ausf_Href.setHref(resourceURI);
......@@ -353,8 +349,8 @@ void ausf_app::handle_ue_authentications(
//------------------------------------------------------------------------------
void ausf_app::handle_ue_authentications_confirmation(
const std::string& authCtxId, const ConfirmationData& confirmationData,
nlohmann::json& json_data, Pistache::Http::Code& code) {
const std::string &authCtxId, const ConfirmationData &confirmationData,
nlohmann::json &json_data, Pistache::Http::Code &code) {
// SEAF-> AUSF
ProblemDetails problemDetails;
nlohmann::json problemDetails_json = {};
......@@ -363,13 +359,12 @@ void ausf_app::handle_ue_authentications_confirmation(
// Get the security context
std::shared_ptr<security_context> sc = {};
if (is_contextId_2_security_context(authCtxId)) {
Logger::ausf_app().debug(
"Retrieve security context with authCtxId: ", authCtxId.c_str());
Logger::ausf_app().debug("Retrieve security context with authCtxId: ",
authCtxId.c_str());
sc = contextId_2_security_context(authCtxId);
} else { // No ue-authentications request before
Logger::ausf_app().debug(
"Security context with authCtxId ", authCtxId.c_str(),
"does not exist");
} else { // No ue-authentications request before
Logger::ausf_app().debug("Security context with authCtxId ",
authCtxId.c_str(), "does not exist");
problemDetails.setCause("SERVING_NETWORK_NOT_AUTHORIZED");
problemDetails.setStatus(403);
......@@ -378,23 +373,23 @@ void ausf_app::handle_ue_authentications_confirmation(
Logger::ausf_app().error("Serving Network Not Authorized");
Logger::ausf_app().info("Send 403 Forbidden response");
code = Pistache::Http::Code::Forbidden;
code = Pistache::Http::Code::Forbidden;
json_data = problemDetails_json;
return;
}
Logger::ausf_app().info(
"Received authCtxId %s", authCtxId.c_str()); // authCtxId
Logger::ausf_app().info(
"Received res* %s", confirmationData.getResStar().c_str());
Logger::ausf_app().info("Received authCtxId %s",
authCtxId.c_str()); // authCtxId
Logger::ausf_app().info("Received res* %s",
confirmationData.getResStar().c_str());
uint8_t resStar[16] = {0};
conv::hex_str_to_uint8(confirmationData.getResStar().c_str(), resStar);
ConfirmationDataResponse confirmResponse;
uint8_t authCtxId_seaf[16];
conv::hex_str_to_uint8(
authCtxId.c_str(), authCtxId_seaf); // authCtxId in SEAF
conv::hex_str_to_uint8(authCtxId.c_str(),
authCtxId_seaf); // authCtxId in SEAF
Logger::ausf_app().debug(
"authCtxId in AUSF: %s",
......@@ -402,38 +397,37 @@ void ausf_app::handle_ue_authentications_confirmation(
bool is_auth_vectors_present =
Authentication_5gaka::equal_uint8(sc->ausf_av_s.autn, authCtxId_seaf, 16);
if (!is_auth_vectors_present) // AV expired
if (!is_auth_vectors_present) // AV expired
{
Logger::ausf_app().error(
"Authentication failure by home network with authCtxId %s: AV expired",
authCtxId.c_str());
confirmResponse.setAuthResult(is_auth_vectors_present);
sc->kausf_tmp = "invalid";
} else // AV valid
} else // AV valid
{
Logger::ausf_app().info("AV is up to date, handling received res*...");
// Get stored xres* and compare with res*
uint8_t xresStar[16] = {0};
// xres* stored for 5g-aka-confirmation
std::copy(
std::begin(sc->xres_star), std::end(sc->xres_star),
std::begin(xresStar));
std::copy(std::begin(sc->xres_star), std::end(sc->xres_star),
std::begin(xresStar));
Logger::ausf_app().debug(
"xres* in AUSF: %s", (conv::uint8_to_hex_string(xresStar, 16)).c_str());
Logger::ausf_app().debug(
"xres in AMF: %s", (conv::uint8_to_hex_string(resStar, 16)).c_str());
Logger::ausf_app().debug("xres* in AUSF: %s",
(conv::uint8_to_hex_string(xresStar, 16)).c_str());
Logger::ausf_app().debug("xres in AMF: %s",
(conv::uint8_to_hex_string(resStar, 16)).c_str());
bool authResult = Authentication_5gaka::equal_uint8(xresStar, resStar, 16);
confirmResponse.setAuthResult(authResult);
if (!authResult) // Authentication failed
if (!authResult) // Authentication failed
{
Logger::ausf_app().error(
"Authentication failure by home network with authCtxId %s: res* != "
"xres*",
authCtxId.c_str());
} else // Authentication success
} else // Authentication success
{
Logger::ausf_app().info("Authentication successful by home network!");
// Send Kseaf to SEAF
......@@ -445,13 +439,13 @@ void ausf_app::handle_ue_authentications_confirmation(
confirmResponse.setSupi(sc->supi_ausf);
}
// Send authResult to UDM (authentication result info)
std::string udm_uri = {};
std::string method = "POST";
std::string udm_uri = {};
std::string method = "POST";
std::string response = {};
udm_uri =
"http://" +
std::string(
inet_ntoa(*((struct in_addr*) &ausf_cfg.udm_addr.ipv4_addr))) +
inet_ntoa(*((struct in_addr *)&ausf_cfg.udm_addr.ipv4_addr))) +
":" + std::to_string(ausf_cfg.udm_addr.port) + "/nudm-ueau/" +
ausf_cfg.udm_addr.api_version + "/" + sc->supi_ausf + "/auth-events";
......@@ -460,8 +454,8 @@ void ausf_app::handle_ue_authentications_confirmation(
// Form request body
nlohmann::json confirmResultInfo = {};
confirmResultInfo["nfInstanceId"] =
"400346f4-087e-40b1-a4cd-00566953999d"; // TODO: remove hardcoded
// value
"400346f4-087e-40b1-a4cd-00566953999d"; // TODO: remove hardcoded
// value
confirmResultInfo["success"] = true;
// TODO: Update timestamp
......@@ -469,17 +463,17 @@ void ausf_app::handle_ue_authentications_confirmation(
time(&rawtime);
char buf[32];
strftime(buf, sizeof(buf), "%FT%TZ", gmtime(&rawtime));
confirmResultInfo["timeStamp"] = buf; // timestamp generated
confirmResultInfo["timeStamp"] = buf; // timestamp generated
// Get info from the security context (stored in AUSF)
confirmResultInfo["authType"] = sc->auth_type;
confirmResultInfo["authType"] = sc->auth_type;
confirmResultInfo["servingNetworkName"] = sc->serving_nn;
confirmResultInfo["authRemovalInd"] = false;
confirmResultInfo["authRemovalInd"] = false;
Logger::ausf_app().debug(
"confirmResultInfo: %s", confirmResultInfo.dump().c_str());
ausf_client_inst->curl_http_client(
udm_uri, method, confirmResultInfo.dump(), response);
Logger::ausf_app().debug("confirmResultInfo: %s",
confirmResultInfo.dump().c_str());
ausf_client_inst->curl_http_client(udm_uri, method,
confirmResultInfo.dump(), response);
}
}
......
......@@ -29,15 +29,16 @@
#ifndef FILE_AUSF_APP_HPP_SEEN
#define FILE_AUSF_APP_HPP_SEEN
#include "ausf_event.hpp"
#include <string>
#include "AuthenticationInfo.h"
#include "UEAuthenticationCtx.h"
#include "ConfirmationData.h"
#include "UEAuthenticationCtx.h"
#include "ausf.h"
#include <pistache/http.h>
#include <map>
#include <pistache/http.h>
#include <shared_mutex>
#include <string>
namespace oai {
namespace ausf {
......@@ -46,56 +47,58 @@ namespace app {
using namespace oai::ausf_server::model;
class security_context {
public:
public:
security_context() : xres_star() {
// supi = {};
ausf_av_s = {};
supi_ausf = "";
auth_type = "";
ausf_av_s = {};
supi_ausf = "";
auth_type = "";
serving_nn = "";
kausf_tmp = "";
kausf_tmp = "";
}
// supi64_t supi;
AUSF_AV_s ausf_av_s;
uint8_t xres_star[16]; // store xres*
std::string supi_ausf; // store supi
std::string auth_type; // store authType
std::string serving_nn; // store serving network name
std::string kausf_tmp; // store Kausf(string)
uint8_t xres_star[16]; // store xres*
std::string supi_ausf; // store supi
std::string auth_type; // store authType
std::string serving_nn; // store serving network name
std::string kausf_tmp; // store Kausf(string)
};
// class ausf_config;
class ausf_app {
public:
explicit ausf_app(const std::string& config_file);
ausf_app(ausf_app const&) = delete;
void operator=(ausf_app const&) = delete;
public:
explicit ausf_app(const std::string &config_file, ausf_event &ev);
ausf_app(ausf_app const &) = delete;
void operator=(ausf_app const &) = delete;
virtual ~ausf_app();
void handle_ue_authentications(
const AuthenticationInfo& authenticationInfo, nlohmann::json& json_data,
std::string& location, Pistache::Http::Code& code,
uint8_t http_version = 1);
void handle_ue_authentications(const AuthenticationInfo &authenticationInfo,
nlohmann::json &json_data,
std::string &location,
Pistache::Http::Code &code,
uint8_t http_version = 1);
void handle_ue_authentications_confirmation(
const std::string& authCtxId, const ConfirmationData& confirmation_data,
nlohmann::json& json_data, Pistache::Http::Code& code);
bool is_supi_2_security_context(const std::string& supi) const;
std::shared_ptr<security_context> supi_2_security_context(
const std::string& supi) const;
void set_supi_2_security_context(
const std::string& supi, std::shared_ptr<security_context> sc);
bool is_contextId_2_security_context(const std::string& contextId) const;
std::shared_ptr<security_context> contextId_2_security_context(
const std::string& contextId) const;
void set_contextId_2_security_context(
const std::string& contextId, std::shared_ptr<security_context> sc);
private:
const std::string &authCtxId, const ConfirmationData &confirmation_data,
nlohmann::json &json_data, Pistache::Http::Code &code);
bool is_supi_2_security_context(const std::string &supi) const;
std::shared_ptr<security_context>
supi_2_security_context(const std::string &supi) const;
void set_supi_2_security_context(const std::string &supi,
std::shared_ptr<security_context> sc);
bool is_contextId_2_security_context(const std::string &contextId) const;
std::shared_ptr<security_context>
contextId_2_security_context(const std::string &contextId) const;
void set_contextId_2_security_context(const std::string &contextId,
std::shared_ptr<security_context> sc);
private:
ausf_event &event_sub;
std::map<supi64_t, std::shared_ptr<security_context>> imsi2security_context;
mutable std::shared_mutex m_imsi2security_context;
......@@ -107,9 +110,9 @@ class ausf_app {
contextId2security_context;
mutable std::shared_mutex m_contextId2security_context;
};
} // namespace app
} // namespace ausf
} // namespace oai
} // namespace app
} // namespace ausf
} // namespace oai
#include "ausf_config.hpp"
#endif /* FILE_AUSF_APP_HPP_SEEN */
......@@ -30,13 +30,13 @@
#include "ausf_client.hpp"
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <pistache/http.h>
#include <pistache/mime.h>
#include <nlohmann/json.hpp>
#include <stdexcept>
#include "logger.hpp"
#include "ausf.h"
#include "logger.hpp"
using namespace Pistache::Http;
using namespace Pistache::Http::Mime;
......@@ -44,13 +44,13 @@ using namespace oai::ausf::app;
using namespace config;
using json = nlohmann::json;
extern ausf_client* ausf_client_inst;
extern ausf_client *ausf_client_inst;
extern ausf_config ausf_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) {
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;
......@@ -65,25 +65,25 @@ ausf_client::~ausf_client() {
}
//------------------------------------------------------------------------------
void ausf_client::curl_http_client(
std::string remoteUri, std::string method, std::string msgBody,
std::string& response) {
void ausf_client::curl_http_client(std::string remoteUri, std::string method,
std::string msgBody, std::string &response) {
Logger::ausf_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);
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);
memcpy((void *)body_data, (void *)msgBody.c_str(), str_len);
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl_easy_init();
CURL *curl = curl_easy_init();
uint8_t http_version = 1;
if (ausf_cfg.use_http2) http_version = 2;
if (ausf_cfg.use_http2)
http_version = 2;
if (curl) {
CURLcode res = {};
struct curl_slist* headers = nullptr;
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";
......@@ -112,8 +112,8 @@ void ausf_client::curl_http_client(
// 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);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
......@@ -135,13 +135,13 @@ void ausf_client::curl_http_client(
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
// Process the response
response = *httpData.get();
response = *httpData.get();
bool is_response_ok = true;
Logger::ausf_app().info("Get response with HTTP code (%d)", httpCode);
if (httpCode == 0) {
Logger::ausf_app().info(
"Cannot get response when calling %s", remoteUri.c_str());
Logger::ausf_app().info("Cannot get response when calling %s",
remoteUri.c_str());
// free curl before returning
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
......@@ -166,14 +166,14 @@ void ausf_client::curl_http_client(
if (!is_response_ok) {
try {
response_data = nlohmann::json::parse(response);
} catch (nlohmann::json::exception& e) {
} catch (nlohmann::json::exception &e) {
Logger::ausf_app().info("Could not get JSON content from the response");
// Set the default Cause
response_data["error"]["cause"] = "504 Gateway Timeout";
}
Logger::ausf_app().info(
"Get response with jsonData: %s", response.c_str());
Logger::ausf_app().info("Get response with jsonData: %s",
response.c_str());
std::string cause = response_data["error"]["cause"];
Logger::ausf_app().info("Call Network Function services failure");
......
......@@ -34,26 +34,25 @@
#include <curl/curl.h>
#include "logger.hpp"
#include "ausf_config.hpp"
#include "logger.hpp"
namespace oai {
namespace ausf {
namespace app {
class ausf_client {
private:
public:
private:
public:
ausf_client();
virtual ~ausf_client();
ausf_client(ausf_client const&) = delete;
ausf_client(ausf_client const &) = delete;
void curl_http_client(
std::string remoteUri, std::string method, std::string msgBody,
std::string& response);
void curl_http_client(std::string remoteUri, std::string method,
std::string msgBody, std::string &response);
};
} // namespace app
} // namespace ausf
} // namespace oai
} // namespace app
} // namespace ausf
} // namespace oai
#endif /* FILE_AUSF_CLIENT_HPP_SEEN */
......@@ -28,13 +28,13 @@
#include "ausf_config.hpp"
#include "string.hpp"
#include <iostream>
#include <libconfig.h++>
#include "string.hpp"
#include "logger.hpp"
#include "if.hpp"
#include "fqdn.hpp"
#include "if.hpp"
#include "logger.hpp"
#include "string.hpp"
......@@ -58,93 +58,91 @@ namespace config {
//------------------------------------------------------------------------------
ausf_config::ausf_config() : sbi(), ausf_name(), pid_dir(), instance() {
udm_addr.ipv4_addr.s_addr = INADDR_ANY;
udm_addr.port = 80;
udm_addr.api_version = "v1";
udm_addr.fqdn = {};
use_fqdn_dns = false;
use_http2 = false;
udm_addr.port = 80;
udm_addr.api_version = "v1";
udm_addr.fqdn = {};
use_fqdn_dns = false;
use_http2 = false;
}
//------------------------------------------------------------------------------
ausf_config::~ausf_config() {}
//------------------------------------------------------------------------------
int ausf_config::load(const std::string& config_file) {
Logger::config().debug(
"\nLoad AUSF system configuration file(%s)", config_file.c_str());
int ausf_config::load(const std::string &config_file) {
Logger::config().debug("\nLoad AUSF system configuration file(%s)",
config_file.c_str());
Config cfg;
unsigned char buf_in6_addr[sizeof(struct in6_addr)];
try {
cfg.readFile(config_file.c_str());
} catch (const FileIOException& fioex) {
Logger::config().error(
"I/O error while reading file %s - %s", config_file.c_str(),
fioex.what());
} catch (const FileIOException &fioex) {
Logger::config().error("I/O error while reading file %s - %s",
config_file.c_str(), fioex.what());
throw;
} catch (const ParseException& pex) {
Logger::config().error(
"Parse error at %s:%d - %s", pex.getFile(), pex.getLine(),
pex.getError());
} catch (const ParseException &pex) {
Logger::config().error("Parse error at %s:%d - %s", pex.getFile(),
pex.getLine(), pex.getError());
throw;
}
const Setting& root = cfg.getRoot();
const Setting &root = cfg.getRoot();
try {
const Setting& ausf_cfg = root[AUSF_CONFIG_STRING_AUSF_CONFIG];
} catch (const SettingNotFoundException& nfex) {
const Setting &ausf_cfg = root[AUSF_CONFIG_STRING_AUSF_CONFIG];
} catch (const SettingNotFoundException &nfex) {
Logger::config().error("%s : %s", nfex.what(), nfex.getPath());
return RETURNerror;
}
const Setting& ausf_cfg = root[AUSF_CONFIG_STRING_AUSF_CONFIG];
const Setting &ausf_cfg = root[AUSF_CONFIG_STRING_AUSF_CONFIG];
try {
ausf_cfg.lookupValue(AUSF_CONFIG_STRING_INSTANCE_ID, instance);
} catch (const SettingNotFoundException& nfex) {
Logger::config().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
} catch (const SettingNotFoundException &nfex) {
Logger::config().error("%s : %s, using defaults", nfex.what(),
nfex.getPath());
}
try {
ausf_cfg.lookupValue(AUSF_CONFIG_STRING_PID_DIRECTORY, pid_dir);
} catch (const SettingNotFoundException& nfex) {
Logger::config().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
} catch (const SettingNotFoundException &nfex) {
Logger::config().error("%s : %s, using defaults", nfex.what(),
nfex.getPath());
}
try {
ausf_cfg.lookupValue(AUSF_CONFIG_STRING_AUSF_NAME, ausf_name);
} catch (const SettingNotFoundException& nfex) {
Logger::config().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
} catch (const SettingNotFoundException &nfex) {
Logger::config().error("%s : %s, using defaults", nfex.what(),
nfex.getPath());
}
// AUSF SBI interface
try {
const Setting& new_if_cfg = ausf_cfg[AUSF_CONFIG_STRING_INTERFACES];
const Setting &new_if_cfg = ausf_cfg[AUSF_CONFIG_STRING_INTERFACES];
const Setting& sbi_cfg = new_if_cfg[AUSF_CONFIG_STRING_INTERFACE_SBI];
const Setting &sbi_cfg = new_if_cfg[AUSF_CONFIG_STRING_INTERFACE_SBI];
load_interface(sbi_cfg, sbi);
// HTTP2 port
if (!(sbi_cfg.lookupValue(
AUSF_CONFIG_STRING_SBI_HTTP2_PORT, sbi_http2_port))) {
if (!(sbi_cfg.lookupValue(AUSF_CONFIG_STRING_SBI_HTTP2_PORT,
sbi_http2_port))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
throw(AUSF_CONFIG_STRING_SBI_HTTP2_PORT " failed");
}
// API Version
if (!(sbi_cfg.lookupValue(
AUSF_CONFIG_STRING_API_VERSION, sbi_api_version))) {
if (!(sbi_cfg.lookupValue(AUSF_CONFIG_STRING_API_VERSION,
sbi_api_version))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_API_VERSION " failed");
throw(AUSF_CONFIG_STRING_API_VERSION " failed");
}
} catch (const SettingNotFoundException& nfex) {
Logger::config().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
} catch (const SettingNotFoundException &nfex) {
Logger::config().error("%s : %s, using defaults", nfex.what(),
nfex.getPath());
return RETURNerror;
}
// Support features
try {
const Setting& support_features =
const Setting &support_features =
ausf_cfg[AUSF_CONFIG_STRING_SUPPORT_FEATURES];
std::string opt = {};
......@@ -156,8 +154,8 @@ int ausf_config::load(const std::string& config_file) {
use_fqdn_dns = false;
}
support_features.lookupValue(
AUSF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2, opt);
support_features.lookupValue(AUSF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2,
opt);
if (boost::iequals(opt, "yes")) {
use_http2 = true;
} else {
......@@ -172,9 +170,9 @@ int ausf_config::load(const std::string& config_file) {
register_nrf = false;
}
} catch (const SettingNotFoundException& nfex) {
Logger::ausf_app().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
} catch (const SettingNotFoundException &nfex) {
Logger::ausf_app().error("%s : %s, using defaults", nfex.what(),
nfex.getPath());
return RETURNerror;
}
......@@ -182,16 +180,15 @@ int ausf_config::load(const std::string& config_file) {
try {
std::string astring = {};
const Setting& udm_cfg = ausf_cfg[AUSF_CONFIG_STRING_UDM];
const Setting &udm_cfg = ausf_cfg[AUSF_CONFIG_STRING_UDM];
struct in_addr udm_ipv4_addr = {};
unsigned int udm_port = 0;
std::string udm_api_version = {};
unsigned int udm_port = 0;
std::string udm_api_version = {};
if (!use_fqdn_dns) {
udm_cfg.lookupValue(AUSF_CONFIG_STRING_UDM_IPV4_ADDRESS, astring);
IPV4_STR_ADDR_TO_INADDR(
util::trim(astring).c_str(), udm_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR UDM !");
IPV4_STR_ADDR_TO_INADDR(util::trim(astring).c_str(), udm_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR UDM !");
udm_addr.ipv4_addr = udm_ipv4_addr;
if (!(udm_cfg.lookupValue(AUSF_CONFIG_STRING_UDM_PORT, udm_port))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_UDM_PORT "failed");
......@@ -199,8 +196,8 @@ int ausf_config::load(const std::string& config_file) {
}
udm_addr.port = udm_port;
if (!(udm_cfg.lookupValue(
AUSF_CONFIG_STRING_API_VERSION, udm_api_version))) {
if (!(udm_cfg.lookupValue(AUSF_CONFIG_STRING_API_VERSION,
udm_api_version))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_API_VERSION "failed");
throw(AUSF_CONFIG_STRING_API_VERSION "failed");
}
......@@ -208,16 +205,15 @@ int ausf_config::load(const std::string& config_file) {
} else {
udm_cfg.lookupValue(AUSF_CONFIG_STRING_FQDN_DNS, astring);
uint8_t addr_type = {0};
uint8_t addr_type = {0};
std::string address = {};
fqdn::resolve(astring, address, udm_port, addr_type);
if (addr_type != 0) { // IPv6
if (addr_type != 0) { // IPv6
// TODO:
throw("DO NOT SUPPORT IPV6 ADDR FOR UDM!");
} else { // IPv4
IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), udm_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR NRF !");
} else { // IPv4
IPV4_STR_ADDR_TO_INADDR(util::trim(address).c_str(), udm_ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR NRF !");
udm_addr.ipv4_addr = udm_ipv4_addr;
// udm_addr.port = udm_port;
// We hardcode udm port from config for the moment
......@@ -225,20 +221,20 @@ int ausf_config::load(const std::string& config_file) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_UDM_PORT "failed");
throw(AUSF_CONFIG_STRING_UDM_PORT "failed");
}
udm_addr.port = udm_port;
udm_addr.port = udm_port;
std::string udm_api_version = {};
if (!(udm_cfg.lookupValue(
AUSF_CONFIG_STRING_API_VERSION, udm_api_version))) {
if (!(udm_cfg.lookupValue(AUSF_CONFIG_STRING_API_VERSION,
udm_api_version))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_API_VERSION "failed");
throw(AUSF_CONFIG_STRING_API_VERSION "failed");
}
udm_addr.api_version =
udm_api_version; // TODO: to get API version from DNS
udm_api_version; // TODO: to get API version from DNS
udm_addr.fqdn = astring;
}
}
} catch (const SettingNotFoundException& nfex) {
} catch (const SettingNotFoundException &nfex) {
Logger::ausf_app().error("%s : %s", nfex.what(), nfex.getPath());
return RETURNerror;
}
......@@ -248,16 +244,15 @@ int ausf_config::load(const std::string& config_file) {
try {
std::string astring = {};
const Setting& nrf_cfg = ausf_cfg[AUSF_CONFIG_STRING_NRF];
const Setting &nrf_cfg = ausf_cfg[AUSF_CONFIG_STRING_NRF];
struct in_addr nrf_ipv4_addr = {};
unsigned int nrf_port = 0;
std::string nrf_api_version = {};
unsigned int nrf_port = 0;
std::string nrf_api_version = {};
if (!use_fqdn_dns) {
nrf_cfg.lookupValue(AUSF_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 !");
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(AUSF_CONFIG_STRING_NRF_PORT, nrf_port))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_NRF_PORT "failed");
......@@ -265,8 +260,8 @@ int ausf_config::load(const std::string& config_file) {
}
nrf_addr.port = nrf_port;
if (!(nrf_cfg.lookupValue(
AUSF_CONFIG_STRING_API_VERSION, nrf_api_version))) {
if (!(nrf_cfg.lookupValue(AUSF_CONFIG_STRING_API_VERSION,
nrf_api_version))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_API_VERSION "failed");
throw(AUSF_CONFIG_STRING_API_VERSION "failed");
}
......@@ -274,20 +269,19 @@ int ausf_config::load(const std::string& config_file) {
} else {
nrf_cfg.lookupValue(AUSF_CONFIG_STRING_FQDN_DNS, astring);
uint8_t addr_type = {0};
uint8_t addr_type = {0};
std::string address = {};
fqdn::resolve(astring, address, nrf_port, addr_type);
if (addr_type != 0) { // IPv6
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 !");
} 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;
// nrf_addr.port = nrf_port;
nrf_addr.api_version = "v1"; // TODO: to get API version from DNS
nrf_addr.fqdn = astring;
nrf_addr.api_version = "v1"; // TODO: to get API version from DNS
nrf_addr.fqdn = astring;
// We hardcode nrf port from config for the moment
if (!(nrf_cfg.lookupValue(AUSF_CONFIG_STRING_NRF_PORT, nrf_port))) {
Logger::ausf_app().error(AUSF_CONFIG_STRING_NRF_PORT "failed");
......@@ -296,7 +290,7 @@ int ausf_config::load(const std::string& config_file) {
nrf_addr.port = nrf_port;
}
}
} catch (const SettingNotFoundException& nfex) {
} catch (const SettingNotFoundException &nfex) {
Logger::ausf_app().error("%s : %s", nfex.what(), nfex.getPath());
return RETURNerror;
}
......@@ -306,8 +300,8 @@ int ausf_config::load(const std::string& config_file) {
//------------------------------------------------------------------------------
void ausf_config::display() {
Logger::config().info(
"==== OAI-CN5G %s v%s ====", PACKAGE_NAME, PACKAGE_VERSION);
Logger::config().info("==== OAI-CN5G %s v%s ====", PACKAGE_NAME,
PACKAGE_VERSION);
Logger::config().info("================= AUSF =================");
Logger::config().info("Configuration AUSF:");
Logger::config().info("- Instance ...............: %d", instance);
......@@ -319,40 +313,38 @@ void ausf_config::display() {
Logger::config().info(" IPv4 Addr ............: %s", inet_ntoa(sbi.addr4));
Logger::config().info(" HTTP1 Port ...........: %d", sbi.port);
Logger::config().info(" HTTP2 Port............: %d", sbi_http2_port);
Logger::config().info(
" API Version...........: %s", sbi_api_version.c_str());
Logger::config().info(" API Version...........: %s",
sbi_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(" 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("- UDM:");
Logger::config().info(
" IPv4 Addr ............: %s",
inet_ntoa(*((struct in_addr*) &udm_addr.ipv4_addr)));
Logger::config().info(" IPv4 Addr ............: %s",
inet_ntoa(*((struct in_addr *)&udm_addr.ipv4_addr)));
Logger::config().info(" Port .................: %lu ", udm_addr.port);
Logger::config().info(
" API version ..........: %s", udm_addr.api_version.c_str());
Logger::config().info(" API version ..........: %s",
udm_addr.api_version.c_str());
Logger::config().info("- NRF:");
Logger::config().info(
" IPv4 Addr ............: %s",
inet_ntoa(*((struct in_addr*) &nrf_addr.ipv4_addr)));
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());
Logger::config().info(" API version ..........: %s",
nrf_addr.api_version.c_str());
if (use_fqdn_dns)
Logger::config().info(
" FQDN .................: %s", udm_addr.fqdn.c_str());
Logger::config().info(" FQDN .................: %s",
nrf_addr.fqdn.c_str());
}
//------------------------------------------------------------------------------
int ausf_config::load_interface(
const libconfig::Setting& if_cfg, interface_cfg_t& cfg) {
int ausf_config::load_interface(const libconfig::Setting &if_cfg,
interface_cfg_t &cfg) {
if_cfg.lookupValue(AUSF_CONFIG_STRING_INTERFACE_NAME, cfg.if_name);
util::trim(cfg.if_name);
if (not boost::iequals(cfg.if_name, "none")) {
......@@ -360,23 +352,23 @@ int ausf_config::load_interface(
if_cfg.lookupValue(AUSF_CONFIG_STRING_IPV4_ADDRESS, address);
util::trim(address);
if (boost::iequals(address, "read")) {
if (get_inet_addr_infos_from_iface(
cfg.if_name, cfg.addr4, cfg.network4, cfg.mtu)) {
if (get_inet_addr_infos_from_iface(cfg.if_name, cfg.addr4, cfg.network4,
cfg.mtu)) {
Logger::config().error(
"Could not read %s network interface configuration", cfg.if_name);
return RETURNerror;
}
} else {
std::vector<std::string> words;
boost::split(
words, address, boost::is_any_of("/"), boost::token_compress_on);
boost::split(words, address, boost::is_any_of("/"),
boost::token_compress_on);
if (words.size() != 2) {
Logger::config().error(
"Bad value " AUSF_CONFIG_STRING_IPV4_ADDRESS " = %s in config file",
address.c_str());
Logger::config().error("Bad value " AUSF_CONFIG_STRING_IPV4_ADDRESS
" = %s in config file",
address.c_str());
return RETURNerror;
}
unsigned char buf_in_addr[sizeof(struct in6_addr)]; // you never know...
unsigned char buf_in_addr[sizeof(struct in6_addr)]; // you never know...
if (inet_pton(AF_INET, util::trim(words.at(0)).c_str(), buf_in_addr) ==
1) {
memcpy(&cfg.addr4, buf_in_addr, sizeof(struct in_addr));
......@@ -387,13 +379,13 @@ int ausf_config::load_interface(
util::trim(words.at(0)).c_str());
return RETURNerror;
}
cfg.network4.s_addr = htons(
ntohs(cfg.addr4.s_addr) &
0xFFFFFFFF << (32 - std::stoi(util::trim(words.at(1)))));
cfg.network4.s_addr =
htons(ntohs(cfg.addr4.s_addr) &
0xFFFFFFFF << (32 - std::stoi(util::trim(words.at(1)))));
}
if_cfg.lookupValue(AUSF_CONFIG_STRING_PORT, cfg.port);
}
return RETURNok;
}
} // namespace config
} // namespace config
......@@ -33,11 +33,11 @@
#include <arpa/inet.h>
#include <libconfig.h++>
#include <mutex>
#include <netinet/in.h>
#include <string>
#include <sys/socket.h>
#include <mutex>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
......@@ -85,11 +85,11 @@ typedef struct interface_cfg_s {
} interface_cfg_t;
class ausf_config {
public:
public:
ausf_config();
~ausf_config();
int load(const std::string& config_file);
int load_interface(const Setting& if_cfg, interface_cfg_t& cfg);
int load(const std::string &config_file);
int load_interface(const Setting &if_cfg, interface_cfg_t &cfg);
void display();
unsigned int instance;
......@@ -120,6 +120,6 @@ class ausf_config {
bool use_http2;
};
} // namespace config
} // namespace config
#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 ausf_event.cpp
\brief
\author Tien-Thinh NGUYEN (EURECOM)
\company
\date 2022
\email: contact@openairinterface.org
*/
#include "ausf_event.hpp"
using namespace oai::ausf::app;
bs2::connection
ausf_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);
}
//------------------------------------------------------------------------------
bs2::connection ausf_event::subscribe_loss_of_connectivity(
const loss_of_connectivity_sig_t::slot_type &sig) {
return loss_of_connectivity.connect(sig);
}
//------------------------------------------------------------------------------
bs2::connection ausf_event::subscribe_ue_reachability_for_data(
const ue_reachability_for_data_sig_t::slot_type &sig) {
return ue_reachability_for_data.connect(sig);
}
/*
* 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 ausf_event.hpp
\brief
\author Tien-Thinh NGUYEN (EURECOM)
\company
\date 2022
\email: contact@openairinterface.org
*/
#ifndef FILE_AUSF_EVENT_HPP_SEEN
#define FILE_AUSF_EVENT_HPP_SEEN
#include <boost/signals2.hpp>
namespace bs2 = boost::signals2;
#include "ausf.h"
#include "ausf_event_sig.hpp"
#include "task_manager.hpp"
namespace oai::ausf::app {
class task_manager;
class ausf_event {
public:
ausf_event(){};
ausf_event(ausf_event const &) = delete;
void operator=(ausf_event const &) = delete;
static ausf_event &get_instance() {
static ausf_event instance;
return instance;
}
// class register/handle event
friend class ausf_app;
friend class ausf_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);
//------------------------------------------------------------------------------
/*
* Subscribe to UE Loss of Connectivity Status signal
* @param [const loss_of_connectivity_sig_t::slot_type&] sig: slot_type
* parameter
* @return boost::signals2::connection: the connection between the signal and
* the slot
*/
bs2::connection subscribe_loss_of_connectivity(
const loss_of_connectivity_sig_t::slot_type &sig);
/*
* Subscribe to UE Reachability for Data signal
* @param [const ue_reachability_for_data_sig_t::slot_type&] sig: slot_type
* parameter
* @return boost::signals2::connection: the connection between the signal and
* the slot
*/
bs2::connection subscribe_ue_reachability_for_data(
const ue_reachability_for_data_sig_t::slot_type &sig);
private:
task_sig_t task_tick;
loss_of_connectivity_sig_t
loss_of_connectivity; // Signal for Loss of Connectivity Report
ue_reachability_for_data_sig_t
ue_reachability_for_data; // Signal for UE Reachability for Data Report
};
} // namespace oai::ausf::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 ausf_event_sig.hpp
\brief
\author Tien-Thinh NGUYEN (EURECOM)
\company
\date 2022
\email: contact@openairinterface.org
*/
#ifndef FILE_AUSF_EVENT_SIG_HPP_SEEN
#define FILE_AUSF_EVENT_SIG_HPP_SEEN
#include <boost/signals2.hpp>
#include <string>
namespace bs2 = boost::signals2;
namespace oai::ausf::app {
typedef bs2::signal_type<void(uint64_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
task_sig_t;
// Signal for Loss of Connectivity
// SUPI, Connectivity status, HTTP version
typedef bs2::signal_type<void(std::string, uint8_t, uint8_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
loss_of_connectivity_sig_t;
// Signal for UE Reachability for Data
// SUPI, Reachability status, HTTP version
typedef bs2::signal_type<void(std::string, uint8_t, uint8_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
ue_reachability_for_data_sig_t;
// UE_REACHABILITY_FOR_SMS
// LOCATION_REPORTING
// CHANGE_OF_SUPI_PEI_ASSOCIATION
// ROAMING_STATUS
// COMMUNICATION_FAILURE
// AVAILABILITY_AFTER_DNN_FAILURE
// CN_TYPE_CHANGE
} // namespace oai::ausf::app
#endif
......@@ -29,19 +29,19 @@
#include "ausf_nrf.hpp"
#include "ausf_app.hpp"
#include "ausf_profile.hpp"
#include "ausf_client.hpp"
#include "ausf_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 <nlohmann/json.hpp>
#include <stdexcept>
#include "logger.hpp"
#include "ausf.h"
#include "logger.hpp"
using namespace config;
// using namespace ausf;
......@@ -50,22 +50,22 @@ using namespace oai::ausf::app;
using json = nlohmann::json;
extern ausf_config ausf_cfg;
extern ausf_nrf* ausf_nrf_inst;
ausf_client* ausf_client_instance = nullptr;
extern ausf_nrf *ausf_nrf_inst;
ausf_client *ausf_client_instance = nullptr;
//------------------------------------------------------------------------------
ausf_nrf::ausf_nrf() {}
ausf_nrf::ausf_nrf(ausf_event &ev) : m_event_sub(ev) {}
//---------------------------------------------------------------------------------------------
void ausf_nrf::get_ausf_api_root(std::string& api_root) {
void ausf_nrf::get_ausf_api_root(std::string &api_root) {
api_root = std::string(
inet_ntoa(*((struct in_addr*) &ausf_cfg.nrf_addr.ipv4_addr))) +
inet_ntoa(*((struct in_addr *)&ausf_cfg.nrf_addr.ipv4_addr))) +
":" + std::to_string(ausf_cfg.nrf_addr.port) + NNRF_NFM_BASE +
ausf_cfg.nrf_addr.api_version;
}
//---------------------------------------------------------------------------------------------
void ausf_nrf::generate_ausf_profile(
ausf_profile& ausf_nf_profile, std::string& ausf_instance_id) {
void ausf_nrf::generate_ausf_profile(ausf_profile &ausf_nf_profile,
std::string &ausf_instance_id) {
// TODO: remove hardcoded values
ausf_nf_profile.set_nf_instance_id(ausf_instance_id);
ausf_nf_profile.set_nf_instance_name("OAI-AUSF");
......@@ -75,7 +75,7 @@ void ausf_nrf::generate_ausf_profile(
ausf_nf_profile.set_nf_priority(1);
ausf_nf_profile.set_nf_capacity(100);
// ausf_nf_profile.set_fqdn(ausf_cfg.fqdn);
ausf_nf_profile.add_nf_ipv4_addresses(ausf_cfg.sbi.addr4); // N4's Addr
ausf_nf_profile.add_nf_ipv4_addresses(ausf_cfg.sbi.addr4); // N4's Addr
// AUSF info (Hardcoded for now)
ausf_info_t ausf_info_item;
......@@ -83,9 +83,9 @@ void ausf_nrf::generate_ausf_profile(
ausf_info_item.groupid = "oai-ausf-testgroupid";
ausf_info_item.routing_indicators.push_back("0210");
ausf_info_item.routing_indicators.push_back("9876");
supi_ranges.supi_range.start = "109238210938";
supi_ranges.supi_range.start = "109238210938";
supi_ranges.supi_range.pattern = "209238210938";
supi_ranges.supi_range.start = "q0930j0c80283ncjf";
supi_ranges.supi_range.start = "q0930j0c80283ncjf";
ausf_info_item.supi_ranges.push_back(supi_ranges);
ausf_nf_profile.set_ausf_info(ausf_info_item);
// AUSF info item end
......@@ -95,8 +95,7 @@ void ausf_nrf::generate_ausf_profile(
//---------------------------------------------------------------------------------------------
void ausf_nrf::register_to_nrf() {
// generate UUID
std::string ausf_instance_id; // AUSF instance id
ausf_instance_id = to_string(boost::uuids::random_generator()());
ausf_instance_id = to_string(boost::uuids::random_generator()());
nlohmann::json response_data = {};
// Generate NF Profile
......@@ -105,8 +104,8 @@ void ausf_nrf::register_to_nrf() {
// Send NF registeration request
std::string ausf_api_root = {};
std::string response = {};
std::string method = {"PUT"};
std::string response = {};
std::string method = {"PUT"};
get_ausf_api_root(ausf_api_root);
std::string remoteUri =
ausf_api_root + AUSF_NF_REGISTER_URL + ausf_instance_id;
......@@ -114,16 +113,63 @@ void ausf_nrf::register_to_nrf() {
ausf_nf_profile.to_json(json_data);
Logger::ausf_nrf().info("Sending NF registeration request");
ausf_client_instance->curl_http_client(
remoteUri, method, json_data.dump().c_str(), response);
ausf_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
response_data = nlohmann::json::parse(response);
if (response.find("REGISTERED") != 0) {
start_event_nf_heartbeat(remoteUri);
}
} catch (nlohmann::json::exception& e) {
} catch (nlohmann::json::exception &e) {
Logger::ausf_nrf().info("NF registeration procedure failed");
}
}
//---------------------------------------------------------------------------------------------
void ausf_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(&ausf_nrf::trigger_nf_heartbeat_procedure, this, _1),
interval, ms + interval);
}
//---------------------------------------------------------------------------------------------
void ausf_nrf::trigger_nf_heartbeat_procedure(uint64_t ms) {
_unused(ms);
oai::ausf_server::model::PatchItem patch_item = {};
std::vector<oai::ausf_server::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::ausf_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 ausf_api_root = {};
get_ausf_api_root(ausf_api_root);
std::string remoteUri =
ausf_api_root + AUSF_NF_REGISTER_URL + ausf_instance_id;
ausf_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
......@@ -34,34 +34,49 @@
#include <curl/curl.h>
#include "logger.hpp"
#include "PatchItem.h"
#include "ausf_config.hpp"
#include "ausf_event.hpp"
#include "ausf_profile.hpp"
#include "logger.hpp"
using namespace oai::ausf_server::model;
namespace oai {
namespace ausf {
namespace app {
class ausf_nrf {
private:
public:
ausf_profile ausf_nf_profile; // AUSF profile
std::string ausf_instance_id; // AUSF instance id
private:
public:
ausf_profile ausf_nf_profile; // AUSF profile
std::string ausf_instance_id; // AUSF instance id
// timer_id_t timer_ausf_heartbeat;
ausf_nrf();
ausf_nrf(ausf_nrf const&) = delete;
void operator=(ausf_nrf const&) = delete;
ausf_nrf(ausf_event &ev);
ausf_nrf(ausf_nrf const &) = delete;
void operator=(ausf_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 AUSF profile for this instance
* @param [void]
* @return void
*/
void generate_ausf_profile(
ausf_profile& ausf_nf_profile, std::string& ausf_instance_id);
void generate_ausf_profile(ausf_profile &ausf_nf_profile,
std::string &ausf_instance_id);
/*
* Trigger NF instance registration to NRF
......@@ -74,9 +89,13 @@ class ausf_nrf {
* @param [std::string& ] api_root: ausf's API Root
* @return void
*/
void get_ausf_api_root(std::string& api_root);
void get_ausf_api_root(std::string &api_root);
private:
ausf_event &m_event_sub;
bs2::connection task_connection;
};
} // namespace app
} // namespace ausf
} // namespace oai
} // namespace app
} // namespace ausf
} // namespace oai
#endif /* FILE_AUSF_NRF_SEEN */
......@@ -30,35 +30,33 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include "logger.hpp"
#include "ausf_profile.hpp"
#include "logger.hpp"
#include "string.hpp"
// using namespace ausf;
using namespace oai::ausf::app;
//------------------------------------------------------------------------------
void ausf_profile::set_nf_instance_id(const std::string& instance_id) {
void ausf_profile::set_nf_instance_id(const std::string &instance_id) {
nf_instance_id = instance_id;
}
//------------------------------------------------------------------------------
void ausf_profile::get_nf_instance_id(std::string& instance_id) const {
void ausf_profile::get_nf_instance_id(std::string &instance_id) const {
instance_id = nf_instance_id;
}
//------------------------------------------------------------------------------
std::string ausf_profile::get_nf_instance_id() const {
return nf_instance_id;
}
std::string ausf_profile::get_nf_instance_id() const { return nf_instance_id; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_instance_name(const std::string& instance_name) {
void ausf_profile::set_nf_instance_name(const std::string &instance_name) {
nf_instance_name = instance_name;
}
//------------------------------------------------------------------------------
void ausf_profile::get_nf_instance_name(std::string& instance_name) const {
void ausf_profile::get_nf_instance_name(std::string &instance_name) const {
instance_name = nf_instance_name;
}
......@@ -68,122 +66,92 @@ std::string ausf_profile::get_nf_instance_name() const {
}
//------------------------------------------------------------------------------
void ausf_profile::set_nf_type(const std::string& type) {
nf_type = type;
}
void ausf_profile::set_nf_type(const std::string &type) { nf_type = type; }
//------------------------------------------------------------------------------
std::string ausf_profile::get_nf_type() const {
return nf_type;
}
std::string ausf_profile::get_nf_type() const { return nf_type; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_status(const std::string& status) {
void ausf_profile::set_nf_status(const std::string &status) {
nf_status = status;
}
//------------------------------------------------------------------------------
void ausf_profile::get_nf_status(std::string& status) const {
void ausf_profile::get_nf_status(std::string &status) const {
status = nf_status;
}
//------------------------------------------------------------------------------
std::string ausf_profile::get_nf_status() const {
return nf_status;
}
std::string ausf_profile::get_nf_status() const { return nf_status; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_heartBeat_timer(const int32_t& timer) {
void ausf_profile::set_nf_heartBeat_timer(const int32_t &timer) {
heartBeat_timer = timer;
}
//------------------------------------------------------------------------------
void ausf_profile::get_nf_heartBeat_timer(int32_t& timer) const {
void ausf_profile::get_nf_heartBeat_timer(int32_t &timer) const {
timer = heartBeat_timer;
}
//------------------------------------------------------------------------------
int32_t ausf_profile::get_nf_heartBeat_timer() const {
return heartBeat_timer;
}
int32_t ausf_profile::get_nf_heartBeat_timer() const { return heartBeat_timer; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_priority(const uint16_t& p) {
priority = p;
}
void ausf_profile::set_nf_priority(const uint16_t &p) { priority = p; }
//------------------------------------------------------------------------------
void ausf_profile::get_nf_priority(uint16_t& p) const {
p = priority;
}
void ausf_profile::get_nf_priority(uint16_t &p) const { p = priority; }
//------------------------------------------------------------------------------
uint16_t ausf_profile::get_nf_priority() const {
return priority;
}
uint16_t ausf_profile::get_nf_priority() const { return priority; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_capacity(const uint16_t& c) {
capacity = c;
}
void ausf_profile::set_nf_capacity(const uint16_t &c) { capacity = c; }
//------------------------------------------------------------------------------
void ausf_profile::get_nf_capacity(uint16_t& c) const {
c = capacity;
}
void ausf_profile::get_nf_capacity(uint16_t &c) const { c = capacity; }
//------------------------------------------------------------------------------
uint16_t ausf_profile::get_nf_capacity() const {
return capacity;
}
uint16_t ausf_profile::get_nf_capacity() const { return capacity; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_snssais(const std::vector<snssai_t>& s) {
void ausf_profile::set_nf_snssais(const std::vector<snssai_t> &s) {
snssais = s;
}
//------------------------------------------------------------------------------
void ausf_profile::get_nf_snssais(std::vector<snssai_t>& s) const {
void ausf_profile::get_nf_snssais(std::vector<snssai_t> &s) const {
s = snssais;
}
//------------------------------------------------------------------------------
void ausf_profile::add_snssai(const snssai_t& s) {
snssais.push_back(s);
}
void ausf_profile::add_snssai(const snssai_t &s) { snssais.push_back(s); }
//------------------------------------------------------------------------------
void ausf_profile::set_fqdn(const std::string& fqdN) {
fqdn = fqdN;
}
void ausf_profile::set_fqdn(const std::string &fqdN) { fqdn = fqdN; }
//------------------------------------------------------------------------------
std::string ausf_profile::get_fqdn() const {
return fqdn;
}
std::string ausf_profile::get_fqdn() const { return fqdn; }
//------------------------------------------------------------------------------
void ausf_profile::set_nf_ipv4_addresses(const std::vector<struct in_addr>& a) {
void ausf_profile::set_nf_ipv4_addresses(const std::vector<struct in_addr> &a) {
ipv4_addresses = a;
}
//------------------------------------------------------------------------------
void ausf_profile::add_nf_ipv4_addresses(const struct in_addr& a) {
void ausf_profile::add_nf_ipv4_addresses(const struct in_addr &a) {
ipv4_addresses.push_back(a);
}
//------------------------------------------------------------------------------
void ausf_profile::get_nf_ipv4_addresses(std::vector<struct in_addr>& a) const {
void ausf_profile::get_nf_ipv4_addresses(std::vector<struct in_addr> &a) const {
a = ipv4_addresses;
}
//------------------------------------------------------------------------------
void ausf_profile::set_ausf_info(const ausf_info_t& s) {
ausf_info = s;
}
void ausf_profile::set_ausf_info(const ausf_info_t &s) { ausf_info = s; }
//------------------------------------------------------------------------------
void ausf_profile::get_ausf_info(ausf_info_t& s) const {
s = ausf_info;
}
void ausf_profile::get_ausf_info(ausf_info_t &s) const { s = ausf_info; }
//------------------------------------------------------------------------------
void ausf_profile::display() const {
......@@ -225,18 +193,18 @@ void ausf_profile::display() const {
}
//------------------------------------------------------------------------------
void ausf_profile::to_json(nlohmann::json& data) const {
data["nfInstanceId"] = nf_instance_id;
void ausf_profile::to_json(nlohmann::json &data) const {
data["nfInstanceId"] = nf_instance_id;
data["nfInstanceName"] = nf_instance_name;
data["nfType"] = nf_type;
data["nfStatus"] = nf_status;
data["nfType"] = nf_type;
data["nfStatus"] = nf_status;
data["heartBeatTimer"] = heartBeat_timer;
// SNSSAIs
data["sNssais"] = nlohmann::json::array();
for (auto s : snssais) {
nlohmann::json tmp = {};
tmp["sst"] = s.sST;
tmp["sd"] = s.sD;
tmp["sst"] = s.sST;
tmp["sd"] = s.sD;
data["sNssais"].push_back(tmp);
}
data["fqdn"] = fqdn;
......@@ -251,14 +219,14 @@ void ausf_profile::to_json(nlohmann::json& data) const {
data["capacity"] = capacity;
// AUSF Info
data["ausfInfo"]["groupId"] = ausf_info.groupid;
data["ausfInfo"]["supiRanges"] = nlohmann::json::array();
data["ausfInfo"]["groupId"] = ausf_info.groupid;
data["ausfInfo"]["supiRanges"] = nlohmann::json::array();
data["ausfInfo"]["routingIndicators"] = nlohmann::json::array();
for (auto supi : ausf_info.supi_ranges) {
nlohmann::json tmp = {};
tmp["start"] = supi.supi_range.start;
tmp["end"] = supi.supi_range.end;
tmp["pattern"] = supi.supi_range.pattern;
tmp["start"] = supi.supi_range.start;
tmp["end"] = supi.supi_range.end;
tmp["pattern"] = supi.supi_range.pattern;
data["ausfInfo"]["supiRanges"].push_back(tmp);
}
for (auto route_ind : ausf_info.routing_indicators) {
......@@ -270,7 +238,7 @@ void ausf_profile::to_json(nlohmann::json& data) const {
}
//------------------------------------------------------------------------------
void ausf_profile::from_json(const nlohmann::json& data) {
void ausf_profile::from_json(const nlohmann::json &data) {
if (data.find("nfInstanceId") != data.end()) {
nf_instance_id = data["nfInstanceId"].get<std::string>();
}
......@@ -294,8 +262,8 @@ void ausf_profile::from_json(const nlohmann::json& data) {
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>();
s.sST = it["sst"].get<int>();
s.sD = it["sd"].get<std::string>();
snssais.push_back(s);
}
}
......@@ -305,13 +273,13 @@ void ausf_profile::from_json(const nlohmann::json& data) {
for (auto it : addresses) {
struct in_addr addr4 = {};
std::string address = it.get<std::string>();
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::ausf_app().warn(
"Address conversion: Bad value %s", util::trim(address).c_str());
Logger::ausf_app().warn("Address conversion: Bad value %s",
util::trim(address).c_str());
}
add_nf_ipv4_addresses(addr4);
}
......@@ -342,8 +310,8 @@ void ausf_profile::from_json(const nlohmann::json& data) {
nlohmann::json supi_ranges = data["ausfInfo"]["supiRanges"];
for (auto d : supi_ranges) {
supi_range_ausf_info_item_t supi;
supi.supi_range.start = d["start"];
supi.supi_range.end = d["end"];
supi.supi_range.start = d["start"];
supi.supi_range.end = d["end"];
supi.supi_range.pattern = d["pattern"];
ausf_info.supi_ranges.push_back(supi);
}
......@@ -354,8 +322,7 @@ void ausf_profile::from_json(const nlohmann::json& data) {
//------------------------------------------------------------------------------
void ausf_profile::handle_heartbeart_timeout(uint64_t ms) {
Logger::ausf_app().info(
"Handle heartbeart timeout profile %s, time %d", nf_instance_id.c_str(),
ms);
Logger::ausf_app().info("Handle heartbeart timeout profile %s, time %d",
nf_instance_id.c_str(), ms);
set_nf_status("SUSPENDED");
}
......@@ -36,53 +36,42 @@
#include <shared_mutex>
#include <vector>
#include "logger.hpp"
#include "3gpp_29.510.h"
#include "ausf.h"
#include "logger.hpp"
namespace oai {
namespace ausf {
namespace app {
class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
public:
public:
ausf_profile()
: nf_type("NF_TYPE_UNKNOWN"),
heartBeat_timer(0),
snssais(),
fqdn(),
ipv4_addresses(),
priority(0),
capacity(0) {
: nf_type("NF_TYPE_UNKNOWN"), heartBeat_timer(0), snssais(), fqdn(),
ipv4_addresses(), priority(0), capacity(0) {
nf_instance_name = {};
nf_status = {};
nf_status = {};
}
ausf_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") {
ausf_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 = {};
nf_status = {};
}
ausf_profile& operator=(const ausf_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;
ausf_profile &operator=(const ausf_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;
ausf_info = s.ausf_info;
nf_status = s.nf_status;
ausf_info = s.ausf_info;
return *this;
}
// ausf_profile(ausf_profile &b) = delete;
......@@ -96,13 +85,13 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const std::string &] instance_id: instance id
* @return void
*/
void set_nf_instance_id(const std::string& instance_id);
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;
void get_nf_instance_id(std::string &instance_id) const;
/*
* Get NF instance ID
......@@ -116,14 +105,14 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const std::string &] instance_name: instance name
* @return void
*/
void set_nf_instance_name(const std::string& instance_name);
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;
void get_nf_instance_name(std::string &instance_name) const;
/*
* Get NF instance name
......@@ -137,14 +126,14 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const std::string &] status: instance status
* @return void
*/
void set_nf_status(const std::string& status);
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;
void get_nf_status(std::string &status) const;
/*
* Get NF status
......@@ -165,21 +154,21 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const nf_type_t &] type: nf type
* @return void
*/
void set_nf_type(const std::string& type);
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);
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;
void get_nf_heartBeat_timer(int32_t &timer) const;
/*
* Get NF heartBeat_timer
......@@ -193,14 +182,14 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const uint16_t] p: instance priority
* @return void
*/
void set_nf_priority(const uint16_t& p);
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;
void get_nf_priority(uint16_t &p) const;
/*
* Get NF instance priority
......@@ -214,14 +203,14 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const uint16_t] c: instance capacity
* @return void
*/
void set_nf_capacity(const uint16_t& c);
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;
void get_nf_capacity(uint16_t &c) const;
/*
* Get NF instance priority
......@@ -235,21 +224,21 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [std::vector<snssai_t> &] s: SNSSAIs
* @return void
*/
void set_nf_snssais(const std::vector<snssai_t>& s);
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);
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;
void get_nf_snssais(std::vector<snssai_t> &s) const;
/*
* Get NF fqdn
......@@ -263,42 +252,42 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [const fqdn_t &] fqdn: nf fqdn
* @return void
*/
void set_fqdn(const std::string& fqdn);
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);
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);
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;
void get_nf_ipv4_addresses(std::vector<struct in_addr> &a) const;
/*
* Set ausf info
* @param [ausf_info_t &] s: ausf info
* @return void
*/
void set_ausf_info(const ausf_info_t& s);
void set_ausf_info(const ausf_info_t &s);
/*
* Get NF instance ausf info
* @param [ausf_info_t &] s: store instance's ausf info
* @return void:
*/
void get_ausf_info(ausf_info_t& s) const;
void get_ausf_info(ausf_info_t &s) const;
/*
* Print related-information for NF profile
......@@ -312,14 +301,14 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
* @param [nlohmann::json &] data: Json data
* @return void
*/
void to_json(nlohmann::json& data) const;
void to_json(nlohmann::json &data) const;
/*
* Covert from a json represetation to ausf profile
* @param [nlohmann::json &] data: Json data
* @return void
*/
void from_json(const nlohmann::json& data);
void from_json(const nlohmann::json &data);
/*
* Handle heartbeart timeout event
......@@ -328,7 +317,7 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
*/
void handle_heartbeart_timeout(uint64_t ms);
protected:
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;
......@@ -343,8 +332,8 @@ class ausf_profile : public std::enable_shared_from_this<ausf_profile> {
ausf_info_t ausf_info;
};
} // namespace app
} // namespace ausf
} // namespace oai
} // namespace app
} // namespace ausf
} // namespace oai
#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 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::ausf::app;
//------------------------------------------------------------------------------
task_manager::task_manager(ausf_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::ausf_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::ausf_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 "ausf_event.hpp"
#include <linux/types.h>
#include <sys/timerfd.h>
using namespace oai::ausf::app;
namespace oai {
namespace ausf {
namespace app {
class ausf_event;
class task_manager {
public:
task_manager(ausf_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();
ausf_event &event_sub_;
int sfd;
};
} // namespace app
} // namespace ausf
} // namespace oai
#endif
......@@ -24,29 +24,32 @@
#define HEART_BEAT_TIMER 10
#define _unused(x) ((void) (x))
#define _unused(x) ((void)(x))
#define NNRF_NFM_BASE "/nnrf-nfm/"
#define AUSF_NF_REGISTER_URL "/nf-instances/"
typedef enum nf_type_s {
NF_TYPE_NRF = 0,
NF_TYPE_AMF = 1,
NF_TYPE_SMF = 2,
NF_TYPE_AUSF = 3,
NF_TYPE_NEF = 4,
NF_TYPE_PCF = 5,
NF_TYPE_SMSF = 6,
NF_TYPE_NSSF = 7,
NF_TYPE_UDR = 8,
NF_TYPE_LMF = 9,
NF_TYPE_GMLC = 10,
NF_TYPE_5G_EIR = 11,
NF_TYPE_SEPP = 12,
NF_TYPE_UPF = 13,
NF_TYPE_N3IWF = 14,
NF_TYPE_AF = 15,
NF_TYPE_UDSF = 16,
NF_TYPE_BSF = 17,
NF_TYPE_CHF = 18,
NF_TYPE_NWDAF = 19,
NF_TYPE_NRF = 0,
NF_TYPE_AMF = 1,
NF_TYPE_SMF = 2,
NF_TYPE_AUSF = 3,
NF_TYPE_NEF = 4,
NF_TYPE_PCF = 5,
NF_TYPE_SMSF = 6,
NF_TYPE_NSSF = 7,
NF_TYPE_UDR = 8,
NF_TYPE_LMF = 9,
NF_TYPE_GMLC = 10,
NF_TYPE_5G_EIR = 11,
NF_TYPE_SEPP = 12,
NF_TYPE_UPF = 13,
NF_TYPE_N3IWF = 14,
NF_TYPE_AF = 15,
NF_TYPE_UDSF = 16,
NF_TYPE_BSF = 17,
NF_TYPE_CHF = 18,
NF_TYPE_NWDAF = 19,
NF_TYPE_UNKNOWN = 20
} nf_type_t;
......@@ -56,12 +59,12 @@ static const std::vector<std::string> nf_type_e2str = {
"N3IWF", "AF", "UDSF", "BSF", "CHF", "NWDAF", "UNKNOWN"};
typedef enum patch_op_type_s {
PATCH_OP_ADD = 0,
PATCH_OP_REMOVE = 1,
PATCH_OP_ADD = 0,
PATCH_OP_REMOVE = 1,
PATCH_OP_REPLACE = 2,
PATCH_OP_MOVE = 3,
PATCH_OP_COPY = 4,
PATCH_OP_TEST = 5,
PATCH_OP_MOVE = 3,
PATCH_OP_COPY = 4,
PATCH_OP_TEST = 5,
PATCH_OP_UNKNOWN = 6
} patch_op_type_t;
......@@ -70,7 +73,7 @@ static const std::vector<std::string> patch_op_type_e2str = {
"ADD", "REMOVE", "REPLACE", "MOVE", "COPY", "TEST", "UNKNOWN"};
#define CURL_TIMEOUT_MS 1000L
#define MAX_WAIT_MSECS 20000 // 1 second
#define MAX_WAIT_MSECS 20000 // 1 second
typedef struct {
uint8_t rand[16];
......@@ -83,29 +86,29 @@ typedef uint64_t supi64_t;
// 3GPP TS 29.571 (Common data)
enum http_response_codes_e {
HTTP_RESPONSE_CODE_OK = 200,
HTTP_RESPONSE_CODE_CREATED = 201,
HTTP_RESPONSE_CODE_ACCEPTED = 202,
HTTP_RESPONSE_CODE_NO_CONTENT = 204,
HTTP_RESPONSE_CODE_BAD_REQUEST = 400,
HTTP_RESPONSE_CODE_UNAUTHORIZED = 401,
HTTP_RESPONSE_CODE_FORBIDDEN = 403,
HTTP_RESPONSE_CODE_NOT_FOUND = 404,
HTTP_RESPONSE_CODE_METHOD_NOT_ALLOWED = 405,
HTTP_RESPONSE_CODE_REQUEST_TIMEOUT = 408,
HTTP_RESPONSE_CODE_406_NOT_ACCEPTED = 406,
HTTP_RESPONSE_CODE_CONFLICT = 409,
HTTP_RESPONSE_CODE_GONE = 410,
HTTP_RESPONSE_CODE_LENGTH_REQUIRED = 411,
HTTP_RESPONSE_CODE_PRECONDITION_FAILED = 412,
HTTP_RESPONSE_CODE_PAYLOAD_TOO_LARGE = 413,
HTTP_RESPONSE_CODE_URI_TOO_LONG = 414,
HTTP_RESPONSE_CODE_OK = 200,
HTTP_RESPONSE_CODE_CREATED = 201,
HTTP_RESPONSE_CODE_ACCEPTED = 202,
HTTP_RESPONSE_CODE_NO_CONTENT = 204,
HTTP_RESPONSE_CODE_BAD_REQUEST = 400,
HTTP_RESPONSE_CODE_UNAUTHORIZED = 401,
HTTP_RESPONSE_CODE_FORBIDDEN = 403,
HTTP_RESPONSE_CODE_NOT_FOUND = 404,
HTTP_RESPONSE_CODE_METHOD_NOT_ALLOWED = 405,
HTTP_RESPONSE_CODE_REQUEST_TIMEOUT = 408,
HTTP_RESPONSE_CODE_406_NOT_ACCEPTED = 406,
HTTP_RESPONSE_CODE_CONFLICT = 409,
HTTP_RESPONSE_CODE_GONE = 410,
HTTP_RESPONSE_CODE_LENGTH_REQUIRED = 411,
HTTP_RESPONSE_CODE_PRECONDITION_FAILED = 412,
HTTP_RESPONSE_CODE_PAYLOAD_TOO_LARGE = 413,
HTTP_RESPONSE_CODE_URI_TOO_LONG = 414,
HTTP_RESPONSE_CODE_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_RESPONSE_CODE_TOO_MANY_REQUESTS = 429,
HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR = 500,
HTTP_RESPONSE_CODE_NOT_IMPLEMENTED = 501,
HTTP_RESPONSE_CODE_SERVICE_UNAVAILABLE = 503,
HTTP_RESPONSE_CODE_GATEWAY_TIMEOUT = 504
HTTP_RESPONSE_CODE_TOO_MANY_REQUESTS = 429,
HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR = 500,
HTTP_RESPONSE_CODE_NOT_IMPLEMENTED = 501,
HTTP_RESPONSE_CODE_SERVICE_UNAVAILABLE = 503,
HTTP_RESPONSE_CODE_GATEWAY_TIMEOUT = 504
};
#define NAUSF_AUTH_BASE "/nausf-auth/"
......
......@@ -24,22 +24,23 @@
#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) {
bool fqdn::resolve(const std::string &host_name, std::string &address,
uint32_t &port, uint8_t &addr_type,
const std::string &protocol) {
try {
Logger::ausf_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
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();
address = endpoint.address().to_string();
port = endpoint.port();
Logger::ausf_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);
......@@ -49,9 +50,9 @@ bool fqdn::resolve(
addr_type = 1;
return true;
}
} catch (std::exception& e) {
throw std::runtime_error(
"Cannot resolve a DNS name " + std::string(e.what()));
} catch (std::exception &e) {
throw std::runtime_error("Cannot resolve a DNS name " +
std::string(e.what()));
return false;
}
......
......@@ -14,11 +14,11 @@
* limitations under the License.
*/
#include "logger.hpp"
#include "ausf-api-server.h"
#include "ausf-http2-server.h"
#include "ausf_config.hpp"
#include "ausf_app.hpp"
#include "ausf_config.hpp"
#include "logger.hpp"
#include "options.hpp"
#include "pid_file.hpp"
......@@ -26,12 +26,12 @@
#include "pistache/http.h"
#include "pistache/router.h"
#include <iostream>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h> // srand
#include <unistd.h> // get_pid(), pause()
#include <iostream>
#include <stdlib.h> // srand
#include <thread>
#include <unistd.h> // get_pid(), pause()
using namespace oai::ausf::app;
using namespace util;
......@@ -40,9 +40,9 @@ using namespace std;
using namespace config;
ausf_config ausf_cfg;
ausf_app* ausf_app_inst = nullptr;
AUSFApiServer* api_server = nullptr;
ausf_http2_server* ausf_api_server_2 = nullptr;
ausf_app *ausf_app_inst = nullptr;
AUSFApiServer *api_server = nullptr;
ausf_http2_server *ausf_api_server_2 = nullptr;
//------------------------------------------------------------------------------
void my_app_signal_handler(int s) {
......@@ -68,7 +68,7 @@ void my_app_signal_handler(int s) {
}
//------------------------------------------------------------------------------
int main(int argc, char** argv) {
int main(int argc, char **argv) {
srand(time(NULL));
// Command line options
......@@ -87,42 +87,49 @@ int main(int argc, char** argv) {
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
// Event subsystem
ausf_event ev;
// Config
ausf_cfg.load(Options::getlibconfigConfig());
ausf_cfg.display();
// AUSF application layer
ausf_app_inst = new ausf_app(Options::getlibconfigConfig());
ausf_app_inst = new ausf_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.
string pid_file_name = get_exe_absolute_path("/var/run", ausf_cfg.instance);
if (!is_pid_file_lock_success(pid_file_name.c_str())) {
Logger::ausf_server().error(
"Lock PID file %s failed\n", pid_file_name.c_str());
Logger::ausf_server().error("Lock PID file %s failed\n",
pid_file_name.c_str());
exit(-EDEADLK);
}
// AUSF Pistache API server (HTTP1)
Pistache::Address addr(
std::string(inet_ntoa(*((struct in_addr*) &ausf_cfg.sbi.addr4))),
std::string(inet_ntoa(*((struct in_addr *)&ausf_cfg.sbi.addr4))),
Pistache::Port(ausf_cfg.sbi.port));
api_server = new AUSFApiServer(addr, ausf_app_inst);
api_server->init(2);
std::thread ausf_manager(&AUSFApiServer::start, api_server);
// AUSF NGHTTP API server (HTTP2)
ausf_api_server_2 = new ausf_http2_server(
conv::toString(ausf_cfg.sbi.addr4), ausf_cfg.sbi_http2_port,
ausf_app_inst);
ausf_api_server_2 =
new ausf_http2_server(conv::toString(ausf_cfg.sbi.addr4),
ausf_cfg.sbi_http2_port, ausf_app_inst);
std::thread ausf_http2_manager(&ausf_http2_server::start, ausf_api_server_2);
ausf_manager.join();
ausf_http2_manager.join();
FILE* fp = NULL;
FILE *fp = NULL;
std::string filename = fmt::format("/tmp/ausf_{}.status", getpid());
fp = fopen(filename.c_str(), "w+");
fp = fopen(filename.c_str(), "w+");
fprintf(fp, "STARTED\n");
fflush(fp);
fclose(fp);
......
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