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
......
...@@ -78,7 +78,7 @@ amf_config::amf_config() { ...@@ -78,7 +78,7 @@ amf_config::amf_config() {
statistics_interval = 0; statistics_interval = 0;
guami = {}; guami = {};
guami_list = {}; guami_list = {};
relativeAMFCapacity = 0; relative_amf_capacity = 0;
plmn_list = {}; plmn_list = {};
auth_conf auth_para = {}; auth_conf auth_para = {};
nas_cfg = {}; nas_cfg = {};
...@@ -158,7 +158,7 @@ int amf_config::load(const std::string& config_file) { ...@@ -158,7 +158,7 @@ int amf_config::load(const std::string& config_file) {
// AMF Name // AMF Name
try { try {
amf_cfg.lookupValue(AMF_CONFIG_STRING_AMF_NAME, AMF_Name); amf_cfg.lookupValue(AMF_CONFIG_STRING_AMF_NAME, amf_name);
} catch (const SettingNotFoundException& nfex) { } catch (const SettingNotFoundException& nfex) {
Logger::amf_app().error( Logger::amf_app().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath()); "%s : %s, using defaults", nfex.what(), nfex.getPath());
...@@ -200,7 +200,7 @@ int amf_config::load(const std::string& config_file) { ...@@ -200,7 +200,7 @@ int amf_config::load(const std::string& config_file) {
// AMF Capacity // AMF Capacity
try { try {
amf_cfg.lookupValue( amf_cfg.lookupValue(
AMF_CONFIG_STRING_RELATIVE_AMF_CAPACITY, relativeAMFCapacity); AMF_CONFIG_STRING_RELATIVE_AMF_CAPACITY, relative_amf_capacity);
} catch (const SettingNotFoundException& nfex) { } catch (const SettingNotFoundException& nfex) {
Logger::amf_app().error( Logger::amf_app().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath()); "%s : %s, using defaults", nfex.what(), nfex.getPath());
...@@ -375,6 +375,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -375,6 +375,9 @@ int amf_config::load(const std::string& config_file) {
std::string smf_api_version = {}; std::string smf_api_version = {};
std::string selected = {}; std::string selected = {};
// Store FQDN
smf_addr_item.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, smf_inst.fqdn);
smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_ID, smf_inst.id); smf_addr_item.lookupValue(AMF_CONFIG_STRING_SMF_INSTANCE_ID, smf_inst.id);
if (!support_features.use_fqdn_dns) { if (!support_features.use_fqdn_dns) {
smf_addr_item.lookupValue( smf_addr_item.lookupValue(
...@@ -401,9 +404,7 @@ int amf_config::load(const std::string& config_file) { ...@@ -401,9 +404,7 @@ int amf_config::load(const std::string& config_file) {
throw(AMF_CONFIG_STRING_SMF_INSTANCE_VERSION "failed"); throw(AMF_CONFIG_STRING_SMF_INSTANCE_VERSION "failed");
} }
} else { } else {
std::string smf_fqdn = {}; smf_addr_item.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, smf_inst.fqdn);
smf_addr_item.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, smf_fqdn);
smf_inst.fqdn = smf_fqdn;
} }
smf_addr_item.lookupValue( smf_addr_item.lookupValue(
...@@ -423,6 +424,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -423,6 +424,9 @@ int amf_config::load(const std::string& config_file) {
string address = {}; string address = {};
if (!support_features.use_fqdn_dns) { if (!support_features.use_fqdn_dns) {
// Store FQDN
nrf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, nrf_addr.fqdn);
nrf_cfg.lookupValue(AMF_CONFIG_STRING_NRF_IPV4_ADDRESS, address); nrf_cfg.lookupValue(AMF_CONFIG_STRING_NRF_IPV4_ADDRESS, address);
IPV4_STR_ADDR_TO_INADDR( IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), nrf_ipv4_addr, util::trim(address).c_str(), nrf_ipv4_addr,
...@@ -440,10 +444,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -440,10 +444,9 @@ int amf_config::load(const std::string& config_file) {
} }
nrf_addr.api_version = nrf_api_version; nrf_addr.api_version = nrf_api_version;
} else { } else {
std::string nrf_fqdn = {}; nrf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, nrf_addr.fqdn);
nrf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, nrf_fqdn);
uint8_t addr_type = {}; uint8_t addr_type = {};
fqdn::resolve(nrf_fqdn, address, nrf_port, addr_type); fqdn::resolve(nrf_addr.fqdn, address, nrf_port, addr_type);
if (addr_type != 0) { // IPv6: TODO if (addr_type != 0) { // IPv6: TODO
throw("DO NOT SUPPORT IPV6 ADDR FOR NRF!"); throw("DO NOT SUPPORT IPV6 ADDR FOR NRF!");
} else { // IPv4 } else { // IPv4
...@@ -472,6 +475,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -472,6 +475,9 @@ int amf_config::load(const std::string& config_file) {
std::string ausf_api_version = {}; std::string ausf_api_version = {};
if (!support_features.use_fqdn_dns) { if (!support_features.use_fqdn_dns) {
// Store FQDN
ausf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, ausf_addr.fqdn);
ausf_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address); ausf_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address);
IPV4_STR_ADDR_TO_INADDR( IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), ausf_ipv4_addr, util::trim(address).c_str(), ausf_ipv4_addr,
...@@ -490,10 +496,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -490,10 +496,9 @@ int amf_config::load(const std::string& config_file) {
} }
ausf_addr.api_version = ausf_api_version; ausf_addr.api_version = ausf_api_version;
} else { } else {
std::string ausf_fqdn = {}; ausf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, ausf_addr.fqdn);
ausf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, ausf_fqdn);
uint8_t addr_type = {}; uint8_t addr_type = {};
fqdn::resolve(ausf_fqdn, address, ausf_port, addr_type); fqdn::resolve(ausf_addr.fqdn, address, ausf_port, addr_type);
if (addr_type != 0) { // IPv6: TODO if (addr_type != 0) { // IPv6: TODO
throw("DO NOT SUPPORT IPV6 ADDR FOR AUSF!"); throw("DO NOT SUPPORT IPV6 ADDR FOR AUSF!");
} else { // IPv4 } else { // IPv4
...@@ -520,6 +525,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -520,6 +525,9 @@ int amf_config::load(const std::string& config_file) {
std::string udm_api_version = {}; std::string udm_api_version = {};
if (!support_features.use_fqdn_dns) { if (!support_features.use_fqdn_dns) {
// Store FQDN
udm_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, udm_addr.fqdn);
udm_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address); udm_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address);
IPV4_STR_ADDR_TO_INADDR( IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), udm_ipv4_addr, util::trim(address).c_str(), udm_ipv4_addr,
...@@ -538,10 +546,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -538,10 +546,9 @@ int amf_config::load(const std::string& config_file) {
} }
udm_addr.api_version = udm_api_version; udm_addr.api_version = udm_api_version;
} else { } else {
std::string udm_fqdn = {}; udm_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, udm_addr.fqdn);
udm_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, udm_fqdn);
uint8_t addr_type = {}; uint8_t addr_type = {};
fqdn::resolve(udm_fqdn, address, udm_port, addr_type); fqdn::resolve(udm_addr.fqdn, address, udm_port, addr_type);
if (addr_type != 0) { // IPv6: TODO if (addr_type != 0) { // IPv6: TODO
throw("DO NOT SUPPORT IPV6 ADDR FOR UDM!"); throw("DO NOT SUPPORT IPV6 ADDR FOR UDM!");
} else { // IPv4 } else { // IPv4
...@@ -563,6 +570,8 @@ int amf_config::load(const std::string& config_file) { ...@@ -563,6 +570,8 @@ int amf_config::load(const std::string& config_file) {
std::string nssf_api_version = {}; std::string nssf_api_version = {};
if (!support_features.use_fqdn_dns) { if (!support_features.use_fqdn_dns) {
// Store FQDN
nssf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, nssf_addr.fqdn);
nssf_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address); nssf_cfg.lookupValue(AMF_CONFIG_STRING_IPV4_ADDRESS, address);
IPV4_STR_ADDR_TO_INADDR( IPV4_STR_ADDR_TO_INADDR(
util::trim(address).c_str(), nssf_ipv4_addr, util::trim(address).c_str(), nssf_ipv4_addr,
...@@ -581,10 +590,9 @@ int amf_config::load(const std::string& config_file) { ...@@ -581,10 +590,9 @@ int amf_config::load(const std::string& config_file) {
} }
nssf_addr.api_version = nssf_api_version; nssf_addr.api_version = nssf_api_version;
} else { } else {
std::string nssf_fqdn = {}; nssf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, nssf_addr.fqdn);
nssf_cfg.lookupValue(AMF_CONFIG_STRING_FQDN_DNS, nssf_fqdn);
uint8_t addr_type = {}; uint8_t addr_type = {};
fqdn::resolve(nssf_fqdn, address, nssf_port, addr_type); fqdn::resolve(nssf_addr.fqdn, address, nssf_port, addr_type);
if (addr_type != 0) { // IPv6: TODO if (addr_type != 0) { // IPv6: TODO
throw("DO NOT SUPPORT IPV6 ADDR FOR NSSF!"); throw("DO NOT SUPPORT IPV6 ADDR FOR NSSF!");
} else { // IPv4 } else { // IPv4
...@@ -682,7 +690,7 @@ void amf_config::display() { ...@@ -682,7 +690,7 @@ void amf_config::display() {
Logger::config().info("Configuration AMF:"); Logger::config().info("Configuration AMF:");
Logger::config().info("- Instance ................: %d", instance); Logger::config().info("- Instance ................: %d", instance);
Logger::config().info("- PID dir .................: %s", pid_dir.c_str()); Logger::config().info("- PID dir .................: %s", pid_dir.c_str());
Logger::config().info("- AMF NAME.................: %s", AMF_Name.c_str()); Logger::config().info("- AMF NAME.................: %s", amf_name.c_str());
Logger::config().info( Logger::config().info(
"- GUAMI (MCC, MNC, Region ID, AMF Set ID, AMF pointer): "); "- GUAMI (MCC, MNC, Region ID, AMF Set ID, AMF pointer): ");
Logger::config().info( Logger::config().info(
...@@ -695,7 +703,8 @@ void amf_config::display() { ...@@ -695,7 +703,8 @@ void amf_config::display() {
guami_list[i].mnc.c_str(), guami_list[i].regionID.c_str(), guami_list[i].mnc.c_str(), guami_list[i].regionID.c_str(),
guami_list[i].AmfSetID.c_str(), guami_list[i].AmfPointer.c_str()); guami_list[i].AmfSetID.c_str(), guami_list[i].AmfPointer.c_str());
} }
Logger::config().info("- Relative Capacity .......: %d", relativeAMFCapacity); Logger::config().info(
"- Relative Capacity .......: %d", relative_amf_capacity);
Logger::config().info("- PLMN Support: "); Logger::config().info("- PLMN Support: ");
for (int i = 0; i < plmn_list.size(); i++) { for (int i = 0; i < plmn_list.size(); i++) {
Logger::config().info( Logger::config().info(
...@@ -707,12 +716,16 @@ void amf_config::display() { ...@@ -707,12 +716,16 @@ void amf_config::display() {
std::string str = {}; std::string str = {};
str = str.append(" SST") str = str.append(" SST")
.append( .append(
(plmn_list[i].slice_list[j].sst > 127) ? ", SD " : " ....") (plmn_list[i].slice_list[j].sst >
SST_MAX_STANDARDIZED_VALUE) ?
", SD " :
" ....")
.append("...........: ") .append("...........: ")
.append(std::to_string(plmn_list[i].slice_list[j].sst)) .append(std::to_string(plmn_list[i].slice_list[j].sst))
.append("") .append("")
.append( .append(
(plmn_list[i].slice_list[j].sst > 127) ? (plmn_list[i].slice_list[j].sst >
SST_MAX_STANDARDIZED_VALUE) ?
", " + std::to_string(plmn_list[i].slice_list[j].sd) : ", " + std::to_string(plmn_list[i].slice_list[j].sd) :
" "); " ");
Logger::config().info(str.c_str()); Logger::config().info(str.c_str());
...@@ -721,7 +734,7 @@ void amf_config::display() { ...@@ -721,7 +734,7 @@ void amf_config::display() {
Logger::config().info( Logger::config().info(
"- Emergency Support .......: %s", is_emergency_support.c_str()); "- Emergency Support .......: %s", is_emergency_support.c_str());
Logger::config().info("- Database : "); Logger::config().info("- Database: ");
Logger::config().info( Logger::config().info(
" MySQL Server Addr .....: %s", auth_para.mysql_server.c_str()); " MySQL Server Addr .....: %s", auth_para.mysql_server.c_str());
Logger::config().info( Logger::config().info(
...@@ -731,6 +744,19 @@ void amf_config::display() { ...@@ -731,6 +744,19 @@ void amf_config::display() {
Logger::config().info( Logger::config().info(
" MySQL DB ..............: %s", auth_para.mysql_db.c_str()); " MySQL DB ..............: %s", auth_para.mysql_db.c_str());
// TODO:
/*
Logger::config().info("- Supported NAS Algorithm: ");
Logger::config().info(
" Integrity Algorithm ...: %s","");
Logger::config().info(
" Ciphering Algorithm ...: %s", "");
st::string nas_itegrity_algorithm_list = {};
for(auto s: nas_cfg.prefered_integrity_algorithm){
}
*/
Logger::config().info("- N2 Networking:"); Logger::config().info("- N2 Networking:");
Logger::config().info(" Iface .................: %s", n2.if_name.c_str()); Logger::config().info(" Iface .................: %s", n2.if_name.c_str());
Logger::config().info(" IP Addr ...............: %s", inet_ntoa(n2.addr4)); Logger::config().info(" IP Addr ...............: %s", inet_ntoa(n2.addr4));
...@@ -871,6 +897,26 @@ int amf_config::load_interface( ...@@ -871,6 +897,26 @@ int amf_config::load_interface(
return RETURNok; return RETURNok;
} }
//------------------------------------------------------------------------------
bool amf_config::resolve_fqdn(
const std::string& fqdn, struct in_addr& ipv4_addr) {
uint8_t addr_type = {};
unsigned int port = 0;
string address = {};
fqdn::resolve(fqdn, address, port, addr_type);
if (addr_type != 0) { // IPv6: TODO
Logger::amf_app().error("DO NOT SUPPORT IPV6 ADDR FOR THIS NF");
return false;
} else { // IPv4
if (inet_aton(util::trim(address).c_str(), &ipv4_addr) <= 0) return false;
// IPV4_STR_ADDR_TO_INADDR(
// util::trim(address).c_str(), ipv4_addr,
// "BAD IPv4 ADDRESS FORMAT FOR NF !");
}
return true;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::string amf_config::get_amf_n1n2_message_subscribe_uri( std::string amf_config::get_amf_n1n2_message_subscribe_uri(
const std::string& ue_cxt_id) { const std::string& ue_cxt_id) {
...@@ -926,14 +972,14 @@ std::string amf_config::get_ausf_ue_authentications_uri() { ...@@ -926,14 +972,14 @@ std::string amf_config::get_ausf_ue_authentications_uri() {
void amf_config::to_json(nlohmann::json& json_data) const { void amf_config::to_json(nlohmann::json& json_data) const {
json_data["instance"] = instance; json_data["instance"] = instance;
json_data["pid_dir"] = pid_dir; json_data["pid_dir"] = pid_dir;
json_data["amf_name"] = AMF_Name; // TODO: amf_name json_data["amf_name"] = amf_name;
json_data["guami"] = guami.to_json(); json_data["guami"] = guami.to_json();
json_data["guami_list"] = nlohmann::json::array(); json_data["guami_list"] = nlohmann::json::array();
for (auto s : guami_list) { for (auto s : guami_list) {
json_data["guami_list"].push_back(s.to_json()); json_data["guami_list"].push_back(s.to_json());
} }
json_data["relativeAMFCapacity"] = relativeAMFCapacity; json_data["relative_amf_capacity"] = relative_amf_capacity;
json_data["plmn_list"] = nlohmann::json::array(); json_data["plmn_list"] = nlohmann::json::array();
for (auto s : plmn_list) { for (auto s : plmn_list) {
...@@ -954,15 +1000,15 @@ void amf_config::to_json(nlohmann::json& json_data) const { ...@@ -954,15 +1000,15 @@ void amf_config::to_json(nlohmann::json& json_data) const {
} }
if (support_features.enable_external_nssf) { if (support_features.enable_external_nssf) {
json_data["nrf"] = nssf_addr.to_json(); json_data["nssf"] = nssf_addr.to_json();
} }
if (support_features.enable_external_ausf) { if (support_features.enable_external_ausf) {
json_data["nrf"] = ausf_addr.to_json(); json_data["ausf"] = ausf_addr.to_json();
} }
if (support_features.enable_external_udm) { if (support_features.enable_external_udm) {
json_data["nrf"] = udm_addr.to_json(); json_data["udm"] = udm_addr.to_json();
} }
json_data["smf_pool"] = nlohmann::json::array(); json_data["smf_pool"] = nlohmann::json::array();
...@@ -970,4 +1016,135 @@ void amf_config::to_json(nlohmann::json& json_data) const { ...@@ -970,4 +1016,135 @@ void amf_config::to_json(nlohmann::json& json_data) const {
json_data["smf_pool"].push_back(s.to_json()); json_data["smf_pool"].push_back(s.to_json());
} }
} }
//------------------------------------------------------------------------------
bool amf_config::from_json(nlohmann::json& json_data) {
try {
if (json_data.find("instance") != json_data.end()) {
instance = json_data["instance"].get<int>();
}
if (json_data.find("pid_dir") != json_data.end()) {
pid_dir = json_data["pid_dir"].get<std::string>();
}
if (json_data.find("amf_name") != json_data.end()) {
amf_name = json_data["amf_name"].get<std::string>();
}
if (json_data.find("guami") != json_data.end()) {
guami.from_json(json_data["guami"]);
}
if (json_data.find("guami_list") != json_data.end()) {
guami_list.clear();
for (auto s : json_data["guami_list"]) {
guami_t g = {};
g.from_json(s);
guami_list.push_back(g);
}
}
if (json_data.find("relative_amf_capacity") != json_data.end()) {
relative_amf_capacity = json_data["relative_amf_capacity"].get<int>();
}
if (json_data.find("plmn_list") != json_data.end()) {
plmn_list.clear();
for (auto s : json_data["plmn_list"]) {
plmn_item_t p = {};
p.from_json(s);
plmn_list.push_back(p);
}
}
if (json_data.find("is_emergency_support") != json_data.end()) {
is_emergency_support =
json_data["is_emergency_support"].get<std::string>();
}
if (json_data.find("auth_para") != json_data.end()) {
auth_para.from_json(json_data["auth_para"]);
}
if (json_data.find("n2") != json_data.end()) {
n2.from_json(json_data["n2"]);
}
if (json_data.find("n11") != json_data.end()) {
n11.from_json(json_data["n11"]);
}
if (json_data.find("sbi_http2_port") != json_data.end()) {
sbi_http2_port = json_data["sbi_http2_port"].get<int>();
}
if (json_data.find("support_features") != json_data.end()) {
support_features.from_json(json_data["support_features"]);
}
if (support_features.enable_external_nrf) {
if (json_data.find("nrf") != json_data.end()) {
nrf_addr.from_json(json_data["nrf"]);
// if use FQDN -> update IP addr accordingly
if (support_features.use_fqdn_dns) {
resolve_fqdn(nrf_addr.fqdn, nrf_addr.ipv4_addr);
}
}
}
if (support_features.enable_external_nssf) {
if (json_data.find("nssf") != json_data.end()) {
nssf_addr.from_json(json_data["nssf"]);
// if use FQDN -> update IP addr accordingly
if (support_features.use_fqdn_dns) {
resolve_fqdn(nssf_addr.fqdn, nssf_addr.ipv4_addr);
}
}
}
if (support_features.enable_external_ausf) {
if (json_data.find("ausf") != json_data.end()) {
ausf_addr.from_json(json_data["ausf"]);
// if use FQDN -> update IP addr accordingly
if (support_features.use_fqdn_dns) {
resolve_fqdn(ausf_addr.fqdn, ausf_addr.ipv4_addr);
}
}
}
if (support_features.enable_external_udm) {
if (json_data.find("udm") != json_data.end()) {
udm_addr.from_json(json_data["udm"]);
// if use FQDN -> update IP addr accordingly
if (support_features.use_fqdn_dns) {
resolve_fqdn(udm_addr.fqdn, udm_addr.ipv4_addr);
}
}
}
if (json_data.find("smf_pool") != json_data.end()) {
smf_pool.clear();
for (auto s : json_data["smf_pool"]) {
smf_inst_t smf_item = {};
struct in_addr ipv4_addr = {};
smf_item.from_json(s);
// if use FQDN -> update IP addr accordingly
if (support_features.use_fqdn_dns) {
resolve_fqdn(smf_item.fqdn, ipv4_addr);
smf_item.ipv4 = inet_ntoa(ipv4_addr);
}
smf_pool.push_back(smf_item);
}
}
} catch (nlohmann::detail::exception& e) {
Logger::amf_app().error(
"Exception when reading configuration from json %s", e.what());
return false;
} catch (std::exception& e) {
Logger::amf_app().error(
"Exception when reading configuration from json %s", e.what());
return false;
}
return true;
}
} // namespace config } // namespace config
...@@ -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