Commit 6b5e7d46 authored by Stefan Spettel's avatar Stefan Spettel

refact(smf): Send PDU session establishment reject as response to request if applicable

Signed-off-by: default avatarStefan Spettel <stefan.spettel@phine.tech>
parent d0ddfa2d
...@@ -1433,21 +1433,13 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1433,21 +1433,13 @@ void smf_context::handle_pdu_session_create_sm_context_request(
Logger::smf_app().warn( Logger::smf_app().warn(
"Received a PDU Session Create SM Context Request, the request is not " "Received a PDU Session Create SM Context Request, the request is not "
"valid!"); "valid!");
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject( send_pdu_session_establishment_response_reject(
smreq->req, n1_sm_message, smreq,
cause_value_5gsm_e:: cause_value_5gsm_e::
CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED)) { CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED,
conv::convert_string_2_hex(n1_sm_message, n1_sm_msg_hex); pdu_session_application_error_e::
// trigger to send reply to AMF PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED,
smf_app_inst->trigger_create_context_error_response( http_status_code_e::HTTP_STATUS_CODE_401_UNAUTHORIZED);
http_status_code_e::HTTP_STATUS_CODE_401_UNAUTHORIZED,
PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED, n1_sm_msg_hex,
smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
// TODO: // TODO:
// SMF unsubscribes to the modifications of Session Management Subscription // SMF unsubscribes to the modifications of Session Management Subscription
// data for (SUPI, DNN, S-NSSAI) using Nudm_SDM_Unsubscribe() // data for (SUPI, DNN, S-NSSAI) using Nudm_SDM_Unsubscribe()
...@@ -1606,10 +1598,12 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1606,10 +1598,12 @@ void smf_context::handle_pdu_session_create_sm_context_request(
set_paa = true; set_paa = true;
} else { } else {
// ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED; // ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED;
set_paa = false; send_pdu_session_establishment_response_reject(
request_accepted = false; smreq, cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES,
sm_context_resp_pending->res.set_cause(static_cast<uint8_t>( pdu_session_application_error_e::
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES)); PDU_SESSION_APPLICATION_ERROR_INSUFFICIENT_RESOURCES_SLICE_DNN,
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
return;
} }
} else if ((paa_static_ip) && (paa.is_ip_assigned())) { } else if ((paa_static_ip) && (paa.is_ip_assigned())) {
set_paa = true; set_paa = true;
...@@ -1634,11 +1628,12 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1634,11 +1628,12 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (success) { if (success) {
set_paa = true; set_paa = true;
} else { } else {
// ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED; send_pdu_session_establishment_response_reject(
set_paa = false; smreq, cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES,
request_accepted = false; pdu_session_application_error_e::
sm_context_resp_pending->res.set_cause(static_cast<uint8_t>( PDU_SESSION_APPLICATION_ERROR_INSUFFICIENT_RESOURCES_SLICE_DNN,
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES)); http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
return;
} }
} else if ((paa_static_ip) && (paa.is_ip_assigned())) { } else if ((paa_static_ip) && (paa.is_ip_assigned())) {
...@@ -1651,7 +1646,13 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1651,7 +1646,13 @@ void smf_context::handle_pdu_session_create_sm_context_request(
Logger::smf_app().info( Logger::smf_app().info(
"UE requests to use DHCPv4 for IPv4 address assignment, this " "UE requests to use DHCPv4 for IPv4 address assignment, this "
"feature has not been supported yet!"); "feature has not been supported yet!");
request_accepted = false; // TODO maybe find a better response code
send_pdu_session_establishment_response_reject(
smreq, cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE,
pdu_session_application_error_e::
PDU_SESSION_APPLICATION_ERROR_PDUTYPE_NOT_SUPPORTED,
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN);
return;
// TODO // TODO
} }
...@@ -1659,30 +1660,27 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1659,30 +1660,27 @@ void smf_context::handle_pdu_session_create_sm_context_request(
case PDU_SESSION_TYPE_E_IPV6: { case PDU_SESSION_TYPE_E_IPV6: {
// TODO: // TODO:
Logger::smf_app().debug("IPv6 has not been supported yet!"); Logger::smf_app().warn("IPv6 is not supported yet!");
request_accepted = false; // PDU Session Establishment Reject
send_pdu_session_establishment_response_reject(
smreq, cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE,
pdu_session_application_error_e::
PDU_SESSION_APPLICATION_ERROR_PDUTYPE_NOT_SUPPORTED,
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN);
return;
} break; } break;
default: { default: {
Logger::smf_app().error( Logger::smf_app().error(
"Unknown PDN type %d", sp->pdu_session_type.pdu_session_type); "Unknown PDN type %d", sp->pdu_session_type.pdu_session_type);
// PDU Session Establishment Reject // PDU Session Establishment Reject
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject( send_pdu_session_establishment_response_reject(
smreq->req, n1_sm_message, smreq, cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE,
cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE)) { pdu_session_application_error_e::
conv::convert_string_2_hex(n1_sm_message, n1_sm_msg_hex); PDU_SESSION_APPLICATION_ERROR_PDUTYPE_NOT_SUPPORTED,
// trigger to send reply to AMF http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN);
smf_app_inst->trigger_create_context_error_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
PDU_SESSION_APPLICATION_ERROR_PDUTYPE_DENIED, n1_sm_msg_hex,
smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
// sm_context_resp_pending->res.set_cause(static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE)); // sm_context_resp_pending->res.set_cause(static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE));
request_accepted = false; return;
} }
} }
...@@ -1724,74 +1722,54 @@ void smf_context::handle_pdu_session_create_sm_context_request( ...@@ -1724,74 +1722,54 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// Step 9. Create session establishment procedure and run the procedure // Step 9. Create session establishment procedure and run the procedure
// if request is accepted // if request is accepted
if (request_accepted) { if (set_paa) {
if (set_paa) { sm_context_resp_pending->res.set_paa(paa);
sm_context_resp_pending->res.set_paa(paa); sp->set(paa);
sp->set(paa); }
} else {
// TODO:
}
// Trigger SMF APP to send response to SMF-HTTP-API-SERVER (Step // Trigger SMF APP to send response to SMF-HTTP-API-SERVER (Step
// 5, 4.3.2.2.1 TS 23.502) // 5, 4.3.2.2.1 TS 23.502)
Logger::smf_app().debug( Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of Server"); "Send ITTI msg to SMF APP to trigger the response of Server");
pdu_session_create_sm_context_response sm_context_response = {}; pdu_session_create_sm_context_response sm_context_response = {};
// headers: Location: contains the URI of the newly created resource, // headers: Location: contains the URI of the newly created resource,
// according to the structure: // according to the structure:
// {apiRoot}/nsmf-pdusession/{apiVersion}/sm-contexts/{smContextRef} // {apiRoot}/nsmf-pdusession/{apiVersion}/sm-contexts/{smContextRef}
std::string smf_context_uri = std::string smf_context_uri = smreq->req.get_api_root() + "/" + smContextRef;
smreq->req.get_api_root() + "/" + smContextRef; sm_context_response.set_smf_context_uri(smf_context_uri);
sm_context_response.set_smf_context_uri(smf_context_uri); sm_context_response.set_cause(static_cast<uint8_t>(
sm_context_response.set_cause(static_cast<uint8_t>( cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)); // TODO
cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED)); // TODO
nlohmann::json json_data = {};
nlohmann::json json_data = {}; json_data["smfServiceInstanceId"] = smf_app_inst->get_smf_instance_id();
json_data["smfServiceInstanceId"] = smf_app_inst->get_smf_instance_id(); sm_context_response.set_json_data(json_data);
sm_context_response.set_json_data(json_data);
sm_context_response.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_201_CREATED);
smf_app_inst->trigger_session_create_sm_context_response(
sm_context_response, smreq->pid);
// TODO: PDU Session authentication/authorization (Optional)
// see section 4.3.2.3@3GPP TS 23.502 and section 6.3.1@3GPP TS 24.501
Logger::smf_app().info("Create a procedure to process this message.");
auto proc = std::make_shared<session_create_sm_context_procedure>(sp);
std::shared_ptr<smf_procedure> sproc = proc;
insert_procedure(sproc);
if (proc->run(smreq, sm_context_resp_pending, shared_from_this()) ==
smf_procedure_code::ERROR) {
// error !
Logger::smf_app().info(
"PDU Session Establishment Request: Create SM Context Request "
"procedure failed");
remove_procedure(sproc.get());
// Set cause to error to trigger PDU session establishment reject (step
// 10)
sm_context_resp_pending->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING);
}
} else { // if request is rejected
// TODO:
// un-subscribe to the modifications of Session Management Subscription data
// for (SUPI, DNN, S-NSSAI)
// Send HTTP reply to PDU Session Establishment Request sm_context_response.set_http_code(
// TODO Stefan: I believe this is not standard-compliant, we should just http_status_code_e::HTTP_STATUS_CODE_201_CREATED);
// send an error code here (see 29.502 Table 6.1.3.2.3.1-3)
pdu_session_create_sm_context_response sm_context_response = {}; smf_app_inst->trigger_session_create_sm_context_response(
sm_context_response.set_http_code( sm_context_response, smreq->pid);
http_status_code_e::HTTP_STATUS_CODE_201_CREATED);
smf_app_inst->trigger_session_create_sm_context_response(
sm_context_response, smreq->pid);
// TODO: PDU Session authentication/authorization (Optional)
// see section 4.3.2.3@3GPP TS 23.502 and section 6.3.1@3GPP TS 24.501
Logger::smf_app().info("Create a procedure to process this message.");
auto proc = std::make_shared<session_create_sm_context_procedure>(sp);
std::shared_ptr<smf_procedure> sproc = proc;
insert_procedure(sproc);
if (proc->run(smreq, sm_context_resp_pending, shared_from_this()) ==
smf_procedure_code::ERROR) {
// error !
Logger::smf_app().info(
"PDU Session Establishment Request: Create SM Context Request "
"procedure failed");
remove_procedure(sproc.get());
// Set cause to error to trigger PDU session establishment reject (step
// 10)
sm_context_resp_pending->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING);
} }
// Step 10. if error when establishing the pdu session, // Step 10. if error when establishing the pdu session,
...@@ -4886,6 +4864,29 @@ bool smf_context::check_handover_possibility( ...@@ -4886,6 +4864,29 @@ bool smf_context::check_handover_possibility(
return true; return true;
} }
//------------------------------------------------------------------------------
void smf_context::send_pdu_session_establishment_response_reject(
const std::shared_ptr<itti_n11_create_sm_context_request> smreq,
cause_value_5gsm_e cause, pdu_session_application_error_e application_error,
http_status_code_e http_status) {
std::string n1_sm_message = {};
std::string n1_sm_msg_hex = {};
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, n1_sm_message, cause)) {
conv::convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
// trigger to send reply to AMF
smf_app_inst->trigger_create_context_error_response(
http_status, application_error, n1_sm_msg_hex, smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
// TODO this may be a good point to unsubscribe from UDM/PCF
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void smf_context::send_pdu_session_create_response( void smf_context::send_pdu_session_create_response(
const std::shared_ptr<itti_n11_create_sm_context_response>& resp) { const std::shared_ptr<itti_n11_create_sm_context_response>& resp) {
...@@ -5061,8 +5062,8 @@ void smf_context::send_pdu_session_update_response( ...@@ -5061,8 +5062,8 @@ void smf_context::send_pdu_session_update_response(
// UE-Triggered Service Request Procedure (Step 1) // UE-Triggered Service Request Procedure (Step 1)
case session_management_procedures_type_e:: case session_management_procedures_type_e::
SERVICE_REQUEST_UE_TRIGGERED_STEP1: { SERVICE_REQUEST_UE_TRIGGERED_STEP1: {
// Create N2 SM Information: PDU Session Resource Setup Request Transfer // Create N2 SM Information: PDU Session Resource Setup Request
// IE // Transfer IE
// N2 SM Information // N2 SM Information
smf_n2::get_instance() smf_n2::get_instance()
...@@ -5120,7 +5121,8 @@ void smf_context::send_pdu_session_update_response( ...@@ -5120,7 +5121,8 @@ void smf_context::send_pdu_session_update_response(
} break; } break;
case session_management_procedures_type_e::HO_PATH_SWITCH_REQ: { case session_management_procedures_type_e::HO_PATH_SWITCH_REQ: {
// Create N2 SM Information: Path Switch Request Acknowledge Transfer IE // Create N2 SM Information: Path Switch Request Acknowledge Transfer
// IE
// N2 SM Information // N2 SM Information
smf_n2::get_instance().create_n2_path_switch_request_ack( smf_n2::get_instance().create_n2_path_switch_request_ack(
...@@ -5224,12 +5226,14 @@ void smf_context::send_pdu_session_release_response( ...@@ -5224,12 +5226,14 @@ void smf_context::send_pdu_session_release_response(
std::string n1_sm_msg_hex = {}; std::string n1_sm_msg_hex = {};
smf_n1::get_instance().create_n1_pdu_session_release_command( smf_n1::get_instance().create_n1_pdu_session_release_command(
session_release_msg, n1_sm_msg, session_release_msg, n1_sm_msg,
cause_value_5gsm_e::CAUSE_36_REGULAR_DEACTIVATION); // TODO: check cause_value_5gsm_e::CAUSE_36_REGULAR_DEACTIVATION); // TODO:
// check
// Cause // Cause
conv::convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); conv::convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
resp->res.set_n1_sm_message(n1_sm_msg_hex); resp->res.set_n1_sm_message(n1_sm_msg_hex);
// Create N2 SM info (if the UP connection of the PDU Session is active) // Create N2 SM info (if the UP connection of the PDU Session is
// active)
if (sps->get_upCnx_state() == upCnx_state_e::UPCNX_STATE_ACTIVATED) { if (sps->get_upCnx_state() == upCnx_state_e::UPCNX_STATE_ACTIVATED) {
// N2 SM Information // N2 SM Information
std::string n2_sm_info = {}; std::string n2_sm_info = {};
...@@ -5340,7 +5344,8 @@ void smf_context::send_pdu_session_release_response( ...@@ -5340,7 +5344,8 @@ void smf_context::send_pdu_session_release_response(
// associated QoS flows // associated QoS flows
sps->deallocate_ressources(resp->res.get_dnn()); sps->deallocate_ressources(resp->res.get_dnn());
// send ITTI message to SMF_APP interface to trigger the response towards AMFs // send ITTI message to SMF_APP interface to trigger the response towards
// AMFs
Logger::smf_app().info( Logger::smf_app().info(
"Sending ITTI message %s to task TASK_SMF_APP", resp->get_msg_name()); "Sending ITTI message %s to task TASK_SMF_APP", resp->get_msg_name());
int ret = itti_inst->send_msg(resp); int ret = itti_inst->send_msg(resp);
......
...@@ -1359,6 +1359,19 @@ class smf_context : public std::enable_shared_from_this<smf_context> { ...@@ -1359,6 +1359,19 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
const ng_ran_target_id_t& ran_target_id, const ng_ran_target_id_t& ran_target_id,
const pdu_session_id_t& pdu_session_id) const; const pdu_session_id_t& pdu_session_id) const;
/**
* Send a PDU Session Establishment response with a reject
* @param smreq Original request
* @param cause NAS cause value for PDU session establishment reject
* @param application_error PDU session establishment application error
* @param http_status
*/
void send_pdu_session_establishment_response_reject(
const std::shared_ptr<itti_n11_create_sm_context_request> smreq,
cause_value_5gsm_e cause,
pdu_session_application_error_e application_error,
http_status_code_e http_status);
/** /**
* Send a PDU session Create Response, based on the content of resp. * Send a PDU session Create Response, based on the content of resp.
* @param resp * @param resp
......
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