Commit 9893f7f6 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'fix_stability_test' into 'develop'

Fix stability test

See merge request oai/cn5g/oai-cn5g-smf!40
parents 4e2e3a1e 0f94d23f
......@@ -80,8 +80,15 @@ SMF =
DEFAULT_DNS_IPV6_ADDRESS = "2001:4860:4860::8888"; # YOUR DNS CONFIG HERE
DEFAULT_DNS_SEC_IPV6_ADDRESS = "2001:4860:4860::8844"; # YOUR DNS CONFIG HERE
# Non standard feature, normally should be set to "no", but you may need to set to yes for UE that do not explicitly request a PDN address through NAS signalling
FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS = "no"; # STRING, {"yes", "no"}.
SUPPORT_FEATURES:
{
# STRING, {"yes", "no"},
REGISTER_NRF = "no"; # Set to yes if SMF resgisters to an NRF
DISCOVER_UPF = "no"; # Set to yes to enable UPF discovery and selection
FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS = "no"; # Non standard feature, normally should be set to "no",
# but you may need to set to yes for UE that do not explicitly request a PDN address through NAS signalling
USE_LOCAL_SUBSCRIPTION_INFO = "yes"; # Set to yes if SMF uses local subscription information instead of from an UDM
}
AMF :
{
......
......@@ -252,7 +252,8 @@ enum class cause_value_5gsm_e {
CAUSE_99_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED = 99,
CAUSE_100_CONDITIONAL_IE_ERROR = 100,
CAUSE_101_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101,
CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED = 111
CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED = 111,
CAUSE_255_REQUEST_ACCEPTED = 255
};
// The 5GSM sublayer states for PDU session handling in the network
......
......@@ -25,9 +25,9 @@
#include <stdint.h>
typedef enum extended_protocol_discriminator_e {
// Protocol discriminator identifier for 5G Session Management
// 5G Session Management
EPD_5GS_SESSION_MANAGEMENT_MESSAGES = 0x2e,
// Protocol discriminator identifier for 5G Mobility Management
// 5G Mobility Management
EPD_5GS_MOBILITY_MANAGEMENT_MESSAGES = 0x7e,
} extended_protocol_discriminator_t;
......
......@@ -248,23 +248,20 @@ typedef struct nf_service_version_s {
} nf_service_version_t;
typedef struct ip_endpoint_s {
std::vector<struct in_addr> ipv4_addresses;
// std::vector<struct in6_addr> ipv6_addresses;
//struct in6_addr ipv6_address;
struct in_addr ipv4_address;
std::string transport; // TCP
unsigned int port;
std::string to_string() const {
std::string s = {};
s.append("Ipv4 Addresses: ");
for (auto ipv4 : ipv4_addresses) {
s.append(inet_ntoa(ipv4));
}
s.append("Ipv4 Address: ");
s.append(inet_ntoa(ipv4_address));
s.append(", TransportProtocol: ");
s.append(transport);
s.append(", Port: ");
s.append(std::to_string(port));
return s;
}
} ip_endpoint_t;
typedef struct nf_service_s {
......@@ -326,4 +323,11 @@ typedef struct patch_item_s {
}
} patch_item_t;
//TODO: move to 23.003
typedef struct guami_5g_s {
plmn_t plmn;
std::string amf_id;
} guami_5g_t;
#endif
......@@ -36,6 +36,8 @@
#include "SmContextUpdateData.h"
#include "SmContextReleaseData.h"
#include "3gpp_29.500.h"
#include "3gpp_24.501.h"
#include "conversions.hpp"
//------------------------------------------------------------------------------
void xgpp_conv::paa_to_pfcp_ue_ip_address(
......@@ -159,13 +161,23 @@ void xgpp_conv::sm_context_create_from_openapi(
"Convert SmContextMessage (OpenAPI) to "
"PDUSession_CreateSMContext");
oai::smf_server::model::SmContextCreateData context_data = scd.getJsonData();
oai::smf_server::model::SmContextCreateData context_data = {};
if (scd.jsonDataIsSet()) {
context_data = scd.getJsonData();
} else {
Logger::smf_app().warn("No Json data available");
}
if (scd.binaryDataN1SmMessageIsSet()) {
std::string n1_sm_msg = scd.getBinaryDataN1SmMessage();
// N1 SM Message
pcr.set_n1_sm_message(n1_sm_msg);
Logger::smf_app().debug("N1 SM message: %s", n1_sm_msg.c_str());
} else {
Logger::smf_app().warn("No N1 SM Message available");
}
if (context_data.supiIsSet()) {
// supi
supi_t supi = {.length = 0};
std::size_t pos = context_data.getSupi().find("-");
......@@ -177,24 +189,41 @@ void xgpp_conv::sm_context_create_from_openapi(
Logger::smf_app().debug(
"SUPI %s, SUPI Prefix %s, IMSI %s", context_data.getSupi().c_str(),
supi_prefix.c_str(), supi_str.c_str());
} else {
Logger::smf_app().warn("No SUPI available");
}
// dnn
// TODO: unauthenticatedSupi
// DNN
if (context_data.dnnIsSet()) {
Logger::smf_app().debug("DNN %s", context_data.getDnn().c_str());
pcr.set_dnn(context_data.getDnn().c_str());
} else {
Logger::smf_app().warn("No DNN available");
}
// S-Nssai
if (context_data.sNssaiIsSet()) {
Logger::smf_app().debug(
"S-NSSAI SST %d, SD %s", context_data.getSNssai().getSst(),
context_data.getSNssai().getSd().c_str());
snssai_t snssai(
context_data.getSNssai().getSst(), context_data.getSNssai().getSd());
pcr.set_snssai(snssai);
} else {
Logger::smf_app().warn("No SNSSAI available");
}
// PDU session ID
Logger::smf_app().debug("PDU Session ID %d", context_data.getPduSessionId());
if (context_data.pduSessionIdIsSet()) {
Logger::smf_app().debug(
"PDU Session ID %d", context_data.getPduSessionId());
pcr.set_pdu_session_id(context_data.getPduSessionId());
} else {
Logger::smf_app().warn("No PDU Session ID available");
}
// AMF ID (ServingNFId)
// AMF ID (ServingNFId/NfInstanceId)
Logger::smf_app().debug(
"ServingNfId %s", context_data.getServingNfId().c_str());
pcr.set_serving_nf_id(context_data.getServingNfId()
......@@ -202,9 +231,59 @@ void xgpp_conv::sm_context_create_from_openapi(
// is stored in GUAMI or ServingNfId
// Request Type
if (context_data.requestTypeIsSet()) {
Logger::smf_app().debug(
"RequestType %s", context_data.getRequestType().c_str());
pcr.set_request_type(context_data.getRequestType());
} else {
Logger::smf_app().warn("No Request Type available");
}
// SMContextStatusUri
pcr.set_sm_context_status_uri(context_data.getSmContextStatusUri());
Logger::smf_app().debug(
"SMContextStatusUri %s", context_data.getSmContextStatusUri().c_str());
// DNN Selection Mode
if (context_data.selModeIsSet()) {
Logger::smf_app().debug("SelMode %s", context_data.getSelMode().c_str());
pcr.set_dnn_selection_mode(context_data.getSelMode());
} else {
Logger::smf_app().warn("No SelMode available");
}
// ServingNetwork (PlmnId)
Logger::smf_app().debug(
"Serving Network (MCC %s, MNC %s)",
context_data.getServingNetwork().getMcc().c_str(),
context_data.getServingNetwork().getMnc().c_str());
plmn_t p = {};
if (conv::plmnFromString(
p, context_data.getServingNetwork().getMcc(),
context_data.getServingNetwork().getMnc())) {
pcr.set_plmn(p);
} else {
Logger::smf_app().warn("Error while converting MCC, MNC to PLMN");
}
// anType (AccessType)
Logger::smf_app().debug("AN Type %s", context_data.getAnType().c_str());
pcr.set_an_type(context_data.getAnType());
// Guami
if (context_data.guamiIsSet()) {
// Logger::smf_app().debug("GUAMI %s", context_data.getGuami().c_str());
guami_5g_t guami = {};
guami.amf_id = context_data.getGuami().getAmfId();
if (!conv::plmnFromString(
guami.plmn, context_data.getGuami().getPlmnId().getMcc(),
context_data.getGuami().getPlmnId().getMnc())) {
Logger::smf_app().warn("Error while converting MCC, MNC to PLMN");
}
pcr.set_guami(guami);
}
// TODO:
// PCF ID
// Priority Access
// User Location Information
......@@ -212,28 +291,8 @@ void xgpp_conv::sm_context_create_from_openapi(
// PEI
// GPSI
// UE presence in LADN service area
// Guami
// servingNetwork
// anType
// UETimeZone
// SMContextStatusUri
pcr.set_sm_context_status_uri(context_data.getSmContextStatusUri());
// PCFId
// DNN Selection Mode
Logger::smf_app().debug("SelMode %s", context_data.getSelMode().c_str());
pcr.set_dnn_selection_mode(context_data.getSelMode().c_str());
// Subscription for PDU Session Status Notification
// Trace requirement
// SSC mode (Optional)
// 5GSM capability (Optional)
// Maximum number of supported (Optional)
// Maximum number of supported packet filters (Optional)
// Always-on PDU session requested (Optional)
// SM PDU DN request container (Optional)
// Extended protocol configuration options (Optional) e.g, FOR DHCP
}
//------------------------------------------------------------------------------
......@@ -464,7 +523,8 @@ void xgpp_conv::create_sm_context_response_from_ct_request(
ctx_response->res.set_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK);
ctx_response->res.set_supi(ctx_request->req.get_supi());
ctx_response->res.set_supi_prefix(ctx_request->req.get_supi_prefix());
ctx_response->res.set_cause(REQUEST_ACCEPTED);
ctx_response->res.set_cause(
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
ctx_response->res.set_pdu_session_id(ctx_request->req.get_pdu_session_id());
ctx_response->res.set_snssai(ctx_request->req.get_snssai());
ctx_response->res.set_dnn(ctx_request->req.get_dnn());
......@@ -478,18 +538,13 @@ void xgpp_conv::create_sm_context_response_from_ct_request(
void xgpp_conv::update_sm_context_response_from_ct_request(
const std::shared_ptr<itti_n11_update_sm_context_request>& ct_request,
std::shared_ptr<itti_n11_update_sm_context_response>& ct_response) {
ct_response->res.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK); // default status code
ct_response->res.set_supi(ct_request->req.get_supi());
ct_response->res.set_supi_prefix(
ct_request->req.get_supi_prefix());
ct_response->res.set_cause(REQUEST_ACCEPTED);
ct_response->res.set_pdu_session_id(
ct_request->req.get_pdu_session_id());
ct_response->res.set_supi_prefix(ct_request->req.get_supi_prefix());
ct_response->res.set_cause(
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
ct_response->res.set_pdu_session_id(ct_request->req.get_pdu_session_id());
ct_response->res.set_snssai(ct_request->req.get_snssai());
ct_response->res.set_dnn(ct_request->req.get_dnn());
}
......@@ -117,6 +117,40 @@ std::string conv::mncToString(
return s;
}
bool conv::plmnFromString(
plmn_t& p, const std::string mcc, const std::string mnc) {
// MCC
if (isdigit(mcc[0]))
p.mcc_digit1 = mcc[0] - '0';
else
return false;
if (isdigit(mcc[1]))
p.mcc_digit2 = mcc[1] - '0';
else
return false;
if (isdigit(mcc[2]))
p.mcc_digit3 = mcc[2] - '0';
else
return false;
// MNC
if (isdigit(mnc[0]))
p.mnc_digit1 = mnc[0] - '0';
else
return false;
if (isdigit(mnc[1]))
p.mnc_digit2 = mnc[1] - '0';
else
return false;
if (mnc.length() > 2) {
if (isdigit(mnc[2]))
p.mnc_digit3 = mnc[2] - '0';
else
return false;
}
return true;
}
//------------------------------------------------------------------------------
struct in_addr conv::fromString(const std::string addr4) {
unsigned char buf[sizeof(struct in6_addr)] = {};
......
......@@ -269,6 +269,7 @@
pLMN.mnc_digit2 * 10 + pLMN.mnc_digit1; \
} while (0)
/*
* TS 36.413 v10.9.0 section 9.2.1.37:
* Macro eNB ID:
......
......@@ -32,6 +32,8 @@
#include <string>
#include <netinet/in.h>
#include "3gpp_23.003.h"
/* Used to format an uint32_t containing an ipv4 address */
#define IN_ADDR_FMT "%u.%u.%u.%u"
#define PRI_IN_ADDR(aDDRESS) \
......@@ -53,6 +55,7 @@ class conv {
static void hexa_to_ascii(uint8_t* from, char* to, size_t length);
static int ascii_to_hex(uint8_t* dst, const char* h);
static struct in_addr fromString(const std::string addr4);
static bool plmnFromString(plmn_t& p, const std::string mcc, const std::string mnc);
static std::string toString(const struct in_addr& inaddr);
static std::string toString(const struct in6_addr& in6addr);
static std::string mccToString(
......
......@@ -343,12 +343,16 @@ smf_app::smf_app(const std::string& config_file)
start_upf_association(*it);
}
// Register to NRF
register_to_nrf();
// Trigger NFStatusNotify
// Register to NRF (if this option is enabled)
if (smf_cfg.register_nrf) register_to_nrf();
if (smf_cfg.discover_upf) {
// Trigger NFStatusNotify subscription to be noticed when a new UPF becomes
// available (if this option is enabled)
unsigned int microsecond = 10000; // 10ms
usleep(microsecond);
trigger_upf_status_notification_subscribe();
}
Logger::smf_app().startup("Started");
}
......@@ -478,7 +482,7 @@ void smf_app::handle_itti_msg(
"Got successful response from AMF (response code %d), set session "
"status to %s",
m.response_code,
pdu_session_status_e2str[static_cast<int>(status)].c_str());
pdu_session_status_e2str.at(static_cast<int>(status)).c_str());
} else {
// TODO:
Logger::smf_app().debug(
......@@ -537,7 +541,8 @@ void smf_app::handle_itti_msg(
void smf_app::handle_itti_msg(itti_n11_update_pdu_session_status& m) {
Logger::smf_app().info(
"Set PDU Session Status to %s",
pdu_session_status_e2str[static_cast<int>(m.pdu_session_status)].c_str());
pdu_session_status_e2str.at(static_cast<int>(m.pdu_session_status))
.c_str());
update_pdu_session_status(m.scid, m.pdu_session_status);
}
......@@ -631,8 +636,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
PDU_SESSION_TYPE_E_IPV4};
// Step 1. Decode NAS and get the necessary information
// std::string n1_sm_msg = smreq->req.get_n1_sm_message();
int decoder_rc = smf_n1::get_instance().decode_n1_sm_container(
decoded_nas_msg, smreq->req.get_n1_sm_message());
......@@ -1419,7 +1422,7 @@ void smf_app::update_pdu_session_status(
sp.get()->set_pdu_session_status(status);
Logger::smf_app().info(
"Set PDU Session Status to %s",
pdu_session_status_e2str[static_cast<int>(status)].c_str());
pdu_session_status_e2str.at(static_cast<int>(status)).c_str());
}
//---------------------------------------------------------------------------------------------
......@@ -1474,7 +1477,7 @@ void smf_app::update_pdu_session_upCnx_state(
sp.get()->set_upCnx_state(state);
Logger::smf_app().info(
"Set PDU Session UpCnxState to %s",
upCnx_state_e2str[static_cast<int>(state)].c_str());
upCnx_state_e2str.at(static_cast<int>(state)).c_str());
}
//---------------------------------------------------------------------------------------------
void smf_app::timer_t3591_timeout(timer_id_t timer_id, uint64_t arg2_user) {
......@@ -1527,7 +1530,7 @@ n2_sm_info_type_e smf_app::n2_sm_info_type_str2e(
const std::string& n2_info_type) const {
std::size_t number_of_types = n2_sm_info_type_e2str.size();
for (auto i = 0; i < number_of_types; ++i) {
if (n2_info_type.compare(n2_sm_info_type_e2str[i]) == 0) {
if (n2_info_type.compare(n2_sm_info_type_e2str.at(i)) == 0) {
return static_cast<n2_sm_info_type_e>(i);
}
}
......@@ -1645,7 +1648,7 @@ void smf_app::trigger_create_context_error_response(
oai::smf_server::model::ProblemDetails problem_details = {};
oai::smf_server::model::RefToBinaryData refToBinaryData = {};
Logger::smf_app().warn("Create SmContextCreateError");
problem_details.setCause(pdu_session_application_error_e2str[cause]);
problem_details.setCause(pdu_session_application_error_e2str.at(cause));
sm_context.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
sm_context.setN1SmMsg(refToBinaryData);
......@@ -1677,7 +1680,7 @@ void smf_app::trigger_update_context_error_response(
oai::smf_server::model::SmContextUpdateError smContextUpdateError = {};
oai::smf_server::model::ProblemDetails problem_details = {};
problem_details.setCause(pdu_session_application_error_e2str[cause]);
problem_details.setCause(pdu_session_application_error_e2str.at(cause));
smContextUpdateError.setError(problem_details);
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
......@@ -1707,7 +1710,7 @@ void smf_app::trigger_update_context_error_response(
oai::smf_server::model::SmContextUpdateError smContextUpdateError = {};
oai::smf_server::model::ProblemDetails problem_details = {};
problem_details.setCause(pdu_session_application_error_e2str[cause]);
problem_details.setCause(pdu_session_application_error_e2str.at(cause));
smContextUpdateError.setError(problem_details);
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
......@@ -1834,6 +1837,7 @@ void smf_app::get_ee_subscriptions(
//---------------------------------------------------------------------------------------------
void smf_app::generate_smf_profile() {
// TODO: remove hardcoded values
// generate UUID
generate_uuid();
nf_instance_profile.set_nf_instance_id(smf_instance_id);
......@@ -1859,9 +1863,7 @@ void smf_app::generate_smf_profile() {
ip_endpoint_t endpoint = {};
std::vector<struct in_addr> addrs;
nf_instance_profile.get_nf_ipv4_addresses(addrs);
for (auto a : addrs) {
endpoint.ipv4_addresses.push_back(a);
}
endpoint.ipv4_address = addrs[0]; // TODO: use first IP ADDR for now
endpoint.transport = "TCP";
endpoint.port = smf_cfg.sbi.port;
nf_service.ip_endpoints.push_back(endpoint);
......@@ -1908,9 +1910,9 @@ void smf_app::generate_smf_profile() {
//---------------------------------------------------------------------------------------------
void smf_app::register_to_nrf() {
// create a NF profile to this instance
// Create a NF profile to this instance
generate_smf_profile();
// send request to N11 to send NF registration to NRF
// Send request to N11 to send NF registration to NRF
trigger_nf_registration_request();
}
......
......@@ -88,6 +88,7 @@ class smf_context_ref {
dnn = "";
pdu_session_id = 0;
amf_status_uri = "";
amf_addr = "";
}
supi_t supi;
......@@ -95,6 +96,7 @@ class smf_context_ref {
pdu_session_id_t pdu_session_id;
snssai_t nssai;
std::string amf_status_uri;
std::string amf_addr;
};
class smf_app {
......
......@@ -542,13 +542,49 @@ int smf_config::load(const string& config_file) {
astring.c_str());
}
smf_cfg.lookupValue(SMF_CONFIG_STRING_NAS_FORCE_PUSH_PCO, astring);
if (boost::iequals(astring, "yes")) {
smf_cfg.lookupValue(SMF_CONFIG_STRING_UE_MTU, ue_mtu);
// Support features
try {
const Setting& support_features =
smf_cfg[SMF_CONFIG_STRING_SUPPORT_FEATURES];
string opt;
support_features.lookupValue(
SMF_CONFIG_STRING_SUPPORT_FEATURES_REGISTER_NRF, opt);
if (boost::iequals(opt, "yes")) {
register_nrf = true;
} else {
register_nrf = false;
}
support_features.lookupValue(
SMF_CONFIG_STRING_SUPPORT_FEATURES_DISCOVER_UPF, opt);
if (boost::iequals(opt, "yes")) {
discover_upf = true;
} else {
discover_upf = false;
}
support_features.lookupValue(
SMF_CONFIG_STRING_SUPPORT_FEATURES_USE_LOCAL_SUBSCRIPTION_INFO, opt);
if (boost::iequals(opt, "yes")) {
use_local_subscription_info = true;
} else {
use_local_subscription_info = false;
}
support_features.lookupValue(SMF_CONFIG_STRING_NAS_FORCE_PUSH_PCO, opt);
if (boost::iequals(opt, "yes")) {
force_push_pco = true;
} else {
force_push_pco = false;
}
smf_cfg.lookupValue(SMF_CONFIG_STRING_UE_MTU, ue_mtu);
} catch (const SettingNotFoundException& nfex) {
Logger::smf_app().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
return -1;
}
// AMF
const Setting& amf_cfg = smf_cfg[SMF_CONFIG_STRING_AMF];
......@@ -859,6 +895,7 @@ void smf_config::display() {
Logger::smf_app().info(
" API version .........: %s", amf_addr.api_version.c_str());
if (!use_local_subscription_info) {
Logger::smf_app().info("- UDM:");
Logger::smf_app().info(
" IPv4 Addr ...........: %s",
......@@ -866,7 +903,9 @@ void smf_config::display() {
Logger::smf_app().info(" Port ................: %lu ", udm_addr.port);
Logger::smf_app().info(
" API version .........: %s", udm_addr.api_version.c_str());
}
if (register_nrf) {
Logger::smf_app().info("- NRF:");
Logger::smf_app().info(
" IPv4 Addr ...........: %s",
......@@ -874,10 +913,18 @@ void smf_config::display() {
Logger::smf_app().info(" Port ................: %lu ", nrf_addr.port);
Logger::smf_app().info(
" API version .........: %s", nrf_addr.api_version.c_str());
}
Logger::smf_app().info("- Helpers:");
Logger::smf_app().info("- Supported Features:");
Logger::smf_app().info(
" Register to NRF............: %s", register_nrf ? "Yes" : "No");
Logger::smf_app().info(
" Discover UPF...............: %s", discover_upf ? "Yes" : "No");
Logger::smf_app().info(
" Use Local Subscription Info: %s",
use_local_subscription_info ? "Yes" : "No");
Logger::smf_app().info(
" Push PCO (DNS+MTU) ..: %s", force_push_pco == 0 ? "false" : "true");
" Push PCO (DNS+MTU).........: %s", force_push_pco ? "Yes" : "No");
if (local_configuration) {
Logger::smf_app().info(
......
......@@ -55,9 +55,6 @@
#define SMF_CONFIG_STRING_SBI_HTTP2_PORT "HTTP2_PORT"
#define SMF_CONFIG_STRING_API_VERSION "API_VERSION"
#define SMF_CONFIG_STRING_NAS_FORCE_PUSH_PCO \
"FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS"
#define SMF_CONFIG_STRING_IP_ADDRESS_POOL "IP_ADDRESS_POOL"
#define SMF_CONFIG_STRING_ARP_UE "ARP_UE"
#define SMF_CONFIG_STRING_ARP_UE_CHOICE_NO "NO"
......@@ -135,6 +132,14 @@
#define SMF_CONFIG_STRING_SESSION_AMBR_UL "SESSION_AMBR_UL"
#define SMF_CONFIG_STRING_SESSION_AMBR_DL "SESSION_AMBR_DL"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES "SUPPORT_FEATURES"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_REGISTER_NRF "REGISTER_NRF"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_DISCOVER_UPF "DISCOVER_UPF"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_USE_LOCAL_SUBSCRIPTION_INFO \
"USE_LOCAL_SUBSCRIPTION_INFO"
#define SMF_CONFIG_STRING_NAS_FORCE_PUSH_PCO \
"FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS"
#define SMF_MAX_ALLOCATED_PDN_ADDRESSES 1024
namespace smf {
......@@ -211,6 +216,10 @@ class smf_config {
bool force_push_pco;
uint ue_mtu;
bool register_nrf;
bool discover_upf;
bool use_local_subscription_info;
struct {
struct in_addr ipv4_addr;
unsigned int port;
......
This diff is collapsed.
......@@ -390,6 +390,21 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
*/
pdu_session_type_t get_pdu_session_type() const;
/*
* Set AMF Addr of the serving AMF
* @param [const std::string&] addr: AMF Addr in string representation
* @return void
*/
void set_amf_addr(const std::string& addr);
/*
* Get AMF Addr of the serving AMF (in string representation)
* @param [const std::string&] addr: store AMF IP Addr
* @return void
*/
void get_amf_addr(std::string& addr) const;
std::string get_amf_addr() const;
bool ipv4; // IP Address(es): IPv4 address and/or IPv6 prefix
bool ipv6; // IP Address(es): IPv4 address and/or IPv6 prefix
struct in_addr
......@@ -412,6 +427,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
uint32_t pdu_session_id;
std::string amf_id;
std::string amf_addr;
pdu_session_status_e pdu_session_status;
upCnx_state_e
upCnx_state; // N3 tunnel status (ACTIVATED, DEACTIVATED, ACTIVATING)
......@@ -549,16 +565,27 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
scid(0),
event_sub(smf_event::get_instance()) {
supi_prefix = {};
// subscribe to sm context status change
// Subscribe to sm context status change
sm_context_status_connection =
event_sub.subscribe_sm_context_status(boost::bind(
&smf_context::handle_sm_context_status_change, this, _1, _1, _1));
// subscribe to pdu session release (event exposure)
&smf_context::handle_sm_context_status_change, this, _1, _2, _3));
// Subscribe to pdu session release (event exposure)
ee_pdu_session_release_connection =
event_sub.subscribe_ee_pdu_session_release(boost::bind(
&smf_context::handle_ee_pdu_session_release, this, _1, _1, _1));
&smf_context::handle_ee_pdu_session_release, this, _1, _2, _3));
}
smf_context(smf_context& b) = delete;
virtual ~smf_context() {
Logger::smf_app().debug("Delete SMF Context instance...");
// Disconnect the boost connection
if (sm_context_status_connection.connected())
sm_context_status_connection.disconnect();
if (ee_pdu_session_release_connection.connected())
ee_pdu_session_release_connection.disconnect();
}
/*
* Insert a procedure to be processed
* @param [std::shared_ptr<smf_procedure> &] sproc: procedure to be processed
......@@ -977,7 +1004,7 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
* @return void
*/
void handle_sm_context_status_change(
scid_t scid, uint8_t status, uint8_t http_version);
scid_t scid, const std::string& status, uint8_t http_version);
/*
* Handle SM Context Status Change (Send notification AMF)
......@@ -1003,6 +1030,20 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
smf::pdu_session_update_sm_context_response& res,
const nas_message_t& nas_msg);
/*
* Set AMF Addr of the serving AMF
* @param [const std::string&] addr: AMF Addr in string representation
* @return void
*/
void set_amf_addr(const std::string& addr);
/*
* Get AMF Addr of the serving AMF (in string representation)
* @param [const std::string&] addr: store AMF IP Addr
* @return void
*/
void get_amf_addr(std::string& addr) const;
private:
std::vector<std::shared_ptr<dnn_context>> dnns;
std::vector<std::shared_ptr<smf_procedure>> pending_procedures;
......@@ -1012,10 +1053,16 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
supi_t supi;
std::string supi_prefix;
scid_t scid; // SM Context ID
// AMF IP addr
string amf_addr;
// Big recursive lock
mutable std::recursive_mutex m_context;
// for Event Handling
smf_event& event_sub;
bs2::connection sm_context_status_connection;
bs2::connection ee_pdu_session_release_connection;
};
} // namespace smf
......
......@@ -31,6 +31,7 @@
#define FILE_SMF_EVENT_SIG_HPP_SEEN
#include <boost/signals2.hpp>
#include <string>
#include "3gpp_24.007.h"
namespace bs2 = boost::signals2;
......@@ -40,7 +41,7 @@ namespace smf {
// Signal for PDU session status
// SCID, PDU Session Status, HTTP version
typedef bs2::signal_type<
void(scid_t, uint8_t, uint8_t),
void(scid_t, const std::string&, uint8_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type sm_context_status_sig_t;
// Signal for Event exposure
......
......@@ -352,6 +352,38 @@ void pdu_session_create_sm_context_request::get_epco(
p = m_epco;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_plmn(const plmn_t p) {
m_serving_network = p;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::get_plmn(plmn_t& p) const {
p = m_serving_network;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_an_type(
const std::string& an_type) {
m_an_type = an_type;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::get_an_type(
std::string& an_type) const {
an_type = m_an_type;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_guami(const guami_5g_t& guami) {
m_guami = guami;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::get_guami(guami_5g_t& guami) const {
guami = m_guami;
}
/*
* class: PDU Session Create SM Context Response
*/
......
......@@ -30,13 +30,13 @@
#define FILE_SMF_MSG_HPP_SEEN
#include "smf.h"
#include "3gpp_23.003.h"
#include "3gpp_24.007.h"
#include "3gpp_24.501.h"
#include "3gpp_29.244.h"
#include "3gpp_29.274.h"
#include "3gpp_29.508.h"
#include "3gpp_29.571.h"
#include "Guami.h"
#include "NgRanTargetId.h"
#include "pistache/http.h"
#include "smf_profile.hpp"
......@@ -268,6 +268,12 @@ class pdu_session_create_sm_context_request
std::string get_sm_context_status_uri() const;
void set_epco(const protocol_configuration_options_t& p);
void get_epco(protocol_configuration_options_t& p) const;
void set_plmn(const plmn_t p);
void get_plmn(plmn_t& p) const;
void set_an_type(const std::string& an_type);
void get_an_type(std::string& an_type) const;
void set_guami(const guami_5g_t& guami);
void get_guami(guami_5g_t& guami) const;
private:
bool m_unauthenticated_supi;
......@@ -279,6 +285,8 @@ class pdu_session_create_sm_context_request
std::string m_dnn_selection_mode; // SelMode
std::string m_sm_context_status_uri;
protocol_configuration_options_t m_epco;
plmn_t m_serving_network;
guami_5g_t m_guami;
};
//---------------------------------------------------------------------------------------
......
......@@ -160,8 +160,8 @@ bool smf_n1::create_n1_pdu_session_establishment_accept(
// PDUAddress
paa_t paa = sm_context_res.get_paa();
sm_msg->pdu_session_establishment_accept.pduaddress
.pdu_address_information = bfromcstralloc(4, "\0");
sm_msg->pdu_session_establishment_accept.pduaddress.pdu_address_information =
bfromcstralloc(4, "\0");
util::ipv4_to_bstring(
paa.ipv4_address, sm_msg->pdu_session_establishment_accept.pduaddress
.pdu_address_information);
......@@ -228,7 +228,8 @@ bool smf_n1::create_n1_pdu_session_establishment_accept(
.extendedprotocolconfigurationoptions);
// DNN
sm_msg->pdu_session_establishment_accept.dnn = bfromcstralloc(sm_context_res.get_dnn().length(), "\0");
sm_msg->pdu_session_establishment_accept.dnn =
bfromcstralloc(sm_context_res.get_dnn().length(), "\0");
util::string_to_bstring(
sm_context_res.get_dnn(), sm_msg->pdu_session_establishment_accept.dnn);
Logger::smf_n1().debug("DNN %s", sm_context_res.get_dnn().c_str());
......
......@@ -252,7 +252,8 @@ void smf_n11::send_n1n2_message_transfer_request(
itti_msg->set_procedure_type(session_management_procedures_type_e::
PDU_SESSION_ESTABLISHMENT_UE_REQUESTED);
itti_msg->set_cause(response_data["cause"]);
if (sm_context_res->res.get_cause() == REQUEST_ACCEPTED) {
if (sm_context_res->res.get_cause() ==
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)) {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_ACCEPT);
} else {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_REJECT);
......@@ -794,8 +795,8 @@ void smf_n11::update_nf_instance(
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers =
curl_slist_append(headers, "content-type: application/json-patch+json");
headers = curl_slist_append(
headers, "content-type: application/json"); // TODO: json-patch+json
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
......
......@@ -49,6 +49,7 @@
#include "smf_n2.hpp"
#include "smf_pfcp_association.hpp"
#include "ProblemDetails.h"
#include "3gpp_24.501.h"
using namespace pfcp;
using namespace smf;
......@@ -303,7 +304,8 @@ void session_create_sm_context_procedure::handle_itti_msg(
resp.pfcp_ies.get(cause);
if (cause.cause_value == pfcp::CAUSE_VALUE_REQUEST_ACCEPTED) {
resp.pfcp_ies.get(sps->up_fseid);
n11_triggered_pending->res.set_cause(REQUEST_ACCEPTED);
n11_triggered_pending->res.set_cause(
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
}
for (auto it : resp.pfcp_ies.created_pdrs) {
......@@ -333,12 +335,15 @@ void session_create_sm_context_procedure::handle_itti_msg(
qos_flow_context_updated flow_updated = {};
QOSRulesIE qos_rule = {};
flow_updated.set_cause(REQUEST_ACCEPTED);
flow_updated.set_cause(
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
if (not sps->get_default_qos_flow(default_qos_flow)) {
flow_updated.set_cause(SYSTEM_FAILURE);
flow_updated.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_31_REQUEST_REJECTED_UNSPECIFIED));
} else {
if (default_qos_flow.ul_fteid.is_zero()) {
flow_updated.set_cause(SYSTEM_FAILURE);
flow_updated.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_31_REQUEST_REJECTED_UNSPECIFIED));
} else {
flow_updated.set_ul_fteid(default_qos_flow.ul_fteid); // tunnel info
}
......@@ -363,7 +368,8 @@ void session_create_sm_context_procedure::handle_itti_msg(
std::string n2_sm_info, n2_sm_info_hex;
if (n11_triggered_pending->res.get_cause() !=
REQUEST_ACCEPTED) { // PDU Session Establishment Reject
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)) {
// PDU Session Establishment Reject
Logger::smf_app().debug(
"Prepare a PDU Session Establishment Reject message and send to UE");
cause_n1 = cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE;
......@@ -413,8 +419,10 @@ void session_create_sm_context_procedure::handle_itti_msg(
std::string supi_str = n11_triggered_pending->res.get_supi_prefix() + "-" +
smf_supi_to_string(supi);
std::string url =
std::string(inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
":" + std::to_string(smf_cfg.amf_addr.port) + NAMF_COMMUNICATION_BASE +
// std::string(inet_ntoa(*((struct in_addr*)
// &smf_cfg.amf_addr.ipv4_addr))) +
//":" + std::to_string(smf_cfg.amf_addr.port) + NAMF_COMMUNICATION_BASE +
sps.get()->get_amf_addr() + NAMF_COMMUNICATION_BASE +
smf_cfg.amf_addr.api_version +
fmt::format(
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL, supi_str.c_str());
......@@ -429,7 +437,8 @@ void session_create_sm_context_procedure::handle_itti_msg(
json_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID; // NAS part
// N2SM
if (n11_triggered_pending->res.get_cause() == REQUEST_ACCEPTED) {
if (n11_triggered_pending->res.get_cause() ==
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)) {
json_data["n2InfoContainer"]["n2InformationClass"] = N1N2_MESSAGE_CLASS;
json_data["n2InfoContainer"]["smInfo"]["pduSessionId"] =
n11_triggered_pending->res.get_pdu_session_id();
......@@ -446,9 +455,10 @@ void session_create_sm_context_procedure::handle_itti_msg(
// N1N2MsgTxfrFailureNotification
std::string callback_uri =
std::string(
inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
":" + std::to_string(smf_cfg.amf_addr.port) + NSMF_PDU_SESSION_BASE +
// std::string(
// inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
//":" + std::to_string(smf_cfg.amf_addr.port) + NSMF_PDU_SESSION_BASE +
sps.get()->get_amf_addr() + NSMF_PDU_SESSION_BASE +
smf_cfg.sbi_api_version +
fmt::format(
NSMF_CALLBACK_N1N2_MESSAGE_TRANSFER_FAILURE, supi_str.c_str());
......@@ -520,8 +530,8 @@ int session_update_sm_context_procedure::run(
Logger::smf_app().debug(
"Session procedure type: %s",
session_management_procedures_type_e2str[static_cast<int>(
session_procedure_type)]
session_management_procedures_type_e2str
.at(static_cast<int>(session_procedure_type))
.c_str());
switch (session_procedure_type) {
......@@ -545,7 +555,8 @@ int session_update_sm_context_procedure::run(
"could not found any QoS flow with QFI %d", qfi.qfi);
// Set cause to SYSTEM_FAILURE and send response
qos_flow_context_updated qcu = {};
qcu.set_cause(SYSTEM_FAILURE);
qcu.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_31_REQUEST_REJECTED_UNSPECIFIED));
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
continue;
......@@ -561,7 +572,8 @@ int session_update_sm_context_procedure::run(
if ((dl_fteid == flow.dl_fteid) and (not flow.released)) {
Logger::smf_app().debug("QFI %d dl_fteid unchanged", qfi.qfi);
qos_flow_context_updated qcu = {};
qcu.set_cause(REQUEST_ACCEPTED);
qcu.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
continue;
......@@ -777,7 +789,8 @@ int session_update_sm_context_procedure::run(
sps->add_qos_flow(flow);
qos_flow_context_updated qcu = {};
qcu.set_cause(REQUEST_ACCEPTED);
qcu.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
}
......@@ -796,7 +809,8 @@ int session_update_sm_context_procedure::run(
qfi.qfi);
// Set cause to SYSTEM_FAILURE and send response
qos_flow_context_updated qcu = {};
qcu.set_cause(SYSTEM_FAILURE);
qcu.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_31_REQUEST_REJECTED_UNSPECIFIED));
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
continue;
......@@ -893,8 +907,8 @@ void session_update_sm_context_procedure::handle_itti_msg(
Logger::smf_app().debug(
"Session procedure type: %s",
session_management_procedures_type_e2str[static_cast<int>(
session_procedure_type)]
session_management_procedures_type_e2str
.at(static_cast<int>(session_procedure_type))
.c_str());
switch (session_procedure_type) {
......@@ -948,7 +962,8 @@ void session_update_sm_context_procedure::handle_itti_msg(
sps->add_qos_flow(flow);
qos_flow_context_updated qcu = {};
qcu.set_cause(REQUEST_ACCEPTED);
qcu.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
qcu.set_qfi(pfcp::qfi_t(it.first));
qcu.set_ul_fteid(flow.ul_fteid);
qcu.set_dl_fteid(flow.dl_fteid);
......@@ -979,7 +994,8 @@ void session_update_sm_context_procedure::handle_itti_msg(
sps->add_qos_flow(flow);
qos_flow_context_updated qcu = {};
qcu.set_cause(REQUEST_ACCEPTED);
qcu.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
qcu.set_qfi(pfcp::qfi_t(it.first));
qcu.set_ul_fteid(flow.ul_fteid);
qcu.set_dl_fteid(flow.dl_fteid);
......@@ -1310,9 +1326,8 @@ void session_release_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
} else {
oai::smf_server::model::ProblemDetails problem_details = {};
problem_details.setCause(
pdu_session_application_error_e2str
[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]);
problem_details.setCause(pdu_session_application_error_e2str.at(
PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE));
// trigger to send reply to AMF
/*
smf_app_inst->trigger_http_response(
......
......@@ -371,10 +371,7 @@ void smf_profile::to_json(nlohmann::json& data) const {
srv_tmp["ipEndPoints"] = nlohmann::json::array();
for (auto endpoint : service.ip_endpoints) {
nlohmann::json ep_tmp = {};
ep_tmp["ipv4Address"] = nlohmann::json::array();
for (auto address : endpoint.ipv4_addresses) {
ep_tmp["ipv4Address"].push_back(inet_ntoa(address));
}
ep_tmp["ipv4Address"] = inet_ntoa(endpoint.ipv4_address);
ep_tmp["transport"] = endpoint.transport;
ep_tmp["port"] = endpoint.port;
srv_tmp["ipEndPoints"].push_back(ep_tmp);
......
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