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

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) {