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
......@@ -79,10 +79,17 @@ SMF =
DEFAULT_DNS_SEC_IPV4_ADDRESS = "@DEFAULT_DNS_SEC_IPV4_ADDRESS@"; # YOUR DNS CONFIG HERE
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 :
{
IPV4_ADDRESS = "@AMF_IPV4_ADDRESS@"; # YOUR AMF CONFIG HERE
......
......@@ -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,42 +161,69 @@ void xgpp_conv::sm_context_create_from_openapi(
"Convert SmContextMessage (OpenAPI) to "
"PDUSession_CreateSMContext");
oai::smf_server::model::SmContextCreateData context_data = scd.getJsonData();
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());
// supi
supi_t supi = {.length = 0};
std::size_t pos = context_data.getSupi().find("-");
std::string supi_str = context_data.getSupi().substr(pos + 1);
std::string supi_prefix = context_data.getSupi().substr(0, pos);
smf_string_to_supi(&supi, supi_str.c_str());
pcr.set_supi(supi);
pcr.set_supi_prefix(supi_prefix);
Logger::smf_app().debug(
"SUPI %s, SUPI Prefix %s, IMSI %s", context_data.getSupi().c_str(),
supi_prefix.c_str(), supi_str.c_str());
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");
}
// dnn
Logger::smf_app().debug("DNN %s", context_data.getDnn().c_str());
pcr.set_dnn(context_data.getDnn().c_str());
if (context_data.supiIsSet()) {
// supi
supi_t supi = {.length = 0};
std::size_t pos = context_data.getSupi().find("-");
std::string supi_str = context_data.getSupi().substr(pos + 1);
std::string supi_prefix = context_data.getSupi().substr(0, pos);
smf_string_to_supi(&supi, supi_str.c_str());
pcr.set_supi(supi);
pcr.set_supi_prefix(supi_prefix);
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");
}
// 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
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);
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());
pcr.set_pdu_session_id(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(
"RequestType %s", context_data.getRequestType().c_str());
pcr.set_request_type(context_data.getRequestType());
"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_snssai(ct_request->req.get_snssai());
ct_response->res.set_dnn(ct_request->req.get_dnn());
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(
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
unsigned int microsecond = 10000; // 10ms
usleep(microsecond);
trigger_upf_status_notification_subscribe();
// 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,11 +1863,9 @@ 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.transport = "TCP";
endpoint.port = smf_cfg.sbi.port;
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);
nf_instance_profile.add_nf_service(nf_service);
......@@ -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,14 +542,50 @@ 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")) {
force_push_pco = true;
} else {
force_push_pco = false;
}
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;
}
} 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];
struct in_addr amf_ipv4_addr;
......@@ -859,25 +895,36 @@ void smf_config::display() {
Logger::smf_app().info(
" API version .........: %s", amf_addr.api_version.c_str());
Logger::smf_app().info("- UDM:");
Logger::smf_app().info(
" IPv4 Addr ...........: %s",
inet_ntoa(*((struct in_addr*) &udm_addr.ipv4_addr)));
Logger::smf_app().info(" Port ................: %lu ", udm_addr.port);
Logger::smf_app().info(
" API version .........: %s", udm_addr.api_version.c_str());
if (!use_local_subscription_info) {
Logger::smf_app().info("- UDM:");
Logger::smf_app().info(
" IPv4 Addr ...........: %s",
inet_ntoa(*((struct in_addr*) &udm_addr.ipv4_addr)));
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",
inet_ntoa(*((struct in_addr*) &nrf_addr.ipv4_addr)));
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("- NRF:");
Logger::smf_app().info("- Supported Features:");
Logger::smf_app().info(
" IPv4 Addr ...........: %s",
inet_ntoa(*((struct in_addr*) &nrf_addr.ipv4_addr)));
Logger::smf_app().info(" Port ................: %lu ", nrf_addr.port);
" Register to NRF............: %s", register_nrf ? "Yes" : "No");
Logger::smf_app().info(
" API version .........: %s", nrf_addr.api_version.c_str());
Logger::smf_app().info("- Helpers:");
" 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;
......
......@@ -30,6 +30,7 @@
#include "smf_context.hpp"
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include "3gpp_24.501.h"
#include "3gpp_29.500.h"
......@@ -47,6 +48,7 @@
#include "smf_pfcp_association.hpp"
#include "smf_procedure.hpp"
#include "3gpp_conversions.hpp"
#include "string.hpp"
extern "C" {
#include "Ngap_AssociatedQosFlowItem.h"
......@@ -409,7 +411,7 @@ void smf_pdu_session::set_pdu_session_status(
// TODO: Should consider congestion handling
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());
std::unique_lock lock(m_pdu_session_mutex);
pdu_session_status = status;
}
......@@ -424,7 +426,7 @@ pdu_session_status_e smf_pdu_session::get_pdu_session_status() const {
void smf_pdu_session::set_upCnx_state(const upCnx_state_e& state) {
Logger::smf_app().info(
"Set upCnxState to %s",
upCnx_state_e2str[static_cast<int>(state)].c_str());
upCnx_state_e2str.at(static_cast<int>(state)).c_str());
std::unique_lock lock(m_pdu_session_mutex);
upCnx_state = state;
}
......@@ -570,6 +572,21 @@ void smf_pdu_session::add_qos_rule(const QOSRulesIE& qos_rule) {
}
}
//------------------------------------------------------------------------------
void smf_pdu_session::set_amf_addr(const std::string& addr) {
amf_addr = addr;
}
//------------------------------------------------------------------------------
void smf_pdu_session::get_amf_addr(std::string& addr) const {
addr = amf_addr;
}
//------------------------------------------------------------------------------
std::string smf_pdu_session::get_amf_addr() const {
return amf_addr;
}
//------------------------------------------------------------------------------
void session_management_subscription::insert_dnn_configuration(
const std::string& dnn,
......@@ -757,10 +774,11 @@ void smf_context::handle_itti_msg(
get_supi_prefix(supi_prefix);
std::string supi_str = 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 + smf_cfg.amf_addr.api_version +
// std::string(inet_ntoa(
// *((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
//":" + std::to_string(smf_cfg.amf_addr.port) +
sp.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());
......@@ -1342,8 +1360,11 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (success) {
set_paa = true;
} else {
// TODO:
// cause: ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED; //check for 5G?
// ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED;
set_paa = false;
request_accepted = false;
sm_context_resp->res.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES));
}
// Static IP address allocation
} else if ((paa_res) && (paa.is_ip_assigned())) {
......@@ -1389,6 +1410,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
// sm_context_resp->res.set_cause(static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE));
request_accepted = false;
}
}
......@@ -1418,6 +1440,28 @@ void smf_context::handle_pdu_session_create_sm_context_request(
}
scf.get()->amf_status_uri = smreq->req.get_sm_context_status_uri();
// Get and Store AMF Addr if available
std::vector<std::string> split_result;
std::string amf_addr_str = {};
amf_addr_str = std::string(inet_ntoa(
*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
":" + std::to_string(smf_cfg.amf_addr.port);
boost::split(
split_result, scf.get()->amf_status_uri, boost::is_any_of("/"));
if (split_result.size() >= 3) {
std::string addr = split_result[2];
struct in_addr amf_ipv4_addr;
if (inet_aton(util::trim(addr).c_str(), &amf_ipv4_addr) == 0) {
Logger::smf_api_server().warn("Bad IPv4 for AMF");
} else {
amf_addr_str = addr;
Logger::smf_api_server().debug("AMF IP Addr %s", amf_addr_str.c_str());
}
}
scf.get()->amf_addr = amf_addr_str;
sp.get()->set_amf_addr(amf_addr_str);
// Trigger SMF APP to send response to SMF-HTTP-API-SERVER (Step
// 5, 4.3.2.2.1 TS 23.502)
Logger::smf_app().debug(
......@@ -1434,7 +1478,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
std::string smf_context_uri =
smreq->req.get_api_root() + "/" + smContextRef.c_str();
sm_context_response.set_smf_context_uri(smf_context_uri);
sm_context_response.set_cause(0); // TODO
sm_context_response.set_cause(static_cast<uint8_t>(
cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)); // TODO
nlohmann::json json_data = {};
json_data["cause"] = 0;
......@@ -1479,7 +1524,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// Step 10. if error when establishing the pdu session,
// send ITTI message to APP to trigger N1N2MessageTransfer towards AMFs (PDU
// Session Establishment Reject)
if (sm_context_resp->res.get_cause() != REQUEST_ACCEPTED) {
if (sm_context_resp->res.get_cause() !=
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)) {
// clear pco, ambr
// TODO:
// free paa
......@@ -1506,12 +1552,9 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// Create PDU Session Establishment Reject and embedded in
// Namf_Communication_N1N2MessageTransfer Request
Logger::smf_app().debug("Create PDU Session Establishment Reject");
// TODO: Should check Cause for other cases
cause_value_5gsm_e cause_n1 = {
cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE};
if (sm_context_resp->res.get_cause() == NO_RESOURCES_AVAILABLE) {
cause_n1 = cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES;
}
cause_value_5gsm_e cause_n1 =
static_cast<cause_value_5gsm_e>(sm_context_resp->res.get_cause());
smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
sm_context_resp_pending->res, n1_sm_message, cause_n1);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
......@@ -1523,9 +1566,11 @@ void smf_context::handle_pdu_session_create_sm_context_request(
supi_str = sm_context_resp_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
// +
sp.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());
......@@ -1882,21 +1927,21 @@ bool smf_context::handle_pdu_session_release_complete(
// TODO: return;
}
Logger::smf_app().debug("Signal the SM Context Status Change");
std::string status = "RELEASED";
event_sub.sm_context_status(
scid,
static_cast<uint32_t>(sm_context_status_e::SM_CONTEXT_STATUS_RELEASED),
sm_context_request.get()->http_version);
scid, status, sm_context_request.get()->http_version);
// Get SUPI
supi64_t supi64 = smf_supi_to_u64(sm_context_request.get()->req.get_supi());
// Trigger PDU Session Release event notification
supi64_t supi64 = smf_supi_to_u64(sm_context_request.get()->req.get_supi());
Logger::smf_app().debug("Signal the PDU Session Release Event notification");
event_sub.ee_pdu_session_release(
supi64, sm_context_request.get()->req.get_pdu_session_id(),
sm_context_request.get()->http_version);
// TODO: if dynamic PCC applied, SMF invokes an SM Policy Association
// Termination
// TODO: SMF unsubscribes from Session Management Subscription data
// TODO: SMF un-subscribes from Session Management Subscription data
// changes notification from UDM by invoking Numd_SDM_Unsubscribe
// TODO: should check if sd context exist
......@@ -1995,7 +2040,6 @@ bool smf_context::handle_pdu_session_resource_setup_response_transfer(
.array[i])
->qosFlowIdentifier);
}
return true;
}
//-------------------------------------------------------------------------------------
......@@ -2156,7 +2200,8 @@ bool smf_context::handle_service_request(
sm_context_request.get()->req.add_qfi(i.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(i.qfi);
qcu.set_ul_fteid(i.ul_fteid);
qcu.set_qos_profile(i.qos_profile);
......@@ -2511,8 +2556,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
Logger::smf_app().info(
"PDU Update SM Context Request procedure failed (session procedure "
"type %s)",
session_management_procedures_type_e2str[static_cast<int>(
procedure_type)]
session_management_procedures_type_e2str
.at(static_cast<int>(procedure_type))
.c_str());
remove_procedure(proc);
......@@ -2624,7 +2669,8 @@ void smf_context::handle_pdu_session_release_sm_context_request(
http_status_code_e::HTTP_STATUS_CODE_200_OK);
n11_sm_context_resp->res.set_supi(smreq->req.get_supi());
n11_sm_context_resp->res.set_supi_prefix(smreq->req.get_supi_prefix());
n11_sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
n11_sm_context_resp->res.set_cause(
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
n11_sm_context_resp->res.set_pdu_session_id(smreq->req.get_pdu_session_id());
n11_sm_context_resp->res.set_snssai(smreq->req.get_snssai());
n11_sm_context_resp->res.set_dnn(smreq->req.get_dnn());
......@@ -2719,8 +2765,10 @@ void smf_context::handle_pdu_session_modification_network_requested(
std::string supi_str =
itti_msg->msg.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 +
sp.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());
......@@ -2894,7 +2942,7 @@ bool smf_context::find_pdu_session(
//------------------------------------------------------------------------------
void smf_context::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) {
Logger::smf_app().debug(
"Send request to N11 to triger SM Context Status Notification to AMF, "
"SMF Context ID " SCID_FMT " ",
......@@ -2916,7 +2964,7 @@ void smf_context::handle_sm_context_status_change(
std::make_shared<itti_n11_notify_sm_context_status>(
TASK_SMF_APP, TASK_SMF_N11);
itti_msg->scid = scid;
itti_msg->sm_context_status = sm_context_status_e2str[status];
itti_msg->sm_context_status = status;
itti_msg->amf_status_uri = scf.get()->amf_status_uri;
itti_msg->http_version = http_version;
......@@ -2990,15 +3038,7 @@ void smf_context::update_qos_info(
QOSFlowDescriptionsContents qos_flow_description_content = {};
// Only one flow description for new requested QoS Flow
// QOSFlowDescriptionsContents* qos_flow_description =
// (QOSFlowDescriptionsContents*) calloc(
// number_of_flow_descriptions, sizeof(QOSFlowDescriptionsContents));
if (number_of_flow_descriptions > 0) {
// qos_flow_description =
// nas_msg.plain.sm.pdu_session_modification_request
// .qosflowdescriptions.qosflowdescriptionscontents;
for (int i = 0; i < number_of_flow_descriptions; i++) {
if (nas_msg.plain.sm.pdu_session_modification_request.qosflowdescriptions
.qosflowdescriptionscontents[i]
......@@ -3127,8 +3167,16 @@ void smf_context::update_qos_info(
// rule identifier
i++;
}
}
//------------------------------------------------------------------------------
void smf_context::set_amf_addr(const std::string& addr) {
amf_addr = addr;
}
// free_wrapper((void**) &qos_flow_description);
//------------------------------------------------------------------------------
void smf_context::get_amf_addr(std::string& addr) const {
addr = amf_addr;
}
//------------------------------------------------------------------------------
......
......@@ -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
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)
event_sub.subscribe_ee_pdu_session_release(boost::bind(
&smf_context::handle_ee_pdu_session_release, this, _1, _1, _1));
// 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, _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, _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,12 +371,9 @@ 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["transport"] = endpoint.transport;
ep_tmp["port"] = endpoint.port;
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);
}
......
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -33,6 +33,8 @@
#include <unistd.h>
#include <stdexcept>
#include <thread>
#include <sstream>
#include <iomanip>
#ifndef CURLPIPE_MULTIPLEX
#define CURLPIPE_MULTIPLEX 0
......@@ -43,30 +45,36 @@
#define HTTP_CODE_OK 200
#define HTTP_CODE_CREATED 201
#define MAX_NUMBER_SESSIONS 15
#define MAX_NUMBER_UES 999
/*
* To read content of the response from UDM
*/
static std::size_t callback(const char *in, std::size_t size, std::size_t num,
std::string *out) {
static std::size_t callback(
const char* in, std::size_t size, std::size_t num, std::string* out) {
const std::size_t totalBytes(size * num);
out->append(in, totalBytes);
return totalBytes;
}
#define ENCODE_U8(buffer, value, size) \
*(uint8_t*)(buffer) = value; \
size += sizeof(uint8_t)
#define ENCODE_U8(buffer, value, size) \
*(uint8_t*) (buffer) = value; \
size += sizeof(uint8_t)
static const char hex_to_ascii_table[16] = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', };
static const char hex_to_ascii_table[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
};
static const signed char ascii_to_hex_table[0x100] = { -1, -1, -1, -1, -1, -1,
static const signed char ascii_to_hex_table[0x100] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1,
10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
......@@ -74,78 +82,64 @@ static const signed char ascii_to_hex_table[0x100] = { -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1 };
-1, -1, -1, -1, -1, -1, -1, -1, -1};
int ascii_to_hex(uint8_t *dst, const char *h) {
const unsigned char *hex = (const unsigned char*) h;
unsigned i = 0;
int ascii_to_hex(uint8_t* dst, const char* h) {
const unsigned char* hex = (const unsigned char*) h;
unsigned i = 0;
for (;;) {
int high, low;
while (*hex && isspace(*hex))
hex++;
while (*hex && isspace(*hex)) hex++;
if (!*hex)
return 1;
if (!*hex) return 1;
high = ascii_to_hex_table[*hex++];
if (high < 0)
return 0;
if (high < 0) return 0;
while (*hex && isspace(*hex))
hex++;
while (*hex && isspace(*hex)) hex++;
if (!*hex)
return 0;
if (!*hex) return 0;
low = ascii_to_hex_table[*hex++];
if (low < 0)
return 0;
if (low < 0) return 0;
dst[i++] = (high << 4) | low;
}
}
enum class multipart_related_content_part_e {
JSON = 0,
NAS = 1,
NGAP = 2
};
enum class multipart_related_content_part_e { JSON = 0, NAS = 1, NGAP = 2 };
//------------------------------------------------------------------------------
unsigned char* format_string_as_hex(std::string str) {
unsigned int str_len = str.length();
char *data = (char*) malloc(str_len + 1);
char* data = (char*) malloc(str_len + 1);
memset(data, 0, str_len + 1);
memcpy((void*) data, (void*) str.c_str(), str_len);
unsigned char *data_hex = (uint8_t*) malloc(str_len / 2 + 1);
unsigned char* data_hex = (uint8_t*) malloc(str_len / 2 + 1);
ascii_to_hex(data_hex, (const char*) data);
std::cout << "[Format string as Hex] Input string" << str.c_str() << "("
<< str_len << " bytes)" << std::endl;
std::cout << "Data (formatted):" << std::endl;
for (int i = 0; i < str_len / 2; i++)
printf(" %02x ", data_hex[i]);
for (int i = 0; i < str_len / 2; i++) printf(" %02x ", data_hex[i]);
printf("\n");
//free memory
// free memory
free(data);
return data_hex;
}
//------------------------------------------------------------------------------
void create_multipart_related_content(std::string &body, std::string &json_part,
std::string &boundary,
std::string &n1_message,
std::string &n2_message) {
void create_multipart_related_content(
std::string& body, std::string& json_part, std::string& boundary,
std::string& n1_message, std::string& n2_message) {
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
......@@ -154,15 +148,15 @@ void create_multipart_related_content(std::string &body, std::string &json_part,
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF + "Content-Id: n1SmMsg"
+ CRLF);
"Content-Type: application/vnd.3gpp.5gnas" + CRLF +
"Content-Id: n1SmMsg" + CRLF);
body.append(CRLF);
body.append(n1_message + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg" +
CRLF);
body.append(CRLF);
body.append(n2_message + CRLF);
body.append("--" + boundary + "--" + CRLF);
......@@ -170,9 +164,8 @@ void create_multipart_related_content(std::string &body, std::string &json_part,
//------------------------------------------------------------------------------
void create_multipart_related_content(
std::string &body, std::string &json_part, std::string &boundary,
std::string &message, multipart_related_content_part_e content_type) {
std::string& body, std::string& json_part, std::string& boundary,
std::string& message, multipart_related_content_part_e content_type) {
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
......@@ -180,14 +173,14 @@ void create_multipart_related_content(
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
if (content_type == multipart_related_content_part_e::NAS) { //NAS
if (content_type == multipart_related_content_part_e::NAS) { // NAS
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF
+ "Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { //NGAP
"Content-Type: application/vnd.3gpp.5gnas" + CRLF +
"Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { // NGAP
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg" +
CRLF);
}
body.append(CRLF);
body.append(message + CRLF);
......@@ -195,31 +188,34 @@ void create_multipart_related_content(
}
//------------------------------------------------------------------------------
bool send_pdu_session_establishment_request(uint8_t pid,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
//TODO: return the created SM context Id
bool send_pdu_session_establishment_request(
std::string supi, uint8_t pid, std::string smf_ip_address,
uint8_t http_version, std::string port) {
// TODO: return the created SM context Id
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Create)"
<< std::endl;
// Response information.
long httpCode = { 0 };
long httpCode = {0};
nlohmann::json pdu_session_establishment_request;
//encode PDU Session Establishment Request
// encode PDU Session Establishment Request
/*
0000 2e 01 01 c1 ff ff 91 00 00 00 00 00 00 00 00 00
0000 2e 01 01 c1 ff ff 91 00 00 00 00 00 00 00 00 00
*/
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xc1, size); //MessageType - PDU_SESSION_ESTABLISHMENT_REQUEST
ENCODE_U8(buffer + size, 0xff, size); //Integrity Protection Maximum Data Rate
ENCODE_U8(buffer + size, 0xff, size); //Integrity Protection Maximum Data Rate
ENCODE_U8(buffer + size, 0x91, size); //01 PDU Session Type - Ipv4
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); // ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); // PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); // ProcedureTransactionIdentity
ENCODE_U8(
buffer + size, 0xc1,
size); // MessageType - PDU_SESSION_ESTABLISHMENT_REQUEST
ENCODE_U8(
buffer + size, 0xff, size); // Integrity Protection Maximum Data Rate
ENCODE_U8(
buffer + size, 0xff, size); // Integrity Protection Maximum Data Rate
ENCODE_U8(buffer + size, 0x91, size); // 01 PDU Session Type - Ipv4
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -235,57 +231,57 @@ bool send_pdu_session_establishment_request(uint8_t pid,
}
url.append(std::string("/nsmf-pdusession/v1/sm-contexts"));
//Fill the json part
pdu_session_establishment_request["supi"] = "imsi-200000000000001";
pdu_session_establishment_request["pei"] = "imei-200000000000001";
// Fill the json part
pdu_session_establishment_request["supi"] = supi; //"imsi-200000000000001"
pdu_session_establishment_request["pei"] = "imei-200000000000001";
pdu_session_establishment_request["gpsi"] = "msisdn-200000000001";
pdu_session_establishment_request["dnn"] = "default";
pdu_session_establishment_request["dnn"] = "default";
pdu_session_establishment_request["sNssai"]["sst"] = 222;
pdu_session_establishment_request["sNssai"]["sd"] = "0000D4";
pdu_session_establishment_request["pduSessionId"] = pid;
pdu_session_establishment_request["requestType"] = "INITIAL_REQUEST";
pdu_session_establishment_request["servingNfId"] = "servingNfId";
pdu_session_establishment_request["sNssai"]["sd"] = "0000D4";
pdu_session_establishment_request["pduSessionId"] = pid;
pdu_session_establishment_request["requestType"] = "INITIAL_REQUEST";
pdu_session_establishment_request["servingNfId"] = "servingNfId";
pdu_session_establishment_request["servingNetwork"]["mcc"] = "234";
pdu_session_establishment_request["servingNetwork"]["mnc"] = "067";
pdu_session_establishment_request["anType"] = "3GPP_ACCESS";
pdu_session_establishment_request["anType"] = "3GPP_ACCESS";
pdu_session_establishment_request["smContextStatusUri"] =
"smContextStatusUri";
pdu_session_establishment_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_establishment_request.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
create_multipart_related_content(
body, json_part, boundary, n1_msg, multipart_related_content_part_e::NAS);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -304,11 +300,11 @@ bool send_pdu_session_establishment_request(uint8_t pid,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
......@@ -335,29 +331,31 @@ bool send_pdu_session_update_sm_context_establishment(
<< std::endl;
// Response information.
long httpCode = { 0 };
long httpCode = {0};
nlohmann::json pdu_session_update_request;
//encode PDU Session Resource Setup Response Transfer IE
// encode PDU Session Resource Setup Response Transfer IE
/*
00 03 e0 ac 0a 05 01 00 00 00 01 00 06
00 03 e0 ac 0a 05 01 00 00 00 01 00 06
*/
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x00, size);
ENCODE_U8(buffer + size, 0x03, size);
ENCODE_U8(buffer + size, 0xe0, size);
ENCODE_U8(buffer + size, 0xac, size); //uPTransportLayerInformation IP Addr 172.16.3.103: 172.
ENCODE_U8(buffer + size, 0x10, size); //16
ENCODE_U8(
buffer + size, 0xac,
size); // uPTransportLayerInformation IP Addr 172.16.3.103: 172.
ENCODE_U8(buffer + size, 0x10, size); // 16
ENCODE_U8(buffer + size, 0x03, size); //.3
ENCODE_U8(buffer + size, 0x67, size); //.103
ENCODE_U8(buffer + size, 0x00, size); //gTP_TEID 00 00 00 01: 00
ENCODE_U8(buffer + size, 0x00, size); //00
ENCODE_U8(buffer + size, 0x00, size); //00
ENCODE_U8(buffer + size, 0x01, size); //01
ENCODE_U8(buffer + size, 0x00, size); //Associated QoS Flow 00 06
ENCODE_U8(buffer + size, 0x06, size); //QFI: 06
ENCODE_U8(buffer + size, 0x00, size); // gTP_TEID 00 00 00 01: 00
ENCODE_U8(buffer + size, 0x00, size); // 00
ENCODE_U8(buffer + size, 0x00, size); // 00
ENCODE_U8(buffer + size, 0x01, size); // 01
ENCODE_U8(buffer + size, 0x00, size); // Associated QoS Flow 00 06
ENCODE_U8(buffer + size, 0x06, size); // QFI: 06
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -368,58 +366,60 @@ bool send_pdu_session_update_sm_context_establishment(
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify"
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
// url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
//Fill the json part
pdu_session_update_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
// Fill the json part
pdu_session_update_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2msg"; // NGAP
//pdu_session_update_request["n2InfoContainer"]["n2InformationClass"] = "SM";
//pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2msg";
// pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
// pdu_session_update_request["n2InfoContainer"]["n2InformationClass"] = "SM";
// pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"]
// = "n2msg";
// pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"]
// =
// "PDU_RES_SETUP_RSP"; //NGAP message
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_update_request.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
create_multipart_related_content(
body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -438,20 +438,20 @@ bool send_pdu_session_update_sm_context_establishment(
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
//Set the default Cause
// Set the default Cause
response_data["cause"] = "504 Gateway Timeout";
}
std::cout
<< "[AMF N11] PDU Session Establishment Request, response from SMF, Http Code "
<< httpCode << " cause " << response_data["cause"].dump().c_str()
<< std::endl;
std::cout << "[AMF N11] PDU Session Establishment Request (Update SM "
"Context), response from "
"SMF, Http Code "
<< httpCode << " cause " << response_data["cause"].dump().c_str()
<< std::endl;
curl_easy_cleanup(curl);
}
......@@ -464,58 +464,56 @@ bool send_pdu_session_update_sm_context_establishment(
} else {
return false;
}
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step1(uint8_t pid,
uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Modification Request (SM Context Update, Step 1)"
<< std::endl;
void send_pdu_session_modification_request_step1(
uint8_t pid, uint8_t context_id, std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Modification Request (SM Context Update, "
"Step 1)"
<< std::endl;
nlohmann::json pdu_session_modification_request;
//encode PDU Session Modification Request
// encode PDU Session Modification Request
/*
0000 2e 01 01 d1 00 00 00 00 00 00 00 00 00 00 00 00
0000 2e 01 01 d1 00 00 00 00 00 00 00 00 00 00 00 00
*/
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xc9, size); //MessageType - PDU Session Modification Request
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); // ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); // PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); // ProcedureTransactionIdentity
ENCODE_U8(
buffer + size, 0xc9,
size); // MessageType - PDU Session Modification Request
ENCODE_U8(buffer + size, 0x28, size); //_5GSMCapability
ENCODE_U8(buffer + size, 0x01, size); //_5GSMCapability
ENCODE_U8(buffer + size, 0x00, size); //_5GSMCapability
ENCODE_U8(buffer + size, 0x59, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x00, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x7a, size); //QoS Rules IE
ENCODE_U8(buffer + size, 0x00, size); //QoS Rules length
ENCODE_U8(buffer + size, 0x12, size); //QoS Rules length
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules rule id
ENCODE_U8(buffer + size, 0x00, size); //QoS Rules rule length
ENCODE_U8(buffer + size, 0x06, size); //QoS Rules rule length
ENCODE_U8(buffer + size, 0x31, size); //QoS Rules
ENCODE_U8(buffer + size, 0x31, size); //QoS Rules
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules filter 1 length
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules
ENCODE_U8(buffer + size, 0x06, size); //QoS Rules
ENCODE_U8(buffer + size, 0x02, size); //QoS Rules rule id
ENCODE_U8(buffer + size, 0x00, size); //QoS Rules rule length
ENCODE_U8(buffer + size, 0x06, size); //QoS Rules rule length
ENCODE_U8(buffer + size, 0x21, size); //QoS Rules
ENCODE_U8(buffer + size, 0x31, size); //QoS Rules
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules filter 1 length
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules
ENCODE_U8(buffer + size, 0x01, size); //QoS Rules
ENCODE_U8(buffer + size, 0x06, size); //QoS Rules
ENCODE_U8(buffer + size, 0x7a, size); // QoS Rules IE
ENCODE_U8(buffer + size, 0x00, size); // QoS Rules length
ENCODE_U8(buffer + size, 0x12, size); // QoS Rules length
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules rule id
ENCODE_U8(buffer + size, 0x00, size); // QoS Rules rule length
ENCODE_U8(buffer + size, 0x06, size); // QoS Rules rule length
ENCODE_U8(buffer + size, 0x31, size); // QoS Rules
ENCODE_U8(buffer + size, 0x31, size); // QoS Rules
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules filter 1 length
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules
ENCODE_U8(buffer + size, 0x06, size); // QoS Rules
ENCODE_U8(buffer + size, 0x02, size); // QoS Rules rule id
ENCODE_U8(buffer + size, 0x00, size); // QoS Rules rule length
ENCODE_U8(buffer + size, 0x06, size); // QoS Rules rule length
ENCODE_U8(buffer + size, 0x21, size); // QoS Rules
ENCODE_U8(buffer + size, 0x31, size); // QoS Rules
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules filter 1 length
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules
ENCODE_U8(buffer + size, 0x01, size); // QoS Rules
ENCODE_U8(buffer + size, 0x06, size); // QoS Rules
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -526,53 +524,52 @@ void send_pdu_session_modification_request_step1(uint8_t pid,
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
//url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// /nsmf-pdusession/v1/sm-contexts/{:context_id}1/modify
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_modification_request["pduSessionId"] = pid;
// Fill the json part
pdu_session_modification_request["pduSessionId"] = pid;
pdu_session_modification_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_modification_request.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
create_multipart_related_content(
body, json_part, boundary, n1_msg, multipart_related_content_part_e::NAS);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -580,7 +577,7 @@ void send_pdu_session_modification_request_step1(uint8_t pid,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -593,16 +590,16 @@ void send_pdu_session_modification_request_step1(uint8_t pid,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Modification Request, response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] PDU Session Modification Request, response from "
"SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
......@@ -612,35 +609,37 @@ void send_pdu_session_modification_request_step1(uint8_t pid,
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step2(uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Modification procedure (SM Context Update, step 2)"
<< std::endl;
void send_pdu_session_modification_request_step2(
uint8_t context_id, std::string smf_ip_address, uint8_t http_version,
std::string port) {
std::cout << "[AMF N11] PDU Session Modification procedure (SM Context "
"Update, step 2)"
<< std::endl;
nlohmann::json pdu_session_modification;
//encode PDU Session Resource Modify Response Transfer IE
// encode PDU Session Resource Modify Response Transfer IE
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
//ENCODE_U8(buffer, 0x00, size);
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
// ENCODE_U8(buffer, 0x00, size);
ENCODE_U8(buffer + size, 0x50, size);
ENCODE_U8(buffer + size, 0x03, size);
ENCODE_U8(buffer + size, 0xe0, size); //Id dL_NGU_UP_TNLInformation
ENCODE_U8(buffer + size, 0xac, size); //Transport Layer Address 172.16.3.101: 172
ENCODE_U8(buffer + size, 0x10, size); //Transport Layer Address 172.16.3.101: 16
ENCODE_U8(buffer + size, 0x03, size); //Transport Layer Address 172.16.3.101: 3
ENCODE_U8(buffer + size, 0x65, size); //Transport Layer Address 172.16.3.101: 101
ENCODE_U8(buffer + size, 0x00, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x01, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); //QoSFlowAddorModifyResponseList
ENCODE_U8(buffer + size, 0x0c, size); //60: QFI
ENCODE_U8(buffer + size, 0xe0, size); // Id dL_NGU_UP_TNLInformation
ENCODE_U8(
buffer + size, 0xac, size); // Transport Layer Address 172.16.3.101: 172
ENCODE_U8(
buffer + size, 0x10, size); // Transport Layer Address 172.16.3.101: 16
ENCODE_U8(
buffer + size, 0x03, size); // Transport Layer Address 172.16.3.101: 3
ENCODE_U8(
buffer + size, 0x65, size); // Transport Layer Address 172.16.3.101: 101
ENCODE_U8(buffer + size, 0x00, size); // Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); // Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); // Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x01, size); // Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); // QoSFlowAddorModifyResponseList
ENCODE_U8(buffer + size, 0x0c, size); // 60: QFI
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -651,53 +650,53 @@ void send_pdu_session_modification_request_step2(uint8_t context_id,
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
// url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify"
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_modification["n2SmInfoType"] = "PDU_RES_MOD_RSP"; //"PDU_RES_SETUP_RSP"
pdu_session_modification["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
// Fill the json part
pdu_session_modification["n2SmInfoType"] = "PDU_RES_MOD_RSP";
pdu_session_modification["n2SmInfo"]["contentId"] = "n2msg"; // NGAP
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_modification.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
create_multipart_related_content(
body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -705,7 +704,7 @@ void send_pdu_session_modification_request_step2(uint8_t context_id,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -718,16 +717,16 @@ void send_pdu_session_modification_request_step2(uint8_t context_id,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Modification procedure (step 2), response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] PDU Session Modification procedure (step 2), "
"response from SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
......@@ -737,26 +736,25 @@ void send_pdu_session_modification_request_step2(uint8_t context_id,
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_complete(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Modification Complete (Update SM Context): N1 SM - PDU Session Modification Complete"
<< std::endl;
void send_pdu_session_modification_complete(
uint8_t pid, uint8_t context_id, std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Modification Complete (Update SM "
"Context): N1 SM - PDU Session Modification Complete"
<< std::endl;
nlohmann::json pdu_session_modification_complete;
//encode PDU Session Modification Complete
// encode PDU Session Modification Complete
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xcc, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //presence
ENCODE_U8(buffer + size, 0x00, size); //Extended protocol configuration options
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); // ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); // PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); // ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xcc, size); // MessageType
ENCODE_U8(buffer + size, 0x00, size); // presence
ENCODE_U8(
buffer + size, 0x00, size); // Extended protocol configuration options
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -767,52 +765,51 @@ void send_pdu_session_modification_complete(uint8_t pid, uint8_t context_id,
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
// url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// /nsmf-pdusession/v1/sm-contexts/{:context_id}/modify
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
// Fill the json part
pdu_session_modification_complete["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_modification_complete.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
create_multipart_related_content(
body, json_part, boundary, n1_msg, multipart_related_content_part_e::NAS);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -820,7 +817,7 @@ void send_pdu_session_modification_complete(uint8_t pid, uint8_t context_id,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -833,16 +830,16 @@ void send_pdu_session_modification_complete(uint8_t pid, uint8_t context_id,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Modification Complete, response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] PDU Session Modification Complete, response from "
"SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
......@@ -852,26 +849,25 @@ void send_pdu_session_modification_complete(uint8_t pid, uint8_t context_id,
}
//------------------------------------------------------------------------------
void send_pdu_session_release_request(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version, std::string port) {
void send_pdu_session_release_request(
uint8_t pid, uint8_t context_id, std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release Request (SM Context Update)"
<< std::endl;
nlohmann::json pdu_session_release_request;
//encode PDU Session Release Request
// encode PDU Session Release Request
/*
0000 2e 01 01 d1 00 00 00 00 00 00 00 00 00 00 00 00
0000 2e 01 01 d1 00 00 00 00 00 00 00 00 00 00 00 00
*/
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xd1, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //presence
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); // ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); // PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); // ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xd1, size); // MessageType
ENCODE_U8(buffer + size, 0x00, size); // presence
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -882,53 +878,53 @@ void send_pdu_session_release_request(uint8_t pid, uint8_t context_id,
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
//url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify"));
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_release_request["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
// Fill the json part
pdu_session_release_request["cause"] =
"INSUFFICIENT_UP_RESOURCES"; // need to be updated
pdu_session_release_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_release_request.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
create_multipart_related_content(
body, json_part, boundary, n1_msg, multipart_related_content_part_e::NAS);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -936,7 +932,7 @@ void send_pdu_session_release_request(uint8_t pid, uint8_t context_id,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -949,16 +945,16 @@ void send_pdu_session_release_request(uint8_t pid, uint8_t context_id,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Release Request, response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] PDU Session Release Request, response from SMF, "
"Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
......@@ -968,20 +964,18 @@ void send_pdu_session_release_request(uint8_t pid, uint8_t context_id,
}
//------------------------------------------------------------------------------
void send_pdu_session_release_resource_release_ack(uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Release Ack (Update SM Context): N2 SM - Resource Release Ack"
<< std::endl;
void send_pdu_session_release_resource_release_ack(
uint8_t context_id, std::string smf_ip_address, uint8_t http_version,
std::string port) {
std::cout << "[AMF N11] PDU Session Release Ack (Update SM Context): N2 SM - "
"Resource Release Ack"
<< std::endl;
nlohmann::json pdu_session_release_ack;
//encode PDU Session Resource Release Response Transfer IE
// encode PDU Session Resource Release Response Transfer IE
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x00, size);
std::cout << "Buffer: " << std::endl;
......@@ -993,53 +987,53 @@ void send_pdu_session_release_resource_release_ack(uint8_t context_id,
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
// url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_release_ack["n2SmInfoType"] = "PDU_RES_REL_RSP";
pdu_session_release_ack["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
// Fill the json part
pdu_session_release_ack["n2SmInfoType"] = "PDU_RES_REL_RSP";
pdu_session_release_ack["n2SmInfo"]["contentId"] = "n2msg"; // NGAP
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_release_ack.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
create_multipart_related_content(
body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -1047,7 +1041,7 @@ void send_pdu_session_release_resource_release_ack(uint8_t context_id,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -1060,13 +1054,12 @@ void send_pdu_session_release_resource_release_ack(uint8_t context_id,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Release Ack, response from SMF, Http Code "
......@@ -1080,28 +1073,28 @@ void send_pdu_session_release_resource_release_ack(uint8_t context_id,
}
//------------------------------------------------------------------------------
void send_pdu_session_release_complete(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout
<< "[AMF N11] PDU Session Release Complete (Update SM Context): N1 SM - PDU Session Release Complete"
<< std::endl;
void send_pdu_session_release_complete(
uint8_t pid, uint8_t context_id, std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release Complete (Update SM Context): N1 "
"SM - PDU Session Release Complete"
<< std::endl;
nlohmann::json pdu_session_release_complete;
//encode PDU Session Release Complete
// encode PDU Session Release Complete
/*
0000 2e 01 01 c1 d4 00 00 00 00 00 00 00 00 00 00 00
0000 2e 01 01 c1 d4 00 00 00 00 00 00 00 00 00 00 00
*/
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xd4, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //Cause
ENCODE_U8(buffer + size, 0x00, size); //Extended protocol configuration options
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); // ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, pid, size); // PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); // ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xd4, size); // MessageType
ENCODE_U8(buffer + size, 0x00, size); // Cause
ENCODE_U8(
buffer + size, 0x00, size); // Extended protocol configuration options
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -1112,53 +1105,53 @@ void send_pdu_session_release_complete(uint8_t pid, uint8_t context_id,
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
//url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_release_complete["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
// Fill the json part
pdu_session_release_complete["cause"] =
"INSUFFICIENT_UP_RESOURCES"; // need to be updated
pdu_session_release_complete["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = pdu_session_release_complete.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
create_multipart_related_content(
body, json_part, boundary, n1_msg, multipart_related_content_part_e::NAS);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -1166,7 +1159,7 @@ void send_pdu_session_release_complete(uint8_t pid, uint8_t context_id,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -1179,16 +1172,16 @@ void send_pdu_session_release_complete(uint8_t pid, uint8_t context_id,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Release Complete, response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] PDU Session Release Complete, response from SMF, "
"Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
......@@ -1206,49 +1199,49 @@ void send_pdu_session_update_sm_context_ue_service_request(
<< std::endl;
nlohmann::json service_requests;
//NO NAS, No NGAP
// NO NAS, No NGAP
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
//url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//PDU session ID (as specified in section 4.2.3.2 @ 3GPP TS 23.502, but can't find in Yaml file)
// PDU session ID (as specified in section 4.2.3.2 @ 3GPP TS 23.502, but can't
// find in Yaml file)
service_requests["upCnxState"] = "ACTIVATING";
service_requests["ratType"] = "NR";
service_requests["anType"] = "3GPP_ACCESS";
service_requests["ratType"] = "NR";
service_requests["anType"] = "3GPP_ACCESS";
std::string body;
body = service_requests.dump();
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -1256,7 +1249,7 @@ void send_pdu_session_update_sm_context_ue_service_request(
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -1269,21 +1262,20 @@ void send_pdu_session_update_sm_context_ue_service_request(
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get response from SMF
// get response from SMF
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] UE Triggered Service Request (Step 1), response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] UE Triggered Service Request (Step 1), response "
"from SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
//------------------------------------------------------------------------------
......@@ -1295,26 +1287,28 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
<< std::endl;
nlohmann::json service_requests;
//encode PDU Session Resource Setup Response Transfer IE
// encode PDU Session Resource Setup Response Transfer IE
/*
00 03 e0 ac 0a 05 01 00 00 00 01 00 06
00 03 e0 ac 0a 05 01 00 00 00 01 00 06
*/
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
char* buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x00, size);
ENCODE_U8(buffer + size, 0x03, size);
ENCODE_U8(buffer + size, 0xe0, size);
ENCODE_U8(buffer + size, 0xac, size); //uPTransportLayerInformation IP Addr 172.10.5.1: 172.
ENCODE_U8(buffer + size, 0x0a, size); //10
ENCODE_U8(
buffer + size, 0xac,
size); // uPTransportLayerInformation IP Addr 172.10.5.1: 172.
ENCODE_U8(buffer + size, 0x0a, size); // 10
ENCODE_U8(buffer + size, 0x05, size); //.5
ENCODE_U8(buffer + size, 0x01, size); //.1
ENCODE_U8(buffer + size, 0x00, size); //gTP_TEID 00 00 00 01: 00
ENCODE_U8(buffer + size, 0x00, size); //00
ENCODE_U8(buffer + size, 0x00, size); //00
ENCODE_U8(buffer + size, 0x01, size); //01
ENCODE_U8(buffer + size, 0x00, size); //Associated QoS Flow 00 06
ENCODE_U8(buffer + size, 0x06, size); //QFI: 06
ENCODE_U8(buffer + size, 0x00, size); // gTP_TEID 00 00 00 01: 00
ENCODE_U8(buffer + size, 0x00, size); // 00
ENCODE_U8(buffer + size, 0x00, size); // 00
ENCODE_U8(buffer + size, 0x01, size); // 01
ENCODE_U8(buffer + size, 0x00, size); // Associated QoS Flow 00 06
ENCODE_U8(buffer + size, 0x06, size); // QFI: 06
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
......@@ -1325,61 +1319,63 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
//url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/modify"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/modify"));
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
service_requests["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
service_requests["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
// Fill the json part
service_requests["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
service_requests["n2SmInfo"]["contentId"] = "n2msg"; // NGAP
//service_requests["n2InfoContainer"]["n2InformationClass"] = "SM";
//service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2msg";
// service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
// service_requests["n2InfoContainer"]["n2InformationClass"] = "SM";
// service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"]
// = "n2msg";
// service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"]
// =
// "PDU_RES_SETUP_RSP"; //NGAP message
service_requests["anType"] = "3GPP_ACCESS";
service_requests["anType"] = "3GPP_ACCESS";
service_requests["ratType"] = "NR";
std::string body;
std::string boundary = "----Boundary";
std::string boundary = "----Boundary";
std::string json_part = service_requests.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
create_multipart_related_content(
body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
unsigned char* data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -1387,7 +1383,7 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -1400,20 +1396,19 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
//Set the default Cause
// Set the default Cause
response_data["cause"] = "504 Gateway Timeout";
}
std::cout
<< "[AMF N11] UE Triggered Service Request (Step 2), response from SMF, Http Code "
<< httpCode << " cause " << response_data["cause"].dump().c_str()
<< std::endl;
std::cout << "[AMF N11] UE Triggered Service Request (Step 2), response "
"from SMF, Http Code "
<< httpCode << " cause " << response_data["cause"].dump().c_str()
<< std::endl;
curl_easy_cleanup(curl);
}
......@@ -1423,10 +1418,9 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
}
//------------------------------------------------------------------------------
void send_release_sm_context_request(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version, std::string port) {
void send_release_sm_context_request(
uint8_t pid, uint8_t context_id, std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release SM context Request" << std::endl;
nlohmann::json send_release_sm_context_request;
......@@ -1437,37 +1431,37 @@ void send_release_sm_context_request(uint8_t pid, uint8_t context_id,
url.append(std::string(":"));
url.append(port);
}
//url.append(std::string("/nsmf-pdusession/v1/sm-contexts/1/release"));
// nsmf-pdusession/v1/sm-contexts/{:context_id}/release"
url.append(std::string("/nsmf-pdusession/v1/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/release"));
//Fill the json part
// Fill the json part
send_release_sm_context_request["pduSessionId"] = pid;
std::string body = send_release_sm_context_request.dump();
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
CURL* curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
CURLcode res = {};
struct curl_slist* headers = nullptr;
// headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
......@@ -1475,7 +1469,7 @@ void send_release_sm_context_request(uint8_t pid, uint8_t context_id,
}
// Response information.
long httpCode = { 0 };
long httpCode = {0};
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -1488,153 +1482,148 @@ void send_release_sm_context_request(uint8_t pid, uint8_t context_id,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
// get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
} catch (nlohmann::json::exception& e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Release SM Context Request, response from SMF, Http Code "
<< httpCode << std::endl;
std::cout << "[AMF N11] PDU Session Release SM Context Request, response "
"from SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
//------------------------------------------------------------------------------
bool pdu_session_establishment(uint8_t pid, uint8_t context_id,
std::string smf_ip_address, uint8_t http_version,
std::string port) {
bool pdu_session_establishment(
std::string supi, uint8_t pid, uint8_t context_id,
std::string smf_ip_address, uint8_t http_version, std::string port) {
bool status = false;
if (send_pdu_session_establishment_request(pid, smf_ip_address, http_version,
port)) {
//usleep(100000);
status = send_pdu_session_update_sm_context_establishment(context_id,
smf_ip_address,
http_version,
port);
if (send_pdu_session_establishment_request(
supi, pid, smf_ip_address, http_version, port)) {
// usleep(100000);
status = send_pdu_session_update_sm_context_establishment(
context_id, smf_ip_address, http_version, port);
}
return status;
}
//------------------------------------------------------------------------------
void test_all_procedures_for_one_session(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
void test_all_procedures_for_one_session(
std::string supi, uint8_t pid, uint8_t context_id,
std::string smf_ip_address, uint8_t http_version, std::string port) {
bool status = false;
if (send_pdu_session_establishment_request(pid, smf_ip_address, http_version,
port)) {
if (send_pdu_session_establishment_request(
supi, pid, smf_ip_address, http_version, port)) {
usleep(100000);
status = send_pdu_session_update_sm_context_establishment(context_id,
smf_ip_address,
http_version,
port);
status = send_pdu_session_update_sm_context_establishment(
context_id, smf_ip_address, http_version, port);
}
if (status) {
usleep(200000);
//UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(context_id,
smf_ip_address,
http_version, port);
// UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(
context_id, smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(context_id,
smf_ip_address,
http_version,
port);
send_pdu_session_update_sm_context_ue_service_request_step2(
context_id, smf_ip_address, http_version, port);
usleep(200000);
//PDU Session Modification
send_pdu_session_modification_request_step1(pid, context_id, smf_ip_address,
http_version, port);
// PDU Session Modification
send_pdu_session_modification_request_step1(
pid, context_id, smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_modification_request_step2(context_id, smf_ip_address,
http_version, port);
send_pdu_session_modification_request_step2(
context_id, smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_modification_complete(pid, context_id, smf_ip_address,
http_version, port);
send_pdu_session_modification_complete(
pid, context_id, smf_ip_address, http_version, port);
usleep(200000);
//PDU Session Release procedure
send_pdu_session_release_request(pid, context_id, smf_ip_address,
http_version, port);
// PDU Session Release procedure
send_pdu_session_release_request(
pid, context_id, smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_release_resource_release_ack(context_id, smf_ip_address,
http_version, port);
send_pdu_session_release_resource_release_ack(
context_id, smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_release_complete(pid, context_id, smf_ip_address,
http_version, port);
send_pdu_session_release_complete(
pid, context_id, smf_ip_address, http_version, port);
usleep(200000);
//Release SM context
//send_release_sm_context_request(pid, smf_ip_address, http_version, port);
// Release SM context
// send_release_sm_context_request(pid, smf_ip_address, http_version, port);
}
}
//------------------------------------------------------------------------------
void test_session_establishment_multiple_threads(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
void test_session_establishment_multiple_threads(
int number_thread, std::string supi, std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::vector<std::thread> pdu_threads;
for (int i = 0; i < 10; i++) {
std::thread session_establishment(&pdu_session_establishment, i, i,
smf_ip_address, http_version, port);
for (int i = 1; i < number_thread; i++) {
std::thread session_establishment(
&pdu_session_establishment, supi, i, i, smf_ip_address, http_version,
port);
pdu_threads.push_back(std::move(session_establishment));
}
for (auto &t : pdu_threads) {
for (auto& t : pdu_threads) {
t.join();
}
}
//------------------------------------------------------------------------------
void test_all_procedures_for_multiple_threads(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
uint8_t pid = 1;
void test_all_procedures_for_multiple_threads(
std::string supi, std::string smf_ip_address, uint8_t http_version,
std::string port) {
uint8_t pid = 1;
uint8_t context_id = 1;
//bool status = false;
/* std::thread t1(&send_pdu_session_establishment_request, pid, smf_ip_address,
http_version, port);
std::thread t2(&send_pdu_session_update_sm_context_establishment, context_id,
smf_ip_address, http_version, port);
*/
std::thread t1(&pdu_session_establishment, pid, context_id, smf_ip_address,
http_version, port);
std::thread t3(&send_pdu_session_update_sm_context_ue_service_request,
context_id, smf_ip_address, http_version, port);
std::thread t4(&send_pdu_session_update_sm_context_ue_service_request_step2,
context_id, smf_ip_address, http_version, port);
std::thread t5(&send_pdu_session_modification_request_step1, pid, context_id,
smf_ip_address, http_version, port);
std::thread t6(&send_pdu_session_modification_request_step2, context_id,
smf_ip_address, http_version, port);
std::thread t7(&send_pdu_session_modification_complete, pid, context_id,
smf_ip_address, http_version, port);
//PDU Session Release procedure
std::thread t8(&send_pdu_session_release_request, pid, context_id,
smf_ip_address, http_version, port);
std::thread t9(&send_pdu_session_release_resource_release_ack, context_id,
smf_ip_address, http_version, port);
std::thread t10(&send_pdu_session_release_complete, pid, context_id,
smf_ip_address, http_version, port);
//Release SM context
//send_release_sm_context_request(pid, smf_ip_address, http_version, port);
/* std::thread t1(&send_pdu_session_establishment_request, supi, pid,
smf_ip_address, http_version, port); std::thread
t2(&send_pdu_session_update_sm_context_establishment, context_id,
smf_ip_address, http_version, port);
*/
std::thread t1(
&pdu_session_establishment, supi, pid, context_id, smf_ip_address,
http_version, port);
std::thread t3(
&send_pdu_session_update_sm_context_ue_service_request, context_id,
smf_ip_address, http_version, port);
std::thread t4(
&send_pdu_session_update_sm_context_ue_service_request_step2, context_id,
smf_ip_address, http_version, port);
std::thread t5(
&send_pdu_session_modification_request_step1, pid, context_id,
smf_ip_address, http_version, port);
std::thread t6(
&send_pdu_session_modification_request_step2, context_id, smf_ip_address,
http_version, port);
std::thread t7(
&send_pdu_session_modification_complete, pid, context_id, smf_ip_address,
http_version, port);
// PDU Session Release procedure
std::thread t8(
&send_pdu_session_release_request, pid, context_id, smf_ip_address,
http_version, port);
std::thread t9(
&send_pdu_session_release_resource_release_ack, context_id,
smf_ip_address, http_version, port);
std::thread t10(
&send_pdu_session_release_complete, pid, context_id, smf_ip_address,
http_version, port);
// Release SM context
// send_release_sm_context_request(pid, smf_ip_address, http_version, port);
t1.join();
// t2.join();
// t2.join();
t3.join();
t4.join();
t5.join();
......@@ -1643,17 +1632,36 @@ void test_all_procedures_for_multiple_threads(std::string smf_ip_address,
t8.join();
t9.join();
t10.join();
}
//------------------------------------------------------------------------------
// MAX 999 UEs for now
void test_multiple_ues_multipe_sessions(
uint32_t number_ues, uint8_t number_sessions, std::string smf_ip_address,
uint8_t http_version, std::string port) {
// generate UE ID
for (int ue = 1; ue < number_ues; ue++) {
std::stringstream ss;
ss << std::setw(3) << std::setfill('0') << ue;
std::string ue_str = ss.str();
std::string ue_supi = "imsi-200000000000" + ue_str;
std::cout << "UE SUPI " << ue_supi << std::endl;
for (int i = 1; i <= number_sessions; i++) {
test_all_procedures_for_one_session(
ue_supi, i, i, smf_ip_address, http_version, port);
}
}
}
//------------------------------------------------------------------------------
int main(int argc, char *argv[]) {
int main(int argc, char* argv[]) {
std::string smf_ip_address;
uint8_t http_version = 1;
std::string port;
http_version = 1;
port = std::string("80");
port = std::string("80");
if ((argc != 1) && (argc != 3) && (argc != 5) && (argc != 7)) {
std::cout << "Error: Usage is " << std::endl;
......@@ -1690,15 +1698,31 @@ int main(int argc, char *argv[]) {
<< std::to_string(http_version) << ", -p " << port.c_str()
<< std::endl;
bool cont = false;
bool cont = false;
uint8_t context_id = 1;
uint8_t pid = 1;
uint8_t pid = 1;
std::string supi = "imsi-200000000000001";
uint32_t number_ues = 100;
test_all_procedures_for_one_session(supi, pid, context_id, smf_ip_address,
http_version, port);
/* for (int i=1; i<=MAX_NUMBER_SESSIONS; i++) {
test_all_procedures_for_one_session(pid, context_id, smf_ip_address,
http_version, port);
//test_session_establishment_multiple_threads(smf_ip_address, http_version, port);
//test_all_procedures_for_multiple_threads(smf_ip_address, http_version,
test_all_procedures_for_one_session(supi, i, i, smf_ip_address,
http_version, port);
}
*/
// test_session_establishment_multiple_threads(MAX_NUMBER_SESSIONS, supi,
// smf_ip_address, http_version, port);
// test_all_procedures_for_multiple_threads(supi, smf_ip_address,
// http_version,
// port);
//test_multiple_ues_multipe_sessions(
// number_ues, 1, smf_ip_address, http_version, port);
return 0;
}
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