diff --git a/lib/diameter/gy/message.c b/lib/diameter/gy/message.c index 23ac5b4a2..c50b277e2 100644 --- a/lib/diameter/gy/message.c +++ b/lib/diameter/gy/message.c @@ -54,6 +54,7 @@ struct dict_object *ogs_diam_gy_pdp_address = NULL; 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_feature_list_id = NULL; struct dict_object *ogs_diam_gy_feature_list = NULL; @@ -115,6 +116,7 @@ int ogs_diam_gy_init(void) CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "SGSN-Address", &ogs_diam_gy_sgsn_address); 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, "Feature-List-ID", &ogs_diam_gy_feature_list_id); diff --git a/lib/diameter/gy/message.h b/lib/diameter/gy/message.h index 0f3210d56..1db2ac99f 100644 --- a/lib/diameter/gy/message.h +++ b/lib/diameter/gy/message.h @@ -105,6 +105,7 @@ extern struct dict_object *ogs_diam_gy_pdp_address; 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_feature_list_id; extern struct dict_object *ogs_diam_gy_feature_list; extern struct dict_object *ogs_diam_gy_qos_information; diff --git a/lib/gtp/v1/message.c b/lib/gtp/v1/message.c index 01f123627..524fc3280 100644 --- a/lib/gtp/v1/message.c +++ b/lib/gtp/v1/message.c @@ -21,7 +21,7 @@ /******************************************************************************* * This file had been created by gtp1-tlv.py script v0.1.0 * Please do not modify this file but regenerate it via script. - * Created on: 2022-02-18 19:21:27.743742 by pespin + * Created on: 2022-05-12 14:42:38.611950 by pespin * from 29060-g00.docx ******************************************************************************/ @@ -150,7 +150,7 @@ ogs_tlv_desc_t ogs_gtp1_tlv_desc_recovery = ogs_tlv_desc_t ogs_gtp1_tlv_desc_selection_mode = { - OGS_TV_FIXED_STR, + OGS_TV_UINT8, "Selection Mode", OGS_GTP1_SELECTION_MODE_TYPE, 1, diff --git a/lib/gtp/v1/message.h b/lib/gtp/v1/message.h index 011bc4cc2..98155e46e 100644 --- a/lib/gtp/v1/message.h +++ b/lib/gtp/v1/message.h @@ -21,7 +21,7 @@ /******************************************************************************* * This file had been created by gtp1-tlv.py script v0.1.0 * Please do not modify this file but regenerate it via script. - * Created on: 2022-02-18 19:21:27.730656 by pespin + * Created on: 2022-05-12 14:42:38.599141 by pespin * from 29060-g00.docx ******************************************************************************/ @@ -471,7 +471,7 @@ typedef ogs_tlv_octet_t ogs_gtp1_tlv_map_cause_t; typedef ogs_tlv_octet_t ogs_gtp1_tlv_p_tmsi_signature_t; typedef ogs_tlv_octet_t ogs_gtp1_tlv_ms_validated_t; typedef ogs_tlv_uint8_t ogs_gtp1_tlv_recovery_t; -typedef ogs_tlv_octet_t ogs_gtp1_tlv_selection_mode_t; +typedef ogs_tlv_uint8_t ogs_gtp1_tlv_selection_mode_t; typedef ogs_tlv_uint32_t ogs_gtp1_tlv_tunnel_endpoint_identifier_data_i_t; typedef ogs_tlv_uint32_t ogs_gtp1_tlv_tunnel_endpoint_identifier_control_plane_t; typedef ogs_tlv_octet_t ogs_gtp1_tlv_tunnel_endpoint_identifier_data_ii_t; diff --git a/lib/gtp/v1/support/gtp1-tlv.py b/lib/gtp/v1/support/gtp1-tlv.py index 655592ca7..c68481099 100644 --- a/lib/gtp/v1/support/gtp1-tlv.py +++ b/lib/gtp/v1/support/gtp1-tlv.py @@ -315,6 +315,7 @@ set_c_type("Trace Type", 'uint') set_c_type("MS Not Reachable Reason", 'uint') set_c_type("Charging ID", 'uint') set_c_type("Reordering Required", 'uint') +set_c_type("Selection Mode", 'uint') msg_list["Echo Request"]["table"] = 12 msg_list["Echo Response"]["table"] = 13 diff --git a/src/smf/context.h b/src/smf/context.h index e4561f0e3..f2980be91 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -318,6 +318,7 @@ typedef struct smf_sess_s { ogs_tlv_octet_t ue_timezone; 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. */ struct { uint8_t nsapi; } v1; /* GTPv1C specific fields */ diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 665e00140..27556e98f 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -77,6 +77,10 @@ uint8_t smf_gn_handle_create_pdp_context_request( ogs_error("No IMSI"); cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; } + if (req->selection_mode.presence == 0) { + ogs_error("No Selection Mode"); + cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; + } if (req->tunnel_endpoint_identifier_data_i.presence == 0) { ogs_error("No TEID"); cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; @@ -119,6 +123,10 @@ uint8_t smf_gn_handle_create_pdp_context_request( /* Store NSAPI */ sess->gtp.v1.nsapi = req->nsapi.u8; + /* Selection Mode, TS 29.060 7.7.12 */ + sess->gtp.selection_mode = req->selection_mode.u8 & 0x03; + if (sess->gtp.selection_mode > 2) + sess->gtp.selection_mode = 2; /* Control Plane(DL) : SGW-S5C */ sess->sgw_s5c_teid = req->tunnel_endpoint_identifier_control_plane.u32; diff --git a/src/smf/gy-path.c b/src/smf/gy-path.c index 577cd7b15..900673b2d 100644 --- a/src/smf/gy-path.c +++ b/src/smf/gy-path.c @@ -255,6 +255,7 @@ static void fill_service_information_ccr(smf_sess_t *sess, struct sockaddr_in sin; struct sockaddr_in6 sin6; char buf[OGS_PLMNIDSTRLEN]; + char digit; /* Service-Information, TS 32.299 sec 7.2.192 */ ret = fd_msg_avp_new(ogs_diam_gy_service_information, 0, &avp); @@ -373,6 +374,18 @@ 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-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; + 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 8ce542958..f70fe1549 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -166,6 +166,13 @@ uint8_t smf_s5c_handle_create_session_request( } } + /* Set Selection Mode, TS 29.274 8.58 */ + if (req->selection_mode.presence == 1) { + sess->gtp.selection_mode = req->selection_mode.u8 & 0x03; + if (sess->gtp.selection_mode > 2) + sess->gtp.selection_mode = 2; + } + if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_EUTRAN) { /* User Location Inforation is mandatory only for E-UTRAN */ ogs_assert(req->user_location_information.presence);