From 960dc473c5b57042a5c97b4adb8833f55df097f6 Mon Sep 17 00:00:00 2001 From: Tien-Thinh Nguyen <Tien-Thinh.nguyen@eurecom.fr> Date: Sun, 17 May 2020 14:44:30 +0200 Subject: [PATCH] fix issue for loading Subscription Data from the configuration filke --- etc/smf.conf | 4 +- src/smf_app/smf_app.cpp | 86 ++++++++++++++++++------------------- src/smf_app/smf_config.cpp | 23 +++++++--- src/smf_app/smf_config.hpp | 1 + src/smf_app/smf_context.cpp | 52 ++++++++++++++++------ src/smf_app/smf_context.hpp | 19 +++++++- src/smf_app/smf_n1_n2.cpp | 4 ++ 7 files changed, 121 insertions(+), 68 deletions(-) diff --git a/etc/smf.conf b/etc/smf.conf index 8dc1afc7..4158ee6c 100644 --- a/etc/smf.conf +++ b/etc/smf.conf @@ -109,10 +109,10 @@ SMF = USE_LOCAL_CONFIGURATION = "yes"; SESSION_MANAGEMENT_SUBSCRIPTION_LIST = ( { NSSAI_SST = 222; NSSAI_SD = "123", DNN = "default", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1, - QOS_PROFILE_5QI = 6, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT", + QOS_PROFILE_5QI = 6, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT", QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"}, { NSSAI_SST = 222; NSSAI_SD = "123", DNN = "carrier.com", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1, - QOS_PROFILE_5QI = 7, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT", + QOS_PROFILE_5QI = 7, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT", QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "10Mbps", SESSION_AMBR_DL = "11Mbps"} ); }; diff --git a/src/smf_app/smf_app.cpp b/src/smf_app/smf_app.cpp index 78584a1a..9791f161 100755 --- a/src/smf_app/smf_app.cpp +++ b/src/smf_app/smf_app.cpp @@ -648,56 +648,56 @@ void smf_app::handle_pdu_session_create_sm_context_request( } //Step 6. retrieve Session Management Subscription data from UDM if not available (step 4, section 4.3.2 3GPP TS 23.502) - //TODO: Test with UDM (TESTER) std::string dnn_selection_mode = smreq->req.get_dnn_selection_mode(); - if (not use_local_configuration_subscription_data(dnn_selection_mode) - && not is_supi_dnn_snssai_subscription_data(supi, dnn, snssai)) { - //uses a dummy UDM to test this part + //if the Session Management Subscription data is not available, get from configuration file or UDM + if (not sc.get()->is_dnn_snssai_subscription_data(dnn, snssai)) { Logger::smf_app().debug( - "Retrieve Session Management Subscription data from the UDM"); + "The Session Management Subscription data is not available"); + session_management_subscription *s = new session_management_subscription( snssai); std::shared_ptr<session_management_subscription> subscription = std::shared_ptr<session_management_subscription>(s); - if (smf_n10_inst->get_sm_data(supi64, dnn, snssai, subscription)) { - //update dnn_context with subscription info - sc.get()->insert_dnn_subscription(snssai, subscription); + + if (not use_local_configuration_subscription_data(dnn_selection_mode)) { + Logger::smf_app().debug( + "Retrieve Session Management Subscription data from the UDM"); + if (smf_n10_inst->get_sm_data(supi64, dnn, snssai, subscription)) { + //update dnn_context with subscription info + sc.get()->insert_dnn_subscription(snssai, subscription); + } else { + // 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( + pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED]); + 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" + smf_n1_n2_inst.create_n1_sm_container( + smreq->req, + PDU_SESSION_ESTABLISHMENT_REJECT, + n1_sm_message, + cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED); + smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex); + //Send response (PDU Session Establishment Reject) 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; + } } else { - // 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( - pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED]); - 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" - smf_n1_n2_inst.create_n1_sm_container( - smreq->req, - PDU_SESSION_ESTABLISHMENT_REJECT, - n1_sm_message, - cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED); - smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex); - //Send response (PDU Session Establishment Reject) 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; - } - } else { - //use local configuration - Logger::smf_app().debug( - "Retrieve Session Management Subscription data from local configuration"); - session_management_subscription *s = new session_management_subscription( - snssai); - std::shared_ptr<session_management_subscription> subscription = - std::shared_ptr<session_management_subscription>(s); - if (get_session_management_subscription_data(supi64, dnn, snssai, - subscription)) { - //update dnn_context with subscription info - sc.get()->insert_dnn_subscription(snssai, subscription); - } + //use local configuration + Logger::smf_app().debug( + "Retrieve Session Management Subscription data from local configuration"); + if (get_session_management_subscription_data(supi64, dnn, snssai, + subscription)) { + //update dnn_context with subscription info + sc.get()->insert_dnn_subscription(snssai, subscription); + } + } } // Step 7. generate a SMF context Id and store the corresponding information in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id)) @@ -1003,7 +1003,7 @@ bool smf_app::scid_2_smf_context(const scid_t &scid, bool smf_app::use_local_configuration_subscription_data( const std::string &dnn_selection_mode) { //TODO: should be implemented - return true; //get Session Management Subscription from UDM + return smf_cfg.local_configuration; } //------------------------------------------------------------------------------ diff --git a/src/smf_app/smf_config.cpp b/src/smf_app/smf_config.cpp index 356111f0..916b8ee5 100644 --- a/src/smf_app/smf_config.cpp +++ b/src/smf_app/smf_config.cpp @@ -580,13 +580,14 @@ int smf_config::load(const string &config_file) { const Setting &session_management_subscription_cfg = session_management_subscription_list_cfg[i]; - unsigned int nssai_sst = { 0 }; + unsigned int nssai_sst = 0; string nssai_sd = { }; string dnn = { }; string default_session_type = { }; - unsigned int default_ssc_mode = { 0 }; - unsigned int qos_profile_5qi = { 0 }; - unsigned int qos_profile_arp_priority_level = { }; + unsigned int default_ssc_mode = 0; + unsigned int qos_profile_5qi = 0; + unsigned int qos_profile_priority_level = 0; + unsigned int qos_profile_arp_priority_level = 0; string qos_profile_arp_preemptcap = { }; string qos_profile_arp_preemptvuln = { }; string session_ambr_ul = { }; @@ -608,6 +609,9 @@ int smf_config::load(const string &config_file) { session_management_subscription_cfg.lookupValue( SMF_CONFIG_STRING_QOS_PROFILE_5QI, qos_profile_5qi); + session_management_subscription_cfg.lookupValue( + SMF_CONFIG_STRING_QOS_PROFILE_PRIORITY_LEVEL, + qos_profile_priority_level); session_management_subscription_cfg.lookupValue( SMF_CONFIG_STRING_QOS_PROFILE_ARP_PRIORITY_LEVEL, qos_profile_arp_priority_level); @@ -621,7 +625,8 @@ int smf_config::load(const string &config_file) { SMF_CONFIG_STRING_SESSION_AMBR_UL, session_ambr_ul); session_management_subscription_cfg.lookupValue( - SMF_CONFIG_STRING_SESSION_AMBR_DL, session_ambr_dl); + SMF_CONFIG_STRING_SESSION_AMBR_DL, + session_ambr_dl); session_management_subscription[i].single_nssai.sST = nssai_sst; session_management_subscription[i].single_nssai.sD = nssai_sd; @@ -629,6 +634,8 @@ int smf_config::load(const string &config_file) { session_management_subscription[i].dnn = dnn; session_management_subscription[i].ssc_mode = default_ssc_mode; session_management_subscription[i].default_qos._5qi = qos_profile_5qi; + session_management_subscription[i].default_qos.priority_level = + qos_profile_priority_level; session_management_subscription[i].default_qos.arp.priority_level = qos_profile_arp_priority_level; session_management_subscription[i].default_qos.arp.preempt_cap = @@ -788,10 +795,12 @@ void smf_config::display() { Logger::smf_app().info( " " SMF_CONFIG_STRING_QOS_PROFILE_5QI ": %d", session_management_subscription[i].default_qos._5qi); - + Logger::smf_app().info( + " " SMF_CONFIG_STRING_QOS_PROFILE_PRIORITY_LEVEL ": %d", + session_management_subscription[i].default_qos.priority_level); Logger::smf_app().info( " " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PRIORITY_LEVEL ": %d", - session_management_subscription[i].default_qos.priority_level); + session_management_subscription[i].default_qos.arp.priority_level); Logger::smf_app().info( " " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTCAP ": %s", session_management_subscription[i].default_qos.arp.preempt_cap.c_str()); diff --git a/src/smf_app/smf_config.hpp b/src/smf_app/smf_config.hpp index c66ca647..2d018234 100644 --- a/src/smf_app/smf_config.hpp +++ b/src/smf_app/smf_config.hpp @@ -125,6 +125,7 @@ #define SMF_CONFIG_STRING_DEFAULT_SESSION_TYPE "DEFAULT_SESSION_TYPE" #define SMF_CONFIG_STRING_DEFAULT_SSC_MODE "DEFAULT_SSC_MODE" #define SMF_CONFIG_STRING_QOS_PROFILE_5QI "QOS_PROFILE_5QI" +#define SMF_CONFIG_STRING_QOS_PROFILE_PRIORITY_LEVEL "QOS_PROFILE_PRIORITY_LEVEL" #define SMF_CONFIG_STRING_QOS_PROFILE_ARP_PRIORITY_LEVEL "QOS_PROFILE_ARP_PRIORITY_LEVEL" #define SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTCAP "QOS_PROFILE_ARP_PREEMPTCAP" #define SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTVULN "QOS_PROFILE_ARP_PREEMPTVULN" diff --git a/src/smf_app/smf_context.cpp b/src/smf_app/smf_context.cpp index 4d32f0d7..79dc584f 100644 --- a/src/smf_app/smf_context.cpp +++ b/src/smf_app/smf_context.cpp @@ -454,18 +454,15 @@ void smf_pdu_session::update_qos_rule(const QOSRulesIE &qos_rule) { qos_rules.insert(std::pair<uint8_t, QOSRulesIE>(rule_id, qos_rule)); //marked to be synchronised with UE qos_rules_to_be_synchronised.push_back(rule_id); - Logger::smf_app().trace("Update QoS rule (%d) success", - rule_id); + Logger::smf_app().trace("Update QoS rule (%d) success", rule_id); } else { Logger::smf_app().error( - "Update QoS Rule (%d) failed, rule does not existed", - rule_id); + "Update QoS Rule (%d) failed, rule does not existed", rule_id); } } else { - Logger::smf_app().error( - "Update QoS rule (%d) failed, invalid Rule Id", - rule_id); + Logger::smf_app().error("Update QoS rule (%d) failed, invalid Rule Id", + rule_id); } } @@ -518,7 +515,8 @@ void smf_pdu_session::add_qos_rule(const QOSRulesIE &qos_rule) { //------------------------------------------------------------------------------ void session_management_subscription::insert_dnn_configuration( - std::string dnn, std::shared_ptr<dnn_configuration_t> &dnn_configuration) { + const std::string &dnn, + std::shared_ptr<dnn_configuration_t> &dnn_configuration) { dnn_configurations.insert( std::pair<std::string, std::shared_ptr<dnn_configuration_t>>( dnn, dnn_configuration)); @@ -526,13 +524,24 @@ void session_management_subscription::insert_dnn_configuration( //------------------------------------------------------------------------------ void session_management_subscription::find_dnn_configuration( - std::string dnn, std::shared_ptr<dnn_configuration_t> &dnn_configuration) { + const std::string &dnn, + std::shared_ptr<dnn_configuration_t> &dnn_configuration) const { Logger::smf_app().info("Find DNN configuration with DNN %s", dnn.c_str()); if (dnn_configurations.count(dnn) > 0) { dnn_configuration = dnn_configurations.at(dnn); } } +//------------------------------------------------------------------------------ +bool session_management_subscription::dnn_configuration( + const std::string &dnn) const { + if (dnn_configurations.count(dnn) > 0) { + return true; + } else { + return false; + } +} + //------------------------------------------------------------------------------ void smf_context::insert_procedure(std::shared_ptr<smf_procedure> &sproc) { std::unique_lock<std::recursive_mutex> lock(m_context); @@ -876,8 +885,6 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr, void smf_context::get_session_ambr( Ngap_PDUSessionAggregateMaximumBitRate_t &session_ambr, const snssai_t &snssai, const std::string &dnn) { - Logger::smf_app().debug( - "Get AMBR info from the subscription information (DNN %s)", dnn.c_str()); std::shared_ptr<session_management_subscription> ss = { }; std::shared_ptr<dnn_configuration_t> sdc = { }; @@ -898,9 +905,9 @@ void smf_context::get_session_ambr( if (nullptr != sdc.get()) { Logger::smf_app().debug( - "Default AMBR info from the DNN configuration, downlink %s, uplink %s", - (sdc.get()->session_ambr).downlink.c_str(), - (sdc.get()->session_ambr).uplink.c_str()); + "Default AMBR info from the DNN configuration, uplink %s, downlink %s", + (sdc.get()->session_ambr).uplink.c_str(), + (sdc.get()->session_ambr).downlink.c_str()); //Downlink size_t leng_of_session_ambr_dl = (sdc.get()->session_ambr).downlink.length(); @@ -958,6 +965,9 @@ void smf_context::get_session_ambr( session_ambr.pDUSessionAggregateMaximumBitRateUL.buf); } + Logger::smf_app().debug( + "Get AMBR info from the subscription information (DNN %s), uplink %d downlink %d", + dnn.c_str(), bit_rate_ul, bit_rate_dl); } //------------------------------------------------------------------------------ @@ -2410,6 +2420,20 @@ void smf_context::insert_dnn_subscription( (uint8_t) snssai.sST); } +//------------------------------------------------------------------------------ +bool smf_context::is_dnn_snssai_subscription_data(std::string &dnn, + snssai_t &snssai) { + if (dnn_subscriptions.count((uint8_t) snssai.sST) > 0) { + std::shared_ptr<session_management_subscription> ss = dnn_subscriptions.at( + (uint8_t) snssai.sST); + if (ss.get()->dnn_configuration(dnn)) + return true; + else + return false; + } + return false; +} + //------------------------------------------------------------------------------ bool smf_context::find_dnn_subscription( const snssai_t &snssai, diff --git a/src/smf_app/smf_context.hpp b/src/smf_app/smf_context.hpp index 3166e4de..b6cf3989 100644 --- a/src/smf_app/smf_context.hpp +++ b/src/smf_app/smf_context.hpp @@ -441,7 +441,7 @@ class session_management_subscription { * @return void */ void insert_dnn_configuration( - std::string dnn, std::shared_ptr<dnn_configuration_t> &dnn_configuration); + const std::string &dnn, std::shared_ptr<dnn_configuration_t> &dnn_configuration); /* * Find a DNN configuration @@ -450,7 +450,14 @@ class session_management_subscription { * @return void */ void find_dnn_configuration( - std::string dnn, std::shared_ptr<dnn_configuration_t> &dnn_configuration); + const std::string &dnn, std::shared_ptr<dnn_configuration_t> &dnn_configuration) const; + + /* + * Verify whether DNN configuration with a given DNN exist + * @param [std::string &] dnn + * @return bool: return true if the configuration exist, otherwise return false + */ + bool dnn_configuration(const std::string &dnn) const; private: snssai_t single_nssai; @@ -654,6 +661,14 @@ class smf_context : public std::enable_shared_from_this<smf_context> { const snssai_t &snssai, std::shared_ptr<session_management_subscription> &ss); + /* + * Verify whether a subscription data exist with a given dnn and snssai + * @param [std::string &] dnn: DNN + * @param [const snssai_t&] snssai: single NSSAI + *@return bool: Return true if a subscription data corresponding with dnn and snssai exist, otherwise return false + */ + bool is_dnn_snssai_subscription_data(std::string &dnn, snssai_t &snssai); + /* * Find a session management subscription from a SMF context * @param [const snssai_t&] snssai diff --git a/src/smf_app/smf_n1_n2.cpp b/src/smf_app/smf_n1_n2.cpp index f7c000c3..6b663d40 100644 --- a/src/smf_app/smf_n1_n2.cpp +++ b/src/smf_app/smf_n1_n2.cpp @@ -872,6 +872,10 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, ngap_QosFlowSetupRequestItem); ASN_SEQUENCE_ADD(&ngap_IEs->protocolIEs.list, qosFlowSetupRequestList); + Logger::smf_app().info( + "QoS parameters: QFI %d, ARP priority level %d, qos_flow.qos_profile.arp.preempt_cap %s, qos_flow.qos_profile.arp.preempt_vuln %s", + qos_flow.qfi.qfi, qos_flow.qos_profile.arp.priority_level,qos_flow.qos_profile.arp.preempt_cap.c_str(), qos_flow.qos_profile.arp.preempt_vuln.c_str()); + //encode size_t buffer_size = BUF_LEN; char *buffer = (char*) calloc(1, buffer_size); -- GitLab