diff --git a/src/common/3gpp_29.274.h b/src/common/3gpp_29.274.h index b1da3026e002e0a837b74e46c4c9892c76ebbbd0..e961522b812dce8c0dffc0d82fe94520103a0dbc 100644 --- a/src/common/3gpp_29.274.h +++ b/src/common/3gpp_29.274.h @@ -930,6 +930,7 @@ typedef struct indication_s { uint8_t enbcpi :1; uint8_t tspcmi :1; } indication_t; + //------------------------------------- // 8.13 Protocol Configuration Options (PCO) //------------------------------------- @@ -940,6 +941,7 @@ enum pdn_type_e { PDN_TYPE_E_IPV4V6 = 3, PDN_TYPE_E_NON_IP = 4, }; + static const std::vector<std::string> pdn_type_e2str = { "Error", "IPV4", "IPV6", "IPV4V6", "NON_IP" }; diff --git a/src/common/smf.h b/src/common/smf.h index 858da597298a8d24087ff04b7012a791e9985a21..d957401229c910436231f9aace0fd3cb450805c2 100644 --- a/src/common/smf.h +++ b/src/common/smf.h @@ -180,7 +180,8 @@ static const std::vector<std::string> session_management_procedures_type_e2str = "PDU_SESSION_RELEASE_UE_REQUESTED_STEP1", "PDU_SESSION_RELEASE_UE_REQUESTED_STEP2", "PDU_SESSION_RELEASE_UE_REQUESTED_STEP3", - "PDU_SESSION_RELEASE_NETWORK_REQUESTED" + "PDU_SESSION_RELEASE_NETWORK_REQUESTED", + "PDU_SESSION_TEST" }; diff --git a/src/smf_app/smf_app.cpp b/src/smf_app/smf_app.cpp index 6a7662fcf9686a7a53806227f7bf96e14e3d3a4d..8340e07a6b56da2054223d36ea8e24042055af37 100755 --- a/src/smf_app/smf_app.cpp +++ b/src/smf_app/smf_app.cpp @@ -61,8 +61,6 @@ extern "C" { #include "nas_message.h" } -#define BUF_LEN 512 - using namespace smf; #define SYSTEM_CMD_MAX_STR_SIZE 512 @@ -447,7 +445,7 @@ void smf_app::handle_itti_msg( void smf_app::handle_itti_msg(itti_n11_update_pdu_session_status &m) { Logger::smf_app().info( "Set PDU Session Status to %s", - pdu_session_status_e2str[static_cast<int>(m.pdu_session_status)]); + pdu_session_status_e2str[static_cast<int>(m.pdu_session_status)].c_str()); update_pdu_session_status(m.scid, m.pdu_session_status); } @@ -484,7 +482,7 @@ void smf_app::handle_pdu_session_create_sm_context_request( //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, - cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE); //TODO: should define 5GSM cause in 24.501 + 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( @@ -506,6 +504,7 @@ void smf_app::handle_pdu_session_create_sm_context_request( smreq->req.set_message_type(decoded_nas_msg.plain.sm.header.message_type); //Integrity protection maximum data rate (Mandatory) + //TODO: //PDU session type (Optional) smreq->req.set_pdu_session_type(PDU_SESSION_TYPE_E_IPV4); //set default value @@ -516,7 +515,7 @@ void smf_app::handle_pdu_session_create_sm_context_request( "NAS, pdu_session_type %d", decoded_nas_msg.plain.sm.pdu_session_establishment_request ._pdusessiontype.pdu_session_type_value); - //sm_context_req_msg.set_pdu_session_type(decoded_nas_msg.plain.sm.pdu_session_establishment_request._pdusessiontype.pdu_session_type_value); + smreq->req.set_pdu_session_type(decoded_nas_msg.plain.sm.pdu_session_establishment_request._pdusessiontype.pdu_session_type_value); } //Get necessary information @@ -556,7 +555,7 @@ void smf_app::handle_pdu_session_create_sm_context_request( //(24.501 (section 7.3.1)) NAS N1 SM message: response with a 5GSM STATUS message including cause "#81 Invalid PTI value" smf_n1_n2_inst.create_n1_sm_container( context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message, - cause_value_5gsm_e::CAUSE_81_INVALID_PTI_VALUE); //TODO: should define 5GSM cause in 24.501 + 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( @@ -742,23 +741,16 @@ void smf_app::handle_pdu_session_update_sm_context_request( scid_t scid = { }; try { scid = std::stoi(smreq->scid); - } - /*catch (const std::out_of_range& err){ - - } catch (const std::invalid_argument& err){ - - }*/ - catch (const std::exception &err) { + } catch (const std::exception &err) { //TODO: send PDUSession_SMUpdateContext Response (including PDU Session EStablishment Reject) to AMF with CAUSE: invalid context Logger::smf_app().warn( - "Received PDU_SESSION_UPDATESMCONTEXT_REQUEST, couldn't retrieve the corresponding SMF context, ignore message!"); - + "Received a PDU Session Update SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!"); 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); - //PDU Session Update Reject + //PDU Session Establishment Reject smf_n1_n2_inst.create_n1_sm_container( smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message, cause_value_5gsm_e::CAUSE_54_PDU_SESSION_DOES_NOT_EXIST); @@ -776,7 +768,19 @@ void smf_app::handle_pdu_session_update_sm_context_request( } else { Logger::smf_app().warn( "Context associated with this id " SCID_FMT " does not exit!", scid); - //TODO: send reject to AMF + 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); + //PDU Session Establishment Reject + smf_n1_n2_inst.create_n1_sm_container( + smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message, + cause_value_5gsm_e::CAUSE_54_PDU_SESSION_DOES_NOT_EXIST); + smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex); + smf_n11_inst->send_pdu_session_update_sm_context_response( + smreq->http_response, smContextUpdateError, + Pistache::Http::Code::Forbidden, n1_sm_message_hex); return; } @@ -793,9 +797,9 @@ void smf_app::handle_pdu_session_update_sm_context_request( smreq->req.set_pdu_session_id(pdu_session_id); pdu_session_update_sm_context_request context_req_msg = smreq->req; + //Step 2. find the smf context std::shared_ptr<smf_context> sc = { }; - if (is_supi_2_smf_context(supi64)) { sc = supi_2_smf_context(supi64); Logger::smf_app().debug("Retrieve SMF context with SUPI " SUPI_64_FMT "", @@ -803,7 +807,7 @@ void smf_app::handle_pdu_session_update_sm_context_request( } else { //send PDUSession_SMUpdateContext Response (including PDU Session EStablishment Reject) to AMF Logger::smf_app().warn( - "Received PDU_SESSION_UPDATESMCONTEXT_REQUEST with Supi " SUPI_64_FMT "couldn't retrieve the corresponding SMF context, ignore message!", + "Received PDU Session Update SM Context Request with Supi " SUPI_64_FMT "couldn't retrieve the corresponding SMF context, ignore message!", supi64); problem_details.setCause( pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]); @@ -815,7 +819,7 @@ void smf_app::handle_pdu_session_update_sm_context_request( context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message, - cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED); + cause_value_5gsm_e::CAUSE_54_PDU_SESSION_DOES_NOT_EXIST); smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex); smf_n11_inst->send_pdu_session_update_sm_context_response( smreq->http_response, smContextUpdateError, @@ -831,7 +835,7 @@ void smf_app::handle_pdu_session_update_sm_context_request( //Error, DNN context doesn't exist // send PDUSession_SMUpdateContext Response (including PDU Session EStablishment Reject) to AMF Logger::smf_app().warn( - "Received PDU_SESSION_UPDATESMCONTEXT_REQUEST, couldn't retrieve the corresponding SMF context, ignore message!"); + "Received PDU Session Update SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!"); problem_details.setCause( pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]); smContextUpdateError.setError(problem_details); diff --git a/src/smf_app/smf_context.cpp b/src/smf_app/smf_context.cpp index ba13a9ec22d0f40889f5d8859275917a46fe3cb7..bd15355cddd4584d640c1d4bf8313771a0d26688 100644 --- a/src/smf_app/smf_context.cpp +++ b/src/smf_app/smf_context.cpp @@ -498,20 +498,20 @@ void smf_context::get_default_qos_flow_description( qos_flow_description.parameterslist = (ParametersList*) calloc( 3, sizeof(ParametersList)); qos_flow_description.parameterslist[0].parameteridentifier = - PARAMETER_IDENTIFIER_5QI; + PARAMETER_IDENTIFIER_5QI; qos_flow_description.parameterslist[0].parametercontents._5qi = 60; //TODO: ?? qos_flow_description.parameterslist[1].parameteridentifier = - PARAMETER_IDENTIFIER_GFBR_UPLINK; + PARAMETER_IDENTIFIER_GFBR_UPLINK; qos_flow_description.parameterslist[1].parametercontents .gfbrormfbr_uplinkordownlink.uint = - GFBRORMFBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + GFBRORMFBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; qos_flow_description.parameterslist[1].parametercontents .gfbrormfbr_uplinkordownlink.value = 0x10; qos_flow_description.parameterslist[2].parameteridentifier = - PARAMETER_IDENTIFIER_GFBR_DOWNLINK; + PARAMETER_IDENTIFIER_GFBR_DOWNLINK; qos_flow_description.parameterslist[2].parametercontents .gfbrormfbr_uplinkordownlink.uint = - GFBRORMFBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + GFBRORMFBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; qos_flow_description.parameterslist[2].parametercontents .gfbrormfbr_uplinkordownlink.value = 0x10; @@ -561,19 +561,19 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr, .substr(leng_of_session_ambr_dl - 4); //4 last characters stand for mbps, kbps, .. if (session_ambr_dl_unit.compare("Kbps") == 0) session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1KBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1KBPS; if (session_ambr_dl_unit.compare("Mbps") == 0) session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; if (session_ambr_dl_unit.compare("Gbps") == 0) session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1GBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1GBPS; if (session_ambr_dl_unit.compare("Tbps") == 0) session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1TBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1TBPS; if (session_ambr_dl_unit.compare("Pbps") == 0) session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1PBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1PBPS; session_ambr.session_ambr_for_downlink = std::stoi( (sdc.get()->session_ambr).downlink.substr( @@ -583,7 +583,7 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr, //assign default value session_ambr.session_ambr_for_downlink = 1; session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; } //Uplink @@ -594,19 +594,19 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr, .substr(leng_of_session_ambr_ul - 4); //4 last characters stand for mbps, kbps, .. if (session_ambr_ul_unit.compare("Kbps") == 0) session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1KBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1KBPS; if (session_ambr_ul_unit.compare("Mbps") == 0) session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; if (session_ambr_ul_unit.compare("Gbps") == 0) session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1GBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1GBPS; if (session_ambr_ul_unit.compare("Tbps") == 0) session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1TBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1TBPS; if (session_ambr_ul_unit.compare("Pbps") == 0) session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1PBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1PBPS; session_ambr.session_ambr_for_uplink = std::stoi( (sdc.get()->session_ambr).uplink.substr( @@ -616,17 +616,17 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr, //assign default value session_ambr.session_ambr_for_uplink = 1; session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; } } } else { //use default value session_ambr.session_ambr_for_downlink = 1; session_ambr.uint_for_session_ambr_for_downlink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; session_ambr.session_ambr_for_uplink = 1; session_ambr.uint_for_session_ambr_for_uplink = - AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; + AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS; } } @@ -727,7 +727,7 @@ void smf_context::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_msg_hex; //N1 SM container + std::string n1_sm_message, n1_sm_msg_hex; smf_n1_n2 smf_n1_n2_inst = { }; bool request_accepted = true; @@ -799,16 +799,16 @@ void smf_context::handle_pdu_session_create_sm_context_request( dnn.c_str()); } - //step 3.2. create pdn connection if not exist + //step 3.2. create pdu session if not exist std::shared_ptr<smf_pdu_session> sp = { }; - bool find_pdn = sd.get()->find_pdu_session(pdu_session_id, sp); + bool find_pdu = sd.get()->find_pdu_session(pdu_session_id, sp); if (nullptr == sp.get()) { Logger::smf_app().debug("Create a new PDN connection!"); - //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()->pdu_session_id = pdu_session_id; //should check also nas_msg.pdusessionidentity ?? + sp.get()->pdu_session_id = pdu_session_id; sp.get()->amf_id = sm_context_req_msg.get_serving_nf_id(); //amf id sd->insert_pdu_session(sp); } else { @@ -969,9 +969,9 @@ void smf_context::handle_pdu_session_create_sm_context_request( if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) { // error ! Logger::smf_app().info( - "PDU SESSION CREATE SM CONTEXT REQUEST procedure failed"); + "PDU Session Establishment Request: Create SM Context Request procedure failed"); remove_procedure(proc); - //Set cause to error to trigger PDU session establishment reject (step 9) + //Set cause to error to trigger PDU session establishment reject (step 10) sm_context_resp->res.set_cause(UNKNOWN_ERROR); } @@ -1029,7 +1029,6 @@ void smf_context::handle_pdu_session_create_sm_context_request( supi_t supi = sm_context_resp_pending->res.get_supi(); supi_str = sm_context_resp_pending->res.get_supi_prefix() + "-" + smf_supi_to_string(supi); - //std::string url = std::string(inet_ntoa (*((struct in_addr *)&smf_cfg.amf_addr.ipv4_addr))) + ":" + std::to_string(smf_cfg.amf_addr.port) + "/namf-comm/v2/ue-contexts/" + supi_str.c_str() +"/n1-n2-messages"; std::string url = std::string( inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) + ":" + std::to_string(smf_cfg.amf_addr.port) @@ -1039,9 +1038,9 @@ void smf_context::handle_pdu_session_create_sm_context_request( //Fill the json part sm_context_resp_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; sm_context_resp_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"] = - N1_SM_CONTENT_ID; + N1_SM_CONTENT_ID; //sm_context_resp_pending->res.n1n2_message_transfer_data["ppi"] = 1; //Don't need this info for the moment sm_context_resp_pending->res.n1n2_message_transfer_data["pduSessionId"] = sm_context_resp_pending->res.get_pdu_session_id(); @@ -1069,6 +1068,7 @@ void smf_context::handle_pdu_session_update_sm_context_request( oai::smf_server::model::SmContextUpdateError smContextUpdateError = { }; oai::smf_server::model::ProblemDetails problem_details = { }; oai::smf_server::model::RefToBinaryData refToBinaryData = { }; + std::string n1_sm_msg, n1_sm_msg_hex; bool update_upf = false; session_management_procedures_type_e procedure_type( session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED); @@ -1078,12 +1078,12 @@ void smf_context::handle_pdu_session_update_sm_context_request( std::shared_ptr<smf_pdu_session> sp = { }; bool find_dnn = find_dnn_context(sm_context_req_msg.get_snssai(), sm_context_req_msg.get_dnn(), sd); - bool find_pdn = false; + bool find_pdu = false; if (find_dnn) { - find_pdn = sd.get()->find_pdu_session( + find_pdu = sd.get()->find_pdu_session( sm_context_req_msg.get_pdu_session_id(), sp); } - if (!find_dnn or !find_pdn) { + if (!find_dnn or !find_pdu) { //error, send reply to AMF with error code "Context Not Found" Logger::smf_app().warn("DNN or PDU session context does not exist!"); problem_details.setCause( @@ -1091,9 +1091,15 @@ void smf_context::handle_pdu_session_update_sm_context_request( smContextUpdateError.setError(problem_details); refToBinaryData.setContentId(N1_SM_CONTENT_ID); smContextUpdateError.setN1SmMsg(refToBinaryData); + //Create N1 container + smf_n1_n2_inst.create_n1_sm_container( + sm_context_req_msg, + PDU_SESSION_ESTABLISHMENT_REJECT, + n1_sm_msg, cause_value_5gsm_e::CAUSE_54_PDU_SESSION_DOES_NOT_EXIST); + 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::Not_Found); + Pistache::Http::Code::Not_Found, n1_sm_msg_hex); return; } @@ -1114,7 +1120,6 @@ void smf_context::handle_pdu_session_update_sm_context_request( //Step 2.1. Decode N1 (if content is available) if (sm_context_req_msg.n1_sm_msg_is_set()) { - std::string n1_sm_msg, n1_sm_msg_hex; //N1 SM container nas_message_t decoded_nas_msg = { }; //Decode NAS and get the necessary information @@ -1124,7 +1129,7 @@ void smf_context::handle_pdu_session_update_sm_context_request( 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 error code!! 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]); @@ -1135,10 +1140,12 @@ void smf_context::handle_pdu_session_update_sm_context_request( //24.501: response with a 5GSM STATUS message including cause "#95 Semantically incorrect message" smf_n1_n2_inst.create_n1_sm_container( sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg, - cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE); //TODO: should define 5GSM cause in 24.501 + cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE); + 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); + Pistache::Http::Code::Forbidden, n1_sm_msg_hex); + return; } Logger::smf_app().debug( @@ -1148,14 +1155,11 @@ void smf_context::handle_pdu_session_update_sm_context_request( Logger::smf_app().debug("NAS header information, Message Type %d", decoded_nas_msg.plain.sm.header.message_type); - //FOR TESTing PDU_SESSION_MODIFICATION_REQUEST, should be REMOVED!!! - uint8_t message_type = PDU_SESSION_MODIFICATION_REQUEST; - //end + uint8_t message_type = decoded_nas_msg.plain.sm.header.message_type; switch (message_type) { - // switch (decoded_nas_msg.plain.sm.header.message_type){ - //PDU_SESSION_MODIFICATION_REQUEST - UE initiated PDU session modification request (Step 1) case PDU_SESSION_MODIFICATION_REQUEST: { + //TODO: to be finished Logger::smf_app().debug("PDU_SESSION_MODIFICATION_REQUEST"); //PDU Session Modification procedure (UE-initiated, step 1.a, Section 4.3.3.2@3GPP TS 23.502) procedure_type = @@ -1270,15 +1274,15 @@ void smf_context::handle_pdu_session_update_sm_context_request( //Fill the json part //N1SM n1_sm_context_resp->res.sm_context_updated_data["n1SmMsg"]["n1MessageClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; n1_sm_context_resp->res.sm_context_updated_data["n1SmMsg"]["n1MessageContent"]["contentId"] = - N1_SM_CONTENT_ID; //part 2 + N1_SM_CONTENT_ID; //part 2 n1_sm_context_resp->res.sm_context_updated_data["n2SmInfo"]["n2InformationClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; n1_sm_context_resp->res.sm_context_updated_data["n2SmInfo"]["n2InfoContent"]["ngapIeType"] = "PDU_RES_MOD_REQ"; //NGAP message n1_sm_context_resp->res.sm_context_updated_data["n2SmInfo"]["n2InfoContent"]["ngapData"]["contentId"] = - N2_SM_CONTENT_ID; //part 3 + N2_SM_CONTENT_ID; //part 3 //Store pdu_session_modification_request in itti_n11_update_sm_context_response Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11", @@ -1379,12 +1383,6 @@ void smf_context::handle_pdu_session_update_sm_context_request( case n2_sm_info_type_e::PDU_RES_SETUP_RSP: { Logger::smf_app().info( "PDU Session Establishment Request, processing N2 SM Information"); - //Ngap_PDUSessionResourceSetupResponseTransfer_t - // Ngap_QosFlowPerTNLInformation_t qosFlowPerTNLInformation; - // struct Ngap_QosFlowPerTNLInformation *additionalQosFlowPerTNLInformation; /* OPTIONAL */ - // struct Ngap_SecurityResult *securityResult; /* OPTIONAL */ - // struct Ngap_QosFlowList *qosFlowFailedToSetupList; /* OPTIONAL */ - // struct Ngap_ProtocolExtensionContainer *iE_Extensions; /* OPTIONAL */ //PDU_SESSION_ESTABLISHMENT_UE_REQUESTED & SERVICE_REQUEST_UE_TRIGGERED procedure_type = @@ -1397,13 +1395,28 @@ void smf_context::handle_pdu_session_update_sm_context_request( 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"); - //TODO: send error to AMF + //error, send error to AMF + Logger::smf_app().warn( + "Decode N2 SM (Ngap_PDUSessionResourceSetupResponseTransfer) failed!"); + problem_details.setCause( + pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]); + smContextUpdateError.setError(problem_details); + refToBinaryData.setContentId(N1_SM_CONTENT_ID); + smContextUpdateError.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( + sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg, + cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE); + 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; } - //TODO: store AN Tunnel Info + list of accepted QFIs + //store AN Tunnel Info + list of accepted QFIs fteid_t dl_teid; - //TODO: to be verified which one is teid_gre_key, ipv4_address memcpy( &dl_teid.teid_gre_key, decoded_msg->dLQosFlowPerTNLInformation.uPTransportLayerInformation @@ -1468,16 +1481,26 @@ void smf_context::handle_pdu_session_update_sm_context_request( decoded_msg, n2_sm_information); if (decode_status == RETURNerror) { Logger::smf_api_server().warn("asn_decode failed"); - //TODO: send error to AMF - } + //send error to AMF + Logger::smf_app().warn( + "Decode N2 SM (Ngap_PDUSessionResourceModifyResponseTransfer) failed!"); + problem_details.setCause( + pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]); + smContextUpdateError.setError(problem_details); + refToBinaryData.setContentId(N1_SM_CONTENT_ID); + smContextUpdateError.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( + sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg, + cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE); + 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; - //Ngap_PDUSessionResourceModifyResponseTransfer_t - // struct Ngap_UPTransportLayerInformation *dL_NGU_UP_TNLInformation; /* OPTIONAL */ - // struct Ngap_UPTransportLayerInformation *uL_NGU_UP_TNLInformation; /* OPTIONAL */ - // struct Ngap_QosFlowAddOrModifyResponseList *qosFlowAddOrModifyResponseList; /* OPTIONAL */ - // struct Ngap_QosFlowPerTNLInformation *additionalQosFlowPerTNLInformation; /* OPTIONAL */ - // struct Ngap_QosFlowList *qosFlowFailedToAddOrModifyList; /* OPTIONAL */ - //struct Ngap_ProtocolExtensionContainer *iE_Extensions; /* OPTIONAL */ + } //if dL_NGU_UP_TNLInformation is included, it shall be considered as the new DL transfort layer addr for the PDU session (should be verified) fteid_t dl_teid; @@ -1554,7 +1577,6 @@ void smf_context::handle_pdu_session_update_sm_context_request( //Step 4. Create a procedure for update sm context and let the procedure handle the request if necessary if (update_upf) { - //TODO: session_update_sm_context_procedure *proc = new session_update_sm_context_procedure(sp); std::shared_ptr<smf_procedure> sproc = std::shared_ptr<smf_procedure>(proc); @@ -1564,9 +1586,24 @@ void smf_context::handle_pdu_session_update_sm_context_request( insert_procedure(sproc); if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) { // error ! - Logger::smf_app().info( - "PDU SESSION CREATE SM CONTEXT REQUEST procedure failed"); + Logger::smf_app().info("PDU Update SM Context Request procedure failed"); remove_procedure(proc); + //send error to AMF + problem_details.setCause( + pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]); + smContextUpdateError.setError(problem_details); + refToBinaryData.setContentId(N1_SM_CONTENT_ID); + smContextUpdateError.setN1SmMsg(refToBinaryData); + //PDU Session Establishment Reject + smf_n1_n2_inst.create_n1_sm_container( + sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg, + cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE); + 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; + } } diff --git a/src/smf_app/smf_n1_n2.cpp b/src/smf_app/smf_n1_n2.cpp index 06ee57fb76b553dc6aa2b63c28cc1757725add76..0504f59a779cf6ff00512e6cee09780f0557f163 100644 --- a/src/smf_app/smf_n1_n2.cpp +++ b/src/smf_app/smf_n1_n2.cpp @@ -83,7 +83,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, uint8_t n1_msg_type, std::string &nas_msg_str, cause_value_5gsm_e sm_cause) { - //TODO: should work with BUPT to finish this function + Logger::smf_app().info("Create N1 SM Container, n1 message type %d", n1_msg_type); @@ -99,11 +99,8 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, nas_msg.header.extended_protocol_discriminator = EPD_5GS_SESSION_MANAGEMENT_MESSAGES; nas_msg.header.security_header_type = SECURITY_HEADER_TYPE_NOT_PROTECTED; - //TODO: Should be updated - uint8_t sequencenumber = 0xfe; - uint32_t mac = 0xffee; - //nas_msg.header.sequence_number = sequencenumber; - //nas_msg.header.message_authentication_code= mac; + //nas_msg.header.sequence_number = 0xfe; + //nas_msg.header.message_authentication_code = 0xffee; SM_msg *sm_msg = &nas_msg.plain.sm; sm_msg->header.extended_protocol_discriminator = @@ -115,14 +112,13 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, //PDU Session Establishment Accept case PDU_SESSION_ESTABLISHMENT_ACCEPT: { //PDU Session Establishment Accept is including in the N1N2MessageTransfer Request sent from SMF to AMF (PDU Session Establishment procedure) - - //PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE if (msg.get_msg_type() != PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE) { Logger::smf_app().error( "Cannot create an PDU Session Establishment Accept for this message (type %d)", msg.get_msg_type()); return; } + pdu_session_create_sm_context_response &sm_context_res = static_cast<pdu_session_create_sm_context_response&>(msg); @@ -141,11 +137,12 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, //Fill the content of PDU Session Establishment Request message with hardcoded values (to be completed) //PTI + sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti() + .procedure_transaction_id; Logger::smf_app().debug( "Procedure_transaction_id %d", sm_context_res.get_pti().procedure_transaction_id); - sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti() - .procedure_transaction_id; + Logger::smf_app().debug( "NAS header, encode extended_protocol_discriminator: 0x%x, security_header_type: 0x%x", nas_msg.header.extended_protocol_discriminator, @@ -164,10 +161,10 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, "PDUSessionType: %#0x", sm_msg->pdu_session_establishment_accept._pdusessiontype .pdu_session_type_value); + //SSC Mode - //TODO: should get from sm_context_res sm_msg->pdu_session_establishment_accept.sscmode.ssc_mode_value = - SSC_MODE_1; //TODO: + SSC_MODE_1; //TODO: get from sm_context_res Logger::smf_app().debug( "SSC Mode: %#0x", sm_msg->pdu_session_establishment_accept.sscmode.ssc_mode_value); @@ -268,7 +265,6 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, sm_msg->pdu_session_establishment_accept.pduaddress .pdu_address_information = bfromcstralloc(4, "\0"); - ; sm_msg->pdu_session_establishment_accept.pduaddress .pdu_address_information->slen = 4; @@ -291,10 +287,18 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, sm_msg->pdu_session_establishment_accept.snssai.len = SST_AND_SD_LENGHT; sm_msg->pdu_session_establishment_accept.snssai.sst = sm_context_res .get_snssai().sST; - sm_msg->pdu_session_establishment_accept.snssai.sd = 0x0009; //TODO: sm_context_res.get_snssai().sD; <--- String + + try { + sm_msg->pdu_session_establishment_accept.snssai.sd = std::stoi( + sm_context_res.get_snssai().sD); + } catch (const std::exception &e) { + Logger::smf_app().warn("Undefined error: %s", e.what()); + //"no SD value associated with the SST" + sm_msg->pdu_session_establishment_accept.snssai.sd = 0xFFFFFF; + } + Logger::smf_app().debug( - "SNSSAI, len: %#0x, sst: %#0x, sd: %#0x", - sm_msg->pdu_session_establishment_accept.snssai.len, + "SNSSAI SST: %#0x, SD: %#0x", sm_msg->pdu_session_establishment_accept.snssai.sst, sm_msg->pdu_session_establishment_accept.snssai.sd); @@ -372,14 +376,14 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, static_cast<uint8_t>(sm_cause); sm_msg->pdu_session_establishment_reject.presence = 0x02; sm_msg->pdu_session_establishment_reject.gprstimer3.unit = - GPRSTIMER3_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1_HOUR; + GPRSTIMER3_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1_HOUR; sm_msg->pdu_session_establishment_reject.gprstimer3.timeValue = 0; sm_msg->pdu_session_establishment_reject.allowedsscmode.is_ssc1_allowed = - SSC_MODE1_ALLOWED; + SSC_MODE1_ALLOWED; sm_msg->pdu_session_establishment_reject.allowedsscmode.is_ssc2_allowed = - SSC_MODE2_NOT_ALLOWED; + SSC_MODE2_NOT_ALLOWED; sm_msg->pdu_session_establishment_reject.allowedsscmode.is_ssc3_allowed = - SSC_MODE3_NOT_ALLOWED; + SSC_MODE3_NOT_ALLOWED; /* unsigned char bitStream_eapmessage[2] = {0x01,0x02}; @@ -479,7 +483,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0] .ruleoperationcode = CREATE_NEW_QOS_RULE; sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0].dqrbit = - THE_QOS_RULE_IS_DEFAULT_QOS_RULE; + THE_QOS_RULE_IS_DEFAULT_QOS_RULE; sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0] .numberofpacketfilters = 1; //1st rule @@ -670,7 +674,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, (Ngap_PDUSessionResourceSetupRequestTransferIEs_t*) calloc( 1, sizeof(Ngap_PDUSessionResourceSetupRequestTransferIEs_t)); pduSessionAggregateMaximumBitRate->id = - Ngap_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate; + Ngap_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate; pduSessionAggregateMaximumBitRate->criticality = Ngap_Criticality_reject; pduSessionAggregateMaximumBitRate->value.present = Ngap_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionAggregateMaximumBitRate; @@ -702,7 +706,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, (Ngap_PDUSessionResourceSetupRequestTransferIEs_t*) calloc( 1, sizeof(Ngap_PDUSessionResourceSetupRequestTransferIEs_t)); upTransportLayerInformation->id = - Ngap_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation; + Ngap_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation; upTransportLayerInformation->criticality = Ngap_Criticality_reject; upTransportLayerInformation->value.present = Ngap_PDUSessionResourceSetupRequestTransferIEs__value_PR_UPTransportLayerInformation; @@ -769,7 +773,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, (Ngap_PDUSessionResourceSetupRequestTransferIEs_t*) calloc( 1, sizeof(Ngap_PDUSessionResourceSetupRequestTransferIEs_t)); qosFlowSetupRequestList->id = - Ngap_ProtocolIE_ID_id_QosFlowSetupRequestList; + Ngap_ProtocolIE_ID_id_QosFlowSetupRequestList; qosFlowSetupRequestList->criticality = Ngap_Criticality_reject; qosFlowSetupRequestList->value.present = Ngap_PDUSessionResourceSetupRequestTransferIEs__value_PR_QosFlowSetupRequestList; @@ -879,7 +883,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, (Ngap_PDUSessionResourceModifyRequestTransferIEs_t*) calloc( 1, sizeof(Ngap_PDUSessionResourceModifyRequestTransferIEs_t)); pduSessionAggregateMaximumBitRate->id = - Ngap_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate; + Ngap_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate; pduSessionAggregateMaximumBitRate->criticality = Ngap_Criticality_reject; pduSessionAggregateMaximumBitRate->value.present = Ngap_PDUSessionResourceModifyRequestTransferIEs__value_PR_PDUSessionAggregateMaximumBitRate; @@ -910,7 +914,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, (Ngap_PDUSessionResourceModifyRequestTransferIEs_t*) calloc( 1, sizeof(Ngap_PDUSessionResourceModifyRequestTransferIEs_t)); ul_NGU_UP_TNLModifyList->id = - Ngap_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList; + Ngap_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList; ul_NGU_UP_TNLModifyList->criticality = Ngap_Criticality_reject; ul_NGU_UP_TNLModifyList->value.present = Ngap_PDUSessionResourceModifyRequestTransferIEs__value_PR_UL_NGU_UP_TNLModifyList; @@ -983,7 +987,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, 1, sizeof(Ngap_PDUSessionResourceModifyRequestTransferIEs_t)); qosFlowAddOrModifyRequestList->id = - Ngap_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList; + Ngap_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList; qosFlowAddOrModifyRequestList->criticality = Ngap_Criticality_reject; qosFlowAddOrModifyRequestList->value.present = Ngap_PDUSessionResourceModifyRequestTransferIEs__value_PR_QosFlowAddOrModifyRequestList; diff --git a/src/smf_app/smf_procedure.cpp b/src/smf_app/smf_procedure.cpp index 6c0ce26302a4eaf7aed89136672fc32d5c3faa42..00b0481ddabba0328b202d97847e9c3230ed6d1e 100644 --- a/src/smf_app/smf_procedure.cpp +++ b/src/smf_app/smf_procedure.cpp @@ -44,6 +44,7 @@ #include "smf_pfcp_association.hpp" #include "smf_context.hpp" #include "smf_n1_n2.hpp" +#include "smf_n11.hpp" #include "SmContextCreatedData.h" using namespace pfcp; @@ -53,6 +54,7 @@ using namespace std; extern itti_mw *itti_inst; extern smf::smf_app *smf_app_inst; extern smf::smf_config smf_cfg; +extern smf::smf_n11 *smf_n11_inst; //------------------------------------------------------------------------------ int n4_session_restore_procedure::run() { @@ -231,7 +233,7 @@ int session_create_sm_context_procedure::run( //Framed Route Information outer_header_removal.outer_header_removal_description = - OUTER_HEADER_REMOVAL_GTPU_UDP_IPV4; + OUTER_HEADER_REMOVAL_GTPU_UDP_IPV4; create_pdr.set(pdr_id); create_pdr.set(precedence); @@ -316,7 +318,6 @@ void session_create_sm_context_procedure::handle_itti_msg( if (ppc->get_qos_flow(pdr_id, q)) { pfcp::fteid_t local_up_fteid = { }; if (it.get(local_up_fteid)) { - //b.pgw_fteid_s5_s8_up.interface_type = S5_S8_PGW_GTP_U; //set tunnel id xgpp_conv::pfcp_to_core_fteid(local_up_fteid, q.ul_fteid); //TODO: should be updated to 5G N3/N9 interface @@ -373,27 +374,29 @@ void session_create_sm_context_procedure::handle_itti_msg( std::string n1_sm_msg, n1_sm_msg_hex; std::string n2_sm_info, n2_sm_info_hex; - //TODO: should uncomment this line when including UPF in the test - n11_triggered_pending->res.set_cause(REQUEST_ACCEPTED); //for testing purpose + //TODO: should comment this line when including UPF in the test + //n11_triggered_pending->res.set_cause(REQUEST_ACCEPTED); //for testing purpose if (n11_triggered_pending->res.get_cause() != REQUEST_ACCEPTED) { //PDU Session Establishment Reject - Logger::smf_app().debug("PDU Session Establishment Reject"); - smf_n1_n2_inst.create_n1_sm_container(n11_triggered_pending->res, - PDU_SESSION_ESTABLISHMENT_REJECT, - n1_sm_msg, - cause_value_5gsm_e::CAUSE_0_UNKNOWN); //TODO: need cause? + Logger::smf_app().debug( + "Prepare a PDU Session Establishment Reject message and send to UE"); + smf_n1_n2_inst.create_n1_sm_container( + n11_triggered_pending->res, + PDU_SESSION_ESTABLISHMENT_REJECT, + n1_sm_msg, cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE); 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); + } else { //PDU Session Establishment Accept 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, + 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); - //TODO: N2 SM Information (Step 11, section 4.3.2.2.1 @ 3GPP TS 23.502) + //N2 SM Information (Step 11, section 4.3.2.2.1 @ 3GPP TS 23.502): PDUSessionRessourceSetupRequestTransfer IE smf_n1_n2_inst.create_n2_sm_information( n11_triggered_pending->res, 1, n2_sm_info_type_e::PDU_RES_SETUP_REQ, n2_sm_info); @@ -406,7 +409,6 @@ void session_create_sm_context_procedure::handle_itti_msg( supi_t supi = n11_triggered_pending->res.get_supi(); std::string supi_str = n11_triggered_pending->res.get_supi_prefix() + "-" + smf_supi_to_string(supi); - //std::string url = std::string(inet_ntoa (*((struct in_addr *)&smf_cfg.amf_addr.ipv4_addr))) + ":" + std::to_string(smf_cfg.amf_addr.port) + "/namf-comm/v2/ue-contexts/" + supi_str.c_str() +"/n1-n2-messages"; std::string url = std::string( inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) + ":" + std::to_string(smf_cfg.amf_addr.port) @@ -419,23 +421,21 @@ void session_create_sm_context_procedure::handle_itti_msg( //Fill the json part //N1SM n11_triggered_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; n11_triggered_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"] = - N1_SM_CONTENT_ID; //part 2 - + N1_SM_CONTENT_ID; //NAS part //N2SM if (n11_triggered_pending->res.get_cause() == REQUEST_ACCEPTED) { //TODO: fill the content of N1N2MessageTransferReqData n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["n2InformationClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["PduSessionId"] = n11_triggered_pending->res.get_pdu_session_id(); //N2InfoContent (section 6.1.6.2.27@3GPP TS 29.518) - //n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapMessageType"] = 123; //NGAP message -to be verified: doesn't exist in tester (not required!!) n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] = "PDU_RES_SETUP_REQ"; //NGAP message n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = - N2_SM_CONTENT_ID; //part 3 + N2_SM_CONTENT_ID; //NGAP part n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] = n11_triggered_pending->res.get_snssai().sST; n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] = @@ -444,13 +444,9 @@ void session_create_sm_context_procedure::handle_itti_msg( "SM"; } //Others information - n11_triggered_pending->res.n1n2_message_transfer_data["ppi"] = 1; //Don't need this info for the moment + //n11_triggered_pending->res.n1n2_message_transfer_data["pti"] = 1; //Don't need this info for the moment n11_triggered_pending->res.n1n2_message_transfer_data["pduSessionId"] = n11_triggered_pending->res.get_pdu_session_id(); - //n11_triggered_pending->res.n1n2_message_transfer_data["arp"]["priorityLevel"] = 1; - //n11_triggered_pending->res.n1n2_message_transfer_data["arp"]["preemptCap"] = "NOT_PREEMPT"; - //n11_triggered_pending->res.n1n2_message_transfer_data["arp"]["preemptVuln"] = "NOT_PREEMPTABLE"; - //n11_triggered_pending->res.n1n2_message_transfer_data["5qi"] = ; //send ITTI message to N11 interface to trigger N1N2MessageTransfer towards AMFs Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11", @@ -772,9 +768,7 @@ void session_update_sm_context_procedure::handle_itti_msg( for (auto it : qos_flow_context_to_be_updateds) { flow.dl_fteid = dl_fteid; flow.dl_fteid.interface_type = S1_U_ENODEB_GTP_U; //eNB's N3 interface - // flow.ul_fteid = it.second.ul_fteid; - pfcp::fteid_t local_up_fteid = { }; if (it_created_pdr.get(local_up_fteid)) { xgpp_conv::pfcp_to_core_fteid(local_up_fteid, flow.ul_fteid); @@ -869,9 +863,28 @@ void session_update_sm_context_procedure::handle_itti_msg( resp.pfcp_ies.get_msg_name()); } } + } else { + Logger::smf_app().info("PDU Session Update SM Context, rejected by UPF"); + //send PDU Session Establishment Reject to AMF + oai::smf_server::model::SmContextUpdateError smContextUpdateError = { }; + oai::smf_server::model::ProblemDetails problem_details = { }; + oai::smf_server::model::RefToBinaryData refToBinaryData = { }; + problem_details.setCause( + pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]); + smContextUpdateError.setError(problem_details); + refToBinaryData.setContentId(N1_SM_CONTENT_ID); + smContextUpdateError.setN1SmMsg(refToBinaryData); + smf_n1_n2_inst.create_n1_sm_container( + n11_triggered_pending->res, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg, + cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE); + smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); + smf_n11_inst->send_pdu_session_update_sm_context_response( + n11_triggered_pending->http_response, smContextUpdateError, + Pistache::Http::Code::Forbidden, n1_sm_msg_hex); + return; } - n11_triggered_pending->res.set_cause(cause_gtp.cause_value); + n11_triggered_pending->res.set_cause(cause.cause_value); // TODO // check we got all responses vs n11_triggered_pending->res.flow_context_modified @@ -884,20 +897,20 @@ void session_update_sm_context_procedure::handle_itti_msg( //SHOULD BE REMOVED, FOR TESTING PURPOSE //change value here to test the corresponding message - session_procedure_type = - session_management_procedures_type_e::PDU_SESSION_TEST; + //session_procedure_type = + // session_management_procedures_type_e::PDU_SESSION_TEST; nlohmann::json sm_context_updated_data = { }; sm_context_updated_data["n1MessageContainer"]["n1MessageClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; sm_context_updated_data["n1MessageContainer"]["n1MessageContent"]["contentId"] = - N1_SM_CONTENT_ID; + N1_SM_CONTENT_ID; sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] = - N1N2_MESSAGE_CLASS; + N1N2_MESSAGE_CLASS; sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] = n11_triggered_pending->res.get_pdu_session_id(); sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = - N2_SM_CONTENT_ID; + N2_SM_CONTENT_ID; switch (session_procedure_type) { @@ -910,7 +923,7 @@ void session_update_sm_context_procedure::handle_itti_msg( //N1 SM smf_n1_n2_inst.create_n1_sm_container( n11_triggered_pending->res, PDU_SESSION_MODIFICATION_COMMAND, - n1_sm_msg, cause_value_5gsm_e::CAUSE_0_UNKNOWN); //TODO: need cause? + n1_sm_msg, cause_value_5gsm_e::CAUSE_0_UNKNOWN); 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 @@ -935,6 +948,20 @@ void session_update_sm_context_procedure::handle_itti_msg( "PDU Session Establishment Request (UE-Initiated)"); n11_triggered_pending->res.sm_context_updated_data["cause"] = n11_triggered_pending->res.get_cause(); + + //Send session status update to SMF APP + std::shared_ptr<itti_n11_update_pdu_session_status> itti_status = + std::make_shared<itti_n11_update_pdu_session_status>(TASK_SMF_APP, + TASK_SMF_APP); + itti_status->set_scid(std::stoi(n11_trigger->scid)); + itti_status->set_pdu_session_status( + pdu_session_status_e::PDU_SESSION_ACTIVE); + int ret = itti_inst->send_msg(itti_status); + if (RETURNok != ret) { + Logger::smf_app().error( + "Could not send ITTI message %s to task TASK_SMF_APP", + itti_status->get_msg_name()); + } } break; @@ -1055,7 +1082,6 @@ void session_update_sm_context_procedure::handle_itti_msg( default: { Logger::smf_app().info("Unknown session procedure type %d", session_procedure_type); - } }