Commit 1aedf33f authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'n1_message_notify_api' into 'develop'

n1_message_notify_api

See merge request oai/cn5g/oai-cn5g-amf!90
parents 00f51571 c165d3cd
......@@ -85,6 +85,10 @@ services:
- AUSF_PORT=80
- AUSF_API_VERSION=v1
- AUSF_FQDN=localhost
- UDM_IPV4_ADDRESS=0.0.0.0
- UDM_PORT=80
- UDM_API_VERSION=v1
- UDM_FQDN=localhost
- NSSF_IPV4_ADDRESS=0.0.0.0
- NSSF_PORT=80
- NSSF_API_VERSION=v1
......
......@@ -49,6 +49,7 @@ AMF =
{
MCC = "@PLMN_SUPPORT_MCC@"; MNC = "@PLMN_SUPPORT_MNC@"; TAC = @PLMN_SUPPORT_TAC@; # YOUR PLMN CONFIG HERE
SLICE_SUPPORT_LIST = (
{SST = "4"; SD = "4"}, # YOUR NSSAI CONFIG HERE
{SST = "@SST_0@"; SD = "@SD_0@"}, # YOUR NSSAI CONFIG HERE
{SST = "@SST_1@"; SD = "@SD_1@"} # YOUR NSSAI CONFIG HERE
)
......@@ -97,6 +98,14 @@ AMF =
FQDN = "@AUSF_FQDN@" # YOUR AUSF FQDN CONFIG HERE
};
UDM :
{
IPV4_ADDRESS = "127.0.0.1"; # YOUR UDM CONFIG HERE
PORT = 80; # YOUR UDM CONFIG HERE (default: 80)
API_VERSION = "v2"; # YOUR UDM API VERSION FOR SBI CONFIG HERE
FQDN = "udm-fqdn"; # YOUR UDM FQDN CONFIG HERE
};
NSSF :
{
IPV4_ADDRESS = "@NSSF_IPV4_ADDRESS@"; # YOUR NSSF CONFIG HERE
......@@ -111,11 +120,13 @@ AMF =
# STRING, {"yes", "no"},
NF_REGISTRATION = "@NF_REGISTRATION@"; # Set to yes if AMF resgisters to an NRF
NRF_SELECTION = "@NRF_SELECTION@"; # Set to yes to enable NRF discovery and selection
EXTERNAL_NRF = "no"; # Set to yes if AMF works with an external NRF
SMF_SELECTION = "@SMF_SELECTION@"; # Set to yes to enable SMF discovery and selection
EXTERNAL_AUSF = "@EXTERNAL_AUSF@"; # Set to yes if AMF works with an external AUSF
EXTERNAL_UDM = "@EXTERNAL_UDM@"; # Set to yes if AMF works with an external UDM
EXTERNAL_NSSF = "no"; # Set to yes if AMF works with an external NSSF
USE_FQDN_DNS = "@USE_FQDN_DNS@"; # Set to yes if AMF relies on a DNS to resolve NRF/SMF/UDM/AUSF's FQDN
USE_HTTP2 = "@USE_HTTP2@"; # Set to yes to enable HTTP2 for AMF server
USE_HTTP2 = "@USE_HTTP2@"; # Set to yes to enable HTTP2 for AMF server
}
AUTHENTICATION:
......
......@@ -7,7 +7,13 @@ CONFIG_DIR="/openair-amf/etc"
# Default values
EXTERNAL_AUSF=${EXTERNAL_AUSF:-no}
EXTERNAL_UDM=${EXTERNAL_UDM:-no}
UDM_IPV4_ADDRESS=${UDM_IPV4_ADDRESS:-0.0.0.0}
UDM_PORT=${UDM_PORT:-80}
UDM_API_VERSION=${UDM_API_VERSION:-v2}
UDM_FQDN=${UDM_FQDN:-oai-udm}
EXTERNAL_NRF=${EXTERNAL_NRF:-no}
NRF_SELECTION=${NRF_SELECTION:-no}
EXTERNAL_NSSF=${EXTERNAL_NSSF:-no}
NSSF_IPV4_ADDRESS=${NSSF_IPV4_ADDRESS:-0.0.0.0}
NSSF_PORT=${NSSF_PORT:-80}
NSSF_API_VERSION=${NSSF_API_VERSION:-v2}
......@@ -22,6 +28,7 @@ if [[ ${USE_FQDN_DNS} == "yes" ]];then
SMF_IPV4_ADDR_1=${SMF_IPV4_ADDR_1:-0.0.0.0}
NRF_IPV4_ADDRESS=${NRF_IPV4_ADDRESS:-0.0.0.0}
AUSF_IPV4_ADDRESS=${AUSF_IPV4_ADDRESS:-0.0.0.0}
UDM_IPV4_ADDRESS=${UDM_IPV4_ADDRESS:-0.0.0.0}
fi
for c in ${CONFIG_DIR}/*.conf; do
......
This diff is collapsed.
......@@ -37,6 +37,7 @@
#include "amf_module_from_config.hpp"
#include "amf_profile.hpp"
#include "itti.hpp"
#include "itti_msg_n11.hpp"
#include "itti_msg_amf_app.hpp"
#include "ue_context.hpp"
#include "amf_subscription.hpp"
......@@ -74,6 +75,22 @@ class amf_app {
util::uint_generator<uint32_t> tmsi_generator;
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
mutable std::shared_mutex m_amf_ue_ngap_id2ue_ctx;
std::map<std::string, std::shared_ptr<ue_context>> ue_ctx_key;
mutable std::shared_mutex m_ue_ctx_key;
std::map<std::string, std::shared_ptr<ue_context>> supi2ue_ctx;
mutable std::shared_mutex m_supi2ue_ctx;
mutable std::shared_mutex m_curl_handle_responses_n2_sm;
std::map<uint32_t, boost::shared_ptr<boost::promise<std::string>>>
curl_handle_responses_n2_sm;
mutable std::shared_mutex m_curl_handle_responses_n11;
std::map<uint32_t, boost::shared_ptr<boost::promise<nlohmann::json>>>
curl_handle_responses_n11;
public:
explicit amf_app(const amf_config& amf_cfg);
amf_app(amf_app const&) = delete;
......@@ -83,6 +100,7 @@ class amf_app {
// itti handlers
void handle_itti_message(itti_nas_signalling_establishment_request& itti_msg);
void handle_itti_message(itti_n1n2_message_transfer_request& itti_msg);
void handle_itti_message(itti_sbi_n1_message_notification& itti_msg);
bool is_amf_ue_id_2_ue_context(const long& amf_ue_ngap_id) const;
std::shared_ptr<ue_context> amf_ue_id_2_ue_context(
......@@ -112,9 +130,7 @@ class amf_app {
bool get_pdu_sessions_context(
const string& supi,
std::vector<std::shared_ptr<pdu_session_context>>& sessions_ctx);
// SMF Client response handlers
void handle_post_sm_context_response_error_400();
// others
uint32_t generate_tmsi();
bool generate_5g_guti(
uint32_t ranid, long amfid, std::string& mcc, std::string& mnc,
......@@ -154,12 +170,12 @@ class amf_app {
* Handle NF status notification (e.g., when an UPF becomes available)
* @param [std::shared_ptr<itti_sbi_notification_data>& ] msg: message
* @param [oai::amf::model::ProblemDetails& ] problem_details
* @param [uint8_t&] http_code
* @param [uint32_t&] http_code
* @return true if handle sucessfully, otherwise return false
*/
bool handle_nf_status_notification(
std::shared_ptr<itti_sbi_notification_data>& msg,
oai::amf::model::ProblemDetails& problem_details, uint8_t& http_code);
oai::amf::model::ProblemDetails& problem_details, uint32_t& http_code);
/*
* Generate a random UUID for SMF instance
......@@ -267,24 +283,15 @@ class amf_app {
return util::uint_uid_generator<uint64_t>::get_instance().get_uid();
}
void trigger_process_response(uint32_t pid, uint32_t http_code);
void add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<std::string>>& p);
void add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<nlohmann::json>>& p);
void trigger_process_response(uint32_t pid, uint32_t http_code);
void trigger_process_response(uint32_t pid, std::string n2_sm);
void trigger_process_response(uint32_t pid, nlohmann::json& json_data);
private:
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
mutable std::shared_mutex m_amf_ue_ngap_id2ue_ctx;
std::map<std::string, std::shared_ptr<ue_context>> ue_ctx_key;
mutable std::shared_mutex m_ue_ctx_key;
std::map<std::string, std::shared_ptr<ue_context>> supi2ue_ctx;
mutable std::shared_mutex m_supi2ue_ctx;
mutable std::shared_mutex m_curl_handle_responses_n2_sm;
std::map<uint32_t, boost::shared_ptr<boost::promise<std::string>>>
curl_handle_responses_n2_sm;
std::string get_nf_instance() const;
};
} // namespace amf_application
......
This diff is collapsed.
......@@ -66,7 +66,7 @@
#define AMF_CONFIG_STRING_API_VERSION "API_VERSION"
#define AMF_CONFIG_STRING_AUSF "AUSF"
#define AMF_CONFIG_STRING_UDM "UDM"
#define AMF_CONFIG_STRING_NSSF "NSSF"
#define AMF_CONFIG_STRING_SCHED_PARAMS "SCHED_PARAMS"
......@@ -105,9 +105,11 @@
#define AMF_CONFIG_STRING_SUPPORT_FEATURES "SUPPORT_FEATURES"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_NF_REGISTRATION "NF_REGISTRATION"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_NRF_SELECTION "NRF_SELECTION"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_NRF "EXTERNAL_NRF"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_SMF_SELECTION "SMF_SELECTION"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_AUSF "EXTERNAL_AUSF"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_UDM "EXTERNAL_UDM"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_NSSF "EXTERNAL_NSSF"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_USE_FQDN_DNS "USE_FQDN_DNS"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2 "USE_HTTP2"
......@@ -122,7 +124,6 @@ typedef struct {
std::string mysql_user;
std::string mysql_pass;
std::string mysql_db;
std::string operator_key;
std::string random;
} auth_conf;
......@@ -152,20 +153,20 @@ typedef struct guami_s {
} guami_t;
typedef struct slice_s {
std::string sST;
std::string sD;
uint8_t sst;
uint32_t sd;
bool operator==(const struct slice_s& s) const {
if ((s.sST == this->sST) && (s.sD.compare(this->sD) == 0)) {
if ((s.sst == this->sst) && (s.sd == this->sd)) {
return true;
} else {
return false;
}
}
bool operator>(const struct slice_s& s) const {
if (this->sST.compare(s.sST) > 0) return true;
if (this->sST.compare(s.sST) == 0) {
if (this->sD.compare(s.sD) > 0) return true;
if (this->sD.compare(s.sD) < 0) return false;
if (this->sst > s.sst) return true;
if (this->sst == s.sst) {
if (this->sd > s.sd) return true;
if (this->sd <= s.sd) return false;
}
}
} slice_t;
......@@ -192,12 +193,24 @@ typedef struct {
std::string fqdn;
} smf_inst_t;
typedef struct nf_addr_s {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nf_addr_t;
class amf_config {
public:
amf_config();
~amf_config();
int load(const std::string& config_file);
int load_interface(const Setting& if_cfg, interface_cfg_t& cfg);
std::string get_nrf_nf_discovery_service_uri();
std::string get_nrf_nf_registration_uri(const std::string& nf_instance_id);
std::string get_udm_slice_selection_subscription_data_retrieval_uri(
const std::string& supi);
std::string get_nssf_network_slice_selection_information_uri();
std::string get_ausf_ue_authentications_uri();
void display();
unsigned int instance;
......@@ -222,30 +235,19 @@ class amf_config {
struct {
bool enable_nf_registration;
bool enable_nrf_selection;
bool enable_external_nrf;
bool enable_smf_selection;
bool enable_external_ausf;
bool enable_external_udm;
bool enable_external_nssf;
bool use_fqdn_dns;
bool use_http2;
} support_features;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nrf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} ausf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nssf_addr;
nf_addr_t nrf_addr;
nf_addr_t ausf_addr;
nf_addr_t udm_addr;
nf_addr_t nssf_addr;
};
} // namespace config
......
This diff is collapsed.
......@@ -37,6 +37,7 @@
#include <shared_mutex>
#include "3gpp_ts24501.hpp"
#include "3gpp_29.503.h"
#include "amf.hpp"
#include "amf_statistics.hpp"
#include "bstrlib.h"
......@@ -48,6 +49,9 @@
#include "RegistrationAccept.hpp"
#include "ue_context.hpp"
#include "itti.hpp"
#include "SliceInfoForRegistration.h"
#include "AuthorizedNetworkSliceInfo.h"
#include "Nssai.h"
namespace amf_application {
......@@ -217,6 +221,36 @@ class amf_n1 {
void implicit_deregistration_timer_timeout(
timer_id_t timer_id, uint64_t amf_ue_ngap_id);
bool reroute_registration_request(std::shared_ptr<nas_context>& nc);
bool get_slice_selection_subscription_data(
const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai);
bool get_slice_selection_subscription_data_from_conf_file(
const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai);
bool check_subscribed_nssai(
const std::shared_ptr<nas_context>& nc, oai::amf::model::Nssai& nssai);
bool check_requested_nssai(const std::shared_ptr<nas_context>& nc);
bool get_network_slice_selection(
const std::shared_ptr<nas_context>& nc, const std::string& nf_instance_id,
const oai::amf::model::SliceInfoForRegistration& slice_info,
oai::amf::model::AuthorizedNetworkSliceInfo&
authorized_network_slice_info);
bool get_network_slice_selection_from_conf_file(
const std::string& nf_instance_id,
const oai::amf::model::SliceInfoForRegistration& slice_info,
oai::amf::model::AuthorizedNetworkSliceInfo&
authorized_network_slice_info) const;
bool get_target_amf(
const std::shared_ptr<nas_context>& nc, std::string& target_amf,
const oai::amf::model::AuthorizedNetworkSliceInfo&
authorized_network_slice_info);
bool select_target_amf(
const std::shared_ptr<nas_context>& nc, std::string& target_amf,
const nlohmann::json& amf_candidate_list);
void send_n1_message_notity(
const std::shared_ptr<nas_context>& nc,
const std::string& target_amf) const;
private:
void ue_initiate_de_registration_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas);
......
This diff is collapsed.
......@@ -59,14 +59,20 @@ class amf_n11 {
void handle_itti_message(itti_nsmf_pdusession_release_sm_context& itti_msg);
void handle_itti_message(itti_pdu_session_resource_setup_response& itti_msg);
void handle_itti_message(itti_sbi_notify_subscribed_event& itti_msg);
void handle_itti_message(
itti_n11_slice_selection_subscription_data& itti_msg);
void handle_itti_message(
itti_n11_network_slice_selection_information& itti_msg);
void handle_itti_message(itti_n11_n1_message_notify& itti_msg);
void send_pdu_session_update_sm_context_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn);
bool smf_selection_from_configuration(
std::string& smf_addr, std::string& smf_api_version);
void handle_post_sm_context_response_error_400();
std::string& smf_addr, std::string& smf_port,
std::string& smf_api_version);
void handle_post_sm_context_response_error(
long code, std::string cause, bstring n1sm, std::string supi,
uint8_t pdu_session_id);
......@@ -77,20 +83,19 @@ class amf_n11 {
uint8_t http_version = 1, uint32_t promise_id = 0);
void curl_http_client(
std::string remoteUri, std::string Method, std::string msgBody,
std::string& response, uint8_t http_version = 1);
std::string remote_uri, std::string method, std::string msg_body,
nlohmann::json& response_json, uint32_t& response_code,
uint8_t http_version = 1);
bool discover_smf_from_nsi_info(
std::string& smf_addr, std::string& smf_api_version,
std::string& smf_port, const snssai_t snssai, const plmn_t plmn,
const std::string dnn);
void curl_http_client(
std::string& remote_uri, std::string& json_data, std::string& n1sm_msg,
std::string& n2sm_msg, uint8_t http_version, uint32_t& response_code,
uint32_t promise_id = 0);
bool discover_smf(
std::string& smf_addr, std::string& smf_api_version,
std::string& smf_port, const snssai_t snssai, const plmn_t plmn,
const std::string dnn, const std::string& nrf_addr = {},
const std::string& nrf_port = {},
const std::string& nrf_api_version = {});
std::string& smf_addr, std::string& smf_port,
std::string& smf_api_version, const snssai_t snssai, const plmn_t plmn,
const std::string dnn, const std::string& nrf_uri = {});
void register_nf_instance(
std::shared_ptr<itti_n11_register_nf_instance_request> msg);
......@@ -98,6 +103,10 @@ class amf_n11 {
bool send_ue_authentication_request(
oai::amf::model::AuthenticationInfo& auth_info,
oai::amf::model::UEAuthenticationCtx& ue_auth_ctx, uint8_t http_version);
bool get_nrf_uri(
const snssai_t& snssai, const plmn_t& plmn, const std::string& dnn,
std::string& nrf_uri);
};
} // namespace amf_application
......
......@@ -71,7 +71,6 @@ using namespace std;
extern itti_mw* itti_inst;
extern amf_n2* amf_n2_inst;
extern amf_n1* amf_n1_inst;
extern amf_n11* amf_n11_inst;
extern amf_config amf_cfg;
extern amf_app* amf_app_inst;
extern statistics stacs;
......@@ -377,9 +376,8 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
// Verify PLMN Identity and TAC with configuration and store supportedTAList
// in gNB context, if verified; else response NG SETUP FAILURE with cause
// "Unknown PLMN"(9.3.1.2, ts38413)
std::vector<SupportedItem_t> common_plmn_list = get_common_plmn(s_ta_list);
if (common_plmn_list.size() == 0) {
// if (!verifyPlmn(s_ta_list)) {
// std::vector<SupportedItem_t> common_plmn_list = get_common_plmn(s_ta_list);
if (!get_common_plmn(s_ta_list, gc->s_ta_list)) {
// encode NG SETUP FAILURE MESSAGE and send back
void* buffer = calloc(1, BUFFER_SIZE_1024);
NGSetupFailureMsg ngSetupFailure;
......@@ -393,10 +391,9 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
Logger::amf_n2().error(
"No common PLMN, encoding NG_SETUP_FAILURE with cause (Unknown PLMN)");
return;
} else {
// store only the common PLMN
gc->s_ta_list = common_plmn_list;
for (auto i : common_plmn_list) {
for (auto i : gc->s_ta_list) {
gnbItem.plmn_list.push_back(i);
}
}
......@@ -430,8 +427,8 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
tmp.mnc = amf_cfg.plmn_list[i].mnc;
for (int j = 0; j < amf_cfg.plmn_list[i].slice_list.size(); j++) {
S_Nssai s_tmp;
s_tmp.sst = amf_cfg.plmn_list[i].slice_list[j].sST;
s_tmp.sd = amf_cfg.plmn_list[i].slice_list[j].sD;
s_tmp.sst = std::to_string(amf_cfg.plmn_list[i].slice_list[j].sst);
s_tmp.sd = amf_cfg.plmn_list[i].slice_list[j].sd;
tmp.slice_list.push_back(s_tmp);
}
plmn_list.push_back(tmp);
......@@ -618,7 +615,8 @@ void amf_n2::handle_itti_message(itti_initial_ue_message& init_ue_msg) {
if (unc.get() == nullptr) {
Logger::amf_n2().error(
"Failed to get UE NGAP context for ran_ue_ngap_id 0x%x", 21);
"Failed to get UE NGAP context for ran_ue_ngap_id 0x%x",
ran_ue_ngap_id);
} else {
// Store related information into UE NGAP context
unc.get()->ran_ue_ngap_id = ran_ue_ngap_id;
......@@ -677,6 +675,7 @@ void amf_n2::handle_itti_message(itti_initial_ue_message& init_ue_msg) {
return;
}
}
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = -1;
std::shared_ptr<itti_nas_signalling_establishment_request> i =
......@@ -1410,8 +1409,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
GlobalgNBId* TargetGlobalgNBId = new GlobalgNBId();
itti_msg.handoverReq->getGlobalRanNodeId(TargetGlobalgNBId);
PlmnId* plmn = new PlmnId();
GNB_ID* gnbid = new GNB_ID();
ngap::PlmnId* plmn = new ngap::PlmnId();
GNB_ID* gnbid = new GNB_ID();
TargetGlobalgNBId->getGlobalgNBId(plmn, gnbid);
std::string mcc = {};
std::string mnc = {};
......@@ -1425,8 +1424,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
TAI* tai = new TAI();
itti_msg.handoverReq->getTAI(tai);
PlmnId* plmnOfTAI = new PlmnId();
TAC* tac = new TAC();
ngap::PlmnId* plmnOfTAI = new ngap::PlmnId();
TAC* tac = new TAC();
tai->getTAI(plmnOfTAI, tac);
string mccOfselectTAI = {};
string mncOfselectTAI = {};
......@@ -1463,8 +1462,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
for (int j = 0; j < amf_cfg.plmn_list[i].slice_list.size(); j++) {
S_Nssai s_tmp;
S_NSSAI s_nssai = {};
s_nssai.setSst(amf_cfg.plmn_list[i].slice_list[j].sST);
s_nssai.setSd(amf_cfg.plmn_list[i].slice_list[j].sD);
s_nssai.setSst(amf_cfg.plmn_list[i].slice_list[j].sst);
s_nssai.setSd(amf_cfg.plmn_list[i].slice_list[j].sd);
Allowed_Nssai.push_back(s_nssai);
}
}
......@@ -1477,7 +1476,7 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
guami.regionID = amf_cfg.guami.regionID;
guami.AmfSetID = amf_cfg.guami.AmfSetID;
guami.AmfPointer = amf_cfg.guami.AmfPointer;
PlmnId* m_plmnId = new PlmnId();
ngap::PlmnId* m_plmnId = new ngap::PlmnId();
AMFRegionID* m_aMFRegionID = new AMFRegionID();
AMFSetID* m_aMFSetID = new AMFSetID();
AMFPointer* m_aMFPointer = new AMFPointer();
......@@ -1600,11 +1599,11 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
supi, curl_responses.begin()->first, psc)) {
PDUSessionResourceSetupRequestItem_t item = {};
item.pduSessionId = psc.get()->pdu_session_id;
item.s_nssai.sst = psc.get()->snssai.sST;
item.s_nssai.sd = psc.get()->snssai.sD;
item.pduSessionNAS_PDU = nullptr;
unsigned int data_len = n2_sm.length();
unsigned char* data = (unsigned char*) malloc(data_len + 1);
item.s_nssai.sst = std::to_string(psc.get()->snssai.sST);
item.s_nssai.sd = psc.get()->snssai.sD;
item.pduSessionNAS_PDU = nullptr;
unsigned int data_len = n2_sm.length();
unsigned char* data = (unsigned char*) malloc(data_len + 1);
memset(data, 0, data_len + 1);
memcpy((void*) data, (void*) n2_sm.c_str(), data_len);
item.pduSessionResourceSetupRequestTransfer.buf = data;
......@@ -2105,10 +2104,10 @@ bool amf_n2::verifyPlmn(vector<SupportedItem_t> list) {
}
//------------------------------------------------------------------------------
std::vector<SupportedItem_t> amf_n2::get_common_plmn(
std::vector<SupportedItem_t> list) {
bool amf_n2::get_common_plmn(
std::vector<SupportedItem_t> list, std::vector<SupportedItem_t>& result) {
std::vector<SupportedItem_t> plmn_list = {};
bool found_common_plmn = false;
for (int i = 0; i < amf_cfg.plmn_list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
Logger::amf_n2().debug(
......@@ -2120,11 +2119,34 @@ std::vector<SupportedItem_t> amf_n2::get_common_plmn(
for (int k = 0; k < list[j].b_plmn_list.size(); k++) {
if (!(list[j].b_plmn_list[k].mcc.compare(amf_cfg.plmn_list[i].mcc)) &&
!(list[j].b_plmn_list[k].mnc.compare(amf_cfg.plmn_list[i].mnc))) {
// TODO: compare NSSAI
plmn_list.push_back(list[j]);
Logger::amf_n2().debug(
"Common PLMN MCC %s, MNC %s", amf_cfg.plmn_list[i].mcc.c_str(),
amf_cfg.plmn_list[i].mnc.c_str());
// Get the common S-NSSAI
SupportedItem_t item = {};
PlmnSliceSupport_t plmn_slice_support_item = {};
item.tac = list[j].tac;
plmn_slice_support_item.mcc = list[j].b_plmn_list[k].mcc;
plmn_slice_support_item.mnc = list[j].b_plmn_list[k].mnc;
for (auto s1 : list[j].b_plmn_list[k].slice_list) {
for (auto s2 : amf_cfg.plmn_list[i].slice_list) {
if ((s1.sst.compare(std::to_string(s2.sst)) == 0) and
(s1.sd.compare(std::to_string(s2.sd)) == 0)) {
Logger::amf_n2().debug(
"Common S-NSSAI (SST %s, SD %s)", s1.sst.c_str(),
s1.sd.c_str());
plmn_slice_support_item.slice_list.push_back(s1);
found_common_plmn = true;
}
}
}
item.b_plmn_list.push_back(plmn_slice_support_item);
result.push_back(item);
}
}
}
}
return plmn_list;
return found_common_plmn;
}
......@@ -68,8 +68,8 @@ class amf_n2 : public ngap::ngap_app {
void handle_itti_message(itti_paging& itti_msg);
bool verifyPlmn(std::vector<SupportedItem_t> list);
std::vector<SupportedItem_t> get_common_plmn(
std::vector<SupportedItem_t> list);
bool get_common_plmn(
std::vector<SupportedItem_t> list, std::vector<SupportedItem_t>& result);
std::shared_ptr<ue_ngap_context> ran_ue_id_2_ue_ngap_context(
const uint32_t& ran_ue_ngap_id) const;
......
......@@ -122,17 +122,19 @@ typedef struct amf_set_id_s /*5G ADD it*/
uint16_t amf_set_id : 10;
} amf_set_id_t;
typedef struct allowed_nssai /*5G ADD it*/
/*
typedef struct allowed_nssai
{
uint8_t sST;
uint32_t sD : 24;
} allowed_nssai;
typedef struct allowed_nssai_s /*5G ADD it*/
typedef struct allowed_nssai_s
{
allowed_nssai* s_nssai;
uint32_t count;
} allowed_nssai_t;
*/
typedef struct guami_5g_s {
plmn_t plmn;
......
......@@ -28,7 +28,7 @@ enum class http_response_codes_e {
HTTP_RESPONSE_CODE_200_OK = 200,
HTTP_RESPONSE_CODE_201_CREATED = 201,
HTTP_RESPONSE_CODE_202_ACCEPTED = 202,
HTTP_RESPONSE_CODE_204_UPDATED = 204,
HTTP_RESPONSE_CODE_204_NO_CONTENT = 204,
HTTP_RESPONSE_CODE_BAD_REQUEST = 400,
HTTP_RESPONSE_CODE_UNAUTHORIZED = 401,
HTTP_RESPONSE_CODE_FORBIDDEN = 403,
......
/*
* 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 3gpp_29.503.h
\brief
\author Tien Thinh NGUYEN
\company Eurecom
\email: tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_3GPP_29_503_SEEN
#define FILE_3GPP_29_503_SEEN
#include <stdint.h>
#include <string>
#include <vector>
#include "3gpp_23.003.h"
typedef struct nssai_s {
std::vector<snssai_t> default_single_nssais;
std::vector<snssai_t> single_nssais;
} nssai_t;
#endif
......@@ -90,7 +90,17 @@ class nas_context {
uint8_t ueSecurityCapEEA;
uint8_t ueSecurityCapEIA;
std::vector<nas::SNSSAI_t> requestedNssai;
std::vector<nas::SNSSAI_t>
requestedNssai; // TODO: update with naming convention
std::vector<nas::SNSSAI_t> allowed_nssai; // in Registration Accept
// Set to true if marked as default
std::vector<std::pair<bool, nas::SNSSAI_t>> subscribed_snssai;
std::vector<nas::SNSSAI_t> configured_nssai;
// std::vector<nas::SNSSAI_t> default_configured_nssai;
// std::vector<nas::SNSSAI_t> s_nssai; //for Network Slice selection
bstring registration_request; // for AMF re-allocation procedure
bool registration_request_is_set;
std::string serving_network;
bstring auts;
// NAS EP(s)
......
......@@ -24,7 +24,7 @@
//------------------------------------------------------------------------------
ue_context::ue_context() {
ran_ue_ngap_id = 0;
amf_ue_ngap_id = 0;
amf_ue_ngap_id = -1;
rrc_estb_cause = {};
isUeContextRequest = false;
cgi = {};
......
......@@ -86,9 +86,14 @@ typedef enum {
N11_UPDATE_NF_INSTANCE_REQUEST,
N11_UPDATE_NF_INSTANCE_RESPONSE,
N11_DEREGISTER_NF_INSTANCE,
N11_SLICE_SELECTION_SUBSCRIPTION_DATA,
N11_NETWORK_SLICE_SELECTION_INFORMATION,
N11_NF_INSTANCE_DISCOVERY,
N11_N1_MESSAGE_NOTIFY,
SBI_EVENT_EXPOSURE_REQUEST,
SBI_NOTIFICATION_DATA,
SBI_NOTIFY_SUBSCRIBED_EVENT,
SBI_N1_MESSAGE_NOTIFICATION,
UE_CONTEXT_RELEASE_COMMAND,
NSMF_PDU_SESSION_RELEASE_SM_CTX,
HANDOVER_REQUIRED,
......
......@@ -28,6 +28,7 @@
#include "amf_profile.hpp"
#include "bstrlib.h"
#include "itti_msg.hpp"
#include "SliceInfoForRegistration.h"
class itti_msg_n11 : public itti_msg {
public:
......@@ -191,4 +192,68 @@ class itti_n11_deregister_nf_instance : public itti_msg_n11 {
std::string amf_instance_id;
};
//-----------------------------------------------------------------------------
class itti_n11_slice_selection_subscription_data : public itti_msg_n11 {
public:
itti_n11_slice_selection_subscription_data(
const task_id_t orig, const task_id_t dest)
: itti_msg_n11(N11_SLICE_SELECTION_SUBSCRIPTION_DATA, orig, dest),
http_version(1) {}
const char* get_msg_name() {
return "N11_SLICE_SELECTION_SUBSCRIPTION_DATA";
};
uint8_t http_version;
std::string supi;
plmn_t plmn;
uint32_t promise_id;
};
//-----------------------------------------------------------------------------
class itti_n11_network_slice_selection_information : public itti_msg_n11 {
public:
itti_n11_network_slice_selection_information(
const task_id_t orig, const task_id_t dest)
: itti_msg_n11(N11_NETWORK_SLICE_SELECTION_INFORMATION, orig, dest),
http_version(1) {}
const char* get_msg_name() {
return "N11_NETWORK_SLICE_SELECTION_INFORMATION";
};
uint8_t http_version;
std::string nf_instance_id;
oai::amf::model::SliceInfoForRegistration slice_info;
plmn_t plmn;
uint32_t promise_id;
};
//-----------------------------------------------------------------------------
class itti_n11_nf_instance_discovery : public itti_msg_n11 {
public:
itti_n11_nf_instance_discovery(const task_id_t orig, const task_id_t dest)
: itti_msg_n11(N11_NF_INSTANCE_DISCOVERY, orig, dest),
target_amf_set_is_set(false),
http_version(1) {}
const char* get_msg_name() { return "N11_NF_INSTANCE_DISCOVERY"; };
uint8_t http_version;
std::string target_amf_set;
bool target_amf_set_is_set;
std::string target_nf_type;
uint32_t promise_id;
};
//-----------------------------------------------------------------------------
class itti_n11_n1_message_notify : public itti_msg_n11 {
public:
itti_n11_n1_message_notify(const task_id_t orig, const task_id_t dest)
: itti_msg_n11(N11_N1_MESSAGE_NOTIFY, orig, dest), http_version(1) {}
const char* get_msg_name() { return "N11_N1_MESSAGE_NOTIFY"; };
uint8_t http_version;
std::string target_amf_uri;
std::string supi;
bstring registration_request;
};
#endif
......@@ -33,6 +33,7 @@
#include "itti_msg.hpp"
#include "pistache/http.h"
#include "amf_msg.hpp"
#include "N1MessageNotification.h"
using namespace amf_application;
......@@ -115,4 +116,35 @@ class itti_sbi_notify_subscribed_event : public itti_sbi_msg {
std::vector<amf_application::event_notification> event_notifs;
uint8_t http_version;
};
//-----------------------------------------------------------------------------
class itti_sbi_n1_message_notification : public itti_sbi_msg {
public:
itti_sbi_n1_message_notification(const task_id_t orig, const task_id_t dest)
: itti_sbi_msg(SBI_N1_MESSAGE_NOTIFICATION, orig, dest),
notification_msg(),
ue_id(),
n1sm(),
http_version(1) {}
itti_sbi_n1_message_notification(const itti_sbi_n1_message_notification& i)
: itti_sbi_msg(i),
notification_msg(i.notification_msg),
ue_id(i.ue_id),
n1sm(i.n1sm),
http_version(1) {}
itti_sbi_n1_message_notification(
const itti_sbi_n1_message_notification& i, const task_id_t orig,
const task_id_t dest)
: itti_sbi_msg(i, orig, dest),
notification_msg(i.notification_msg),
ue_id(i.ue_id),
n1sm(i.n1sm),
http_version(i.http_version) {}
const char* get_msg_name() { return "SBI_N1_MESSAGE_NOTIFICATION"; };
oai::amf::model::N1MessageNotification notification_msg;
std::string ue_id;
std::string n1sm;
uint8_t http_version;
};
#endif /* ITTI_MSG_SBI_HPP_INCLUDED_ */
......@@ -609,6 +609,8 @@ int _5GSMobilityIdentity::suci_decodefrombuffer(
decoded_size++;
supi_format_imsi->homeNetworkPKI = octet;
string msin = "";
// TODO: get MSIN according to Protection Scheme ID to support
// ECIES scheme profile A/B
int digit_low = 0, digit_high = 0, numMsin = ie_len - decoded_size;
for (int i = 0; i < numMsin; i++) {
octet = *(buf + decoded_size);
......
......@@ -92,15 +92,15 @@ int NSSAI::encode2buffer(uint8_t* buf, int len) {
*(buf + encoded_size) = (S_NSSAI.at(i).sd & 0x00ff0000) >> 16;
encoded_size++;
Logger::nas_mm().debug(
"Encoded NSSAI len (%x)", *(buf + encoded_size - 1));
"Encoded NSSAI SD first octet (%x)", *(buf + encoded_size - 1));
*(buf + encoded_size) = (S_NSSAI.at(i).sd & 0x0000ff00) >> 8;
encoded_size++;
Logger::nas_mm().debug(
"Encoded NSSAI len (%x)", *(buf + encoded_size - 1));
"Encoded NSSAI SD second octet (%x)", *(buf + encoded_size - 1));
*(buf + encoded_size) = S_NSSAI.at(i).sd & 0x000000ff;
encoded_size++;
Logger::nas_mm().debug(
"Encoded NSSAI len (%x)", *(buf + encoded_size - 1));
"Encoded NSSAI SD third octet (%x)", *(buf + encoded_size - 1));
}
if (S_NSSAI.at(i).mHplmnSst != -1) {
len_s_nssai += 1;
......
......@@ -53,6 +53,7 @@ typedef struct SNSSAI_s {
return *this;
}
} SNSSAI_t;
typedef struct {
uint8_t ie_type;
uint8_t ie_len;
......
......@@ -47,26 +47,32 @@ void GNB_ID::setValue(uint32_t gnbId) {
uint8_t len = 0;
for (uint32_t i = 0x00000001; i <= 0x00000400; i = i << 1, len++) {
if ((i & gnbId)) {
gNBId.biteslen = 32 - len;
gNBId.bit_length = 32 - len;
break;
}
}
if (!((gNBId.biteslen >= 22) && (gNBId.biteslen <= 32))) {
if (!((gNBId.bit_length >= 22) && (gNBId.bit_length <= 32))) {
cout << "[warning][gNBID length out of range]" << endl;
}
}
//------------------------------------------------------------------------------
void GNB_ID::setValue(uint32_t id, uint8_t bit_length) {
gNBId.id = id;
gNBId.bit_length = bit_length;
}
//------------------------------------------------------------------------------
bool GNB_ID::encode2bitstring(Ngap_GNB_ID_t& gnbid) {
gnbid.present = Ngap_GNB_ID_PR_gNB_ID;
if (!(gNBId.biteslen % 8))
gnbid.choice.gNB_ID.size = gNBId.biteslen / 8;
if (!(gNBId.bit_length % 8))
gnbid.choice.gNB_ID.size = gNBId.bit_length / 8;
else
gnbid.choice.gNB_ID.size = gNBId.biteslen / 8 + 1;
gnbid.choice.gNB_ID.size = gNBId.bit_length / 8 + 1;
// printf("m_gNBId.size(%d)\n",m_gNBId.size);
gnbid.choice.gNB_ID.bits_unused = 32 - gNBId.biteslen;
gnbid.choice.gNB_ID.bits_unused = 32 - gNBId.bit_length;
gnbid.choice.gNB_ID.buf = (uint8_t*) calloc(1, 4 * sizeof(uint8_t));
if (!gnbid.choice.gNB_ID.buf) return false;
gnbid.choice.gNB_ID.buf[3] = gNBId.id & 0x000000ff;
......
......@@ -45,10 +45,12 @@ class GNB_ID {
void setValue(uint32_t gnbId);
long getValue();
void setValue(uint32_t id, uint8_t bit_length);
private:
struct gNBId_s {
uint32_t id;
uint8_t biteslen;
uint8_t bit_length;
} gNBId; // 22bits to 32bits
};
......
......@@ -48,6 +48,13 @@ namespace ngap {
typedef struct S_Nssai_s {
std::string sst;
std::string sd;
S_Nssai_s& operator=(const S_Nssai_s& s) {
sst = s.sst;
sd = s.sd;
return *this;
}
bool operator==(const struct S_Nssai_s& s) const {
if ((s.sst == this->sst) && (s.sd.compare(this->sd) == 0)) {
return true;
......
......@@ -76,7 +76,14 @@ bool S_NSSAI::sDEncode2OctetString(Ngap_SD_t* m_sd) {
//------------------------------------------------------------------------------
bool S_NSSAI::sDdecodefromOctetString(Ngap_SD_t* m_sd) {
if (!m_sd->buf) return false;
sd = *(uint32_t*) m_sd->buf & 0x00ffffff;
if (m_sd->size == 3) {
sd = ((m_sd->buf[0] >> 16) + (m_sd->buf[1] >> 8) + m_sd->buf[2]);
} else if (m_sd->size == 4) {
sd = ((m_sd->buf[1] >> 16) + (m_sd->buf[2] >> 8) + m_sd->buf[3]);
}
// sd = *(uint32_t*) m_sd->buf & 0x00ffffff;
return true;
}
......@@ -85,6 +92,10 @@ void S_NSSAI::setSst(const std::string charSst) {
sst = fromString<int>(charSst);
}
//------------------------------------------------------------------------------
void S_NSSAI::setSst(const uint8_t s) {
sst = s;
}
//------------------------------------------------------------------------------
void S_NSSAI::getSst(std::string& charSst) const {
charSst = to_string((int) sst);
......@@ -101,6 +112,11 @@ void S_NSSAI::setSd(const std::string charSd) {
sd = fromString<int>(charSd);
}
//------------------------------------------------------------------------------
void S_NSSAI::setSd(const uint32_t s) {
sdIsSet = true;
sd = s;
}
//------------------------------------------------------------------------------
bool S_NSSAI::getSd(std::string& s_nssaiSd) const {
if (sdIsSet) {
......
......@@ -48,9 +48,11 @@ class S_NSSAI {
bool sDEncode2OctetString(Ngap_SD_t*);
bool sDdecodefromOctetString(Ngap_SD_t*);
void setSst(const std::string charSst);
void setSst(const uint8_t s);
void getSst(std::string& charSst) const;
std::string getSst() const;
void setSd(const std::string charSd);
void setSd(const uint32_t s);
bool getSd(std::string& s_nssaiSd) const;
std::string getSd() const;
bool encode2S_NSSAI(Ngap_S_NSSAI_t*);
......
......@@ -19,6 +19,7 @@ void AMFApiServer::init(size_t thr) {
m_nonUEN2MessagesSubscriptionsCollectionDocumentApiImpl->init();
m_subscriptionsCollectionDocumentApiImpl->init();
m_subscriptionsCollectionDocumentApiImplEventExposure->init();
m_n1MessageNotifyApiImpl->init();
Logger::amf_server().debug("Initiate AMF Server Endpoints done!");
}
......@@ -63,6 +64,9 @@ void AMFApiServer::start() {
Logger::amf_server().debug(
"AMF handler for SubscriptionsCollectionDocumentApiImplEventExposure");
if (m_n1MessageNotifyApiImpl != nullptr)
Logger::amf_server().debug("AMF handler for N1MessageNotifyApiImpl");
m_httpEndpoint->setHandler(m_router->handler());
m_httpEndpoint->serveThreaded();
}
......
......@@ -18,6 +18,7 @@
#include "NonUEN2MessagesSubscriptionsCollectionDocumentApiImpl.h"
#include "SubscriptionsCollectionDocumentApiImpl.h"
#include "SubscriptionsCollectionDocumentApiImplEventExposure.h"
#include "N1MessageNotifyApiImpl.h"
#define PISTACHE_SERVER_THREADS 2
#define PISTACHE_SERVER_MAX_PAYLOAD 32768
......@@ -68,6 +69,8 @@ class AMFApiServer {
m_subscriptionsCollectionDocumentApiImplEventExposure =
std::make_shared<SubscriptionsCollectionDocumentApiImplEventExposure>(
m_router, amf_app_inst);
m_n1MessageNotifyApiImpl =
std::make_shared<N1MessageNotifyApiImpl>(m_router, amf_app_inst);
}
void init(size_t thr = 1);
......@@ -101,6 +104,7 @@ class AMFApiServer {
m_subscriptionsCollectionDocumentApiImpl;
std::shared_ptr<SubscriptionsCollectionDocumentApiImplEventExposure>
m_subscriptionsCollectionDocumentApiImplEventExposure;
std::shared_ptr<N1MessageNotifyApiImpl> m_n1MessageNotifyApiImpl;
std::string m_address;
};
/**
* Namf_Communication
* AMF Communication Service © 2019, 3GPP Organizational Partners (ARIB, ATIS,
* CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
#include "N1MessageNotifyApi.h"
#include "Helpers.h"
#include "mime_parser.hpp"
#include "logger.hpp"
#include "amf_config.hpp"
#include "mime_parser.hpp"
extern config::amf_config amf_cfg;
namespace oai {
namespace amf {
namespace api {
using namespace oai::amf::helpers;
using namespace oai::amf::model;
N1MessageNotifyApi::N1MessageNotifyApi(
std::shared_ptr<Pistache::Rest::Router> rtr) {
router = rtr;
}
void N1MessageNotifyApi::init() {
setupRoutes();
}
void N1MessageNotifyApi::setupRoutes() {
using namespace Pistache::Rest;
Routes::Post(
*router,
base + amf_cfg.sbi_api_version +
"/ue-contexts/:ueContextId/n1-message-notify",
Routes::bind(&N1MessageNotifyApi::n1_message_notify_handler, this));
// Default handler, called when a route is not found
router->addCustomHandler(Routes::bind(
&N1MessageNotifyApi::n1_message_notify_default_handler, this));
}
void N1MessageNotifyApi::n1_message_notify_handler(
const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response) {
// Getting the path params
auto ueContextId = request.param(":ueContextId").as<std::string>();
Logger::amf_server().debug(
"Received a N1MessageNotification with ue_ctx_id %s",
ueContextId.c_str());
N1MessageNotification n1MessageNotification = {};
// simple parser
mime_parser sp = {};
sp.parse(request.body());
std::vector<mime_part> parts = {};
sp.get_mime_parts(parts);
uint8_t size = parts.size();
Logger::amf_server().debug("Number of MIME parts %d", size);
// 2 parts for Json data and N1
if (size != 2) {
response.send(Pistache::Http::Code::Bad_Request);
Logger::amf_server().debug("Bad request: should have 2 MIME parts");
return;
}
Logger::amf_server().debug(
"Request body, part 1: \n%s", parts[0].body.c_str());
Logger::amf_server().debug(
"Request body, part 2: \n %s", parts[1].body.c_str());
try {
nlohmann::json::parse(parts[0].body.c_str()).get_to(n1MessageNotification);
this->receive_n1_message_notification(
ueContextId, n1MessageNotification, parts[1].body, response);
} catch (nlohmann::detail::exception& e) {
// send a 400 error
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (std::exception& e) {
// send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void N1MessageNotifyApi::n1_message_notify_default_handler(
const Pistache::Rest::Request&, Pistache::Http::ResponseWriter response) {
response.send(
Pistache::Http::Code::Not_Found, "The requested method does not exist");
}
} // namespace api
} // namespace amf
} // namespace oai
/**
* Namf_Communication
* AMF Communication Service © 2019, 3GPP Organizational Partners (ARIB, ATIS,
* CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
/*
* N1MessageNotifyApi.h
*
*
*/
#ifndef N1MessageNotifyApi_H_
#define N1MessageNotifyApi_H_
#include <pistache/http.h>
#include <pistache/router.h>
#include <pistache/http_headers.h>
#include <pistache/optional.h>
#include "N1MessageNotification.h"
#include "ProblemDetails.h"
#include <string>
namespace oai {
namespace amf {
namespace api {
using namespace oai::amf::model;
class N1MessageNotifyApi {
public:
N1MessageNotifyApi(std::shared_ptr<Pistache::Rest::Router>);
virtual ~N1MessageNotifyApi() {}
void init();
const std::string base = "/namf-comm/";
private:
void setupRoutes();
void n1_message_notify_handler(
const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response);
void n1_message_notify_default_handler(
const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response);
std::shared_ptr<Pistache::Rest::Router> router;
virtual void receive_n1_message_notification(
const std::string& ueContextId,
const N1MessageNotification& notificationData, std::string& n1sm_str,
Pistache::Http::ResponseWriter& response) = 0;
};
} // namespace api
} // namespace amf
} // namespace oai
#endif /* N1MessageNotifyApi_H_ */
/**
* Namf_Communication
* AMF Communication Service © 2019, 3GPP Organizational Partners (ARIB, ATIS,
* CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
#include "N1MessageNotifyApiImpl.h"
#include "itti_msg_sbi.hpp"
#include "conversions.hpp"
#include "itti.hpp"
using namespace amf_application;
extern itti_mw* itti_inst;
namespace oai {
namespace amf {
namespace api {
using namespace oai::amf::model;
N1MessageNotifyApiImpl::N1MessageNotifyApiImpl(
std::shared_ptr<Pistache::Rest::Router> rtr,
amf_application::amf_app* amf_app_inst)
: N1MessageNotifyApi(rtr), m_amf_app(amf_app_inst) {}
void N1MessageNotifyApiImpl::receive_n1_message_notification(
const std::string& ueContextId,
const N1MessageNotification& notificationData, std::string& n1sm_str,
Pistache::Http::ResponseWriter& response) {
Logger::amf_server().debug("Receive N1MessageNotify, handling...");
std::string supi = ueContextId;
Logger::amf_server().debug("SUPI (%s)", supi.c_str());
// Handle the message in amf_app
std::shared_ptr<itti_sbi_n1_message_notification> itti_msg =
std::make_shared<itti_sbi_n1_message_notification>(
TASK_AMF_SBI, TASK_AMF_APP);
itti_msg->notification_msg = notificationData;
itti_msg->ue_id = supi;
itti_msg->n1sm = n1sm_str;
itti_msg->http_version = 1;
oai::amf::model::ProblemDetails problem_details = {};
uint32_t http_code = {0};
// Send response
response.send(Pistache::Http::Code::No_Content);
// TODO: problem
// Process N1 Notification Message at AMF APP
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_N2",
itti_msg->get_msg_name());
}
}
} // namespace api
} // namespace amf
} // namespace oai
/**
* Namf_Communication
* AMF Communication Service © 2019, 3GPP Organizational Partners (ARIB, ATIS,
* CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator
* (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
* the class manually.
*/
/*
* N1MessageNotifyApiImpl.h
*
*
*/
#ifndef N1_MESSAGE_NOTIFY_API_IMPL_H_
#define N1_MESSAGE_NOTIFY_API_IMPL_H_
#include <pistache/endpoint.h>
#include <pistache/http.h>
#include <pistache/router.h>
#include <memory>
#include <N1MessageNotifyApi.h>
#include <pistache/optional.h>
#include "ProblemDetails.h"
#include "amf_app.hpp"
namespace oai {
namespace amf {
namespace api {
using namespace oai::amf::model;
using namespace oai::amf::api;
class N1MessageNotifyApiImpl : public N1MessageNotifyApi {
public:
N1MessageNotifyApiImpl(
std::shared_ptr<Pistache::Rest::Router>,
amf_application::amf_app* amf_app_inst);
~N1MessageNotifyApiImpl() {}
void receive_n1_message_notification(
const std::string& ueContextId,
const N1MessageNotification& notificationData, std::string& n1sm_str,
Pistache::Http::ResponseWriter& response);
private:
amf_application::amf_app* m_amf_app;
};
} // namespace api
} // namespace amf
} // namespace oai
#endif
......@@ -12,6 +12,9 @@
*/
#include "AllowedNssai.h"
#include "Helpers.h"
#include <sstream>
namespace oai {
namespace amf {
......@@ -19,10 +22,63 @@ namespace model {
AllowedNssai::AllowedNssai() {}
AllowedNssai::~AllowedNssai() {}
void AllowedNssai::validate() const {
std::stringstream msg;
// if (!validate(msg))
// {
// throw oai::nssf_server::helpers::ValidationException(msg.str());
// }
}
bool AllowedNssai::validate(std::stringstream& msg) const {
return validate(msg, "");
}
bool AllowedNssai::validate(
std::stringstream& msg, const std::string& pathPrefix) const {
bool success = true;
const std::string _pathPrefix =
pathPrefix.empty() ? "AllowedNssai" : pathPrefix;
/* AllowedSnssaiList */ {
const std::vector<AllowedSnssai>& value = m_AllowedSnssaiList;
const std::string currentValuePath = _pathPrefix + ".allowedSnssaiList";
if (value.size() < 1) {
success = false;
msg << currentValuePath << ": must have at least 1 elements;";
}
{ // Recursive validation of array elements
const std::string oldValuePath = currentValuePath;
int i = 0;
for (const AllowedSnssai& value : value) {
const std::string currentValuePath =
oldValuePath + "[" + std::to_string(i) + "]";
success =
value.validate(msg, currentValuePath + ".allowedSnssaiList") &&
success;
i++;
}
}
}
void AllowedNssai::validate() {
// TODO: implement validation
return success;
}
bool AllowedNssai::operator==(const AllowedNssai& rhs) const {
return
(getAllowedSnssaiList() == rhs.getAllowedSnssaiList()) // &&
// (getAccessType() == rhs.getAccessType())
;
}
bool AllowedNssai::operator!=(const AllowedNssai& rhs) const {
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const AllowedNssai& o) {
......@@ -36,9 +92,13 @@ void from_json(const nlohmann::json& j, AllowedNssai& o) {
j.at("accessType").get_to(o.m_AccessType);
}
std::vector<AllowedSnssai>& AllowedNssai::getAllowedSnssaiList() {
std::vector<AllowedSnssai> AllowedNssai::getAllowedSnssaiList() const {
return m_AllowedSnssaiList;
}
void AllowedNssai::setAllowedSnssaiList(
std::vector<AllowedSnssai> const& value) {
m_AllowedSnssaiList = value;
}
AccessType AllowedNssai::getAccessType() const {
return m_AccessType;
}
......
......@@ -34,9 +34,28 @@ namespace model {
class AllowedNssai {
public:
AllowedNssai();
virtual ~AllowedNssai();
virtual ~AllowedNssai() = default;
void validate();
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on
/// failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes
/// an error message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and
/// calls it's validate. Not meant to be called outside that case.
/// </summary>
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
bool operator==(const AllowedNssai& rhs) const;
bool operator!=(const AllowedNssai& rhs) const;
/////////////////////////////////////////////
/// AllowedNssai members
......@@ -44,7 +63,8 @@ class AllowedNssai {
/// <summary>
///
/// </summary>
std::vector<AllowedSnssai>& getAllowedSnssaiList();
std::vector<AllowedSnssai> getAllowedSnssaiList() const;
void setAllowedSnssaiList(std::vector<AllowedSnssai> const& value);
/// <summary>
///
/// </summary>
......
......@@ -12,6 +12,9 @@
*/
#include "AllowedSnssai.h"
#include "Helpers.h"
#include <sstream>
namespace oai {
namespace amf {
......@@ -22,16 +25,75 @@ AllowedSnssai::AllowedSnssai() {
m_MappedHomeSnssaiIsSet = false;
}
AllowedSnssai::~AllowedSnssai() {}
void AllowedSnssai::validate() const {
std::stringstream msg;
// if (!validate(msg))
// {
// throw oai::nssf_server::helpers::ValidationException(msg.str());
// }
}
bool AllowedSnssai::validate(std::stringstream& msg) const {
return validate(msg, "");
}
bool AllowedSnssai::validate(
std::stringstream& msg, const std::string& pathPrefix) const {
bool success = true;
const std::string _pathPrefix =
pathPrefix.empty() ? "AllowedSnssai" : pathPrefix;
if (nsiInformationListIsSet()) {
const std::vector<NsiInformation>& value = m_NsiInformationList;
const std::string currentValuePath = _pathPrefix + ".nsiInformationList";
if (value.size() < 1) {
success = false;
msg << currentValuePath << ": must have at least 1 elements;";
}
{ // Recursive validation of array elements
const std::string oldValuePath = currentValuePath;
int i = 0;
for (const NsiInformation& value : value) {
const std::string currentValuePath =
oldValuePath + "[" + std::to_string(i) + "]";
success =
value.validate(msg, currentValuePath + ".nsiInformationList") &&
success;
i++;
}
}
}
void AllowedSnssai::validate() {
// TODO: implement validation
return success;
}
bool AllowedSnssai::operator==(const AllowedSnssai& rhs) const {
return
(getAllowedSnssai() == rhs.getAllowedSnssai()) &&
((!nsiInformationListIsSet() && !rhs.nsiInformationListIsSet()) ||
(nsiInformationListIsSet() && rhs.nsiInformationListIsSet() &&
getNsiInformationList() == rhs.getNsiInformationList())) &&
((!mappedHomeSnssaiIsSet() && !rhs.mappedHomeSnssaiIsSet()) ||
(mappedHomeSnssaiIsSet() && rhs.mappedHomeSnssaiIsSet() &&
getMappedHomeSnssai() == rhs.getMappedHomeSnssai()))
;
}
bool AllowedSnssai::operator!=(const AllowedSnssai& rhs) const {
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const AllowedSnssai& o) {
j = nlohmann::json();
j["allowedSnssai"] = o.m_AllowedSnssai;
if (o.nsiInformationListIsSet())
if (o.nsiInformationListIsSet() || !o.m_NsiInformationList.empty())
j["nsiInformationList"] = o.m_NsiInformationList;
if (o.mappedHomeSnssaiIsSet()) j["mappedHomeSnssai"] = o.m_MappedHomeSnssai;
}
......@@ -54,9 +116,14 @@ Snssai AllowedSnssai::getAllowedSnssai() const {
void AllowedSnssai::setAllowedSnssai(Snssai const& value) {
m_AllowedSnssai = value;
}
std::vector<NsiInformation>& AllowedSnssai::getNsiInformationList() {
std::vector<NsiInformation> AllowedSnssai::getNsiInformationList() const {
return m_NsiInformationList;
}
void AllowedSnssai::setNsiInformationList(
std::vector<NsiInformation> const& value) {
m_NsiInformationList = value;
m_NsiInformationListIsSet = true;
}
bool AllowedSnssai::nsiInformationListIsSet() const {
return m_NsiInformationListIsSet;
}
......
......@@ -34,9 +34,28 @@ namespace model {
class AllowedSnssai {
public:
AllowedSnssai();
virtual ~AllowedSnssai();
virtual ~AllowedSnssai() = default;
void validate();
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on
/// failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes
/// an error message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and
/// calls it's validate. Not meant to be called outside that case.
/// </summary>
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
bool operator==(const AllowedSnssai& rhs) const;
bool operator!=(const AllowedSnssai& rhs) const;
/////////////////////////////////////////////
/// AllowedSnssai members
......@@ -49,7 +68,8 @@ class AllowedSnssai {
/// <summary>
///
/// </summary>
std::vector<NsiInformation>& getNsiInformationList();
std::vector<NsiInformation> getNsiInformationList() const;
void setNsiInformationList(std::vector<NsiInformation> const& value);
bool nsiInformationListIsSet() const;
void unsetNsiInformationList();
/// <summary>
......
This diff is collapsed.
/**
* NSSF NS Selection
* NSSF Network Slice Selection Service. © 2021, 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.
*/
/*
* AuthorizedNetworkSliceInfo.h
*
*
*/
#ifndef AuthorizedNetworkSliceInfo_H_
#define AuthorizedNetworkSliceInfo_H_
#include "AllowedNssai.h"
#include "ConfiguredSnssai.h"
#include "NsiInformation.h"
#include "Snssai.h"
#include <nlohmann/json.hpp>
#include <string>
#include <vector>
namespace oai {
namespace amf {
namespace model {
/// <summary>
///
/// </summary>
class AuthorizedNetworkSliceInfo {
public:
AuthorizedNetworkSliceInfo();
virtual ~AuthorizedNetworkSliceInfo() = default;
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on
/// failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes
/// an error message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and
/// calls it's validate. Not meant to be called outside that case.
/// </summary>
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
bool operator==(const AuthorizedNetworkSliceInfo& rhs) const;
bool operator!=(const AuthorizedNetworkSliceInfo& rhs) const;
/////////////////////////////////////////////
/// AuthorizedNetworkSliceInfo members
/// <summary>
///
/// </summary>
std::vector<AllowedNssai> getAllowedNssaiList() const;
void setAllowedNssaiList(std::vector<AllowedNssai> const& value);
bool allowedNssaiListIsSet() const;
void unsetAllowedNssaiList();
/// <summary>
///
/// </summary>
std::vector<ConfiguredSnssai> getConfiguredNssai() const;
void setConfiguredNssai(std::vector<ConfiguredSnssai> const& value);
bool configuredNssaiIsSet() const;
void unsetConfiguredNssai();
/// <summary>
///
/// </summary>
std::string getTargetAmfSet() const;
void setTargetAmfSet(std::string const& value);
bool targetAmfSetIsSet() const;
void unsetTargetAmfSet();
/// <summary>
///
/// </summary>
std::vector<std::string> getCandidateAmfList() const;
void setCandidateAmfList(std::vector<std::string> const& value);
bool candidateAmfListIsSet() const;
void unsetCandidateAmfList();
/// <summary>
///
/// </summary>
std::vector<Snssai> getRejectedNssaiInPlmn() const;
void setRejectedNssaiInPlmn(std::vector<Snssai> const& value);
bool rejectedNssaiInPlmnIsSet() const;
void unsetRejectedNssaiInPlmn();
/// <summary>
///
/// </summary>
std::vector<Snssai> getRejectedNssaiInTa() const;
void setRejectedNssaiInTa(std::vector<Snssai> const& value);
bool rejectedNssaiInTaIsSet() const;
void unsetRejectedNssaiInTa();
/// <summary>
///
/// </summary>
NsiInformation getNsiInformation() const;
void setNsiInformation(NsiInformation const& value);
bool nsiInformationIsSet() const;
void unsetNsiInformation();
/// <summary>
///
/// </summary>
std::string getSupportedFeatures() const;
void setSupportedFeatures(std::string const& value);
bool supportedFeaturesIsSet() const;
void unsetSupportedFeatures();
/// <summary>
///
/// </summary>
std::string getNrfAmfSet() const;
void setNrfAmfSet(std::string const& value);
bool nrfAmfSetIsSet() const;
void unsetNrfAmfSet();
/// <summary>
///
/// </summary>
std::string getNrfAmfSetNfMgtUri() const;
void setNrfAmfSetNfMgtUri(std::string const& value);
bool nrfAmfSetNfMgtUriIsSet() const;
void unsetNrfAmfSetNfMgtUri();
/// <summary>
///
/// </summary>
std::string getNrfAmfSetAccessTokenUri() const;
void setNrfAmfSetAccessTokenUri(std::string const& value);
bool nrfAmfSetAccessTokenUriIsSet() const;
void unsetNrfAmfSetAccessTokenUri();
/// <summary>
///
/// </summary>
std::string getTargetAmfServiceSet() const;
void setTargetAmfServiceSet(std::string const& value);
bool targetAmfServiceSetIsSet() const;
void unsetTargetAmfServiceSet();
friend void to_json(nlohmann::json& j, const AuthorizedNetworkSliceInfo& o);
friend void from_json(const nlohmann::json& j, AuthorizedNetworkSliceInfo& o);
protected:
std::vector<AllowedNssai> m_AllowedNssaiList;
bool m_AllowedNssaiListIsSet;
std::vector<ConfiguredSnssai> m_ConfiguredNssai;
bool m_ConfiguredNssaiIsSet;
std::string m_TargetAmfSet;
bool m_TargetAmfSetIsSet;
std::vector<std::string> m_CandidateAmfList;
bool m_CandidateAmfListIsSet;
std::vector<Snssai> m_RejectedNssaiInPlmn;
bool m_RejectedNssaiInPlmnIsSet;
std::vector<Snssai> m_RejectedNssaiInTa;
bool m_RejectedNssaiInTaIsSet;
NsiInformation m_NsiInformation;
bool m_NsiInformationIsSet;
std::string m_SupportedFeatures;
bool m_SupportedFeaturesIsSet;
std::string m_NrfAmfSet;
bool m_NrfAmfSetIsSet;
std::string m_NrfAmfSetNfMgtUri;
bool m_NrfAmfSetNfMgtUriIsSet;
std::string m_NrfAmfSetAccessTokenUri;
bool m_NrfAmfSetAccessTokenUriIsSet;
std::string m_TargetAmfServiceSet;
bool m_TargetAmfServiceSetIsSet;
};
} // namespace model
} // namespace amf
} // namespace oai
#endif /* AuthorizedNetworkSliceInfo_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -168,7 +168,7 @@ SMContextsCollectionApi::postSmContexts(
// 4xx - client error : not OK
// 5xx - client error : not OK
if (localVarResponse.status_code() >= 400) {
amf_n11_inst->handle_post_sm_context_response_error_400();
// amf_n11_inst->handle_post_sm_context_response_error_400();
throw ApiException(
localVarResponse.status_code(),
utility::conversions::to_string_t(
......
......@@ -546,11 +546,7 @@ uint8_t* Authentication_5gaka::sqn_ms_derive(
conc_sqn_ms = auts;
mac_s = &auts[6];
sqn_ms = (uint8_t*) malloc(SQN_LENGTH_OCTEST);
/*
* if (hss_config.valid_opc == 0) {
* SetOP(hss_config.operator_key);
* }
*/
/*
* Derive AK from key and rand
*/
......
This diff is collapsed.
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