Commit 508b7d51 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'amf_configuration_nssai' into 'develop'

Amf configuration nssai

See merge request oai/cn5g/oai-cn5g-amf!129
parents 3c6b0792 6d9342a0
...@@ -88,7 +88,10 @@ amf_app::amf_app(const amf_config& amf_cfg) ...@@ -88,7 +88,10 @@ amf_app::amf_app(const amf_config& amf_cfg)
throw; throw;
} }
// Generate an AMF profile (including NF instance) // Generate NF Instance ID (UUID)
generate_uuid();
// Generate an AMF profile
generate_amf_profile(); generate_amf_profile();
// Register to NRF if needed // Register to NRF if needed
...@@ -152,12 +155,19 @@ void amf_app_task(void*) { ...@@ -152,12 +155,19 @@ void amf_app_task(void*) {
} break; } break;
case SBI_AMF_CONFIGURATION: { case SBI_AMF_CONFIGURATION: {
Logger::amf_app().debug("Received N11_AMF_CONFIGURATION"); Logger::amf_app().debug("Received SBI_AMF_CONFIGURATION");
itti_sbi_amf_configuration* m = itti_sbi_amf_configuration* m =
dynamic_cast<itti_sbi_amf_configuration*>(msg); dynamic_cast<itti_sbi_amf_configuration*>(msg);
amf_app_inst->handle_itti_message(ref(*m)); amf_app_inst->handle_itti_message(ref(*m));
} break; } break;
case SBI_UPDATE_AMF_CONFIGURATION: {
Logger::amf_app().debug("Received SBI_UPDATE_AMF_CONFIGURATION");
itti_sbi_update_amf_configuration* m =
dynamic_cast<itti_sbi_update_amf_configuration*>(msg);
amf_app_inst->handle_itti_message(ref(*m));
} break;
case TIME_OUT: { case TIME_OUT: {
if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) { if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
switch (to->arg1_user) { switch (to->arg1_user) {
...@@ -733,12 +743,73 @@ void amf_app::handle_itti_message(itti_sbi_amf_configuration& itti_msg) { ...@@ -733,12 +743,73 @@ void amf_app::handle_itti_message(itti_sbi_amf_configuration& itti_msg) {
} }
} }
//---------------------------------------------------------------------------------------------
void amf_app::handle_itti_message(itti_sbi_update_amf_configuration& itti_msg) {
Logger::amf_app().info(
"Handle a request UpdateAMFConfiguration from a NF (HTTP version "
"%d)",
itti_msg.http_version);
// Process the request and trigger the response from AMF API Server
nlohmann::json response_data = {};
response_data["content"] = itti_msg.configuration;
if (update_amf_configuration(response_data["content"])) {
Logger::amf_app().debug(
"AMF configuration:\n %s", response_data["content"].dump().c_str());
response_data["httpResponseCode"] = 200; // TODO:
// Update AMF profile
generate_amf_profile();
// Update AMF profile (complete replacement of the existing profile by a new
// one)
if (amf_cfg.support_features.enable_nf_registration and
amf_cfg.support_features.enable_external_nrf)
register_to_nrf();
} else {
response_data["httpResponseCode"] = 400; // TODO:
oai::amf::model::ProblemDetails problem_details = {};
// TODO set problem_details
to_json(response_data["ProblemDetails"], problem_details);
}
// Notify to the result
if (itti_msg.promise_id > 0) {
trigger_process_response(itti_msg.promise_id, response_data);
return;
}
}
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------
bool amf_app::read_amf_configuration(nlohmann::json& json_data) { bool amf_app::read_amf_configuration(nlohmann::json& json_data) {
amf_cfg.to_json(json_data); amf_cfg.to_json(json_data);
return true; return true;
} }
//---------------------------------------------------------------------------------------------
bool amf_app::update_amf_configuration(nlohmann::json& json_data) {
if (stacs.get_number_connected_gnbs() > 0) {
Logger::amf_app().info(
"Could not update AMF configuration (connected with gNBs)");
return false;
}
return amf_cfg.from_json(json_data);
}
//---------------------------------------------------------------------------------------------
void amf_app::get_number_registered_ues(uint32_t& num_ues) const {
std::shared_lock lock(m_amf_ue_ngap_id2ue_ctx);
num_ues = amf_ue_ngap_id2ue_ctx.size();
return;
}
//---------------------------------------------------------------------------------------------
uint32_t amf_app::get_number_registered_ues() const {
std::shared_lock lock(m_amf_ue_ngap_id2ue_ctx);
return amf_ue_ngap_id2ue_ctx.size();
}
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------
void amf_app::add_n1n2_message_subscription( void amf_app::add_n1n2_message_subscription(
const std::string& ue_ctx_id, const n1n2sub_id_t& sub_id, const std::string& ue_ctx_id, const n1n2sub_id_t& sub_id,
...@@ -939,15 +1010,14 @@ void amf_app::get_ee_subscriptions( ...@@ -939,15 +1010,14 @@ void amf_app::get_ee_subscriptions(
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------
void amf_app::generate_amf_profile() { void amf_app::generate_amf_profile() {
// generate UUID
generate_uuid();
nf_instance_profile.set_nf_instance_id(amf_instance_id); nf_instance_profile.set_nf_instance_id(amf_instance_id);
nf_instance_profile.set_nf_instance_name("OAI-AMF"); nf_instance_profile.set_nf_instance_name(amf_cfg.amf_name);
nf_instance_profile.set_nf_type("AMF"); nf_instance_profile.set_nf_type("AMF");
nf_instance_profile.set_nf_status("REGISTERED"); nf_instance_profile.set_nf_status("REGISTERED");
nf_instance_profile.set_nf_heartBeat_timer(50); nf_instance_profile.set_nf_heartBeat_timer(50);
nf_instance_profile.set_nf_priority(1); nf_instance_profile.set_nf_priority(1);
nf_instance_profile.set_nf_capacity(100); nf_instance_profile.set_nf_capacity(100);
nf_instance_profile.delete_nf_ipv4_addresses();
nf_instance_profile.add_nf_ipv4_addresses(amf_cfg.n11.addr4); nf_instance_profile.add_nf_ipv4_addresses(amf_cfg.n11.addr4);
// NF services // NF services
...@@ -955,7 +1025,7 @@ void amf_app::generate_amf_profile() { ...@@ -955,7 +1025,7 @@ void amf_app::generate_amf_profile() {
nf_service.service_instance_id = "namf_communication"; nf_service.service_instance_id = "namf_communication";
nf_service.service_name = "namf_communication"; nf_service.service_name = "namf_communication";
nf_service_version_t version = {}; nf_service_version_t version = {};
version.api_version_in_uri = "v1"; version.api_version_in_uri = amf_cfg.sbi_api_version;
version.api_full_version = "1.0.0"; // TODO: to be updated version.api_full_version = "1.0.0"; // TODO: to be updated
nf_service.versions.push_back(version); nf_service.versions.push_back(version);
nf_service.scheme = "http"; nf_service.scheme = "http";
...@@ -967,6 +1037,7 @@ void amf_app::generate_amf_profile() { ...@@ -967,6 +1037,7 @@ void amf_app::generate_amf_profile() {
endpoint.port = amf_cfg.n11.port; endpoint.port = amf_cfg.n11.port;
nf_service.ip_endpoints.push_back(endpoint); nf_service.ip_endpoints.push_back(endpoint);
nf_instance_profile.delete_nf_services();
nf_instance_profile.add_nf_service(nf_service); nf_instance_profile.add_nf_service(nf_service);
// TODO: custom info // TODO: custom info
......
...@@ -159,8 +159,41 @@ class amf_app { ...@@ -159,8 +159,41 @@ class amf_app {
*/ */
void handle_itti_message(itti_sbi_amf_configuration& itti_msg); void handle_itti_message(itti_sbi_amf_configuration& itti_msg);
/*
* Handle ITTI message (Update AMF configuration)
* @param [itti_sbi_update_amf_configuration&]: ITTI message
* @return void
*/
void handle_itti_message(itti_sbi_update_amf_configuration& itti_msg);
/*
* Get the current AMF's configuration
* @param [nlohmann::json&]: json_data: Store AMF configuration
* @return true if success, otherwise return false
*/
bool read_amf_configuration(nlohmann::json& json_data); bool read_amf_configuration(nlohmann::json& json_data);
/*
* Update AMF configuration
* @param [nlohmann::json&]: json_data: New AMF configuration
* @return true if success, otherwise return false
*/
bool update_amf_configuration(nlohmann::json& json_data);
/*
* Get number of registered UEs to this AMF
* @param [uint32_t&]: num_ues: Store the number of registered UEs
* @return void
*/
void get_number_registered_ues(uint32_t& num_ues) const;
/*
* Get number of registered UEs to this AMF
* @param void
* @return: number of registered UEs
*/
uint32_t get_number_registered_ues() const;
/* /*
* Verify if a UE context associated with an AMF UE NGAP ID exist * Verify if a UE context associated with an AMF UE NGAP ID exist
* @param [const long&] amf_ue_ngap_id: AMF UE NGAP ID * @param [const long&] amf_ue_ngap_id: AMF UE NGAP ID
......
This diff is collapsed.
...@@ -37,9 +37,14 @@ ...@@ -37,9 +37,14 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/algorithm/string.hpp>
#include "amf_config.hpp" #include "amf_config.hpp"
#include "amf.hpp"
#include "if.hpp"
#include "string.hpp"
#include "thread_sched.hpp" #include "thread_sched.hpp"
#include "common_defs.h"
#define AMF_CONFIG_STRING_AMF_CONFIG "AMF" #define AMF_CONFIG_STRING_AMF_CONFIG "AMF"
#define AMF_CONFIG_STRING_PID_DIRECTORY "PID_DIRECTORY" #define AMF_CONFIG_STRING_PID_DIRECTORY "PID_DIRECTORY"
...@@ -134,6 +139,15 @@ typedef struct { ...@@ -134,6 +139,15 @@ typedef struct {
json_data["random"] = this->random; json_data["random"] = this->random;
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->mysql_server = json_data["mysql_server"].get<std::string>();
this->mysql_user = json_data["mysql_user"].get<std::string>();
this->mysql_pass = json_data["mysql_pass"].get<std::string>();
this->mysql_db = json_data["mysql_db"].get<std::string>();
this->random = json_data["random"].get<std::string>();
}
} auth_conf; } auth_conf;
typedef struct interface_cfg_s { typedef struct interface_cfg_s {
...@@ -157,6 +171,33 @@ typedef struct interface_cfg_s { ...@@ -157,6 +171,33 @@ typedef struct interface_cfg_s {
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->if_name = json_data["if_name"].get<std::string>();
std::string addr4_str = {};
addr4_str = json_data["addr4"].get<std::string>();
if (boost::iequals(addr4_str, "read")) {
if (get_inet_addr_infos_from_iface(
this->if_name, this->addr4, this->network4, this->mtu)) {
Logger::amf_app().error(
"Could not read %s network interface configuration", this->if_name);
return;
}
} else {
IPV4_STR_ADDR_TO_INADDR(
util::trim(addr4_str).c_str(), this->addr4,
"BAD IPv4 ADDRESS FORMAT FOR INTERFACE !");
std::string network4_str = json_data["network4"].get<std::string>();
IPV4_STR_ADDR_TO_INADDR(
util::trim(network4_str).c_str(), this->network4,
"BAD IPv4 ADDRESS FORMAT FOR INTERFACE !");
// TODO: addr6
this->mtu = json_data["mtu"].get<int>();
this->port = json_data["port"].get<int>();
}
}
} interface_cfg_t; } interface_cfg_t;
typedef struct itti_cfg_s { typedef struct itti_cfg_s {
...@@ -183,6 +224,14 @@ typedef struct guami_s { ...@@ -183,6 +224,14 @@ typedef struct guami_s {
json_data["AmfPointer"] = this->AmfPointer; json_data["AmfPointer"] = this->AmfPointer;
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->mcc = json_data["mcc"].get<std::string>();
this->mnc = json_data["mnc"].get<std::string>();
this->regionID = json_data["regionID"].get<std::string>();
this->AmfSetID = json_data["AmfSetID"].get<std::string>();
this->AmfPointer = json_data["AmfPointer"].get<std::string>();
}
} guami_t; } guami_t;
typedef struct slice_s { typedef struct slice_s {
...@@ -205,10 +254,15 @@ typedef struct slice_s { ...@@ -205,10 +254,15 @@ typedef struct slice_s {
nlohmann::json to_json() const { nlohmann::json to_json() const {
nlohmann::json json_data = {}; nlohmann::json json_data = {};
json_data["sst"] = this->sst; json_data["sst"] = this->sst;
if (sst > 127) json_data["sd"] = this->sd; if (sst > SST_MAX_STANDARDIZED_VALUE) json_data["sd"] = this->sd;
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->sst = json_data["sst"].get<int>();
if (this->sst > SST_MAX_STANDARDIZED_VALUE)
this->sd = json_data["sd"].get<int>();
}
} slice_t; } slice_t;
typedef struct plmn_support_item_s { typedef struct plmn_support_item_s {
...@@ -228,6 +282,19 @@ typedef struct plmn_support_item_s { ...@@ -228,6 +282,19 @@ typedef struct plmn_support_item_s {
} }
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->mcc = json_data["mcc"].get<std::string>();
this->mnc = json_data["mnc"].get<std::string>();
this->tac = json_data["tac"].get<int>();
for (auto s : json_data["slice_list"]) {
slice_t sl = {};
sl.from_json(s);
slice_list.push_back(sl);
}
}
} plmn_item_t; } plmn_item_t;
typedef struct { typedef struct {
...@@ -238,14 +305,29 @@ typedef struct { ...@@ -238,14 +305,29 @@ typedef struct {
nlohmann::json json_data = {}; nlohmann::json json_data = {};
json_data["prefered_integrity_algorithm"] = nlohmann::json::array(); json_data["prefered_integrity_algorithm"] = nlohmann::json::array();
json_data["prefered_ciphering_algorithm"] = nlohmann::json::array(); json_data["prefered_ciphering_algorithm"] = nlohmann::json::array();
for (auto s : prefered_integrity_algorithm) { for (auto s : this->prefered_integrity_algorithm) {
json_data["prefered_integrity_algorithm"].push_back(s); json_data["prefered_integrity_algorithm"].push_back(s);
} }
for (auto s : prefered_ciphering_algorithm) { for (auto s : this->prefered_ciphering_algorithm) {
json_data["prefered_ciphering_algorithm"].push_back(s); json_data["prefered_ciphering_algorithm"].push_back(s);
} }
return json_data; return json_data;
} }
/*
void from_json(nlohmann::json& json_data) {
uint8_t i = 0;
for (auto s : json_data["prefered_integrity_algorithm"]) {
uint8_t integ_alg = s.get<int>();
prefered_integrity_algorithm[i] = integ_alg;
++i;
}
i = 0;
for (auto s : json_data["prefered_ciphering_algorithm"]) {
uint8_t cipher_alg = s.get<int>();
prefered_ciphering_algorithm[i] = cipher_alg;
++i;
}
}*/
} nas_conf_t; } nas_conf_t;
typedef struct { typedef struct {
...@@ -269,20 +351,44 @@ typedef struct { ...@@ -269,20 +351,44 @@ typedef struct {
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->id = json_data["id"].get<int>();
this->ipv4 = json_data["ipv4"].get<std::string>();
this->port = json_data["port"]
.get<std::string>(); // TODO: use int instead of string
this->http2_port = json_data["http2_port"].get<int>();
this->version = json_data["version"].get<std::string>();
this->selected = json_data["selected"].get<bool>();
this->fqdn = json_data["fqdn"].get<std::string>();
}
} smf_inst_t; } smf_inst_t;
typedef struct nf_addr_s { typedef struct nf_addr_s {
struct in_addr ipv4_addr; struct in_addr ipv4_addr;
unsigned int port; unsigned int port;
std::string api_version; std::string api_version;
std::string fqdn;
nlohmann::json to_json() const { nlohmann::json to_json() const {
nlohmann::json json_data = {}; nlohmann::json json_data = {};
json_data["ipv4_addr"] = inet_ntoa(this->ipv4_addr); json_data["ipv4_addr"] = inet_ntoa(this->ipv4_addr);
json_data["port"] = this->port; json_data["port"] = this->port;
json_data["api_version"] = this->api_version; json_data["api_version"] = this->api_version;
json_data["fqdn"] = this->fqdn;
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
std::string ipv4_addr_str = json_data["ipv4_addr"].get<std::string>();
IPV4_STR_ADDR_TO_INADDR(
util::trim(ipv4_addr_str).c_str(), this->ipv4_addr,
"BAD IPv4 ADDRESS FORMAT FOR INTERFACE !");
this->port = json_data["port"].get<int>();
this->api_version = json_data["api_version"].get<std::string>();
this->fqdn = json_data["fqdn"].get<std::string>();
}
} nf_addr_t; } nf_addr_t;
class amf_config { class amf_config {
...@@ -305,6 +411,8 @@ class amf_config { ...@@ -305,6 +411,8 @@ class amf_config {
*/ */
int load_interface(const Setting& if_cfg, interface_cfg_t& cfg); int load_interface(const Setting& if_cfg, interface_cfg_t& cfg);
bool resolve_fqdn(const std::string& fqdn, struct in_addr& ipv4_addr);
/* /*
* Get the URI of AMF N1N2MessageSubscribe * Get the URI of AMF N1N2MessageSubscribe
* @param [const std::string&] ue_cxt_id: UE Context Id * @param [const std::string&] ue_cxt_id: UE Context Id
...@@ -362,6 +470,13 @@ class amf_config { ...@@ -362,6 +470,13 @@ class amf_config {
*/ */
void to_json(nlohmann::json& json_data) const; void to_json(nlohmann::json& json_data) const;
/*
* Update AMF's config from Json
* @param [nlohmann::json &] json_data: Updated configuration in json format
* @return true if success otherwise return false
*/
bool from_json(nlohmann::json& json_data);
unsigned int instance; unsigned int instance;
std::string pid_dir; std::string pid_dir;
interface_cfg_t n2; interface_cfg_t n2;
...@@ -371,10 +486,10 @@ class amf_config { ...@@ -371,10 +486,10 @@ class amf_config {
unsigned int sbi_http2_port; unsigned int sbi_http2_port;
unsigned int statistics_interval; unsigned int statistics_interval;
std::string AMF_Name; std::string amf_name;
guami_t guami; guami_t guami;
std::vector<guami_t> guami_list; std::vector<guami_t> guami_list;
unsigned int relativeAMFCapacity; unsigned int relative_amf_capacity;
std::vector<plmn_item_t> plmn_list; std::vector<plmn_item_t> plmn_list;
std::string is_emergency_support; std::string is_emergency_support;
auth_conf auth_para; auth_conf auth_para;
...@@ -404,6 +519,23 @@ class amf_config { ...@@ -404,6 +519,23 @@ class amf_config {
json_data["use_http2"] = this->use_http2; json_data["use_http2"] = this->use_http2;
return json_data; return json_data;
} }
void from_json(nlohmann::json& json_data) {
this->enable_nf_registration =
json_data["enable_nf_registration"].get<bool>();
this->enable_external_nrf = json_data["enable_external_nrf"].get<bool>();
this->enable_smf_selection =
json_data["enable_smf_selection"].get<bool>();
this->enable_external_nrf = json_data["enable_external_nrf"].get<bool>();
this->enable_external_ausf =
json_data["enable_external_ausf"].get<bool>();
this->enable_external_udm = json_data["enable_external_udm"].get<bool>();
this->enable_external_nssf =
json_data["enable_external_nssf"].get<bool>();
this->use_fqdn_dns = json_data["use_fqdn_dns"].get<bool>();
this->use_http2 = json_data["use_http2"].get<bool>();
}
} support_features; } support_features;
nf_addr_t nrf_addr; nf_addr_t nrf_addr;
......
...@@ -420,7 +420,7 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) { ...@@ -420,7 +420,7 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
// file and send_msg // file and send_msg
uint8_t* buffer = (uint8_t*) calloc(1, BUFFER_SIZE_1024); uint8_t* buffer = (uint8_t*) calloc(1, BUFFER_SIZE_1024);
NGSetupResponseMsg ngSetupResp; NGSetupResponseMsg ngSetupResp;
ngSetupResp.setAMFName(amf_cfg.AMF_Name); ngSetupResp.setAMFName(amf_cfg.amf_name);
std::vector<struct GuamiItem_s> guami_list; std::vector<struct GuamiItem_s> guami_list;
for (int i = 0; i < amf_cfg.guami_list.size(); i++) { for (int i = 0; i < amf_cfg.guami_list.size(); i++) {
struct GuamiItem_s tmp; struct GuamiItem_s tmp;
...@@ -433,7 +433,7 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) { ...@@ -433,7 +433,7 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
} }
ngSetupResp.setGUAMIList(guami_list); ngSetupResp.setGUAMIList(guami_list);
ngSetupResp.setRelativeAmfCapacity(amf_cfg.relativeAMFCapacity); ngSetupResp.setRelativeAmfCapacity(amf_cfg.relative_amf_capacity);
std::vector<PlmnSliceSupport_t> plmn_list; std::vector<PlmnSliceSupport_t> plmn_list;
for (int i = 0; i < amf_cfg.plmn_list.size(); i++) { for (int i = 0; i < amf_cfg.plmn_list.size(); i++) {
PlmnSliceSupport_t tmp; PlmnSliceSupport_t tmp;
......
...@@ -151,6 +151,7 @@ void nf_profile::get_nf_snssais(std::vector<snssai_t>& s) const { ...@@ -151,6 +151,7 @@ void nf_profile::get_nf_snssais(std::vector<snssai_t>& s) const {
void nf_profile::add_snssai(const snssai_t& s) { void nf_profile::add_snssai(const snssai_t& s) {
snssais.push_back(s); snssais.push_back(s);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void nf_profile::set_nf_ipv4_addresses(const std::vector<struct in_addr>& a) { void nf_profile::set_nf_ipv4_addresses(const std::vector<struct in_addr>& a) {
ipv4_addresses = a; ipv4_addresses = a;
...@@ -165,6 +166,10 @@ void nf_profile::get_nf_ipv4_addresses(std::vector<struct in_addr>& a) const { ...@@ -165,6 +166,10 @@ void nf_profile::get_nf_ipv4_addresses(std::vector<struct in_addr>& a) const {
a = ipv4_addresses; a = ipv4_addresses;
} }
//------------------------------------------------------------------------------
void nf_profile::delete_nf_ipv4_addresses() {
ipv4_addresses.clear();
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void nf_profile::display() const { void nf_profile::display() const {
Logger::amf_app().debug("NF instance info"); Logger::amf_app().debug("NF instance info");
...@@ -296,6 +301,11 @@ void amf_profile::get_nf_services(std::vector<nf_service_t>& n) const { ...@@ -296,6 +301,11 @@ void amf_profile::get_nf_services(std::vector<nf_service_t>& n) const {
n = nf_services; n = nf_services;
} }
//------------------------------------------------------------------------------
void amf_profile::delete_nf_services() {
nf_services.clear();
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void amf_profile::set_custom_info(const nlohmann::json& c) { void amf_profile::set_custom_info(const nlohmann::json& c) {
custom_info = c; custom_info = c;
......
...@@ -267,6 +267,12 @@ class nf_profile : public std::enable_shared_from_this<nf_profile> { ...@@ -267,6 +267,12 @@ class nf_profile : public std::enable_shared_from_this<nf_profile> {
*/ */
void get_nf_ipv4_addresses(std::vector<struct in_addr>& a) const; void get_nf_ipv4_addresses(std::vector<struct in_addr>& a) const;
/*
* Remove all NF instance ipv4_addresses
* @param void
* @return void:
*/
void delete_nf_ipv4_addresses();
/* /*
* Print related-information for NF profile * Print related-information for NF profile
* @param void * @param void
...@@ -349,6 +355,12 @@ class amf_profile : public nf_profile { ...@@ -349,6 +355,12 @@ class amf_profile : public nf_profile {
*/ */
void get_nf_services(std::vector<nf_service_t>& n) const; void get_nf_services(std::vector<nf_service_t>& n) const;
/*
* Delete all NF services
* @param void
* @return void:
*/
void delete_nf_services();
/* /*
* Set custom info * Set custom info
* @param [const nlohmann::json &] c: custom info to be set * @param [const nlohmann::json &] c: custom info to be set
......
...@@ -163,3 +163,9 @@ void statistics::update_gnb(const uint32_t& gnb_id, const gnb_infos& gnb) { ...@@ -163,3 +163,9 @@ void statistics::update_gnb(const uint32_t& gnb_id, const gnb_infos& gnb) {
gnbs[gnb_id] = gnb; gnbs[gnb_id] = gnb;
} }
} }
//------------------------------------------------------------------------------
uint32_t statistics::get_number_connected_gnbs() const {
std::shared_lock lock(m_gnbs);
return gnbs.size();
}
...@@ -124,6 +124,13 @@ class statistics { ...@@ -124,6 +124,13 @@ class statistics {
*/ */
void update_gnb(const uint32_t& gnb_id, const gnb_infos& gnb); void update_gnb(const uint32_t& gnb_id, const gnb_infos& gnb);
/*
* Get number of connected gNBs
* @param void
* @return number of connected gNBs
*/
uint32_t get_number_connected_gnbs() const;
public: public:
uint32_t gNB_connected; uint32_t gNB_connected;
uint32_t UE_connected; uint32_t UE_connected;
......
...@@ -95,6 +95,7 @@ typedef enum { ...@@ -95,6 +95,7 @@ typedef enum {
N11_NF_INSTANCE_DISCOVERY, N11_NF_INSTANCE_DISCOVERY,
N11_N1_MESSAGE_NOTIFY, N11_N1_MESSAGE_NOTIFY,
SBI_AMF_CONFIGURATION, SBI_AMF_CONFIGURATION,
SBI_UPDATE_AMF_CONFIGURATION,
SBI_EVENT_EXPOSURE_REQUEST, SBI_EVENT_EXPOSURE_REQUEST,
SBI_NOTIFICATION_DATA, SBI_NOTIFICATION_DATA,
SBI_NOTIFY_SUBSCRIBED_EVENT, SBI_NOTIFY_SUBSCRIBED_EVENT,
......
...@@ -225,4 +225,19 @@ class itti_sbi_amf_configuration : public itti_sbi_msg { ...@@ -225,4 +225,19 @@ class itti_sbi_amf_configuration : public itti_sbi_msg {
uint32_t promise_id; uint32_t promise_id;
}; };
//-----------------------------------------------------------------------------
class itti_sbi_update_amf_configuration : public itti_sbi_msg {
public:
itti_sbi_update_amf_configuration(
const task_id_t orig, const task_id_t dest, uint32_t pid)
: itti_sbi_msg(SBI_UPDATE_AMF_CONFIGURATION, orig, dest),
http_version(1),
promise_id(pid) {}
const char* get_msg_name() { return "SBI_UPDATE_AMF_CONFIGURATION"; };
uint8_t http_version;
uint32_t promise_id;
nlohmann::json configuration;
};
#endif /* ITTI_MSG_SBI_HPP_INCLUDED_ */ #endif /* ITTI_MSG_SBI_HPP_INCLUDED_ */
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#ifndef _3GPP_TS_24501_H_ #ifndef _3GPP_TS_24501_H_
#define _3GPP_TS_24501_H_ #define _3GPP_TS_24501_H_
#include <string>
#include <vector>
/********** epd type **************/ /********** epd type **************/
#define EPD_5GS_MM_MSG 0b01111110 #define EPD_5GS_MM_MSG 0b01111110
...@@ -129,6 +132,10 @@ ...@@ -129,6 +132,10 @@
#define EA1_128_5G 0b001 #define EA1_128_5G 0b001
#define EA2_128_5G 0b010 #define EA2_128_5G 0b010
static const std::vector<std::string> nas_itegrity_algorithm_list_e2str = {
"NIA0", "NIA1", "NIA2"};
static const std::vector<std::string> nas_ciphering_algorithm_list_e2str = {
"NEA0", "NEA1", "NEA2"};
/************************** cause value for 5g mobility management(Annex A) /************************** cause value for 5g mobility management(Annex A)
* ********************************/ * ********************************/
#define _5GMM_CAUSE_ILLEGAL_UE 3 #define _5GMM_CAUSE_ILLEGAL_UE 3
......
...@@ -45,6 +45,10 @@ void AMFConfigurationApi::setupRoutes() { ...@@ -45,6 +45,10 @@ void AMFConfigurationApi::setupRoutes() {
*router, base + amf_cfg.sbi_api_version + "/configuration/", *router, base + amf_cfg.sbi_api_version + "/configuration/",
Routes::bind(&AMFConfigurationApi::read_configuration_handler, this)); Routes::bind(&AMFConfigurationApi::read_configuration_handler, this));
Routes::Put(
*router, base + amf_cfg.sbi_api_version + "/configuration/",
Routes::bind(&AMFConfigurationApi::update_configuration_handler, this));
// Default handler, called when a route is not found // Default handler, called when a route is not found
router->addCustomHandler(Routes::bind( router->addCustomHandler(Routes::bind(
&AMFConfigurationApi::configuration_api_default_handler, this)); &AMFConfigurationApi::configuration_api_default_handler, this));
...@@ -69,6 +73,26 @@ void AMFConfigurationApi::read_configuration_handler( ...@@ -69,6 +73,26 @@ void AMFConfigurationApi::read_configuration_handler(
} }
} }
void AMFConfigurationApi::update_configuration_handler(
const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response) {
try {
auto configuration_info = nlohmann::json::parse(request.body());
this->update_configuration(configuration_info, response);
} catch (nlohmann::detail::exception& e) {
// send a 400 error
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (Pistache::Http::HttpError& e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception& e) {
// send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void AMFConfigurationApi::configuration_api_default_handler( void AMFConfigurationApi::configuration_api_default_handler(
const Pistache::Rest::Request&, Pistache::Http::ResponseWriter response) { const Pistache::Rest::Request&, Pistache::Http::ResponseWriter response) {
response.send( response.send(
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <pistache/optional.h> #include <pistache/optional.h>
#include <pistache/router.h> #include <pistache/router.h>
#include <nlohmann/json.hpp>
namespace oai::amf::api { namespace oai::amf::api {
class AMFConfigurationApi { class AMFConfigurationApi {
...@@ -43,6 +45,9 @@ class AMFConfigurationApi { ...@@ -43,6 +45,9 @@ class AMFConfigurationApi {
void read_configuration_handler( void read_configuration_handler(
const Pistache::Rest::Request& request, const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response); Pistache::Http::ResponseWriter response);
void update_configuration_handler(
const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response);
void configuration_api_default_handler( void configuration_api_default_handler(
const Pistache::Rest::Request& request, const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response); Pistache::Http::ResponseWriter response);
...@@ -50,6 +55,9 @@ class AMFConfigurationApi { ...@@ -50,6 +55,9 @@ class AMFConfigurationApi {
std::shared_ptr<Pistache::Rest::Router> router; std::shared_ptr<Pistache::Rest::Router> router;
virtual void read_configuration(Pistache::Http::ResponseWriter& response) = 0; virtual void read_configuration(Pistache::Http::ResponseWriter& response) = 0;
virtual void update_configuration(
nlohmann::json& configuration_info,
Pistache::Http::ResponseWriter& response) = 0;
}; };
} // namespace oai::amf::api } // namespace oai::amf::api
......
...@@ -102,4 +102,75 @@ void AMFConfigurationApiImpl::read_configuration( ...@@ -102,4 +102,75 @@ void AMFConfigurationApiImpl::read_configuration(
} }
} }
void AMFConfigurationApiImpl::update_configuration(
nlohmann::json& configuration_info,
Pistache::Http::ResponseWriter& response) {
Logger::amf_server().debug("Update AMFConfiguration, handling...");
// Generate a promise and associate this promise to the ITTI message
uint32_t promise_id = m_amf_app->generate_promise_id();
Logger::amf_n1().debug("Promise ID generated %d", promise_id);
boost::shared_ptr<boost::promise<nlohmann::json>> p =
boost::make_shared<boost::promise<nlohmann::json>>();
boost::shared_future<nlohmann::json> f = p->get_future();
m_amf_app->add_promise(promise_id, p);
// Handle the AMFConfiguration in amf_app
std::shared_ptr<itti_sbi_update_amf_configuration> itti_msg =
std::make_shared<itti_sbi_update_amf_configuration>(
TASK_AMF_SBI, TASK_AMF_APP, promise_id);
itti_msg->http_version = 1;
itti_msg->promise_id = promise_id;
itti_msg->configuration = configuration_info;
int ret = itti_inst->send_msg(itti_msg);
if (0 != ret) {
Logger::amf_server().error(
"Could not send ITTI message %s to task TASK_AMF_APP",
itti_msg->get_msg_name());
}
boost::future_status status;
// wait for timeout or ready
status = f.wait_for(boost::chrono::milliseconds(FUTURE_STATUS_TIMEOUT_MS));
if (status == boost::future_status::ready) {
assert(f.is_ready());
assert(f.has_value());
assert(!f.has_exception());
// Wait for the result from APP
// result includes json content and http response code
nlohmann::json result = f.get();
Logger::amf_server().debug("Got result for promise ID %d", promise_id);
// process data
uint32_t http_response_code = 0;
nlohmann::json json_data = {};
if (result.find("httpResponseCode") != result.end()) {
http_response_code = result["httpResponseCode"].get<int>();
}
if (http_response_code == 200) {
if (result.find("content") != result.end()) {
json_data = result["content"];
}
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
response.send(Pistache::Http::Code::Ok, json_data.dump().c_str());
} else {
// Problem details
if (result.find("ProblemDetails") != result.end()) {
json_data = result["ProblemDetails"];
}
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/problem+json"));
response.send(
Pistache::Http::Code(http_response_code), json_data.dump().c_str());
}
}
}
} // namespace oai::amf::api } // namespace oai::amf::api
...@@ -41,6 +41,9 @@ class AMFConfigurationApiImpl : public oai::amf::api::AMFConfigurationApi { ...@@ -41,6 +41,9 @@ class AMFConfigurationApiImpl : public oai::amf::api::AMFConfigurationApi {
~AMFConfigurationApiImpl() {} ~AMFConfigurationApiImpl() {}
void read_configuration(Pistache::Http::ResponseWriter& response); void read_configuration(Pistache::Http::ResponseWriter& response);
void update_configuration(
nlohmann::json& configuration_info,
Pistache::Http::ResponseWriter& response);
}; };
} // namespace oai::amf::api } // namespace oai::amf::api
......
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