Commit 24916e33 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Update the whole SMF App for PDU session establishment procedure

parent 953a3b93
......@@ -33,29 +33,6 @@ include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
add_library (SMF STATIC
${SRC_TOP_DIR}/common/ngap/ngap_common.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_setup_request.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_setup_response.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_release_command.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_release_response.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_modify_request.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_modify_response.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_notify.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_modify_indication.c
${SRC_TOP_DIR}/ngap/ng_pdu_session_resource_modify_confirm.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_required.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_command.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_preparation_failure.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_request.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_request_acknowledge.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_failure.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_notify.c
${SRC_TOP_DIR}/ngap/ng_pdu_path_switch_request.c
${SRC_TOP_DIR}/ngap/ng_pdu_path_switch_request_acknowledge.c
${SRC_TOP_DIR}/ngap/ng_pdu_path_switch_request_failure.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_cancel.c
${SRC_TOP_DIR}/ngap/ng_pdu_handover_cancel_acknowledge.c
${SRC_TOP_DIR}/ngap/ng_pdu_uplink_ran_status_transfer.c
${SRC_TOP_DIR}/ngap/ng_pdu_downlink_ran_status_transfer.c
smf_app.cpp
smf_config.cpp
smf_context.cpp
......
This diff is collapsed.
......@@ -32,6 +32,7 @@
#include "smf.h"
#include "3gpp_29.274.h"
#include "3gpp_29.502.h"
#include "itti_msg_n4.hpp"
#include "itti_msg_n11.hpp"
#include "smf_context.hpp"
......@@ -53,6 +54,19 @@
namespace smf {
#define TASK_SMF_APP_TRIGGER_T3591 (0)
#define TASK_SMF_APP_TIMEOUT_T3591 (1)
//Table 10.3.2 @3GPP TS 24.501 V16.1.0 (2019-06)
#define T3591_TIMER_VALUE_SEC 16
#define T3591_TIMER_MAX_RETRIES 4
typedef enum {
PDU_SESSION_ESTABLISHMENT = 1,
PDU_SESSION_MODIFICATION = 2,
PDU_SESSION_RELEASE = 3
} pdu_session_procedure_t;
class smf_config; // same namespace
class smf_context_ref {
......@@ -133,7 +147,22 @@ public:
void handle_itti_msg (std::shared_ptr<itti_n4_session_report_request> snr);
void handle_itti_msg (itti_n4_association_setup_request& m);
void restore_sx_sessions(const seid_t& seid) const;
/*
* Handle ITTI message from N11 to update PDU session status
* @param [itti_n11_update_pdu_session_status&] itti_n11_update_pdu_session_status
* @return void
*/
void handle_itti_msg (itti_n11_update_pdu_session_status& m);
/*
* Handle ITTI message from N11 (N1N2MessageTransfer Response)
* @param [itti_n11_n1n2_message_transfer_response_status&] itti_n11_n1n2_message_transfer_response_status
* @return void
*/
void handle_itti_msg (itti_n11_n1n2_message_transfer_response_status& m);
void restore_n4_sessions(const seid_t& seid) const;
uint64_t generate_seid();
bool is_seid_n4_exist(const uint64_t& s) const;
......@@ -152,14 +181,21 @@ public:
* @param [std::shared_ptr<itti_n11_create_sm_context_request>&] Request message
* @return void
*/
void handle_amf_msg (std::shared_ptr<itti_n11_create_sm_context_request> smreq);
void handle_pdu_session_create_sm_context_request (std::shared_ptr<itti_n11_create_sm_context_request> smreq);
/*
* Handle PDUSession_UpdateSMContextRequest from AMF
* @param [std::shared_ptr<itti_n11_update_sm_context_request>&] Request message
* @return void
*/
void handle_amf_msg (std::shared_ptr<itti_n11_update_sm_context_request> smreq);
void handle_pdu_session_update_sm_context_request (std::shared_ptr<itti_n11_update_sm_context_request> smreq);
/*
* Handle network-requested pdu session modification
* @param should be updated
* @return void
*/
void handle_network_requested_pdu_session_modification();
/*
* Verify if SM Context is existed for this Supi
......@@ -206,23 +242,6 @@ public:
*/
bool is_create_sm_context_request_valid();
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf_server::model::SmContextCreateError] smContextCreateError
* @param [Pistache::Http::Code] code, response code
*
*/
void send_create_session_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code);
/*
* Send update session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf_server::model::SmContextUpdateError] smContextUpdateError
* @param [Pistache::Http::Code] code, response code
*
*/
void send_update_session_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextUpdateError& smContextUpdateError, Pistache::Http::Code code);
/*
* Convert a string to hex representing this string
......@@ -232,6 +251,23 @@ public:
*/
void convert_string_2_hex(std::string& input_str, std::string& output_str);
unsigned char * format_string_as_hex(std::string str);
void print_string_as_hex(std::string str);
void start_upf_association(const pfcp::node_id_t& node_id);
/*
* Update PDU session status
* @param [const scid_t] id SM Context ID
* @param [const pdu_session_status_e] status PDU Session Status
* @return void
*/
void update_pdu_session_status(const scid_t id, const pdu_session_status_e status);
void timer_t3591_timeout(timer_id_t timer_id, uint64_t arg2_user);
n2_sm_info_type_e n2_sm_info_type_str2e(std::string n2_info_type);
};
}
#include "smf_config.hpp"
......
......@@ -137,15 +137,8 @@ int smf_config::load_itti(const Setting& itti_cfg, itti_cfg_t& cfg)
}
try {
const Setting& s5s8_sched_params_cfg = itti_cfg[SMF_CONFIG_STRING_S5S8_SCHED_PARAMS];
load_thread_sched_params(s5s8_sched_params_cfg, cfg.s5s8_sched_params);
} catch(const SettingNotFoundException &nfex) {
Logger::smf_app().info("%s : %s, using defaults", nfex.what(), nfex.getPath());
}
try {
const Setting& sx_sched_params_cfg = itti_cfg[SMF_CONFIG_STRING_SX_SCHED_PARAMS];
load_thread_sched_params(sx_sched_params_cfg, cfg.sx_sched_params);
const Setting& n4_sched_params_cfg = itti_cfg[SMF_CONFIG_STRING_N4_SCHED_PARAMS];
load_thread_sched_params(n4_sched_params_cfg, cfg.n4_sched_params);
} catch(const SettingNotFoundException &nfex) {
Logger::smf_app().info("%s : %s, using defaults", nfex.what(), nfex.getPath());
}
......@@ -265,9 +258,6 @@ int smf_config::load(const string& config_file)
try {
const Setting &nw_if_cfg = smf_cfg[SMF_CONFIG_STRING_INTERFACES];
const Setting& sx_cfg = nw_if_cfg[SMF_CONFIG_STRING_INTERFACE_SX];
load_interface(sx_cfg, sx);
const Setting& n4_cfg = nw_if_cfg[SMF_CONFIG_STRING_INTERFACE_N4];
load_interface(n4_cfg, n4);
......@@ -376,11 +366,11 @@ int smf_config::load(const string& config_file)
apn_cfg.lookupValue(SMF_CONFIG_STRING_IPV6_POOL, apn[apn_idx].pool_id_iv6);
if ((0 <= apn[apn_idx].pool_id_iv4) && (apn[apn_idx].pdn_type.pdn_type == PDN_TYPE_E_IPV6)) {
Logger::smf_app().error("PDN_TYPE versus pool identifier %d 'th APN in config file\n", i+1);
Logger::smf_app().error("PDN_TYPE versus pool identifier %d 'th APN in config file", i+1);
throw ("PDN_TYPE versus pool identifier APN");
}
if ((0 <= apn[apn_idx].pool_id_iv6) && (apn[apn_idx].pdn_type.pdn_type == PDN_TYPE_E_IPV4)) {
Logger::smf_app().error("PDN_TYPE versus pool identifier %d 'th APN in config file\n", i+1);
Logger::smf_app().error("PDN_TYPE versus pool identifier %d 'th APN in config file", i+1);
throw ("PDN_TYPE versus pool identifier APN");
}
......@@ -390,7 +380,7 @@ int smf_config::load(const string& config_file)
for (int j = 0; j < apn_idx; j++) {
if (boost::iequals(apn[j].apn, apn[apn_idx].apn)) {
doublon = true;
Logger::smf_app().info("%d'th APN %s already found in config file (%d 'th APN %s), bypassing\n", i+1, apn[apn_idx].apn.c_str(), j+1, apn[j].apn.c_str());
Logger::smf_app().info("%d'th APN %s already found in config file (%d 'th APN %s), bypassing", i+1, apn[apn_idx].apn.c_str(), j+1, apn[j].apn.c_str());
}
}
if (not doublon) {
......@@ -398,7 +388,7 @@ int smf_config::load(const string& config_file)
num_apn++;
}
} else {
Logger::smf_app().error("Bypass %d'th APN %s in config file\n", i+1, apn[apn_idx].apn.c_str());
Logger::smf_app().error("Bypass %d'th APN %s in config file", i+1, apn[apn_idx].apn.c_str());
}
}
smf_cfg.lookupValue(SMF_CONFIG_STRING_DEFAULT_DNS_IPV4_ADDRESS, astring);
......@@ -469,6 +459,29 @@ int smf_config::load(const string& config_file)
udm_addr.port = udm_port;
//UPF list
unsigned char buf_in_addr[sizeof (struct in_addr)+1];
const Setting& upf_list_cfg = smf_cfg[SMF_CONFIG_STRING_UPF_LIST];
count = upf_list_cfg.getLength();
for (int i = 0; i < count; i++) {
const Setting &upf_cfg = upf_list_cfg[i];
string address = {};
if (upf_cfg.lookupValue(SMF_CONFIG_STRING_UPF_IPV4_ADDRESS, address)) {
pfcp::node_id_t n = {};
n.node_id_type = pfcp::NODE_ID_TYPE_IPV4_ADDRESS; // actually
if (inet_pton (AF_INET, util::trim(address).c_str(), buf_in_addr) == 1) {
memcpy (&n.u1.ipv4_address, buf_in_addr, sizeof (struct in_addr));
} else {
Logger::smf_app().error("CONFIG: BAD IPV4 ADDRESS in " SMF_CONFIG_STRING_UPF_LIST " item %d", i);
throw ("CONFIG: BAD ADDRESS in " SMF_CONFIG_STRING_UPF_LIST);
}
upfs.push_back(n);
} else {
// TODO IPV6_ADDRESS, FQDN
throw ("Bad value in section %s : item no %d in config file %s", SMF_CONFIG_STRING_UPF_LIST, i, config_file.c_str());
}
}
}
catch(const SettingNotFoundException &nfex)
{
......@@ -486,11 +499,6 @@ void smf_config::display ()
Logger::smf_app().info( "- Instance ..............: %d\n", instance);
Logger::smf_app().info( "- PID dir ...............: %s\n", pid_dir.c_str());
Logger::smf_app().info( "- SX Networking:");
Logger::smf_app().info( " iface ................: %s", sx.if_name.c_str());
Logger::smf_app().info( " ip ...................: %s", inet_ntoa (sx.addr4));
Logger::smf_app().info( " port .................: %d", sx.port);
Logger::smf_app().info( "- N4 Networking:");
Logger::smf_app().info( " iface ................: %s", n4.if_name.c_str());
Logger::smf_app().info( " ip ...................: %s", inet_ntoa (n4.addr4));
......@@ -501,12 +509,6 @@ void smf_config::display ()
Logger::smf_app().info( " ip ...................: %s", inet_ntoa (n11.addr4));
Logger::smf_app().info( " port .................: %d", n11.port);
Logger::smf_app().info( "- SX Threading:");
Logger::smf_app().info( " CPU id............: %d", sx.thread_rd_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", sx.thread_rd_sched_params.sched_policy);
Logger::smf_app().info( " Scheduling prio .: %d", sx.thread_rd_sched_params.sched_priority);
Logger::smf_app().info( "- N4 Threading:");
Logger::smf_app().info( " CPU id............: %d", n4.thread_rd_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", n4.thread_rd_sched_params.sched_policy);
......@@ -516,14 +518,10 @@ void smf_config::display ()
Logger::smf_app().info( " CPU id............: %d", itti.itti_timer_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", itti.itti_timer_sched_params.sched_policy);
Logger::smf_app().info( " Scheduling prio .: %d", itti.itti_timer_sched_params.sched_priority);
Logger::smf_app().info( "- ITTI S5S8 Task Threading:");
Logger::smf_app().info( " CPU id............: %d", itti.s5s8_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", itti.s5s8_sched_params.sched_policy);
Logger::smf_app().info( " Scheduling prio .: %d", itti.s5s8_sched_params.sched_priority);
Logger::smf_app().info( "- ITTI Sx Task Threading:");
Logger::smf_app().info( " CPU id............: %d", itti.sx_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", itti.sx_sched_params.sched_policy);
Logger::smf_app().info( " Scheduling prio .: %d", itti.sx_sched_params.sched_priority);
Logger::smf_app().info( "- ITTI N4 Task Threading:");
Logger::smf_app().info( " CPU id............: %d", itti.n4_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", itti.n4_sched_params.sched_policy);
Logger::smf_app().info( " Scheduling prio .: %d", itti.n4_sched_params.sched_priority);
Logger::smf_app().info( "- ITTI SMF_APP task Threading:");
Logger::smf_app().info( " CPU id............: %d", itti.smf_app_sched_params.cpu_id);
Logger::smf_app().info( " Scheduling policy : %d", itti.smf_app_sched_params.sched_policy);
......@@ -645,8 +643,8 @@ bool smf_config::is_dotted_dnn_handled(const std::string& dnn, const pdu_session
Logger::smf_app().debug( "apn_label: %s, apn: %s", smf_cfg.apn[i].apn_label.c_str(),smf_cfg.apn[i].apn.c_str() );
//if (0 == dnn.compare(smf_cfg.apn[i].apn_label)) {
if (0 == dnn.compare(smf_cfg.apn[i].apn)) {
Logger::smf_app().debug( "DNN matched! \n");
Logger::smf_app().debug( "pdu session type %d, pdn_type %d \n", pdn_session_type.pdu_session_type, smf_cfg.apn[i].pdn_type.pdn_type);
Logger::smf_app().debug( "DNN matched!");
Logger::smf_app().debug( "pdu session type %d, pdn_type %d", pdn_session_type.pdu_session_type, smf_cfg.apn[i].pdn_type.pdn_type);
if (pdn_session_type.pdu_session_type == smf_cfg.apn[i].pdn_type.pdn_type) {
return true;
}
......
......@@ -54,7 +54,6 @@
#define SMF_CONFIG_STRING_INTERFACE_NAME "INTERFACE_NAME"
#define SMF_CONFIG_STRING_IPV4_ADDRESS "IPV4_ADDRESS"
#define SMF_CONFIG_STRING_PORT "PORT"
#define SMF_CONFIG_STRING_INTERFACE_SX "SX"
#define SMF_CONFIG_STRING_INTERFACE_N4 "N4"
#define SMF_CONFIG_STRING_INTERFACE_N11 "N11"
......@@ -120,8 +119,7 @@
#define SMF_CONFIG_STRING_ITTI_TASKS "ITTI_TASKS"
#define SMF_CONFIG_STRING_ITTI_TIMER_SCHED_PARAMS "ITTI_TIMER_SCHED_PARAMS"
#define SMF_CONFIG_STRING_S11_SCHED_PARAMS "S11_SCHED_PARAMS"
#define SMF_CONFIG_STRING_S5S8_SCHED_PARAMS "S5S8_SCHED_PARAMS"
#define SMF_CONFIG_STRING_SX_SCHED_PARAMS "SX_SCHED_PARAMS"
#define SMF_CONFIG_STRING_N4_SCHED_PARAMS "N4_SCHED_PARAMS"
#define SMF_CONFIG_STRING_SMF_APP_SCHED_PARAMS "SMF_APP_SCHED_PARAMS"
#define SMF_CONFIG_STRING_ASYNC_CMD_SCHED_PARAMS "ASYNC_CMD_SCHED_PARAMS"
......@@ -133,6 +131,9 @@
#define SMF_CONFIG_STRING_UDM_IPV4_ADDRESS "IPV4_ADDRESS"
#define SMF_CONFIG_STRING_UDM_PORT "PORT"
#define SMF_CONFIG_STRING_UPF_LIST "UPF_LIST"
#define SMF_CONFIG_STRING_UPF_IPV4_ADDRESS "IPV4_ADDRESS"
#define PGW_MAX_ALLOCATED_PDN_ADDRESSES 1024
namespace smf {
......@@ -149,8 +150,7 @@ typedef struct interface_cfg_s {
typedef struct itti_cfg_s {
util::thread_sched_params itti_timer_sched_params;
util::thread_sched_params sx_sched_params;
util::thread_sched_params s5s8_sched_params;
util::thread_sched_params n4_sched_params;
util::thread_sched_params smf_app_sched_params;
util::thread_sched_params async_cmd_sched_params;
} itti_cfg_t;
......@@ -167,7 +167,6 @@ public:
std::string pid_dir;
unsigned int instance = 0;
interface_cfg_t sx;
interface_cfg_t n4;
interface_cfg_t n11;
itti_cfg_t itti;
......@@ -223,7 +222,9 @@ public:
unsigned int port;
} udm_addr;
smf_config() : m_rw_lock(), pcef(), num_apn(0), pid_dir(), instance(0), sx(), n4(), n11(), itti() {
std::vector<pfcp::node_id_t> upfs;
smf_config() : m_rw_lock(), pcef(), num_apn(0), pid_dir(), instance(0), n4(), n11(), itti(), upfs() {
for (int i = 0; i < PGW_NUM_APN_MAX; i++) {
apn[i] = {};
}
......@@ -247,14 +248,10 @@ public:
ue_mtu = 1500;
itti.itti_timer_sched_params.sched_priority = 85;
itti.sx_sched_params.sched_priority = 84;
itti.s5s8_sched_params.sched_priority = 84;
itti.n4_sched_params.sched_priority = 84;
itti.smf_app_sched_params.sched_priority = 84;
itti.async_cmd_sched_params.sched_priority = 84;
sx.thread_rd_sched_params.sched_priority = 90;
sx.port = pfcp::default_port;
n4.thread_rd_sched_params.sched_priority = 90;
n4.port = pfcp::default_port;
......
This diff is collapsed.
......@@ -41,6 +41,7 @@
#include "3gpp_29.274.h"
#include "3gpp_29.244.h"
#include "3gpp_29.503.h"
#include "3gpp_29.502.h"
#include "common_root_types.h"
#include "smf_procedure.hpp"
#include "uint_generator.hpp"
......@@ -50,6 +51,7 @@
#include "pistache/router.h"
#include "SmContextCreateError.h"
#include "smf_msg.hpp"
#include "itti.hpp"
namespace smf {
......@@ -62,6 +64,7 @@ public:
void clear() {
ul_fteid = {};
dl_fteid = {};
eps_bearer_qos = {};
pdr_id_ul = {};
pdr_id_dl = {};
......@@ -77,7 +80,8 @@ public:
pfcp::qfi_t qfi; //QoS Flow Identifier
fteid_t ul_fteid; //Uplink fteid of UPF
fteid_t ul_fteid; //fteid of UPF
fteid_t dl_fteid; //fteid of AN
bearer_qos_t eps_bearer_qos; // EPS Bearer QoS: ARP, GBR, MBR, QCI.
......@@ -113,48 +117,18 @@ public:
up_fseid = {};
qos_flows.clear();
released = false;
pdu_session_status = pdu_session_status_e::PDU_SESSION_INACTIVE;
timer_T3590 = ITTI_INVALID_TIMER_ID;
timer_T3591 = ITTI_INVALID_TIMER_ID;
}
smf_pdu_session(smf_pdu_session& b) = delete;
void set(const paa_t& paa);
bool get_qos_flow(const pfcp::pdr_id_t& pdr_id, smf_qos_flow& q) {
for (auto it : qos_flows) {
if (it.second.pdr_id_ul.rule_id == pdr_id.rule_id) {
q = it.second;
return true;
}
if (it.second.pdr_id_dl.rule_id == pdr_id.rule_id) {
q = it.second;
return true;
}
}
return false;
}
bool get_qos_flow(const pfcp::far_id_t& far_id, smf_qos_flow& q) {
for (auto it : qos_flows) {
if ((it.second.far_id_ul.first) && (it.second.far_id_ul.second.far_id == far_id.far_id)) {
q = it.second;
return true;
}
if ((it.second.far_id_dl.first) && (it.second.far_id_dl.second.far_id == far_id.far_id)) {
q = it.second;
return true;
}
}
return false;
}
bool get_qos_flow(const pfcp::qfi_t& qfi, smf_qos_flow& q) {
for (auto it : qos_flows) {
if (it.second.qfi == qfi) {
q = it.second;
return true;
}
}
return false;
}
bool get_qos_flow(const pfcp::pdr_id_t& pdr_id, smf_qos_flow& q);
bool get_qos_flow(const pfcp::far_id_t& far_id, smf_qos_flow& q);
bool get_qos_flow(const pfcp::qfi_t& qfi, smf_qos_flow& q);
void add_qos_flow(smf_qos_flow& flow);
smf_qos_flow& get_qos_flow(const pfcp::qfi_t& qfi);
......@@ -163,6 +137,23 @@ public:
void remove_qos_flow(const pfcp::qfi_t& qfi);
void remove_qos_flow(smf_qos_flow& flow);
void set_pdu_session_status (const pdu_session_status_e& status);
pdu_session_status_e get_pdu_session_status () const;
/*
* Set upCnxState for a N3 Tunnel
* @param [upCnx_state_e&] state: new state of the N3 tunnel
* @return void
*/
void set_upCnx_state (const upCnx_state_e& state);
/*
* Get upCnxState of a N3 Tunnel
* @param void
* @return upCnx_state_e: current state of this N3 tunnel
*/
upCnx_state_e get_upCnx_state () const;
// Called by GTPV2-C DELETE_SESSION_REQUEST
// deallocate_ressources is for releasing LTE resources prior to the deletion of objects
......@@ -223,6 +214,15 @@ public:
std::string amf_id;
// QFI
std::map<uint8_t,smf_qos_flow> qos_flows;
//pdu session status
pdu_session_status_e pdu_session_status;
timer_id_t timer_T3590;
timer_id_t timer_T3591;
//N3 tunnel status (ACTIVATED, DEACTIVATED, ACTIVATING)
upCnx_state_e upCnx_state;
};
......@@ -299,14 +299,15 @@ public:
* @param [std::shared_ptr<itti_n11_create_sm_context_request] smreq Request message
* @return void
*/
void handle_amf_msg (std::shared_ptr<itti_n11_create_sm_context_request> smreq);
void handle_pdu_session_create_sm_context_request (std::shared_ptr<itti_n11_create_sm_context_request> smreq);
/*
* Handle messages from AMF (e.g., PDU_SESSION_UPDATESMContextRequest)
* @param [std::shared_ptr<itti_n11_update_sm_context_request] smreq Request message
* @param [pdu_session_procedure_t procedure] pdu session procedure: session establishment/modification/release
* @return void
*/
void handle_amf_msg (std::shared_ptr<itti_n11_update_sm_context_request> smreq);
void handle_pdu_session_update_sm_context_request (std::shared_ptr<itti_n11_update_sm_context_request> smreq);
/*
* Find DNN context with name
......@@ -323,15 +324,6 @@ public:
*/
void insert_dnn(std::shared_ptr<dnn_context>& sd);
/*
* Send a response error to AMF (PDU Session Establishment Reject)
* @param [oai::smf_server::model::SmContextCreateError&] smContextCreateError
* @param [Pistache::Http::Code] code response code
* @param [Pistache::Http::ResponseWriter] httpResponse to reply to AMF
* @return void
*/
void send_create_session_response_error(oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code, Pistache::Http::ResponseWriter& httpResponse);
/*
* Check the validity of the request according to user subscription and local policies
* @param [std::shared_ptr<itti_n11_create_sm_context_request>] smreq
......@@ -391,6 +383,8 @@ public:
* @return std::size_t: the number of contexts
*/
std::size_t get_number_dnn_contexts();
void set_scid(scid_t const& id);
scid_t get_scid() const;
private:
......@@ -417,6 +411,7 @@ private:
std::map<uint8_t, std::shared_ptr<session_management_subscription>> dnn_subscriptions;
supi_t supi;
scid_t scid;
};
}
......
......@@ -407,7 +407,7 @@ bool pdu_session_update_sm_context_request::n2_sm_info_is_set() const
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::add_qfi(pfcp::qfi_t const& qfi)
{
qfis.push_back(qfi);
qfis.push_back(qfi);
}
//-----------------------------------------------------------------------------
......
......@@ -63,7 +63,7 @@ public:
uint8_t cause_value;
pfcp::qfi_t qfi;
fteid_t ul_fteid;
fteid_t ul_fteid;
arp_5gc_t arp;
uint8_t priority_level;//1-127
......@@ -77,7 +77,7 @@ public:
uint8_t cause_value;
pfcp::qfi_t qfi;
fteid_t ul_fteid;
fteid_t ul_fteid;
};
......@@ -377,108 +377,46 @@ private:
oai::smf_server::model::Guami m_guami;
oai::smf_server::model::PlmnId m_serving_network;
//BackupAmfInfo
/*
backupAmfInfo:
type: array
items:
$ref: '../TS29571_CommonData.yaml#/components/schemas/BackupAmfInfo'
minItems: 1
nullable: true
*/
std::string m_an_type;
/*
*
secondAnType:
$ref: '../TS29571_CommonData.yaml#/components/schemas/AccessType'
*/
std::string m_rat_type;
std::string m_rat_type; //ratType: $ref: '../TS29571_CommonData.yaml#/components/schemas/RatType
/* SmContextUpdateData:
presenceInLadn:
$ref: '../TS29571_CommonData.yaml#/components/schemas/PresenceState'
ueLocation:
$ref: '../TS29571_CommonData.yaml#/components/schemas/UserLocation'
ueTimeZone:
$ref: '../TS29571_CommonData.yaml#/components/schemas/TimeZone'
addUeLocation:
$ref: '../TS29571_CommonData.yaml#/components/schemas/UserLocation'
hoState:
$ref: '#/components/schemas/HoState'
toBeSwitched:
type: boolean
default: false
failedToBeSwitched:
type: boolean
/* SmContextUpdateData:
presenceInLadn:
ueLocation:
ueTimeZone:
addUeLocation:
hoState:
toBeSwitched:
failedToBeSwitched:
*/
std::string m_upCnx_state; //'#/components/schemas/UpCnxState'
bool m_upCnx_state_is_set; //'#/components/schemas/UpCnxState'
std::string m_upCnx_state;
bool m_upCnx_state_is_set;
oai::smf_server::model::RefToBinaryData m_n1_sm_msg; //n1SmMsg
oai::smf_server::model::RefToBinaryData m_n2_sm_info; //n2SmInfo
std::string m_n2_sm_info_type; //$ref: '#/components/schemas/N2SmInfoType'
oai::smf_server::model::RefToBinaryData m_n1_sm_msg;
oai::smf_server::model::RefToBinaryData m_n2_sm_info;
std::string m_n2_sm_info_type;
oai::smf_server::model::NgRanTargetId m_target_id; //$ref: '../amf/TS29518_Namf_Communication.yaml#/components/schemas/NgRanTargetId'
std::string m_target_serving_nfId; // $ref: '../TS29571_CommonData.yaml#/components/schemas/NfInstanceId'
std::string m_sm_context_status_uri; //smContextStatusUri $ref: '../TS29571_CommonData.yaml#/components/schemas/Uri'
/*
dataForwarding:
type: boolean
default: false
*/
std::string m_sm_context_status_uri;
bool m_data_forwarding;
/*
epsBearerSetup:
type: array
items:
$ref: '#/components/schemas/EpsBearerContainer'
minItems: 0
*/
std::vector<std::string> m_eps_bearer_setup;
/*
revokeEbiList:
type: array
items:
$ref: '#/components/schemas/EpsBearerId'
minItems: 1
EpsBearerId:
type: integer
minimum: 0
maximum: 15
*/
std::vector<int> m_revoke_ebi_list;
/*
release:
type: boolean
default: false
cause:
$ref: '#/components/schemas/Cause'
*/
//NgApCause m_ngAp_cause; // $ref: '../TS29571_CommonData.yaml#/components/schemas/NgApCause
uint8_t m_5gMm_cause_value; // 5GMmCause, $ref: '../TS29571_CommonData.yaml#/components/schemas/5GMmCause'
//NgApCause m_ngAp_cause;
uint8_t m_5gMm_cause_value;
/*
sNssai:
$ref: '../TS29571_CommonData.yaml#/components/schemas/Snssai'
traceData:
$ref: '../TS29571_CommonData.yaml#/components/schemas/TraceData'
epsInterworkingInd:
$ref: '#/components/schemas/EpsInterworkingIndication'
anTypeCanBeChanged:
type: boolean
default: false
n2SmInfoExt1:
$ref: '../TS29571_CommonData.yaml#/components/schemas/RefToBinaryData'
n2SmInfoTypeExt1:
$ref: '#/components/schemas/N2SmInfoType'
maReleaseInd:
$ref: '#/components/schemas/MaReleaseIndication'
exemptionInd:
$ref: '#/components/schemas/ExemptionInd'
*/
EpsBearerId:
release:
cause:
traceData:
epsInterworkingInd:
anTypeCanBeChanged:
n2SmInfoExt1:
n2SmInfoTypeExt1:
maReleaseInd:
exemptionInd:
*/
};
......
......@@ -39,6 +39,12 @@
#include <nlohmann/json.hpp>
#include <stdexcept>
#include <pistache/http.h>
#include <pistache/mime.h>
using namespace Pistache::Http;
using namespace Pistache::Http::Mime;
//TODO: move to a common file
#define AMF_CURL_TIMEOUT_MS 100L
#define AMF_NUMBER_RETRIES 3
......@@ -123,23 +129,25 @@ smf_n11::smf_n11 ()
//------------------------------------------------------------------------------
void smf_n11::send_n1n2_message_transfer_request(std::shared_ptr<itti_n11_create_sm_context_response> sm_context_res)
{
//TODO: should create N1 SM, N2 SM from Procedure to make sure that in this class we simply do send the message to AMF
//Transfer N1/N2 message via AMF by using N_amf_Communication_N1N2MessageTransfer (see TS29518_Namf_Communication.yaml)
//use curl to send data for the moment
Logger::smf_n11().debug("[SMF N11: N1N2MessageTransfer] Send Communication_N1N2MessageTransfer to AMF");
//TODO: use RestSDK for client, use curl to send data for the moment
Logger::smf_n11().debug("Send Communication_N1N2MessageTransfer to AMF");
nlohmann::json message_transfer_req_data;
std::string n1_message;
std::string n2_message;
smf_n1_n2 smf_n1_n2_inst;
pdu_session_create_sm_context_response context_res_msg = sm_context_res->res;
std::string n1_message = context_res_msg.get_n1_sm_message();
std::string n2_message = context_res_msg.get_n2_sm_information();
//format string as hex
unsigned char *n1_msg_hex = smf_app_inst->format_string_as_hex(n1_message);
unsigned char *n2_msg_hex = smf_app_inst->format_string_as_hex(n2_message);
CURL *curl = curl_easy_init();
//N1N2MessageTransfer Notification URI??
std::string json_part = context_res_msg.n1n2_message_transfer_data.dump();
Logger::smf_n11().debug("[SMF N11: N1N2MessageTransfer] Sending message to AMF....\n ");
Logger::smf_n11().debug("Sending message to AMF....");
if(curl) {
CURLcode res;
......@@ -165,23 +173,22 @@ void smf_n11::send_n1n2_message_transfer_request(std::shared_ptr<itti_n11_create
curl_mime_type(part, "application/json");
//N1 SM Container
Logger::smf_n11().debug("Add N1 SM Container (NAS) into the message: %s (bytes %d)", context_res_msg.get_n1_sm_message().c_str(), context_res_msg.get_n1_sm_message().length()/2);
part = curl_mime_addpart(mime);
curl_mime_data(part, context_res_msg.get_n1_sm_message().c_str(), CURL_ZERO_TERMINATED);
curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex), context_res_msg.get_n1_sm_message().length()/2);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
curl_mime_name (part, context_res_msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"].dump().c_str());
if (context_res_msg.get_cause() == REQUEST_ACCEPTED) {
Logger::smf_n11().debug("[SMF N11: N1N2MessageTransfer] add NGAP into the message....\n ");
//N2 SM Information
part = curl_mime_addpart(mime);
//TODO:
curl_mime_data(part, context_res_msg.get_n2_sm_information().substr(0,86).c_str(), CURL_ZERO_TERMINATED); //TODO: ISSUE need to be solved
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name (part, context_res_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"].dump().c_str());
Logger::smf_n11().debug("Add N2 SM Information (NGAP) into the message: %s (bytes %d)", context_res_msg.get_n2_sm_information().c_str(), context_res_msg.get_n2_sm_information().length()/2);
part = curl_mime_addpart(mime);
//curl_mime_data(part, reinterpret_cast<const char*>(n2_msg_hex), context_res_msg.get_n2_sm_information().length()/2); //TODO: ISSUE need to be solved
curl_mime_data(part, reinterpret_cast<const char*>(n2_msg_hex), 80); //TODO: ISSUE need to be solved
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name (part, context_res_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"].dump().c_str());
}
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
res = curl_easy_perform(curl);
// Response information.
long httpCode(0);
......@@ -203,13 +210,18 @@ void smf_n11::send_n1n2_message_transfer_request(std::shared_ptr<itti_n11_create
//Set the default Cause
response_data["cause"] = "504 Gateway Timeout";
}
Logger::smf_n11().debug("[SMF N11: N1N2MessageTransfer] Response from AMF, Http Code: %d, cause %s", httpCode, response_data["cause"]);
Logger::smf_n11().debug("Response from AMF, Http Code: %d, cause %s", httpCode, response_data["cause"].dump().c_str());
//send response to APP to process
itti_n11_n1n2_message_transfer_response_status *itti_msg = new itti_n11_n1n2_message_transfer_response_status(TASK_SMF_N11, TASK_SMF_APP);
itti_msg->set_response_code(httpCode);
itti_msg->set_scid(sm_context_res->scid);
itti_msg->set_cause(response_data["cause"]);
if (context_res_msg.get_cause() == REQUEST_ACCEPTED) {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_ACCEPT);
}else {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_REJECT);
}
std::shared_ptr<itti_n11_n1n2_message_transfer_response_status> i = std::shared_ptr<itti_n11_n1n2_message_transfer_response_status>(itti_msg);
int ret = itti_inst->send_msg(i);
if (RETURNok != ret) {
......@@ -226,44 +238,64 @@ void smf_n11::send_n1n2_message_transfer_request(std::shared_ptr<itti_n11_create
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_update_sm_context_response(std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res)
{
Logger::smf_n11().debug("[SMF N11] Send PDUSessionUpdateContextResponse to AMF ");
//TODO: to be completed
Logger::smf_n11().debug("Send PDUSessionUpdateContextResponse to AMF ");
//Send reply to AMF
/* Pistache::Http::Code code;
nlohmann::json jsonData;
//to_json(jsonData, smContextCreateError);
std::string resBody = jsonData.dump();
sm_context_res->http_response.send(code,body);
*/
nlohmann::json sm_context_updated_data;
sm_context_updated_data["cause"] = sm_context_res->res.get_cause();
//sm_context_res->http_response.send(Pistache::Http::Code::Ok,sm_context_updated_data.dump());
sm_context_res->http_response.send(Pistache::Http::Code::No_Content);
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_create_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code)
void smf_n11::send_pdu_session_update_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextUpdateError& smContextUpdateError, Pistache::Http::Code code)
{
//TODO: Send multipart message
nlohmann::json jsonData;
to_json(jsonData, smContextCreateError);
to_json(jsonData, smContextUpdateError);
std::string resBody = jsonData.dump();
//httpResponse.headers().add<Pistache::Http::Header::Location>(url);
httpResponse.send(code, resBody);
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_update_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextUpdateError& smContextUpdateError, Pistache::Http::Code code, std::string& n1_sm_msg )
{
Logger::smf_n11().debug("[SMF N11] Send PDUSessionUpdateContextResponse to AMF!");
//TODO: Send multipart message
nlohmann::json jsonData;
to_json(jsonData, smContextUpdateError);
std::string resBody = jsonData.dump();
//http_response.headers().add<Pistache::Http::Header::Location>(uri);
httpResponse.send(code, resBody);
}
void smf_n11::send_pdu_session_create_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code, std::string& n1_sm_msg )
{
Logger::smf_n11().debug("[SMF N11] Send PDUSessionCreateContextResponse to AMF!");
//TODO: Send multipart message
nlohmann::json jsonData;
to_json(jsonData, smContextCreateError);
jsonData["n1SmMsg"]["contentId"] = "n1SmMsg"; //multipart
std::string resBody = jsonData.dump();
auto m1 = MIME(Multipart, Json);
auto m2 = MIME(Multipart, Star);
Pistache::Http::Mime::MediaType m3("application/vnd.3gpp.5gnas", Pistache::Http::Mime::MediaType::DontParse);
//httpResponse.headers().add<Pistache::Http::Header::Location>(url);
httpResponse.send(code, resBody);
httpResponse.send(code, resBody, m3);
}
......
......@@ -33,6 +33,7 @@
#include "3gpp_29.503.h"
#include "smf_context.hpp"
#include "SmContextCreatedData.h"
#include "SmContextUpdateError.h"
#include <thread>
#include <map>
......@@ -52,6 +53,8 @@ public:
void send_n1n2_message_transfer_request(std::shared_ptr<itti_n11_create_sm_context_response> sm_context_res);
void send_pdu_session_update_sm_context_response(std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res);
void send_n1n2_message_transfer_request(std::shared_ptr<itti_n11_modify_session_request_smf_requested> sm_context_mod);
void send_pdu_session_update_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextUpdateError& smContextUpdateError, Pistache::Http::Code code);
//void send_pdu_session_update_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextUpdateError& smContextUpdateError, Pistache::Http::Code code, std::string& n1_sm_msg );
/*
......@@ -64,14 +67,25 @@ public:
void send_pdu_session_create_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code);
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf_server::model::SmContextCreateError] smContextCreateError
* @param [Pistache::Http::Code] code, response code
* @param [std::string] n1_sm_msg, N1 SM message content
*
*/
void send_pdu_session_create_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code, std::string& n1_sm_msg );
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf_server::model::SmContextCreateError] smContextCreateError
* @param [Pistache::Http::Code] code, response code
* @param [std::string] n1_sm_msg, N1 SM message content
*
*/
void send_pdu_session_create_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextCreateError& smContextCreateError, Pistache::Http::Code code, std::string& n1_sm_msg );
/*
* Send update session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf_server::model::SmContextUpdateError] smContextUpdateError
* @param [Pistache::Http::Code] code, response code
* @param [std::string] n1_sm_msg, N1 SM message content
*
*/
void send_pdu_session_update_sm_context_response(Pistache::Http::ResponseWriter& httpResponse, oai::smf_server::model::SmContextUpdateError& smContextUpdateError, Pistache::Http::Code code, std::string& n1_sm_msg );
/*
......
This diff is collapsed.
......@@ -76,10 +76,7 @@ public:
* @param [uint8_t] sm_cause store NAS Cause
*
*/
void create_n1_sm_container(pdu_session_msg& msg, uint8_t msg_type, std::string& nas_msg_str, uint8_t sm_cause);
//for testing purpose!!
void create_n1_sm_container(uint8_t msg_type, std::string& nas_msg_str, uint8_t sm_cause = 0);
void create_n1_sm_container(pdu_session_msg& msg, uint8_t msg_type, std::string& nas_msg_str, cause_value_5gsm_e sm_cause);
/*
* Create N2 SM Information to send to AMF (using NAS lib)
......
......@@ -72,8 +72,8 @@ void smf_n4_task (void *args_p)
case N4_ASSOCIATION_SETUP_REQUEST:
if (itti_n4_association_setup_request* m = dynamic_cast<itti_n4_association_setup_request*>(msg)) {
// m->trxn_id = smf_n4_inst->generate_trxn_id();
smf_n4_inst->send_association_setup_request(ref(*m));
// m->trxn_id = smf_n4_inst->generate_trxn_id();
smf_n4_inst->send_association_setup_request(ref(*m));
//smf_n4_inst->handle_itti_msg(ref(*m));
}
break;
......@@ -358,7 +358,7 @@ void smf_n4::handle_receive_association_setup_request(pfcp::pfcp_msg& msg, const
//------------------------------------------------------------------------------
void smf_n4::handle_receive_association_setup_response(pfcp::pfcp_msg& msg, const endpoint& remote_endpoint)
{
//TODO: To be completed
//TODO: To be completed
Logger::smf_n4().info("Received N4 ASSOCIATION SETUP RESPONSE from an UPF");
bool error = true;
uint64_t trxn_id = 0;
......@@ -561,7 +561,7 @@ void smf_n4::time_out_itti_event(const uint32_t timer_id)
//------------------------------------------------------------------------------
void smf_n4::send_association_setup_request(itti_n4_association_setup_request& i)
{
i.trxn_id = generate_trxn_id();
send_request(i.r_endpoint, i.pfcp_ies, TASK_SMF_N4, i.trxn_id);
i.trxn_id = generate_trxn_id();
send_request(i.r_endpoint, i.pfcp_ies, TASK_SMF_N4, i.trxn_id);
}
......@@ -59,7 +59,7 @@ public:
timer_id_t timer_association;
explicit pfcp_association(const pfcp::node_id_t& node_id) :
node_id(node_id), recovery_time_stamp(), function_features(), m_sessions(), sessions() {
node_id(node_id), recovery_time_stamp(), function_features(), m_sessions(), sessions() {
hash_node_id = std::hash<pfcp::node_id_t>{}(node_id);
timer_heartbeat = ITTI_INVALID_TIMER_ID;
num_retries_timer_heartbeat = 0;
......
This diff is collapsed.
......@@ -141,6 +141,8 @@ public:
std::shared_ptr<itti_n11_update_sm_context_request> n11_trigger;
std::shared_ptr<itti_n11_update_sm_context_response> n11_triggered_pending;
session_management_procedures_type_e session_procedure_type;
};
......
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