diff --git a/src/smf_app/smf_app.cpp b/src/smf_app/smf_app.cpp index 909a57b4323996f30810d70f5970407bedb515e2..86170080814b53ccdf78bc953e79239dc9ceb8c2 100755 --- a/src/smf_app/smf_app.cpp +++ b/src/smf_app/smf_app.cpp @@ -924,7 +924,7 @@ void smf_app::handle_pdu_session_release_sm_context_request( } //------------------------------------------------------------------------------ -void smf_app::trigger_pdu_session_modification () { +void smf_app::trigger_pdu_session_modification() { //SMF-requested session modification, see section 4.3.3.2@3GPP TS 23.502 //The SMF may decide to modify PDU Session. This procedure also may be //triggered based on locally configured policy or triggered from the (R)AN (see clause 4.2.6 and clause 4.9.1). @@ -932,22 +932,27 @@ void smf_app::trigger_pdu_session_modification () { //SMF has marked that the status of one or more QoS Flows are deleted in the 5GC but not synchronized with //the UE yet. - std::shared_ptr<itti_nx_trigger_pdu_session_modification> itti_msg = - std::make_shared<itti_nx_trigger_pdu_session_modification>( - TASK_SMF_N11, TASK_SMF_APP); + std::make_shared<itti_nx_trigger_pdu_session_modification>(TASK_SMF_APP, + TASK_SMF_N11); - //step 1. collect the necessary information + //step 1. collect the necessary information- hardcoded supi_t supi = { }; - std::string dnn; - pdu_session_id_t pdu_session_id = { 0 }; + std::string dnn("default"); + pdu_session_id_t pdu_session_id = { 1 }; snssai_t snssai = { }; + pfcp::qfi_t qfi = { }; + qfi.qfi = 7; + std::string supi_str("200000000000001"); + smf_string_to_supi(&supi, supi_str.c_str()); + snssai.sST = 222; + snssai.sD = "0000D4"; itti_msg->msg.set_supi(supi); itti_msg->msg.set_dnn(dnn); itti_msg->msg.set_pdu_session_id(pdu_session_id); itti_msg->msg.set_snssai(snssai); - + itti_msg->msg.add_qfi(qfi); supi64_t supi64 = smf_supi_to_u64(supi); //Step 2. find the smf context @@ -958,14 +963,13 @@ void smf_app::trigger_pdu_session_modification () { Logger::smf_app().debug("Retrieve SMF context with SUPI " SUPI_64_FMT "", supi64); } else { - Logger::smf_app().debug("SMF context with SUPI " SUPI_64_FMT "does not exist", - supi64); + Logger::smf_app().debug( + "SMF context with SUPI " SUPI_64_FMT "does not exist", supi64); return; } // handle the message in smf_context - sc.get()->handle_pdu_session_modification_network_requested(itti_msg); - + sc.get()->handle_pdu_session_modification_network_requested(itti_msg); } //------------------------------------------------------------------------------ diff --git a/src/smf_app/smf_context.cpp b/src/smf_app/smf_context.cpp index 4c6aca299464fed16d377335dd44dd8c0194b847..40d9e8817b381150637251a40c1bec27545f7bfa 100644 --- a/src/smf_app/smf_context.cpp +++ b/src/smf_app/smf_context.cpp @@ -222,7 +222,6 @@ bool smf_pdu_session::get_qos_flow(const pfcp::qfi_t &qfi, smf_qos_flow &q) { return false; } - //------------------------------------------------------------------------------ void smf_pdu_session::set_default_qos_flow(const pfcp::qfi_t &qfi) { default_qfi.qfi = qfi.qfi; @@ -400,8 +399,10 @@ void smf_pdu_session::get_qos_rules_to_be_synchronised( //------------------------------------------------------------------------------ void smf_pdu_session::get_qos_rules(pfcp::qfi_t qfi, std::vector<QOSRulesIE> &rules) const { + Logger::smf_app().info("Get QoS Rules associated with Flow with QFI %d", + qfi.qfi); for (auto it : qos_rules) { - if (it.first == qfi.qfi) + if (it.second.qosflowidentifer == qfi.qfi) rules.push_back(qos_rules.at(it.first)); } } @@ -457,6 +458,29 @@ void smf_pdu_session::update_qos_rule(QOSRulesIE qos_rule) { } } +//------------------------------------------------------------------------------ +void smf_pdu_session::mark_qos_rule_to_be_synchronised(uint8_t rule_id) { + + if ((rule_id >= QOS_RULE_IDENTIFIER_FIRST ) + and (rule_id <= QOS_RULE_IDENTIFIER_LAST )) { + if (qos_rules.count(rule_id) > 0) { + qos_rules_to_be_synchronised.push_back(rule_id); + Logger::smf_app().trace( + "smf_pdu_session::mark_qos_rule_to_be_synchronised(%d) success", + rule_id); + } else { + Logger::smf_app().error( + "smf_pdu_session::mark_qos_rule_to_be_synchronised(%d) failed, rule does not existed", + rule_id); + } + + } else { + Logger::smf_app().error( + "smf_pdu_session::mark_qos_rule_to_be_synchronised(%d) failed, invalid Rule Id", + rule_id); + } +} + //------------------------------------------------------------------------------ void smf_pdu_session::add_qos_rule(QOSRulesIE qos_rule) { Logger::smf_app().info("Add QoS Rule with Rule Id %d", @@ -683,8 +707,8 @@ void smf_context::get_default_qos_rule(QOSRulesIE &qos_rule, //------------------------------------------------------------------------------ void smf_context::get_default_qos_flow_description( - QOSFlowDescriptionsContents &qos_flow_description, - uint8_t pdu_session_type, const pfcp::qfi_t &qfi) { + QOSFlowDescriptionsContents &qos_flow_description, uint8_t pdu_session_type, + const pfcp::qfi_t &qfi) { //TODO, update according to PDU Session type Logger::smf_app().info( "Get default QoS Flow Description (PDU session type %d)", @@ -2223,7 +2247,6 @@ void smf_context::handle_pdu_session_modification_network_requested( Logger::smf_app().info( "Handle a PDU Session Modification Request (SMF-Requested)"); - pdu_session_modification_network_requested sm_context_msg = itti_msg->msg; smf_n1_n2 smf_n1_n2_inst = { }; oai::smf_server::model::SmContextUpdateError smContextUpdateError = { }; oai::smf_server::model::SmContextUpdatedData smContextUpdatedData = { }; @@ -2236,25 +2259,113 @@ void smf_context::handle_pdu_session_modification_network_requested( //Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and pdu_session must be existed std::shared_ptr<dnn_context> sd = { }; std::shared_ptr<smf_pdu_session> sp = { }; - bool find_dnn = find_dnn_context(sm_context_msg.get_snssai(), - sm_context_msg.get_dnn(), sd); + bool find_dnn = find_dnn_context(itti_msg->msg.get_snssai(), + itti_msg->msg.get_dnn(), sd); bool find_pdu = false; if (find_dnn) { - find_pdu = sd.get()->find_pdu_session(sm_context_msg.get_pdu_session_id(), + find_pdu = sd.get()->find_pdu_session(itti_msg->msg.get_pdu_session_id(), sp); } 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!"); return; } - //prepare + std::vector<pfcp::qfi_t> list_qfis_to_be_updated; + itti_msg->msg.get_qfis(list_qfis_to_be_updated); + + //add QFI(s), QoS Profile(s), QoS Rules + for (auto it : list_qfis_to_be_updated) { + Logger::smf_app().debug("QFI to be updated: %d", it.qfi); + + std::vector<QOSRulesIE> qos_rules; + sp.get()->get_qos_rules(it, qos_rules); + //mark QoS rule to be updated for all rules associated with the QFIs + for (auto r : qos_rules) { + sp.get()->mark_qos_rule_to_be_synchronised(r.qosruleidentifer); + } - // Step 1. verify if dnn context, pdu context exist + //list of QFIs and QoS profiles + smf_qos_flow flow = { }; + if (sp.get()->get_qos_flow(it, flow)) { + qos_flow_context_updated qcu = { }; + qcu.set_qfi(flow.qfi); + qcu.set_qos_profile(flow.qos_profile); + qcu.set_ul_fteid(flow.ul_fteid); + qcu.set_dl_fteid(flow.dl_fteid); + itti_msg->msg.add_qos_flow_context_updated(qcu); + } + } // Step 2. prepare information for N1N2MessageTransfer to send to AMF - // Step 3. Send itti to N11 for sending N1N2MessageTranfer + Logger::smf_app().debug( + "Prepare N1N2MessageTransfer message and send to AMF"); + + //N1: PDU_SESSION_MODIFICATION_COMMAND + smf_n1_n2_inst.create_n1_sm_container(itti_msg->msg, + PDU_SESSION_MODIFICATION_COMMAND, + n1_sm_msg, + cause_value_5gsm_e::CAUSE_0_UNKNOWN); + smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); + itti_msg->msg.set_n1_sm_message(n1_sm_msg_hex); + + //N2: PDU Session Resource Modify Request Transfer + smf_n1_n2_inst.create_n2_sm_information(itti_msg->msg, 1, + n2_sm_info_type_e::PDU_RES_MOD_REQ, + n2_sm_info); + smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex); + itti_msg->msg.set_n2_sm_information(n2_sm_info_hex); + + //Fill N1N2MesasgeTransferRequestData + //get supi and put into URL + supi_t supi = itti_msg->msg.get_supi(); + std::string supi_str = itti_msg->msg.get_supi_prefix() + "-" + + smf_supi_to_string(supi); + std::string url = std::string( + inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) + ":" + + std::to_string(smf_cfg.amf_addr.port) + + fmt::format(NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL, + supi_str.c_str()); + itti_msg->msg.set_amf_url(url); + Logger::smf_n11().debug( + "N1N2MessageTransfer will be sent to AMF with URL: %s", url.c_str()); + + //Fill the json part + //N1SM + itti_msg->msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageClass"] = + N1N2_MESSAGE_CLASS; + itti_msg->msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"] = + N1_SM_CONTENT_ID; //NAS part + //N2SM + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["n2InformationClass"] = + N1N2_MESSAGE_CLASS; + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["PduSessionId"] = + itti_msg->msg.get_pdu_session_id(); + //N2InfoContent (section 6.1.6.2.27@3GPP TS 29.518) + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] = + "PDU_RES_MOD_REQ"; //NGAP message type + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = + N2_SM_CONTENT_ID; //NGAP part + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] = + itti_msg->msg.get_snssai().sST; + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] = + itti_msg->msg.get_snssai().sD; + itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["ranInfo"] = "SM"; + + itti_msg->msg.n1n2_message_transfer_data["pduSessionId"] = itti_msg->msg + .get_pdu_session_id(); + + //Step 3. Send ITTI message to N11 interface to trigger N1N2MessageTransfer towards AMFs + Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11", + itti_msg->get_msg_name()); + + int ret = itti_inst->send_msg(itti_msg); + if (RETURNok != ret) { + Logger::smf_app().error( + "Could not send ITTI message %s to task TASK_SMF_N11", + itti_msg->get_msg_name()); + } + } //------------------------------------------------------------------------------ diff --git a/src/smf_app/smf_context.hpp b/src/smf_app/smf_context.hpp index f5027b38c6326e24381df0ab7ab40682c9173884..8a565ed2673533949bd9c215687707822d7bb7e5 100644 --- a/src/smf_app/smf_context.hpp +++ b/src/smf_app/smf_context.hpp @@ -182,6 +182,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> { void generate_qos_rule_id(uint8_t &rule_id); void release_qos_rule_id(const uint8_t &rule_id); + void mark_qos_rule_to_be_synchronised(uint8_t rule_id); void get_qos_rules_to_be_synchronised(std::vector<QOSRulesIE> &qos_rules) const; /* @@ -229,7 +230,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> { // QFI <-> QoS Flow std::map<uint8_t, smf_qos_flow> qos_flows; pfcp::qfi_t default_qfi; - // QFI <-> QoS Rules + // QRI <-> QoS Rules std::map<uint8_t, QOSRulesIE> qos_rules; std::vector<uint8_t> qos_rules_to_be_synchronised; std::vector<uint8_t> qos_rules_to_be_removed; diff --git a/src/smf_app/smf_msg.cpp b/src/smf_app/smf_msg.cpp index 41c447251559e4f647395002bc060eada2c5d849..462a139b303a51ef3ddabf0378637046d3242d6e 100644 --- a/src/smf_app/smf_msg.cpp +++ b/src/smf_app/smf_msg.cpp @@ -57,8 +57,8 @@ void qos_flow_context_updated::add_qos_rule(const QOSRulesIE &rule) { and (rule_id <= QOS_RULE_IDENTIFIER_LAST )) { qos_rules.erase(rule_id); qos_rules.insert(std::pair<uint8_t, QOSRulesIE>(rule_id, rule)); - Logger::smf_app().trace("qos_flow_context_updated::add_qos_rule(%d) success", - rule_id); + Logger::smf_app().trace( + "qos_flow_context_updated::add_qos_rule(%d) success", rule_id); } } @@ -158,12 +158,10 @@ procedure_transaction_id_t pdu_session_msg::get_pti() const { } //----------------------------------------------------------------------------- -void pdu_session_msg::set_pti( - procedure_transaction_id_t const &pti) { +void pdu_session_msg::set_pti(procedure_transaction_id_t const &pti) { m_pti = pti; } - //----------------------------------------------------------------------------- extended_protocol_discriminator_t pdu_session_create_sm_context::get_epd() const { return m_epd; @@ -438,7 +436,6 @@ bool pdu_session_update_sm_context_request::an_type_is_set() const { return m_an_type_is_set; } - //----------------------------------------------------------------------------- bool pdu_session_update_sm_context_request::release_is_set() const { return m_release_is_set; @@ -446,8 +443,8 @@ bool pdu_session_update_sm_context_request::release_is_set() const { //----------------------------------------------------------------------------- void pdu_session_update_sm_context_request::set_release(bool const value) { - m_release = value; - m_release_is_set = true; + m_release = value; + m_release_is_set = true; } //----------------------------------------------------------------------------- @@ -563,7 +560,6 @@ void pdu_session_update_sm_context_response::remove_all_qos_flow_context_updated qos_flow_context_updateds.clear(); } - //----------------------------------------------------------------------------- void pdu_session_release_sm_context_response::set_cause(uint8_t cause) { m_cause = cause; @@ -574,19 +570,6 @@ uint8_t pdu_session_release_sm_context_response::get_cause() { return m_cause; } - - - -//----------------------------------------------------------------------------- -void pdu_session_modification_network_requested::set_cause(uint8_t cause) { - m_cause = cause; -} - -//----------------------------------------------------------------------------- -uint8_t pdu_session_modification_network_requested::get_cause() { - return m_cause; -} - //----------------------------------------------------------------------------- void pdu_session_modification_network_requested::set_http_code( Pistache::Http::Code code) { @@ -598,48 +581,34 @@ Pistache::Http::Code pdu_session_modification_network_requested::get_http_code() return m_code; } - -//----------------------------------------------------------------------------- -std::string pdu_session_modification_network_requested::get_n2_sm_information() const { - return m_n2_sm_information; -} - //----------------------------------------------------------------------------- -void pdu_session_modification_network_requested::set_n2_sm_information( +void pdu_session_modification_network_requested::set_amf_url( std::string const &value) { - m_n2_sm_information = value; - m_n2_sm_info_is_set = true; -} - -//----------------------------------------------------------------------------- -std::string pdu_session_modification_network_requested::get_n1_sm_message() const { - return m_n1_sm_message; + amf_url = value; } //----------------------------------------------------------------------------- -void pdu_session_modification_network_requested::set_n1_sm_message( - std::string const &value) { - m_n1_sm_message = value; - m_n1_sm_msg_is_set = true; +std::string pdu_session_modification_network_requested::get_amf_url() const { + return amf_url; } //----------------------------------------------------------------------------- -bool pdu_session_modification_network_requested::n1_sm_msg_is_set() const { - return m_n1_sm_msg_is_set; +void pdu_session_modification_network_requested::add_qfi( + pfcp::qfi_t const &qfi) { + qfis.push_back(qfi); } //----------------------------------------------------------------------------- -bool pdu_session_modification_network_requested::n2_sm_info_is_set() const { - return m_n2_sm_info_is_set; +void pdu_session_modification_network_requested::add_qfi(uint8_t const &q) { + pfcp::qfi_t qfi(q); + qfis.push_back(qfi); } //----------------------------------------------------------------------------- -void pdu_session_modification_network_requested::set_amf_url( - std::string const &value) { - amf_url = value; +void pdu_session_modification_network_requested::get_qfis( + std::vector<pfcp::qfi_t> &q) { + for (auto qfi : qfis) { + q.push_back(qfi); + } } -//----------------------------------------------------------------------------- -std::string pdu_session_modification_network_requested::get_amf_url() const { - return amf_url; -} diff --git a/src/smf_app/smf_msg.hpp b/src/smf_app/smf_msg.hpp index c422f20d0861295b6cb9af4342405d75827abd77..a6a863df3143b088cc9aa8bfc55fabc8ea6352cd 100644 --- a/src/smf_app/smf_msg.hpp +++ b/src/smf_app/smf_msg.hpp @@ -68,7 +68,7 @@ class qos_flow_context_updated { qfi(), ul_fteid(), dl_fteid(), - // qos_rule(), + // qos_rule(), qos_profile(), to_be_removed(false) { } @@ -77,15 +77,15 @@ class qos_flow_context_updated { void set_qfi(const pfcp::qfi_t &q); void set_ul_fteid(const fteid_t &teid); void set_dl_fteid(const fteid_t &teid); - void add_qos_rule (const QOSRulesIE &rule); + void add_qos_rule(const QOSRulesIE &rule); void set_qos_profile(const qos_profile_t &profile); void set_priority_level(uint8_t p); uint8_t cause_value; pfcp::qfi_t qfi; fteid_t ul_fteid; fteid_t dl_fteid; - // QOSRulesIE qos_rule; - std::map <uint8_t, QOSRulesIE> qos_rules; + // QOSRulesIE qos_rule; + std::map<uint8_t, QOSRulesIE> qos_rules; qos_profile_t qos_profile; bool to_be_removed; }; @@ -522,6 +522,16 @@ class pdu_session_update_sm_context_response : public pdu_session_msg { } ; + pdu_session_update_sm_context_response(pdu_session_msg_type_t type) + : + pdu_session_msg(type) { + m_cause = 0; + m_n1_sm_msg_is_set = false; + m_n2_sm_info_is_set = false; + qos_flow_context_updateds = { }; + } + ; + void set_cause(uint8_t cause); uint8_t get_cause(); std::string get_n2_sm_information() const; @@ -583,53 +593,34 @@ class pdu_session_release_sm_context_response : public pdu_session_msg { }; //--------------------------------------------------------------------------------------- -class pdu_session_modification_network_requested : public pdu_session_msg { +class pdu_session_modification_network_requested : + public pdu_session_update_sm_context_response { public: pdu_session_modification_network_requested() : - pdu_session_msg(PDU_SESSION_MODIFICATION_SMF_REQUESTED) { - m_n1_sm_msg_is_set = false; - m_n2_sm_info_is_set = false; - m_cause = 0; + pdu_session_update_sm_context_response( + PDU_SESSION_MODIFICATION_SMF_REQUESTED) { m_code = { }; m_supi = { }; } - pdu_session_modification_network_requested(supi_t supi, pdu_session_id_t pdi, - std::string dnn, snssai_t snssai) - : - pdu_session_msg(PDU_SESSION_MODIFICATION_SMF_REQUESTED, supi, pdi, dnn, - snssai) { - m_n1_sm_msg_is_set = false; - m_n2_sm_info_is_set = false; - m_cause = 0; - m_code = { }; - } - void set_cause(uint8_t cause); - uint8_t get_cause(); void set_http_code(Pistache::Http::Code code); Pistache::Http::Code get_http_code(); - std::string get_n2_sm_information() const; - void set_n2_sm_information(std::string const &value); - std::string get_n1_sm_message() const; - void set_n1_sm_message(std::string const &value); - bool n1_sm_msg_is_set() const; - bool n2_sm_info_is_set() const; void set_amf_url(std::string const &value); std::string get_amf_url() const; + void add_qfi(pfcp::qfi_t const &qfi); + void add_qfi(uint8_t const &qfi); + void get_qfis(std::vector<pfcp::qfi_t> &q); nlohmann::json n1n2_message_transfer_data; //N1N2MessageTransferReqData from oai::amf::model private: - std::string m_n1_sm_message; //N1 SM message after decoding - bool m_n1_sm_msg_is_set; - std::string m_n2_sm_information; //N2 SM info after decoding - bool m_n2_sm_info_is_set; - uint8_t m_cause; Pistache::Http::Code m_code; supi_t m_supi; std::string m_supi_prefix; std::string amf_url; + std::vector<pfcp::qfi_t> qfis; + std::map<uint8_t, qos_flow_context_updated> qos_flow_context_updateds; }; } diff --git a/src/smf_app/smf_n11.cpp b/src/smf_app/smf_n11.cpp index 518a5fef3b7663b1d183a070f8e0fa0391f61d29..b16838a404dee8ecb3455db88613e378cddaf218 100644 --- a/src/smf_app/smf_n11.cpp +++ b/src/smf_app/smf_n11.cpp @@ -97,6 +97,11 @@ void smf_n11_task(void *args_p) { std::static_pointer_cast< itti_n11_modify_session_request_smf_requested>(shared_msg)); break; + case NX_TRIGGER_SESSION_MODIFICATION: + smf_n11_inst->send_n1n2_message_transfer_request( + std::static_pointer_cast<itti_nx_trigger_pdu_session_modification>( + shared_msg)); + break; case TERMINATE: if (itti_msg_terminate *terminate = @@ -349,6 +354,92 @@ void smf_n11::send_n1n2_message_transfer_request( */ } + + +//------------------------------------------------------------------------------ +void smf_n11::send_n1n2_message_transfer_request( + std::shared_ptr<itti_nx_trigger_pdu_session_modification> sm_context_res) { + //Transfer N1/N2 message via AMF by using N_amf_Communication_N1N2MessageTransfer (see TS29518_Namf_Communication.yaml) + + Logger::smf_n11().debug("Send Communication_N1N2MessageTransfer to AMF"); + + smf_n1_n2 smf_n1_n2_inst = { }; + std::string n1_message = sm_context_res->msg.get_n1_sm_message(); + std::string json_part = sm_context_res->msg.n1n2_message_transfer_data.dump(); + std::string boundary = "----Boundary"; + std::string body; + + //add N2 content if available + auto n2_sm_found = sm_context_res->msg.n1n2_message_transfer_data.count( + "n2InfoContainer"); + if (n2_sm_found > 0) { + std::string n2_message = sm_context_res->msg.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); + } + + 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(); + + 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"); //TODO: update Boundary + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_URL, + sm_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()); + + // 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()); + + 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 + json response_data = { }; + try { + response_data = json::parse(*httpData.get()); + } catch (json::exception &e) { + Logger::smf_n11().warn("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", + httpCode); + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + free_wrapper((void**) &data); + +} + + //------------------------------------------------------------------------------ void smf_n11::send_pdu_session_update_sm_context_response( std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res) { diff --git a/src/smf_app/smf_n11.hpp b/src/smf_app/smf_n11.hpp index 33d7748ed5c02b8f94abafc0157c33ec084940ad..c744468c382c0f354656485499a2d059f9d83ab1 100644 --- a/src/smf_app/smf_n11.hpp +++ b/src/smf_app/smf_n11.hpp @@ -61,6 +61,14 @@ class smf_n11 { void send_n1n2_message_transfer_request( std::shared_ptr<itti_n11_create_sm_context_response> sm_context_res); + /* + * Send N1N2 Message Transfer Request to AMF + * @param [std::shared_ptr<itti_nx_trigger_pdu_session_modification>] sm_context_res: Content of message to be sent + * + */ + void send_n1n2_message_transfer_request( + std::shared_ptr<itti_nx_trigger_pdu_session_modification> sm_context_res); + /* * Send update session response to AMF * @param [std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res] sm_context_res diff --git a/src/smf_app/smf_n1_n2.cpp b/src/smf_app/smf_n1_n2.cpp index f138255b6802c21a50d9c872699b15d634991ae1..f5ba3b683f1aa8d00a8db7d795791cd1850f929f 100644 --- a/src/smf_app/smf_n1_n2.cpp +++ b/src/smf_app/smf_n1_n2.cpp @@ -324,9 +324,9 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, nas_msg_str = n1Message; //free memory - free_wrapper( - (void**) &sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie[0] - .packetfilterlist.create_modifyandadd_modifyandreplace); +// free_wrapper( +// (void**) &sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie[0] +// .packetfilterlist.create_modifyandadd_modifyandreplace); free_wrapper( (void**) &sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie); free_wrapper( @@ -507,9 +507,13 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg, sm_msg->pdu_session_modification_command.qosrules.lengthofqosrulesie = qos_rules.size(); + sm_msg->pdu_session_modification_command.qosrules.qosrulesie = (QOSRulesIE*) calloc(qos_rules.size(), sizeof(QOSRulesIE)); for (int i = 0; i < qos_rules.size(); i++) { + Logger::smf_app().debug("QoS Rule to be updated (Id %d)", + qos_rules[i].qosruleidentifer); + //sm_msg->pdu_session_modification_command.qosrules.qosrulesie[i] = qos_rules[i]; memcpy (&sm_msg->pdu_session_modification_command.qosrules.qosrulesie[i], &qos_rules[i], sizeof(QOSRulesIE)); } diff --git a/src/smf_app/smf_procedure.cpp b/src/smf_app/smf_procedure.cpp index a6557a6199bfa924b16a63915205c6e50ec4d597..11bdaf3e8b70bf242879d75d12db44869f528153 100644 --- a/src/smf_app/smf_procedure.cpp +++ b/src/smf_app/smf_procedure.cpp @@ -280,6 +280,18 @@ int session_create_sm_context_procedure::run( sps->add_qos_flow(flow2); sps->set_default_qos_flow(flow.qfi); + /* + //add another flow for testing purpose, TODO: SHOULD BE REMOVED + smf_qos_flow flow3 = flow; + flow3.qfi = 7; + sps->add_qos_flow(flow3); + QOSRulesIE qos_rule2 = qos_rule; + qos_rule2.qosruleidentifer = 10; + qos_rule2.qosflowidentifer = 7; + qos_rule2.dqrbit = THE_QOS_RULE_IS_NOT_THE_DEFAULT_QOS_RULE; + sps->add_qos_rule(qos_rule2); + */ + // for finding procedure when receiving response smf_app_inst->set_seid_2_smf_context(cp_fseid.seid, sc); @@ -327,6 +339,13 @@ void session_create_sm_context_procedure::handle_itti_msg( //Update Qos Flow smf_qos_flow flow2 = flow; sps->add_qos_flow(flow2); + + /* + //add another flow for testing purpose, TODO: SHOULD BE REMOVED + smf_qos_flow flow3 = flow; + flow3.qfi = 7; + sps->add_qos_flow(flow3); + */ } } else { Logger::smf_app().error("Could not get QoS Flow for created_pdr %d", @@ -1011,6 +1030,13 @@ void session_update_sm_context_procedure::handle_itti_msg( smf_qos_flow flow2 = flow; sps->add_qos_flow(flow2); + /* + //add another flow for testing purpose, TODO: SHOULD BE REMOVED + smf_qos_flow flow3 = flow; + flow3.qfi = 7; + sps->add_qos_flow(flow3); + */ + qos_flow_context_updated qcu = { }; qcu.set_cause(REQUEST_ACCEPTED); qcu.set_qfi(pfcp::qfi_t(it.first));