From 76fecdb54eee5fe2aa0da0df2fdd4109246f8c13 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Tue, 3 May 2022 22:37:44 +0200 Subject: [PATCH] [SMF] Store MSISDN from GTPC and pass it in Gy CCR (#1519) --- src/smf/context.h | 5 +++++ src/smf/gn-handler.c | 17 +++++++++++++++++ src/smf/gy-path.c | 26 +++++++++++++++++++++++++- src/smf/s5c-handler.c | 16 ++++++++++++++++ tests/common/context.c | 20 ++++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/smf/context.h b/src/smf/context.h index 70a5dddda2..b05c174181 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -109,6 +109,11 @@ typedef struct smf_ue_s { int imsi_len; char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1]; + /* MSISDN */ + uint8_t msisdn[OGS_MAX_MSISDN_LEN]; + int msisdn_len; + char msisdn_bcd[OGS_MAX_MSISDN_BCD_LEN+1]; + ogs_list_t sess_list; } smf_ue_t; diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 0ad7eebcc5..b76965b112 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -93,6 +93,10 @@ uint8_t smf_gn_handle_create_pdp_context_request( ogs_error("No SGSN Address for user traffic"); cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; } + if (req->msisdn.presence == 0) { + ogs_error("No MSISDN"); + cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; + } if (req->quality_of_service_profile.presence == 0) { ogs_error("No QoS Profile"); cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING; @@ -141,6 +145,19 @@ uint8_t smf_gn_handle_create_pdp_context_request( break; } + /* Set MSISDN: */ + /* TS 29.060 sec 7.7.33, TS 29.002 ISDN-AddressString + * 1 byte offset: Get rid of address and numbering plan indicator */ + if (req->msisdn.len == 0 || (req->msisdn.len - 1) > sizeof(smf_ue->msisdn)) { + ogs_error("MSISDN wrong size %u > %zu", (req->msisdn.len - 1), sizeof(smf_ue->msisdn)); + return OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT; + } + smf_ue->msisdn_len = req->msisdn.len - 1; + if (smf_ue->msisdn_len > 0) { + memcpy(smf_ue->msisdn, (uint8_t*)req->msisdn.data + 1, smf_ue->msisdn_len); + ogs_buffer_to_bcd(smf_ue->msisdn, smf_ue->msisdn_len, smf_ue->msisdn_bcd); + } + /* Set Bearer QoS */ rv = ogs_gtp1_parse_qos_profile(&qos_pdec, &req->quality_of_service_profile); diff --git a/src/smf/gy-path.c b/src/smf/gy-path.c index 7ded590ef3..8f8f9db932 100644 --- a/src/smf/gy-path.c +++ b/src/smf/gy-path.c @@ -457,7 +457,7 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact, ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp); ogs_assert(ret == 0); - /* Subscription-Id */ + /* Subscription-Id (IMSI) */ ret = fd_msg_avp_new(ogs_diam_subscription_id, 0, &avp); ogs_assert(ret == 0); @@ -481,6 +481,30 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact, ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp); ogs_assert(ret == 0); + /* Subscription-Id (MSISDN) */ + ret = fd_msg_avp_new(ogs_diam_subscription_id, 0, &avp); + ogs_assert(ret == 0); + + ret = fd_msg_avp_new(ogs_diam_subscription_id_type, 0, &avpch1); + ogs_assert(ret == 0); + val.i32 = OGS_DIAM_SUBSCRIPTION_ID_TYPE_END_USER_E164; + ret = fd_msg_avp_setvalue (avpch1, &val); + ogs_assert(ret == 0); + ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1); + ogs_assert(ret == 0); + + ret = fd_msg_avp_new(ogs_diam_subscription_id_data, 0, &avpch1); + ogs_assert(ret == 0); + val.os.data = (uint8_t *)smf_ue->msisdn_bcd; + val.os.len = strlen(smf_ue->msisdn_bcd); + ret = fd_msg_avp_setvalue (avpch1, &val); + ogs_assert(ret == 0); + ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1); + ogs_assert(ret == 0); + + ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp); + ogs_assert(ret == 0); + /* Termination-Cause */ if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST) { ret = fd_msg_avp_new(ogs_diam_termination_cause, 0, &avp); diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 62e13df252..9cc0629e8a 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -78,6 +78,10 @@ uint8_t smf_s5c_handle_create_session_request( ogs_error("No IMSI"); cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING; } + if (req->msisdn.presence == 0) { + ogs_error("No MSISDN"); + cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING; + } if (req->sender_f_teid_for_control_plane.presence == 0) { ogs_error("No TEID"); cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING; @@ -150,6 +154,18 @@ uint8_t smf_s5c_handle_create_session_request( smf_ue = sess->smf_ue; ogs_assert(smf_ue); + /* Set MSISDN: */ + /* TS 29.274 sec 8.11, TS 29.002 ISDN-AddressString */ + if (req->msisdn.len > sizeof(smf_ue->msisdn)) { + ogs_error("MSISDN wrong size %u > %zu", req->msisdn.len, sizeof(smf_ue->msisdn)); + return OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT; + } + smf_ue->msisdn_len = req->msisdn.len; + if (smf_ue->msisdn_len > 0) { + memcpy(smf_ue->msisdn, req->msisdn.data, smf_ue->msisdn_len); + ogs_buffer_to_bcd(smf_ue->msisdn, smf_ue->msisdn_len, smf_ue->msisdn_bcd); + } + 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); diff --git a/tests/common/context.c b/tests/common/context.c index aa1a7120d3..f65893cb5c 100644 --- a/tests/common/context.c +++ b/tests/common/context.c @@ -1291,6 +1291,10 @@ bson_t *test_db_new_simple(test_ue_t *test_ue) doc = BCON_NEW( "imsi", BCON_UTF8(test_ue->imsi), + "msisdn", "[", + BCON_UTF8(TEST_MSISDN), + BCON_UTF8(TEST_ADDITIONAL_MSISDN), + "]", "ambr", "{", "downlink", "{", "value", BCON_INT32(1), @@ -1351,6 +1355,10 @@ bson_t *test_db_new_qos_flow(test_ue_t *test_ue) doc = BCON_NEW( "imsi", BCON_UTF8(test_ue->imsi), + "msisdn", "[", + BCON_UTF8(TEST_MSISDN), + BCON_UTF8(TEST_ADDITIONAL_MSISDN), + "]", "ambr", "{", "downlink", "{", "value", BCON_INT32(1), @@ -1451,6 +1459,10 @@ bson_t *test_db_new_session(test_ue_t *test_ue) doc = BCON_NEW( "imsi", BCON_UTF8(test_ue->imsi), + "msisdn", "[", + BCON_UTF8(TEST_MSISDN), + BCON_UTF8(TEST_ADDITIONAL_MSISDN), + "]", "ambr", "{", "downlink", "{", "value", BCON_INT32(1), @@ -1725,6 +1737,10 @@ bson_t *test_db_new_slice_with_same_dnn(test_ue_t *test_ue) doc = BCON_NEW( "imsi", BCON_UTF8(test_ue->imsi), + "msisdn", "[", + BCON_UTF8(TEST_MSISDN), + BCON_UTF8(TEST_ADDITIONAL_MSISDN), + "]", "ambr", "{", "downlink", "{", "value", BCON_INT32(1), @@ -2098,6 +2114,10 @@ bson_t *test_db_new_slice_with_different_dnn(test_ue_t *test_ue) doc = BCON_NEW( "imsi", BCON_UTF8(test_ue->imsi), + "msisdn", "[", + BCON_UTF8(TEST_MSISDN), + BCON_UTF8(TEST_ADDITIONAL_MSISDN), + "]", "ambr", "{", "downlink", "{", "value", BCON_INT32(1),