From 99f59be5d7d10e3b3cc799a311d08e561817c45b Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 12 May 2022 23:32:20 +0200 Subject: [PATCH] [SMF] Store Charging Characteristics IE from GTPv1C/2C and append AVP in Gy CCR (#1532) --- lib/diameter/gy/message.c | 3 ++- lib/diameter/gy/message.h | 1 + src/smf/context.h | 1 + src/smf/gn-handler.c | 4 ++++ src/smf/gy-path.c | 20 +++++++++++++++++++- src/smf/s5c-handler.c | 4 ++++ 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/diameter/gy/message.c b/lib/diameter/gy/message.c index c50b277e2..25c296d38 100644 --- a/lib/diameter/gy/message.c +++ b/lib/diameter/gy/message.c @@ -55,6 +55,7 @@ struct dict_object *ogs_diam_gy_sgsn_address = NULL; struct dict_object *ogs_diam_gy_ggsn_address = NULL; struct dict_object *ogs_diam_gy_3gpp_nsapi = NULL; struct dict_object *ogs_diam_gy_3gpp_selection_mode = NULL; +struct dict_object *ogs_diam_gy_3gpp_charging_characteristics = NULL; struct dict_object *ogs_diam_gy_feature_list_id = NULL; struct dict_object *ogs_diam_gy_feature_list = NULL; @@ -117,7 +118,7 @@ int ogs_diam_gy_init(void) CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "GGSN-Address", &ogs_diam_gy_ggsn_address); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-NSAPI", &ogs_diam_gy_3gpp_nsapi); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Selection-Mode", &ogs_diam_gy_3gpp_selection_mode); - + CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Charging-Characteristics", &ogs_diam_gy_3gpp_charging_characteristics); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List-ID", &ogs_diam_gy_feature_list_id); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List", &ogs_diam_gy_feature_list); diff --git a/lib/diameter/gy/message.h b/lib/diameter/gy/message.h index 1db2ac99f..2390694e8 100644 --- a/lib/diameter/gy/message.h +++ b/lib/diameter/gy/message.h @@ -106,6 +106,7 @@ extern struct dict_object *ogs_diam_gy_sgsn_address; extern struct dict_object *ogs_diam_gy_ggsn_address; extern struct dict_object *ogs_diam_gy_3gpp_nsapi; extern struct dict_object *ogs_diam_gy_3gpp_selection_mode; +extern struct dict_object *ogs_diam_gy_3gpp_charging_characteristics; extern struct dict_object *ogs_diam_gy_feature_list_id; extern struct dict_object *ogs_diam_gy_feature_list; extern struct dict_object *ogs_diam_gy_qos_information; diff --git a/src/smf/context.h b/src/smf/context.h index c809836d9..a9b0e5b3d 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -316,6 +316,7 @@ typedef struct smf_sess_s { ogs_tlv_octet_t ue_pco; ogs_tlv_octet_t user_location_information; ogs_tlv_octet_t ue_timezone; + ogs_tlv_octet_t charging_characteristics; bool create_session_response_apn_ambr; bool create_session_response_bearer_qos; uint8_t selection_mode; /* OGS_GTP{1,2}_SELECTION_MODE_*, same in GTPv1C and 2C. */ diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 62257e06f..1fea05fbb 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -128,6 +128,10 @@ uint8_t smf_gn_handle_create_pdp_context_request( if (sess->gtp.selection_mode > 2) sess->gtp.selection_mode = 2; + if (req->charging_characteristics.presence) { + OGS_TLV_STORE_DATA(&sess->gtp.charging_characteristics, &req->charging_characteristics); + } + /* Control Plane(DL) : SGW-S5C */ sess->sgw_s5c_teid = req->tunnel_endpoint_identifier_control_plane.u32; rv = ogs_gtp1_gsn_addr_to_ip(req->sgsn_address_for_signalling.data, diff --git a/src/smf/gy-path.c b/src/smf/gy-path.c index 900673b2d..9818a7ab7 100644 --- a/src/smf/gy-path.c +++ b/src/smf/gy-path.c @@ -377,7 +377,6 @@ static void fill_service_information_ccr(smf_sess_t *sess, /* 3GPP-Selection-Mode, 3GPP TS 29.061 16.4.7.2 12 */ ret = fd_msg_avp_new(ogs_diam_gy_3gpp_selection_mode, 0, &avpch2); ogs_assert(ret == 0); - ogs_assert(sess->session.name); digit = sess->gtp.selection_mode + '0'; val.os.data = (uint8_t*)&digit; val.os.len = 1; @@ -386,6 +385,25 @@ static void fill_service_information_ccr(smf_sess_t *sess, ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2); ogs_assert(ret == 0); + /* 3GPP-Charging-Characteristics, 3GPP TS 29.061 16.4.7.2 13 */ + if (sess->gtp.charging_characteristics.presence && + sess->gtp.charging_characteristics.len > 0) { + uint8_t oct1, oct2; + char digits[5]; + ret = fd_msg_avp_new(ogs_diam_gy_3gpp_charging_characteristics, 0, &avpch2); + ogs_assert(ret == 0); + oct1 = ((uint8_t*)sess->gtp.charging_characteristics.data)[0]; + oct2 = (sess->gtp.charging_characteristics.len > 1) ? + ((uint8_t*)sess->gtp.charging_characteristics.data)[1] : 0; + snprintf(digits, sizeof(digits), "%02x%02x", oct1, oct2); + val.os.data = (uint8_t*)&digits[0]; + val.os.len = 4; + ret = fd_msg_avp_setvalue(avpch2, &val); + ogs_assert(ret == 0); + ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2); + ogs_assert(ret == 0); + } + /* 3GPP-SGSN-MCC-MNC */ ret = fd_msg_avp_new(ogs_diam_gy_3gpp_sgsn_mcc_mnc, 0, &avpch2); ogs_assert(ret == 0); diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 4519d7a5c..de89a4f25 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -341,6 +341,10 @@ uint8_t smf_s5c_handle_create_session_request( OGS_TLV_STORE_DATA(&sess->gtp.ue_timezone, &req->ue_time_zone); } + if (req->charging_characteristics.presence) { + OGS_TLV_STORE_DATA(&sess->gtp.charging_characteristics, &req->charging_characteristics); + } + /* Set MSISDN */ if (req->msisdn.presence && req->msisdn.len && req->msisdn.data) { smf_ue->msisdn_len = req->msisdn.len;