diff --git a/lib/diameter/gy/message.c b/lib/diameter/gy/message.c index 920c36569..23ac5b4a2 100644 --- a/lib/diameter/gy/message.c +++ b/lib/diameter/gy/message.c @@ -53,6 +53,7 @@ struct dict_object *ogs_diam_gy_3gpp_pdp_type = NULL; 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_feature_list_id = NULL; struct dict_object *ogs_diam_gy_feature_list = NULL; @@ -113,6 +114,8 @@ int ogs_diam_gy_init(void) CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PDP-Address", &ogs_diam_gy_pdp_address); 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, "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 e08e1a73c..0f3210d56 100644 --- a/lib/diameter/gy/message.h +++ b/lib/diameter/gy/message.h @@ -104,6 +104,7 @@ extern struct dict_object *ogs_diam_gy_3gpp_pdp_type; 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_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.c b/src/smf/context.c index 79efac178..3663bb976 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -1141,10 +1141,11 @@ smf_sess_t *smf_sess_add_by_gtp1_message(ogs_gtp1_message_t *message) } sess = smf_sess_add_by_apn(smf_ue, apn, req->rat_type.u8); + sess->gtp.version = 1; return sess; } -smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp2_message_t *message) +smf_sess_t *smf_sess_add_by_gtp2_message(ogs_gtp2_message_t *message) { smf_ue_t *smf_ue = NULL; smf_sess_t *sess = NULL; @@ -1204,6 +1205,7 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp2_message_t *message) } sess = smf_sess_add_by_apn(smf_ue, apn, req->rat_type.u8); + sess->gtp.version = 2; return sess; } diff --git a/src/smf/context.h b/src/smf/context.h index b05c17418..e4561f0e3 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -312,16 +312,16 @@ typedef struct smf_sess_s { OpenAPI_rat_type_e sbi_rat_type; struct { + uint8_t version; /* GTPC version */ ogs_tlv_octet_t ue_pco; ogs_tlv_octet_t user_location_information; ogs_tlv_octet_t ue_timezone; bool create_session_response_apn_ambr; bool create_session_response_bearer_qos; - } gtp; /* Saved from S5-C */ - - struct { - uint8_t nsapi; - } gtp1; /* GTPv1C specific fields */ + struct { + uint8_t nsapi; + } v1; /* GTPv1C specific fields */ + } gtp; /* Saved from S5-C/Gn */ struct { uint64_t ul_octets; @@ -412,7 +412,7 @@ smf_ue_t *smf_ue_find_by_supi(char *supi); smf_ue_t *smf_ue_find_by_imsi(uint8_t *imsi, int imsi_len); smf_sess_t *smf_sess_add_by_gtp1_message(ogs_gtp1_message_t *message); -smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp2_message_t *message); +smf_sess_t *smf_sess_add_by_gtp2_message(ogs_gtp2_message_t *message); smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type); smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message); diff --git a/src/smf/gn-build.c b/src/smf/gn-build.c index 085ab3802..a064d3bca 100644 --- a/src/smf/gn-build.c +++ b/src/smf/gn-build.c @@ -157,7 +157,7 @@ ogs_pkbuf_t *smf_gn_build_create_pdp_context_response( /* TODO: NSAPI ? */ rsp->nsapi.presence = 1; - rsp->nsapi.u8 = sess->gtp1.nsapi; + rsp->nsapi.u8 = sess->gtp.v1.nsapi; /* Charging ID */ rsp->charging_id.presence = 1; diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 14597f41c..665e00140 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -118,7 +118,7 @@ uint8_t smf_gn_handle_create_pdp_context_request( ogs_assert(smf_ue); /* Store NSAPI */ - sess->gtp1.nsapi = req->nsapi.u8; + sess->gtp.v1.nsapi = req->nsapi.u8; /* 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 c2cd79002..577cd7b15 100644 --- a/src/smf/gy-path.c +++ b/src/smf/gy-path.c @@ -383,6 +383,34 @@ 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-NSAPI, 3GPP TS 29.061 16.4.7.2 10 */ + if (sess->gtp.version == 1) { + char nsapi_hex; + if (sess->gtp.v1.nsapi <= 9) + nsapi_hex = sess->gtp.v1.nsapi + '0'; + else + nsapi_hex = sess->gtp.v1.nsapi - 10 + 'A'; + ret = fd_msg_avp_new(ogs_diam_gy_3gpp_nsapi, 0, &avpch2); + ogs_assert(ret == 0); + val.os.data = (uint8_t *)&nsapi_hex; + 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); + } else { + /* GTPv2C: For PGW, EPS Bearer ID as specified in 3GPP TS 29.274 8.8 */ + smf_bearer_t *bearer = smf_default_bearer_in_sess(sess); + ret = fd_msg_avp_new(ogs_diam_gy_3gpp_nsapi, 0, &avpch2); + ogs_assert(ret == 0); + val.os.data = (uint8_t *)&bearer->ebi; + 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-MS-Timezone */ if (sess->gtp.ue_timezone.presence && sess->gtp.ue_timezone.len && sess->gtp.ue_timezone.data) { diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index f4ab787ab..f7ced1142 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -132,7 +132,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE: if (gtp2_message.h.teid == 0) { ogs_expect(!sess); - sess = smf_sess_add_by_gtp_message(>p2_message); + sess = smf_sess_add_by_gtp2_message(>p2_message); if (sess) OGS_SETUP_GTP_NODE(sess, gnode); }