Commit 050a6842 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'bug_fixes_for_bupt' into 'develop'

Bug fixes for BUPT

See merge request oai/oai-cn5g-smf!6
parents c98c86ee a15a05c0
......@@ -73,8 +73,8 @@ SMF =
APN_LIST = (
# IPV4_POOL, IPV6_POOL are index in IPV4_LIST, IPV6_LIST, PDN_TYPE choice in {IPv4, IPv6, IPv4v6}
{APN_NI = "carrier.com"; PDN_TYPE = "IPv4"; IPV4_POOL = 0; IPV6_POOL = -1},
{APN_NI = "apn1"; PDN_TYPE = "IPv4"; IPV4_POOL = 1; IPV6_POOL = -1},
{APN_NI = "default"; PDN_TYPE = "IPv4"; IPV4_POOL = 0; IPV6_POOL = -1},
{APN_NI = "carrier.com"; PDN_TYPE = "IPv4"; IPV4_POOL = 1; IPV6_POOL = -1},
{APN_NI = "apn2"; PDN_TYPE = "IPv4"; IPV4_POOL = 2; IPV6_POOL = -1},
{APN_NI = "apn3"; PDN_TYPE = "IPv4"; IPV4_POOL = 3; IPV6_POOL = -1},
{APN_NI = "apn4"; PDN_TYPE = "IPv4"; IPV4_POOL = 4; IPV6_POOL = -1}
......
......@@ -103,7 +103,7 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
smContextCreateData.getSNssai().getSst(),
smContextCreateData.getSNssai().getSd().c_str());
snssai_t snssai(smContextCreateData.getSNssai().getSst(),
smContextCreateData.getSNssai().getSd().c_str());
smContextCreateData.getSNssai().getSd());
sm_context_req_msg.set_snssai(snssai);
//PDU session ID
......
......@@ -459,7 +459,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
oai::smf_server::model::SmContextCreateError smContextCreateError = { };
oai::smf_server::model::ProblemDetails problem_details = { };
oai::smf_server::model::RefToBinaryData refToBinaryData = { };
std::string n1_sm_message, n1_sm_message_hex; //N1 SM container
std::string n1_sm_message, n1_sm_message_hex;
smf_n1_n2 smf_n1_n2_inst = { };
nas_message_t decoded_nas_msg = { };
......@@ -467,46 +467,37 @@ void smf_app::handle_pdu_session_create_sm_context_request(
std::string n1_sm_msg = smreq->req.get_n1_sm_message();
memset(&decoded_nas_msg, 0, sizeof(nas_message_t));
pdu_session_create_sm_context_request context_req_msg = smreq->req;
int decoder_rc = smf_n1_n2_inst.decode_n1_sm_container(decoded_nas_msg,
n1_sm_msg);
if (decoder_rc != RETURNok) {
//error, should send reply to AMF with error code!!
//error, send reply to AMF with PDU Session Establishment Reject
Logger::smf_app().warn("N1 SM container cannot be decoded correctly!");
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N1_SM_ERROR]);
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//24.501: response with a 5GSM STATUS message including cause "#95 Semantically incorrect message"
smf_n1_n2_inst.create_n1_sm_container(
context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//Send response to AMF
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
return;
}
Logger::smf_app().debug(
"NAS header information: extended protocol discriminator %d, security headertype %d",
"NAS information: Extended Protocol Discriminator %d, Security Header Type %d, Message Type %d",
decoded_nas_msg.header.extended_protocol_discriminator,
decoded_nas_msg.header.security_header_type);
decoded_nas_msg.header.security_header_type,
decoded_nas_msg.plain.sm.header.message_type);
//Extended protocol discriminator (Mandatory)
smreq->req.set_epd(decoded_nas_msg.header.extended_protocol_discriminator);
//Message type (Mandatory) (PDU SESSION ESTABLISHMENT REQUEST message identity)
Logger::smf_app().debug("NAS header information, Message Type %d",
decoded_nas_msg.plain.sm.header.message_type);
//Message type (Mandatory)
smreq->req.set_message_type(decoded_nas_msg.plain.sm.header.message_type);
//Integrity protection maximum data rate (Mandatory)
//TODO:
//TODO: Integrity protection maximum data rate (Mandatory)
//PDU session type (Optional)
smreq->req.set_pdu_session_type(PDU_SESSION_TYPE_E_IPV4); //set default value
if (decoded_nas_msg.plain.sm.header.message_type
......@@ -535,8 +526,8 @@ void smf_app::handle_pdu_session_create_sm_context_request(
uint8_t message_type = decoded_nas_msg.plain.sm.header.message_type;
std::string request_type = smreq->req.get_request_type();
Logger::smf_app().info(
"Handle a PDU Session Create SM Context Request message from AMF, supi " SUPI_64_FMT ", dnn %s, snssai_sst %d",
supi64, dnn.c_str(), snssai.sST);
"Handle a PDU Session Create SM Context Request message from AMF, supi " SUPI_64_FMT ", dnn %s, snssai_sst %d, snssai_sd %s",
supi64, dnn.c_str(), snssai.sST, snssai.sD.c_str());
//If no DNN information from UE, set to default value
if (dnn.length() == 0) {
......@@ -554,19 +545,17 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//(24.501 (section 7.3.1)) NAS N1 SM message: response with a 5GSM STATUS message including cause "#81 Invalid PTI value"
//PDU Session Establishment Reject including cause "#81 Invalid PTI value" (section 7.3.1 @3GPP TS 24.501)
smf_n1_n2_inst.create_n1_sm_container(
context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_81_INVALID_PTI_VALUE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//Send response to AMF
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
return;
}
context_req_msg.set_pti(pti);
smreq->req.set_pti(pti);
//check pdu session id
if ((pdu_session_id == PDU_SESSION_IDENTITY_UNASSIGNED )
......@@ -589,12 +578,11 @@ void smf_app::handle_pdu_session_create_sm_context_request(
//PDU Session Establishment Reject
//(24.501 (section 7.4)) implementation dependent->do similar to UE: response with a 5GSM STATUS message including cause "#98 message type not compatible with protocol state."
smf_n1_n2_inst.create_n1_sm_container(
context_req_msg,
smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message,
cause_value_5gsm_e::CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE); //TODO: should define 5GSM cause in 24.501
cause_value_5gsm_e::CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//Send response to AMF
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
......@@ -625,10 +613,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, 24.501 cause "#27 Missing or unknown DNN"
smf_n1_n2_inst.create_n1_sm_container(
context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_27_MISSING_OR_UNKNOWN_DNN);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//Send response to AMF
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
......@@ -683,8 +670,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
//update dnn_context with subscription info
sc.get()->insert_dnn_subscription(snssai, subscription);
} else {
// Cannot retrieve information from UDM,
//Not accept to establish a PDU session
// Cannot retrieve information from UDM, reject PDU session establishment
Logger::smf_app().warn(
"Received PDU_SESSION_CREATESMCONTEXT_REQUEST, couldn't retrieve the Session Management Subscription from UDM, ignore message!");
problem_details.setCause(
......@@ -692,9 +678,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, with cause "29 User authentication or authorization failed"?
//PDU Session Establishment Reject, with cause "29 User authentication or authorization failed"
smf_n1_n2_inst.create_n1_sm_container(
context_req_msg,
smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED);
......@@ -723,8 +709,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
Logger::smf_app().debug("Generated a SCID " SCID_FMT " ", scid);
//Step 8. let the context handle the message
//in this step, SMF will send N4 Session Establishment/Modification to UPF (step 10a, section 4.3.2 3GPP 23.502)
//SMF, then, sends response to AMF
sc.get()->handle_pdu_session_create_sm_context_request(smreq);
}
......@@ -744,7 +728,6 @@ void smf_app::handle_pdu_session_update_sm_context_request(
try {
scid = std::stoi(smreq->scid);
} catch (const std::exception &err) {
//TODO: send PDUSession_SMUpdateContext Response to AMF with CAUSE: invalid context
Logger::smf_app().warn(
"Received a PDU Session Update SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!");
problem_details.setCause(
......@@ -772,19 +755,12 @@ void smf_app::handle_pdu_session_update_sm_context_request(
return;
}
supi_t supi = scf.get()->supi;
std::string dnn = scf.get()->dnn;
pdu_session_id_t pdu_session_id = scf.get()->pdu_session_id;
snssai_t nssai = scf.get()->nssai;
//Step 2. store supi, dnn, nssai in itti_n11_update_sm_context_request to be processed later on
supi64_t supi64 = smf_supi_to_u64(supi);
smreq->req.set_supi(supi);
smreq->req.set_dnn(dnn);
smreq->req.set_snssai(nssai);
smreq->req.set_pdu_session_id(pdu_session_id);
pdu_session_update_sm_context_request context_req_msg = smreq->req;
supi64_t supi64 = smf_supi_to_u64(scf.get()->supi);
smreq->req.set_supi(scf.get()->supi);
smreq->req.set_dnn(scf.get()->dnn);
smreq->req.set_snssai(scf.get()->nssai);
smreq->req.set_pdu_session_id(scf.get()->pdu_session_id);
//Step 2. find the smf context
std::shared_ptr<smf_context> sc = { };
......@@ -809,10 +785,9 @@ void smf_app::handle_pdu_session_update_sm_context_request(
//get dnn context
std::shared_ptr<dnn_context> sd = { };
if (!sc.get()->find_dnn_context(scf.get()->nssai, dnn, sd)) {
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
//Error, DNN context doesn't exist
// send PDUSession_SMUpdateContext Response to AMF
//Error, DNN context doesn't exist, send PDUSession_SMUpdateContext Response to AMF
Logger::smf_app().warn(
"Received PDU Session Update SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!");
problem_details.setCause(
......
......@@ -47,6 +47,7 @@
extern "C" {
#include "Ngap_PDUSessionResourceSetupResponseTransfer.h"
#include "Ngap_PDUSessionResourceModifyResponseTransfer.h"
#include "Ngap_PDUSessionResourceReleaseResponseTransfer.h"
#include "Ngap_GTPTunnel.h"
#include "Ngap_AssociatedQosFlowItem.h"
#include "Ngap_QosFlowAddOrModifyResponseList.h"
......@@ -289,7 +290,7 @@ void smf_pdu_session::deallocate_ressources(const std::string &apn) {
if (ipv4) {
paa_dynamic::get_instance().release_paa(apn, ipv4_address);
}
clear(); //including qos_flows.clear()
clear(); //including qos_flows.clear()
Logger::smf_app().info(
"Resources associated with this PDU Session have been released");
}
......@@ -826,7 +827,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_request> smreq) {
Logger::smf_app().info(
"Handle a PDU Session Create SM Context Request message from AMF");
pdu_session_create_sm_context_request sm_context_req_msg = smreq->req;
oai::smf_server::model::SmContextCreateError smContextCreateError = { };
oai::smf_server::model::ProblemDetails problem_details = { };
oai::smf_server::model::RefToBinaryData refToBinaryData = { };
......@@ -835,12 +836,12 @@ void smf_context::handle_pdu_session_create_sm_context_request(
bool request_accepted = true;
//Step 1. get necessary information
std::string dnn = sm_context_req_msg.get_dnn();
snssai_t snssai = sm_context_req_msg.get_snssai();
std::string request_type = sm_context_req_msg.get_request_type();
supi_t supi = sm_context_req_msg.get_supi();
std::string dnn = smreq->req.get_dnn();
snssai_t snssai = smreq->req.get_snssai();
std::string request_type = smreq->req.get_request_type();
supi_t supi = smreq->req.get_supi();
supi64_t supi64 = smf_supi_to_u64(supi);
uint32_t pdu_session_id = sm_context_req_msg.get_pdu_session_id();
uint32_t pdu_session_id = smreq->req.get_pdu_session_id();
//Step 2. check the validity of the UE request, if valid send PDU Session Accept, otherwise send PDU Session Reject to AMF
if (!verify_sm_context_request(smreq)) {
......@@ -852,9 +853,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg,
smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED);
......@@ -875,11 +875,14 @@ void smf_context::handle_pdu_session_create_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_response> sm_context_resp_pending =
std::shared_ptr<itti_n11_create_sm_context_response>(sm_context_resp);
sm_context_resp->res.set_supi(supi);
sm_context_resp->res.set_supi_prefix(sm_context_req_msg.get_supi_prefix());
sm_context_resp->res.set_supi_prefix(smreq->req.get_supi_prefix());
sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
sm_context_resp->res.set_pdu_session_id(pdu_session_id);
sm_context_resp->res.set_snssai(snssai);
sm_context_resp->res.set_dnn(dnn);
sm_context_resp->res.set_pdu_session_type(
smreq->req.get_pdu_session_type());
sm_context_resp->res.set_pti(smreq->req.get_pti());
sm_context_resp->set_scid(smreq->scid);
//Step 3. find pdu_session
......@@ -908,11 +911,10 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (nullptr == sp.get()) {
Logger::smf_app().debug("Create a new PDN connection!");
//create a new pdu session
sp = std::shared_ptr<smf_pdu_session>(new smf_pdu_session());
sp.get()->pdn_type.pdn_type = sm_context_req_msg.get_pdu_session_type();
sp.get()->pdn_type.pdn_type = smreq->req.get_pdu_session_type();
sp.get()->pdu_session_id = pdu_session_id;
sp.get()->amf_id = sm_context_req_msg.get_serving_nf_id(); //amf id
sp.get()->amf_id = smreq->req.get_serving_nf_id(); //amf id
sd->insert_pdu_session(sp);
} else {
Logger::smf_app().debug("PDN connection is already existed!");
......@@ -948,7 +950,6 @@ void smf_context::handle_pdu_session_create_sm_context_request(
.ci_ip_address_allocation_via_nas_signalling = 0,
.ci_ipv4_address_allocation_via_dhcpv4 = 0,
.ci_ipv4_link_mtu_request = 0 };
//smf_app_inst->process_pco_request(extended_protocol_options, pco_resp, pco_ids);
//Step 7. Address allocation based on PDN type
......@@ -1014,7 +1015,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
......@@ -1050,10 +1051,9 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// std::string smContextRef = sm_context_req_msg.get_supi_prefix() + "-" + smf_supi_to_string(sm_context_req_msg.get_supi());
std::string smContextRef = std::to_string(smreq->scid);
//headers: Location: contains the URI of the newly created resource, according to the structure: {apiRoot}/nsmf-pdusession/{apiVersion}/sm-contexts/{smContextRef}
std::string uri = sm_context_req_msg.get_api_root() + "/"
std::string uri = smreq->req.get_api_root() + "/"
+ smContextRef.c_str();
//TODO: disable two following lines to test PDU SESSION ESTABLISHMENT ACCEPT
sm_context_resp->http_response.headers()
.add<Pistache::Http::Header::Location>(uri);
smf_n11_inst->send_pdu_session_create_sm_context_response(
......@@ -1276,6 +1276,15 @@ void smf_context::handle_pdu_session_update_sm_context_request(
*/
//See section 6.4.2 - UE-requested PDU Session modification procedure@ 3GPP TS 24.501
//PDU Session Identity
//check if the PDU Session Release Command is already sent for this message (see section 6.3.3.5 @3GPP TS 24.501)
if (sp.get()->get_pdu_session_status() == pdu_session_status_e::PDU_SESSION_INACTIVE_PENDING) {
//Ignore the message
Logger::smf_app().info("A PDU Session Release Command has been sent for this session (session ID %d), ignore the message!",
decoded_nas_msg.plain.sm.header.pdu_session_identity);
return;
}
//PTI
Logger::smf_app().info(
"PTI %d",
......@@ -1436,6 +1445,30 @@ void smf_context::handle_pdu_session_update_sm_context_request(
!= decoded_nas_msg.plain.sm.header.pdu_session_identity) {
//TODO: PDU Session ID mismatch
}
//Abnormal cases in network side (see section 6.4.3.6 @3GPP TS 24.501)
if (sp.get()->get_pdu_session_status() == pdu_session_status_e::PDU_SESSION_INACTIVE) {
Logger::smf_app().warn("PDU Session status: INACTIVE, send PDU Session Release Reject to UE!");
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]); //TODO: which cause?
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
}
//Abnormal cases in network side (see section 6.3.3.5 @3GPP TS 24.501)
if (sp.get()->get_pdu_session_status() == pdu_session_status_e::PDU_SESSION_INACTIVE_PENDING) {
//Ignore the message
Logger::smf_app().info("A PDU Session Release Command has been sent for this session (session ID %d), ignore the message!",
decoded_nas_msg.plain.sm.header.pdu_session_identity);
return;
}
//PTI
Logger::smf_app().info(
"PTI %d",
......@@ -1449,19 +1482,27 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//5GSM Cause
//Extended Protocol Configuration Options
//Release the resources related to this PDU Session
//The SMF releases the IP address / Prefix(es) that were allocated to the PDU Session and releases the
//corresponding User Plane resources
//SMF releases the IP address / Prefix(es) that were allocated to the PDU Session
//Release the resources related to this PDU Session (in Procedure)
//find DNN context
std::shared_ptr<dnn_context> sd = { };
if ((!find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd))
or (nullptr == sd.get())) {
//TODO: error cannot find the associated DNN context
Logger::smf_app().warn("Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
return;
}
......@@ -1470,7 +1511,21 @@ void smf_context::handle_pdu_session_update_sm_context_request(
if ((!sd.get()->find_pdu_session(
sm_context_req_msg.get_pdu_session_id(), ss))
or (nullptr == ss.get())) {
//TODO: error cannot find the corresponding PDU Session
Logger::smf_app().warn("Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
return;
}
//get the associated QoS flows: to be used for PFCP Session Modification procedure
......@@ -1482,8 +1537,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//need to update UPF accordingly
update_upf = true;
//TODO:
}
break;
......@@ -1522,8 +1575,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
itti_inst->timer_remove(sp.get()->timer_T3592);
//send response to AMF
//Verify, do we need this?
oai::smf_server::model::SmContextCreatedData smContextCreatedData;
oai::smf_server::model::SmContextCreatedData smContextCreatedData; //Verify, do we need this?
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreatedData,
Pistache::Http::Code::Ok);
......@@ -1755,15 +1807,30 @@ void smf_context::handle_pdu_session_update_sm_context_request(
procedure_type =
session_management_procedures_type_e::PDU_SESSION_RELEASE_UE_REQUESTED_STEP2;
//TODO: SMF does nothing (Step 7, section 4.3.4.2@3GPP TS 23.502)
//SMF send response to AMF
//Verify, do we need this?
oai::smf_server::model::SmContextCreatedData smContextCreatedData;
//Ngap_PDUSessionResourceReleaseResponseTransfer
std::shared_ptr<Ngap_PDUSessionResourceReleaseResponseTransfer_t> decoded_msg =
std::make_shared<Ngap_PDUSessionResourceReleaseResponseTransfer_t>();
int decode_status = smf_n1_n2_inst.decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
Logger::smf_api_server().warn("asn_decode failed");
//send error to AMF
Logger::smf_app().warn(
"Decode N2 SM (Ngap_PDUSessionResourceReleaseResponseTransfer) failed!");
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
return;
}
//SMF send response to AMF
oai::smf_server::model::SmContextCreatedData smContextCreatedData; //Verify, do we need this?
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreatedData,
Pistache::Http::Code::Ok);
}
break;
......@@ -1823,7 +1890,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
Pistache::Http::Code::Forbidden);
return;
}
......
......@@ -44,6 +44,10 @@
#include "smf_config.hpp"
#include "smf_n1_n2.hpp"
extern "C" {
#include "dynamic_memory_check.h"
}
using namespace Pistache::Http;
using namespace Pistache::Http::Mime;
......@@ -124,152 +128,63 @@ void smf_n11::send_n1n2_message_transfer_request(
std::shared_ptr<itti_n11_create_sm_context_response> sm_context_res) {
//Transfer N1/N2 message via AMF by using N_amf_Communication_N1N2MessageTransfer (see TS29518_Namf_Communication.yaml)
//TODO: use RestSDK for client, use curl to send data for the moment
Logger::smf_n11().debug("Send Communication_N1N2MessageTransfer to AMF");
smf_n1_n2 smf_n1_n2_inst = { };
std::string n1_message = sm_context_res->res.get_n1_sm_message();
std::string json_part = sm_context_res->res.n1n2_message_transfer_data.dump();
std::string boundary = "----Boundary";
std::string body;
pdu_session_create_sm_context_response context_res_msg = sm_context_res->res;
std::string n1_message = context_res_msg.get_n1_sm_message();
/*
ENABLE THIS TO TEST NAS PDU SESSION ESTABLISHMENT ACCEPT
Don't forget to disable Http_response in SMF CONTEXT
std::string json_part = context_res_msg.n1n2_message_transfer_data.dump();
std::string boundary = "----Boundary";
std::string body;
create_multipart_related_content(body, json_part, boundary, n1_message, multipart_related_content_part_e::NAS);
sm_context_res->http_response.headers().add<Pistache::Http::Header::ContentType>(Pistache::Http::Mime::MediaType("multipart/related; boundary=" + boundary));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
*/
/*
//format string as hex
unsigned char *msg_hex = smf_app_inst->format_string_as_hex(n1_message);
string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
//NAS
body.append("Content-Type: application/vnd.3gpp.5gnas"+ CRLF + "Content-Id: n1SmMsg" + CRLF);
body.append(CRLF);
body.append(std::string((char *)msg_hex, n1_message.length()/2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
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, context_res_msg.get_amf_url().c_str() );
curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:sn11"); //Only for testing in all-in-one scenario
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
curl_global_cleanup();
//add N2 content if available
auto n2_sm_found = sm_context_res->res.n1n2_message_transfer_data.count(
"n2InfoContainer");
if (n2_sm_found > 0) {
std::string n2_message = sm_context_res->res.get_n2_sm_information();
//prepare the body content for Curl
create_multipart_related_content(body, json_part, boundary, n1_message,
n2_message);
} else {
//prepare the body content for Curl
create_multipart_related_content(body, json_part, boundary, n1_message,
multipart_related_content_part_e::NAS);
}
*/
//format string as hex
unsigned char *n1_msg_hex = smf_app_inst->format_string_as_hex(n1_message);
unsigned int str_len = body.length();
char *data = (char*) malloc(str_len + 1);
memset(data, 0, str_len + 1);
memcpy((void*) data, (void*) body.c_str(), str_len);
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
//N1N2MessageTransfer Notification URI??
std::string json_part = context_res_msg.n1n2_message_transfer_data.dump();
Logger::smf_n11().debug("Sending message to AMF....");
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary"); //TODO: update Boundary
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, context_res_msg.get_amf_url().c_str());
curl_easy_setopt(curl, CURLOPT_URL,
sm_context_res->res.get_amf_url().c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, smf_cfg.sbi.if_name.c_str());
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
//N1 SM Container
Logger::smf_n11().debug(
"Add N1 SM Container (NAS) into the message: %s (bytes %d)",
context_res_msg.get_n1_sm_message().c_str(),
context_res_msg.get_n1_sm_message().length() / 2);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex),
context_res_msg.get_n1_sm_message().length() / 2);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
curl_mime_name(
part,
context_res_msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"]
.dump().c_str());
auto n2_sm_found = context_res_msg.n1n2_message_transfer_data.count(
"n2InfoContainer");
if (n2_sm_found > 0) {
std::string n2_message = context_res_msg.get_n2_sm_information();
unsigned char *n2_msg_hex = smf_app_inst->format_string_as_hex(
n2_message);
Logger::smf_n11().debug(
"Add N2 SM Information (NGAP) into the message: %s (bytes %d)",
n2_message.c_str(), n2_message.length() / 2);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n2_msg_hex), 80); //TODO: n2_message.length()/2 ISSUE need to be solved
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name(
part,
context_res_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"]
.dump().c_str());
}
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
// Hook up data handling function
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
......@@ -277,7 +192,7 @@ void smf_n11::send_n1n2_message_transfer_request(
try {
response_data = json::parse(*httpData.get());
} catch (json::exception &e) {
Logger::smf_n11().error("Could not get the cause from the response");
Logger::smf_n11().warn("Could not get the cause from the response");
//Set the default Cause
response_data["cause"] = "504 Gateway Timeout";
}
......@@ -291,7 +206,7 @@ void smf_n11::send_n1n2_message_transfer_request(
itti_msg->set_response_code(httpCode);
itti_msg->set_scid(sm_context_res->scid);
itti_msg->set_cause(response_data["cause"]);
if (context_res_msg.get_cause() == REQUEST_ACCEPTED) {
if (sm_context_res->res.get_cause() == REQUEST_ACCEPTED) {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_ACCEPT);
} else {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_REJECT);
......@@ -308,9 +223,130 @@ void smf_n11::send_n1n2_message_transfer_request(
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
curl_global_cleanup();
free_wrapper((void**) &data);
/*
//Curl MIME
//format string as hex
unsigned char *n1_msg_hex = smf_app_inst->format_string_as_hex(n1_message);
CURL *curl = curl_easy_init();
//N1N2MessageTransfer Notification URI??
std::string json_part = context_res_msg.n1n2_message_transfer_data.dump();
Logger::smf_n11().debug("Sending message to AMF....");
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, context_res_msg.get_amf_url().c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, smf_cfg.sbi.if_name.c_str());
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
//N1 SM Container
Logger::smf_n11().debug(
"Add N1 SM Container (NAS) into the message: %s (bytes %d)",
context_res_msg.get_n1_sm_message().c_str(),
context_res_msg.get_n1_sm_message().length() / 2);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex),
context_res_msg.get_n1_sm_message().length() / 2);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
curl_mime_name(
part,
context_res_msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"]
.dump().c_str());
auto n2_sm_found = context_res_msg.n1n2_message_transfer_data.count(
"n2InfoContainer");
if (n2_sm_found > 0) {
std::string n2_message = context_res_msg.get_n2_sm_information();
unsigned char *n2_msg_hex = smf_app_inst->format_string_as_hex(
n2_message);
Logger::smf_n11().debug(
"Add N2 SM Information (NGAP) into the message: %s (bytes %d)",
n2_message.c_str(), n2_message.length() / 2);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n2_msg_hex), 80); //TODO: n2_message.length()/2 ISSUE need to be solved
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name(
part,
context_res_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"]
.dump().c_str());
}
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
json response_data = { };
try {
response_data = json::parse(*httpData.get());
} catch (json::exception &e) {
Logger::smf_n11().error("Could not get the cause from the response");
//Set the default Cause
response_data["cause"] = "504 Gateway Timeout";
}
Logger::smf_n11().debug("Response from AMF, Http Code: %d, cause %s",
httpCode, response_data["cause"].dump().c_str());
//send response to APP to process
itti_n11_n1n2_message_transfer_response_status *itti_msg =
new itti_n11_n1n2_message_transfer_response_status(TASK_SMF_N11,
TASK_SMF_APP);
itti_msg->set_response_code(httpCode);
itti_msg->set_scid(sm_context_res->scid);
itti_msg->set_cause(response_data["cause"]);
if (context_res_msg.get_cause() == REQUEST_ACCEPTED) {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_ACCEPT);
} else {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_REJECT);
}
std::shared_ptr<itti_n11_n1n2_message_transfer_response_status> i =
std::shared_ptr<itti_n11_n1n2_message_transfer_response_status>(
itti_msg);
int ret = itti_inst->send_msg(i);
if (RETURNok != ret) {
Logger::smf_n11().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
i->get_msg_name());
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
*/
}
//------------------------------------------------------------------------------
......
......@@ -109,7 +109,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//Extended Protocol Discriminator
sm_msg->header.extended_protocol_discriminator =
EPD_5GS_SESSION_MANAGEMENT_MESSAGES;
//Message Type
//PDU Session Identity
sm_msg->header.pdu_session_identity = msg.get_pdu_session_id();
switch (n1_msg_type) {
......@@ -131,7 +131,6 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//get default QoS value
qos_flow_context_updated qos_flow = { };
qos_flow = sm_context_res.get_qos_flow_context();
//TODO: to be completed
//get the default QoS profile and assign to the NAS message
......@@ -156,7 +155,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
sm_msg->header.procedure_transaction_identity,
sm_msg->header.message_type);
//Fill the content of PDU Session Establishment Request message
//Fill the content of PDU Session Establishment Accept message
//PDU Session Type
sm_msg->pdu_session_establishment_accept._pdusessiontype
.pdu_session_type_value = sm_context_res.get_pdu_session_type();
......@@ -277,10 +276,12 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
.get_snssai().sST;
try {
sm_msg->pdu_session_establishment_accept.snssai.sd = std::stoi(
sm_context_res.get_snssai().sD);
sm_msg->pdu_session_establishment_accept.snssai.sd = std::stoul(
sm_context_res.get_snssai().sD, nullptr, 16);
} catch (const std::exception &e) {
Logger::smf_app().warn("Error when converting from string to int for snssai.SD, error: %s", e.what());
Logger::smf_app().warn(
"Error when converting from string to int for snssai.SD, error: %s",
e.what());
//"no SD value associated with the SST"
sm_msg->pdu_session_establishment_accept.snssai.sd = 0xFFFFFF;
}
......@@ -358,7 +359,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//1 - PDU Session Create SM Context Response (PDU Session Establishment procedure - reject)
//2 - N1N2MessageTransfer Request (PDU Session Establishment procedure - reject)
//3- PDU Session Update SM Context Response (PDU Session Establishment procedure - reject)​
//PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE or PDU_SESSION_CREATE_SM_CONTEXT_REQUEST
//PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE or PDU_SESSION_CREATE_SM_CONTEXT_REQUEST
Logger::smf_app().info(
"PDU_SESSION_ESTABLISHMENT_REJECT, encode starting...");
......@@ -386,7 +387,8 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
sm_msg->pdu_session_establishment_reject._5gsmcause =
static_cast<uint8_t>(sm_cause);
//Presence
sm_msg->pdu_session_establishment_reject.presence = 0x00;
sm_msg->pdu_session_establishment_reject.presence =
PDU_SESSION_ESTABLISHMENT_REJECT_ALLOWED_SSC_MODE_PRESENCE; //Should be updated according to the following IEs
/*
//GPRSTimer3
sm_msg->pdu_session_establishment_reject.gprstimer3.unit =
......@@ -436,8 +438,6 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
.is_ssc2_allowed,
sm_msg->pdu_session_establishment_reject.allowedsscmode
.is_ssc3_allowed);
//Logger::smf_app().debug("SM MSG, GPSR Timer3, unit: 0x%x, value: 0x%x",sm_msg->pdu_session_establishment_reject.gprstimer3.unit,sm_msg->pdu_session_establishment_reject.gprstimer3.timeValue);
//Logger::smf_app().debug("SM MSG, 5G SM Congestion Re-attempt Indicator: 0x%x",sm_msg->pdu_session_establishment_reject._5gsmcongestionreattemptindicator.abo);
//Encode NAS message
bytes = nas_message_encode(data, &nas_msg,
......@@ -455,7 +455,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
break;
case PDU_SESSION_MODIFICATION_COMMAND: {
//PDU Session Modification Command is included in the following msgs:
//PDU Session Modification Command is included in the following messages:
//1- PDU Session Update SM Context Response (PDU Session Modification UE-Initiated procedure - step 1)
//2- N1N2MessageTransfer Request (PDU Session Modification SMF-Requested, step 1 (from SMF to AMF)) ​
......@@ -469,19 +469,35 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
"PDU_SESSION_MODIFICATION_COMMAND, encode starting...");
//Fill the content of PDU Session Establishment Request message with hardcoded values (to be completed)
//Message Type
sm_msg->header.message_type = PDU_SESSION_MODIFICATION_COMMAND;
//PTI
sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti()
.procedure_transaction_id;
//Message Type
sm_msg->header.message_type = PDU_SESSION_MODIFICATION_COMMAND;
//PDU Session Type
sm_msg->pdu_session_modification_command.messagetype = sm_context_res
.get_msg_type();
//Presence
sm_msg->pdu_session_modification_command.presence = 0xff; //TODO: to be updated
//5GSMCause
sm_msg->pdu_session_modification_command._5gsmcause = sm_context_res
.get_cause();
sm_msg->pdu_session_modification_command._5gsmcause =
static_cast<uint8_t>(sm_cause); //sm_context_res.get_cause();
/*
ExtendedProtocolDiscriminator extendedprotocoldiscriminator;
PDUSessionIdentity pdusessionidentity;
ProcedureTransactionIdentity proceduretransactionidentity;
MessageType messagetype;
uint8_t presence;
_5GSMCause _5gsmcause;
SessionAMBR sessionambr;
GPRSTimer gprstimer;
AlwaysonPDUSessionIndication alwaysonpdusessionindication;
QOSRules qosrules;
MappedEPSBearerContexts mappedepsbearercontexts;
QOSFlowDescriptions qosflowdescriptions;
ExtendedProtocolConfigurationOptions extendedprotocolconfigurationoptions;
*/
//SessionAMBR
//TODO: get from subscription DB
......@@ -590,7 +606,6 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//this IE is included in the following message
//1 - PDU Session Update SM Context Response (PDU Session Release UE-Initiated, step 1)
//2 - N1N2MessageTransfer Request (PDU Session Release SMF-Requested, step 1)
//TODO: to be completed
Logger::smf_app().debug(
"[Create N1 SM Message] PDU Session Release Command");
......@@ -599,26 +614,68 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
static_cast<pdu_session_update_sm_context_response&>(msg);
Logger::smf_app().info("PDU_SESSION_RELEASE_COMMAND, encode starting...");
//Fill the content of PDU Session Release Command (with hardcoded values)
//Message Type
sm_msg->header.message_type = PDU_SESSION_RELEASE_COMMAND;
//Fill the content of PDU Session Release Command
//PDU Session ID
sm_msg->header.pdu_session_identity = sm_context_res.get_pdu_session_id();
//PTI
sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti()
.procedure_transaction_id;
//PDU Session Type
sm_msg->pdu_session_release_command.messagetype = sm_context_res
.get_msg_type();
//Message Type
sm_msg->header.message_type = PDU_SESSION_RELEASE_COMMAND;
//5GSMCause
sm_msg->pdu_session_release_command._5gsmcause =
sm_context_res.get_cause();
static_cast<uint8_t>(sm_cause); //sm_context_res.get_cause();
//Presence
sm_msg->pdu_session_modification_command.presence = 0x00; //TODO: to be updated
sm_msg->pdu_session_release_command.presence = 0x00; //TODO: to be updated when adding the following IEs
//GPRSTimer3
//EAPMessage
//_5GSMCongestionReattemptIndicator
// ExtendedProtocolConfigurationOptions
Logger::smf_app().debug("SM MSG, 5GSM Cause: 0x%x, %d",
sm_msg->pdu_session_release_command._5gsmcause,
static_cast<uint8_t>(sm_cause));
//Encode NAS message
bytes = nas_message_encode(data, &nas_msg,
sizeof(data)/*don't know the size*/, nullptr);
Logger::smf_app().debug("Buffer Data: ");
for (int i = 0; i < bytes; i++)
printf("%02x ", data[i]);
printf(" (bytes %d)\n", bytes);
std::string n1Message((char*) data, bytes);
nas_msg_str = n1Message;
}
break;
case PDU_SESSION_RELEASE_REJECT: {
//This IE is included in the PDU Session Update SM Context Response (PDU Session Release UE-Initiated, step 1)
Logger::smf_app().debug(
"[Create N1 SM Message] PDU Session Release Reject");
Logger::smf_app().info("PDU_SESSION_RELEASE_REJECT, encode starting...");
pdu_session_update_sm_context_response &sm_context_res =
static_cast<pdu_session_update_sm_context_response&>(msg);
//Fill the content of PDU Session Release Reject
//PDU Session ID
sm_msg->header.pdu_session_identity = sm_context_res.get_pdu_session_id();
//PTI
sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti()
.procedure_transaction_id;
//Message Type
sm_msg->header.message_type = PDU_SESSION_RELEASE_REJECT;
//5GSMCause
sm_msg->pdu_session_release_reject._5gsmcause =
static_cast<uint8_t>(sm_cause); //sm_context_res.get_cause();
//Presence
sm_msg->pdu_session_release_command.presence = 0x00; //TODO: to be updated when adding the following IE
//Extended protocol configuration options
//Encode NAS message
bytes = nas_message_encode(data, &nas_msg,
sizeof(data)/*don't know the size*/, nullptr);
......@@ -1505,3 +1562,33 @@ int smf_n1_n2::decode_n2_sm_information(
}
//---------------------------------------------------------------------------------------------
int smf_n1_n2::decode_n2_sm_information(
std::shared_ptr<Ngap_PDUSessionResourceReleaseResponseTransfer_t> &ngap_IE,
std::string &n2_sm_info) {
Logger::smf_app().info(
"Decode NGAP message (Ngap_PDUSessionResourceReleaseResponseTransfer) from N2 SM Information");
unsigned int data_len = n2_sm_info.length();
unsigned char *data = (unsigned char*) malloc(data_len + 1);
memset(data, 0, data_len + 1);
memcpy((void*) data, (void*) n2_sm_info.c_str(), data_len);
//Ngap_PDUSessionResourceModifyResponseTransfer
asn_dec_rval_t rc = asn_decode(
nullptr, ATS_ALIGNED_CANONICAL_PER,
&asn_DEF_Ngap_PDUSessionResourceReleaseResponseTransfer,
(void**) &ngap_IE, (void*) data, data_len);
//free memory
free_wrapper((void**) &data);
if (rc.code != RC_OK) {
Logger::smf_api_server().warn("asn_decode failed with code %d", rc.code);
return RETURNerror ;
}
return RETURNok ;
}
......@@ -56,6 +56,7 @@ extern "C" {
#include "Ngap_NGAP-PDU.h"
#include "Ngap_PDUSessionResourceSetupResponseTransfer.h"
#include "Ngap_PDUSessionResourceModifyResponseTransfer.h"
#include "Ngap_PDUSessionResourceReleaseResponseTransfer.h"
}
namespace smf {
......@@ -121,6 +122,16 @@ class smf_n1_n2 {
std::shared_ptr<Ngap_PDUSessionResourceModifyResponseTransfer_t> &ngap_IE,
std::string &n2_sm_info);
/*
* Decode N2 SM Information Ngap_PDUSessionResourceReleaseResponseTransfer_t
* @param [std::shared_ptr<Ngap_PDUSessionResourceReleaseResponseTransfer_t>&] ngap_IE Store decoded NGAP message
* @param [std::string&] n2_sm_info N2 SM Information
* @return status of the decode process
*/
int decode_n2_sm_information(
std::shared_ptr<Ngap_PDUSessionResourceReleaseResponseTransfer_t> &ngap_IE,
std::string &n2_sm_info);
};
} // namespace smf
......
......@@ -389,8 +389,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
Logger::smf_app().debug(
"Prepare a PDU Session Establishment Accept message and send to UE");
smf_n1_n2_inst.create_n1_sm_container(n11_triggered_pending->res,
PDU_SESSION_ESTABLISHMENT_ACCEPT,
n1_sm_msg,
PDU_SESSION_ESTABLISHMENT_ACCEPT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_0_UNKNOWN); //TODO: need cause?
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex);
......@@ -1100,6 +1099,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES); //TODO: check Cause
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex);
//N2 SM Information
smf_n1_n2_inst.create_n2_sm_information(
n11_triggered_pending->res, 1, n2_sm_info_type_e::PDU_RES_REL_CMD,
......
......@@ -127,6 +127,8 @@ int main(int argc, char* argv[]) {
SubscriptionsCollectionDocumentApiImpl SubscriptionsCollectionDocumentApiserver(router);
SubscriptionsCollectionDocumentApiserver.init();
std::cout << "AMF server is listening on address: " << amf_ip_address.c_str() << std::endl;
httpEndpoint->setHandler(router->handler());
httpEndpoint->serve();
......
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdexcept>
/*
* 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;
......@@ -22,35 +19,180 @@ static std::size_t callback(
*(uint8_t*)(buffer) = value; \
size += sizeof(uint8_t)
void send_pdu_session_establishment_request(std::string smf_ip_address)
{
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Create)"<<std::endl;
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,
-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, -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, -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;
for (;;) {
int high, low;
while (*hex && isspace(*hex))
hex++;
if (!*hex)
return 1;
high = ascii_to_hex_table[*hex++];
if (high < 0)
return 0;
while (*hex && isspace(*hex))
hex++;
if (!*hex)
return 0;
low = ascii_to_hex_table[*hex++];
if (low < 0)
return 0;
dst[i++] = (high << 4) | low;
}
}
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);
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);
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]);
printf("\n");
//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) {
//format string as hex
//unsigned char *n1_msg_hex = format_string_as_hex(n1_message);
//unsigned char *n2_msg_hex = format_string_as_hex(n2_message);
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF + "Content-Id: n1SmMsg"
+ CRLF);
body.append(CRLF);
//body.append(std::string((char*) n1_msg_hex, n1_message.length() / 2) + CRLF);
body.append(n1_message + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
+ CRLF);
body.append(CRLF);
//body.append(std::string((char*) n2_msg_hex, n2_message.length() / 2) + CRLF);
body.append(n2_message + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
//------------------------------------------------------------------------------
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) {
//format string as hex
//unsigned char *msg_hex = format_string_as_hex(message);
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
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
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
+ CRLF);
}
body.append(CRLF);
//body.append(std::string((char*) msg_hex, message.length() / 2) + CRLF);
body.append(message + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
//------------------------------------------------------------------------------
void send_pdu_session_establishment_request(std::string smf_ip_address) {
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Create)"
<< std::endl;
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, 0x01 , 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++)
{
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, 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++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: "<<std::endl;
std::cout << "Buffer: " << std::endl;
//Fill Json part
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts"));
......@@ -59,7 +201,7 @@ void send_pdu_session_establishment_request(std::string smf_ip_address)
pdu_session_establishment_request["supi"] = "imsi-200000000000001";
pdu_session_establishment_request["pei"] = "imei-200000000000001";
pdu_session_establishment_request["gpsi"] = "msisdn-200000000001";
pdu_session_establishment_request["dnn"] = "carrier.com";
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"] = 1;
......@@ -68,499 +210,463 @@ void send_pdu_session_establishment_request(std::string smf_ip_address)
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["smContextStatusUri"] = "smContextStatusUri";
pdu_session_establishment_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
pdu_session_establishment_request["smContextStatusUri"] =
"smContextStatusUri";
pdu_session_establishment_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string json_part = pdu_session_establishment_request.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
CURL *curl = curl_easy_init();
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
std::string json_part = pdu_session_establishment_request.dump();
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
std::cout<< "Sending message to SMF....\n";
if(curl) {
CURLcode res;
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
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_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
part = curl_mime_addpart(mime);
//curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex), CURL_ZERO_TERMINATED);
curl_mime_data(part, reinterpret_cast<const char*>(buffer), size);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
curl_mime_name (part, "n1SmMsg");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode(0);
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try{
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception& e){
std::cout << "Could not get the cause from the response" <<std::endl;
} catch (nlohmann::json::exception &e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout << "[AMF N11] PDU session establishment request, response from SMF, Http Code " << httpCode <<std::endl;
std::cout
<< "[AMF N11] PDU session establishment request, response from SMF, Http Code "
<< httpCode << std::endl;
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
curl_global_cleanup();
free(buffer);
}
void send_pdu_session_update_sm_context_establishment(std::string smf_ip_address)
{
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Update)"<<std::endl;
//------------------------------------------------------------------------------
void send_pdu_session_update_sm_context_establishment(
std::string smf_ip_address) {
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Update)"
<< std::endl;
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 3c
00 03 e0 ac 0a 05 01 00 00 00 01 00 3c
*/
size_t buffer_size = 128;
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, 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 3c
ENCODE_U8 (buffer+size, 0x3c , size); //QFI: 60
std::cout << "Buffer: "<<std::endl;
for(int i=0;i<2;i++)
{
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, 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 3c
ENCODE_U8(buffer + size, 0x3c, size); //QFI: 60
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: "<<std::endl;
std::cout << "Buffer: " << std::endl;
//Fill Json part
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
pdu_session_update_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
CURL *curl = curl_easy_init();
//pdu_session_update_request["n2InfoContainer"]["n2InformationClass"] = "SM";
//pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2SmMsg";
// pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
// "PDU_RES_SETUP_RSP"; //NGAP message
std::string body;
std::string boundary = "----Boundary";
std::string json_part = pdu_session_update_request.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
std::cout<< "Sending message to SMF....\n";
if(curl) {
create_multipart_related_content(body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
CURLcode res;
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
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();
headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
if (curl) {
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_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(buffer), size);
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name (part, "n2SmMsg");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode(0);
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try{
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception& e){
std::cout << "Could not get the cause from the response" <<std::endl;
} catch (nlohmann::json::exception &e) {
std::cout << "Could not get json data from the response" << std::endl;
//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, response from SMF, Http Code "
<< httpCode << " cause " << response_data["cause"].dump().c_str()
<< std::endl;
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
curl_global_cleanup();
free(buffer);
}
//------------------------------------------------------------------------------
void send_pdu_session_release_request(std::string smf_ip_address) {
void send_pdu_session_release_request(std::string smf_ip_address)
{
std::cout << "[AMF N11] PDU Session Release Request (SM Context Update)"<<std::endl;
std::cout << "[AMF N11] PDU Session Release Request (SM Context Update)"
<< std::endl;
nlohmann::json pdu_session_release_request;
//encode
//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, 0x01 , 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++)
{
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, 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++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: "<<std::endl;
std::cout << "Buffer: " << std::endl;
//Fill Json part
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
pdu_session_release_request["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
pdu_session_release_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
CURL *curl = curl_easy_init();
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 json_part = pdu_session_release_request.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
std::cout<< "Sending message to SMF....\n";
if(curl) {
CURLcode res;
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
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);
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();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
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_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
part = curl_mime_addpart(mime);
//curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex), CURL_ZERO_TERMINATED);
curl_mime_data(part, reinterpret_cast<const char*>(buffer), size);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
//curl_mime_name (part, "n1SmMsg");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode(0);
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try{
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception& e){
std::cout << "Could not get the cause from the response" <<std::endl;
} 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_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
curl_global_cleanup();
free(buffer);
}
void send_pdu_session_release_resource_release_ack(std::string smf_ip_address)
{
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(
std::string smf_ip_address) {
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
//encode PDU Session Resource Release 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);
std::cout << "Buffer: "<<std::endl;
for(int i=0;i<size;i++)
{
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: "<<std::endl;
std::cout << "Buffer: " << std::endl;
//Fill Json part
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
//Fill the json part
pdu_session_release_ack["n2SmInfoType"] = "PDU_RES_REL_RSP";
pdu_session_release_ack["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
CURL *curl = curl_easy_init();
pdu_session_release_ack["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
std::string body;
std::string boundary = "----Boundary";
std::string json_part = pdu_session_release_ack.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
std::cout<< "Sending message to SMF....\n";
if(curl) {
CURLcode res;
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
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);
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();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
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_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
part = curl_mime_addpart(mime);
//curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex), CURL_ZERO_TERMINATED);
curl_mime_data(part, reinterpret_cast<const char*>(buffer), size);
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name (part, "n2SmMsg");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode(0);
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try{
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception& e){
std::cout << "Could not get the cause from the response" <<std::endl;
} 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 " << httpCode <<std::endl;
std::cout
<< "[AMF N11] PDU Session Establishment Request, response from SMF, Http Code "
<< httpCode << std::endl;
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
curl_global_cleanup();
free(buffer);
}
//------------------------------------------------------------------------------
void send_pdu_session_release_complete(std::string smf_ip_address) {
void send_pdu_session_release_complete(std::string smf_ip_address)
{
std::cout << "[AMF N11] PDU Session Release Complete (Update SM Context): N1 SM - PDU Session Release Complete"<<std::endl;
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
//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, 0x01 , 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++)
{
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, 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++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: "<<std::endl;
std::cout << "Buffer: " << std::endl;
//Fill Json part
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
pdu_session_release_complete["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
pdu_session_release_complete["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
pdu_session_release_complete["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
pdu_session_release_complete["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
//pdu_session_release_complete["n1MessageContainer"]["n1MessageClass"] = "SM";
//pdu_session_release_complete["n1MessageContainer"]["n1MessageContent"]["contentId"] = "n1SmMsg";
std::string body;
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);
CURL *curl = curl_easy_init();
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
std::string json_part = pdu_session_release_complete.dump();
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
std::cout<< "Sending message to SMF....\n";
if(curl) {
CURLcode res;
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
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_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
part = curl_mime_addpart(mime);
//curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex), CURL_ZERO_TERMINATED);
curl_mime_data(part, reinterpret_cast<const char*>(buffer), size);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
curl_mime_name (part, "n1SmMsg");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode(0);
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try{
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception& e){
std::cout << "Could not get the cause from the response" <<std::endl;
} 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_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
curl_global_cleanup();
free(buffer);
}
int main(int argc, char* argv[])
{
//------------------------------------------------------------------------------
int main(int argc, char *argv[]) {
std::string smf_ip_address;
if ((argc != 1) && (argc != 3)) {
std::cout << "Error: Usage is " <<std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz ]" <<std::endl;
std::cout << "Error: Usage is " << std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz ]" << std::endl;
return -1;
}
......@@ -569,15 +675,15 @@ int main(int argc, char* argv[])
} else {
int opt = 0;
while ((opt = getopt(argc, argv, "i:")) != -1) {
switch(opt) {
case 'i':
smf_ip_address.append(optarg);
break;
default:
std::cout << "Error: Usage is " <<std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz ]" <<std::endl;
return -1;
break;
switch (opt) {
case 'i':
smf_ip_address.append(optarg);
break;
default:
std::cout << "Error: Usage is " << std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz ]" << std::endl;
return -1;
break;
}
}
}
......
{
"jsonData": {
"supi": "208931234561000",
"pei": "pei",
"gpsi": "gpsi",
"pduSessionId": 5,
"dnn": "default",
"sNssai": {"sst":1, "sd":123},
"hplmnSnssai": {"sst":1, "sd": 345},
"servingNfId": "",
"guami": {"plmnId": {"mcc": "122", "mnc":"13"}, "amfId":"2"},
"serviceName": "",
"servingNetwork": {"mcc": "122", "mnc":"13"},
"requestType": 1,
"anType": "",
"secondAnType": "",
"ratType": "",
"presenceInLadn": "",
"ueTimeZone": "",
"smContextStatusUri": "",
"hSmfUri": "",
"additionalHsmfUri": [],
"oldPduSessionId": 1,
"pduSessionsActivateList": [1,2],
"ueEpsPdnConnection": "",
"hoState": "",
"pcfId": "",
"nrfUi": "",
"supportedFeatures": "",
"selMode": "VERIFIED",
"udmGroupId": "",
"routingIndicator": "",
"epsBearerCtxStatus": "",
"cpCiotEnabled": true,
"invokeNef": true,
"maPduIndication": false,
"smContextRef": "",
"n2SmInfo": {"contentId":"n2SmInfo"},
"n1SmMsg": {"contentId":"n1SmMsg"}
},
"binaryDataN1SmMessage":"2e031fc100ff93a2390f616263646566406768696a6b2e6c6d",
"binaryDataN1SmMessage_full":"00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 02 00 55 00 01 40 00 40 84 3c 25 7f 00 00 01 7f 00 00 01 df b0 96 0c ea 4c f5 4b 00 00 00 00 00 03 00 35 20 bc ec 86 00 00 00 00 00 00 00 00 00 0f 40 21 00 00 01 00 26 00 1a 19 2e 03 1f c1 00 ff 93 a2 39 0f 61 62 63 64 65 66 40 67 68 69 6a 6b 2e 6c 6d"
}
{
"jsonData": {
"supi": "supi",
"pei": "pei",
"gpsi": "gpsi",
"pduSessionId": 1,
"dnn": "dnn",
"sNssai": {"sst":1, "sd":"sd"},
"hplmnSnssai": {"sst":1, "sd":"sd"},
"servingNfId": "",
"guami": {"plmnId": {"mcc": "122", "mnc":"13"}, "amfId":"2"},
"serviceName": "",
"servingNetwork": {"mcc": "122", "mnc":"13"},
"requestType": "",
"anType": "",
"secondAnType": "",
"ratType": "",
"presenceInLadn": "",
"ueLocation": "",
"ueTimeZone": "",
"addUeLocation": "",
"smContextStatusUri": "",
"hSmfUri": "",
"additionalHsmfUri": [],
"oldPduSessionId": "",
"pduSessionsActivateList": [1,2],
"ueEpsPdnConnection": "",
"hoState": "",
"pcfId": "",
"nrfUi": "",
"supportedFeatures": "",
"selMode": "",
"backupAmfInfo": [],
"traceData": "",
"udmGroupId": "",
"routingIndicator": "",
"epsInterworkingInd": "",
"indirectForwardingFlag": "",
"targetId": "",
"epsBearerCtxStatus": "",
"cpCiotEnabled": "",
"invokeNef": "",
"maPduIndication": "",
"smContextRef": "",
"n2SmInfo": "",
"n1SmMsg": {"contentId":"contentId"}
},
"binaryDataN1SmMessage":"binaryDataN1SmMessage",
"binaryDataN2SmInformation": "binaryDataN2SmInformation"
}
00000 00 00 00 00 00 00 00 00
00008 00 00 00 00 08 00 45 02
00010 00 55 00 01 40 00 40 84
00018 3c 25 7f 00 00 01 7f 00
00020 00 01 df b0 96 0c ea 4c
00028 f5 4b 00 00 00 00 00 03
00030 00 35 20 bc ec 86 00 00
00038 00 00 00 00 00 00 00 0f
00040 40 21 00 00 01 00 26 00
00048 1a 19 2e 03 1f c1 00 ff
00050 93 a2 39 0f 61 62 63 64
00058 65 66 40 67 68 69 6a 6b
00060 2e 6c 6d
{
"singleNssai": {"sst":1, "sd":123},
"dnnConfigurations": {
"default": {
"pduSessionTypes": {"defaultSessionType": "IPV4"} ,
"sscModes": {"defaultSscMode": "SSC_MODE_1"} ,
"5gQosProfile": {"5qi": 12345, "arp": {"priorityLevel": 1 , "preemptCap": "NOT_PREEMPT" , "preemptVuln": "NOT_PREEMPTABLE"} },
"sessionAmbr": {"uplink": "10Mbps", "downlink":"11Mbps"}
}
}
}
......@@ -44,14 +44,23 @@ void SessionManagementSubscriptionDataRetrievalApiImpl::get_sm_data(const std::s
nlohmann::json jsonData;
jsonData["singleNssai"]["sst"] = 222;
jsonData["singleNssai"]["sd"] = 123;
jsonData["dnnConfigurations"]["carrier.com"]["pduSessionTypes"]["defaultSessionType"] = "IPV4";
jsonData["dnnConfigurations"]["carrier.com"]["sscModes"]["defaultSscMode"] = "SSC_MODE_1";
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["5qi"] = 60;
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["arp"]["priorityLevel"] = 1;
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["arp"]["preemptCap"] = "NOT_PREEMPT";
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["arp"]["preemptVuln"] = "NOT_PREEMPTABLE";
jsonData["dnnConfigurations"]["carrier.com"]["sessionAmbr"]["uplink"] = "10Mbps";
jsonData["dnnConfigurations"]["carrier.com"]["sessionAmbr"]["downlink"] = "11Mbps";
jsonData["dnnConfigurations"]["default"]["pduSessionTypes"]["defaultSessionType"] = "IPV4";
jsonData["dnnConfigurations"]["default"]["sscModes"]["defaultSscMode"] = "SSC_MODE_1";
jsonData["dnnConfigurations"]["default"]["5gQosProfile"]["5qi"] = 60;
jsonData["dnnConfigurations"]["default"]["5gQosProfile"]["arp"]["priorityLevel"] = 1;
jsonData["dnnConfigurations"]["default"]["5gQosProfile"]["arp"]["preemptCap"] = "NOT_PREEMPT";
jsonData["dnnConfigurations"]["default"]["5gQosProfile"]["arp"]["preemptVuln"] = "NOT_PREEMPTABLE";
jsonData["dnnConfigurations"]["default"]["sessionAmbr"]["uplink"] = "20Mbps";
jsonData["dnnConfigurations"]["default"]["sessionAmbr"]["downlink"] = "22Mbps";
jsonData["dnnConfigurations"]["carrier.com"]["pduSessionTypes"]["defaultSessionType"] = "IPV4";
jsonData["dnnConfigurations"]["carrier.com"]["sscModes"]["defaultSscMode"] = "SSC_MODE_1";
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["5qi"] = 61;
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["arp"]["priorityLevel"] = 1;
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["arp"]["preemptCap"] = "NOT_PREEMPT";
jsonData["dnnConfigurations"]["carrier.com"]["5gQosProfile"]["arp"]["preemptVuln"] = "NOT_PREEMPTABLE";
jsonData["dnnConfigurations"]["carrier.com"]["sessionAmbr"]["uplink"] = "10Mbps";
jsonData["dnnConfigurations"]["carrier.com"]["sessionAmbr"]["downlink"] = "11Mbps";
/*
SessionManagementSubscriptionData subscriptionData;
......
......@@ -117,7 +117,6 @@ int main(int argc, char* argv[]) {
opts.flags(Pistache::Tcp::Options::ReuseAddr);
opts.maxPayload(PISTACHE_SERVER_MAX_PAYLOAD);
httpEndpoint->init(opts);
AccessAndMobilitySubscriptionDataRetrievalApiImpl AccessAndMobilitySubscriptionDataRetrievalApiserver(router);
AccessAndMobilitySubscriptionDataRetrievalApiserver.init();
......@@ -160,9 +159,12 @@ int main(int argc, char* argv[]) {
UEContextInSMSFDataRetrievalApiImpl UEContextInSMSFDataRetrievalApiserver(router);
UEContextInSMSFDataRetrievalApiserver.init();
std::cout << "UDM is listening on address: " << udm_ip_address.c_str() << std::endl;
httpEndpoint->setHandler(router->handler());
httpEndpoint->serve();
httpEndpoint->shutdown();
}
......
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