From 6e60d3213e25e7284e7ebb070147042867674042 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sun, 27 Aug 2017 17:38:57 +0900 Subject: [PATCH] fix the bug diameter gx message if there is no pcc rule --- lib/fd/fd_message.c | 29 ++++ lib/fd/fd_message.h | 3 + src/hss/hss_fd_path.c | 30 +++- src/mme/mme_fd_path.c | 8 + src/pcrf/pcrf_fd_path.c | 333 ++++++++++++++++++++++------------------ src/pgw/pgw_fd_path.c | 295 ++++++++++++++++++----------------- 6 files changed, 401 insertions(+), 297 deletions(-) diff --git a/lib/fd/fd_message.c b/lib/fd/fd_message.c index 8a66caa6a1..7317fcbb61 100644 --- a/lib/fd/fd_message.c +++ b/lib/fd/fd_message.c @@ -17,6 +17,7 @@ struct dict_object *fd_auth_application_id = NULL; struct dict_object *fd_result_code = NULL; struct dict_object *fd_experimental_result = NULL; struct dict_object *fd_experimental_result_code = NULL; +struct dict_object *fd_vendor_specific_application_id = NULL; struct dict_object *fd_vendor = NULL; struct dict_object *fd_vendor_id = NULL; @@ -38,6 +39,7 @@ int fd_message_init() CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Result-Code", &fd_result_code); CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Experimental-Result", &fd_experimental_result); CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &fd_experimental_result_code); + CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Vendor-Specific-Application-Id", &fd_vendor_specific_application_id); return 0; } @@ -70,3 +72,30 @@ int fd_message_experimental_rescode_set( return 0; } + +int fd_message_vendor_specific_appid_set(struct msg *msg, c_uint32_t app_id) +{ + struct avp *avp; + struct avp *avp_vendor; + struct avp *avp_vendor_specific_application_id; + union avp_value value; + + CHECK_FCT( fd_msg_avp_new(fd_vendor_specific_application_id, 0, &avp) ); + + CHECK_FCT( fd_msg_avp_new(fd_vendor_id, 0, &avp_vendor) ); + value.u32 = FD_3GPP_VENDOR_ID; + CHECK_FCT( fd_msg_avp_setvalue(avp_vendor, &value) ); + CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_vendor) ); + + CHECK_FCT( fd_msg_avp_new( + fd_auth_application_id, 0, &avp_vendor_specific_application_id) ); + value.u32 = app_id; + CHECK_FCT( + fd_msg_avp_setvalue(avp_vendor_specific_application_id, &value) ); + CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, + avp_vendor_specific_application_id) ); + + CHECK_FCT( fd_msg_avp_add(msg, MSG_BRW_LAST_CHILD, avp) ); + + return 0; +} diff --git a/lib/fd/fd_message.h b/lib/fd/fd_message.h index 37cf01c10f..e8c3aa0212 100644 --- a/lib/fd/fd_message.h +++ b/lib/fd/fd_message.h @@ -20,6 +20,7 @@ extern struct dict_object *fd_auth_application_id; extern struct dict_object *fd_result_code; extern struct dict_object *fd_experimental_result; extern struct dict_object *fd_experimental_result_code; +extern struct dict_object *fd_vendor_specific_application_id; extern struct dict_object *fd_vendor; extern struct dict_object *fd_vendor_id; @@ -27,6 +28,8 @@ extern struct dict_object *fd_vendor_id; CORE_DECLARE(int) fd_message_init(void); CORE_DECLARE(int) fd_message_experimental_rescode_set( struct msg *msg, c_uint32_t result_code); +CORE_DECLARE(int) fd_message_vendor_specific_appid_set( + struct msg *msg, c_uint32_t app_id); #ifdef __cplusplus } diff --git a/src/hss/hss_fd_path.c b/src/hss/hss_fd_path.c index 2dcec3a440..47f164d447 100644 --- a/src/hss/hss_fd_path.c +++ b/src/hss/hss_fd_path.c @@ -155,6 +155,10 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp, CHECK_FCT( fd_msg_avp_setvalue(avp, &val) ); CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); + /* Set Vendor-Specific-Application-Id AVP */ + CHECK_FCT_DO( fd_message_vendor_specific_appid_set( + ans, S6A_APPLICATION_ID), goto out ); + /* Send the answer */ CHECK_FCT( fd_msg_send(msg, NULL, NULL) ); @@ -174,6 +178,10 @@ out: CHECK_FCT( fd_msg_avp_setvalue(avp, &val) ); CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); + /* Set Vendor-Specific-Application-Id AVP */ + CHECK_FCT_DO( fd_message_vendor_specific_appid_set( + ans, S6A_APPLICATION_ID), goto out ); + CHECK_FCT( fd_msg_send(msg, NULL, NULL) ); return 0; @@ -191,6 +199,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp, c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1]; status_t rv; + c_uint32_t result_code = 0; s6a_subscription_data_t subscription_data; d_assert(msg, return EINVAL,); @@ -209,6 +218,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp, if (rv != CORE_OK) { d_error("Cannot get Subscription-Data for IMSI:'%s'", imsi_bcd); + result_code = FD_DIAMETER_ERROR_USER_UNKNOWN; goto out; } @@ -221,7 +231,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp, /* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */ CHECK_FCT( fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1) ); - /* Set the Auth-Session-Statee AVP */ + /* Set the Auth-Session-State AVP */ CHECK_FCT( fd_msg_avp_new(fd_auth_session_state, 0, &avp) ); val.i32 = 1; CHECK_FCT( fd_msg_avp_setvalue(avp, &val) ); @@ -428,6 +438,10 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp, CHECK_FCT( fd_msg_avp_setvalue(avp, &val) ); CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); + /* Set Vendor-Specific-Application-Id AVP */ + CHECK_FCT_DO( fd_message_vendor_specific_appid_set( + ans, S6A_APPLICATION_ID), goto out ); + /* Send the answer */ CHECK_FCT( fd_msg_send(msg, NULL, NULL) ); @@ -439,8 +453,18 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp, return 0; out: - CHECK_FCT( fd_msg_rescode_set( - ans, "DIAMETER_AUTHENTICATION_REJECTED", NULL, NULL, 1) ); + CHECK_FCT( fd_message_experimental_rescode_set(ans, result_code) ); + + /* Set the Auth-Session-State AVP */ + CHECK_FCT( fd_msg_avp_new(fd_auth_session_state, 0, &avp) ); + val.i32 = 1; + CHECK_FCT( fd_msg_avp_setvalue(avp, &val) ); + CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); + + /* Set Vendor-Specific-Application-Id AVP */ + CHECK_FCT_DO( fd_message_vendor_specific_appid_set( + ans, S6A_APPLICATION_ID), goto out ); + CHECK_FCT( fd_msg_send(msg, NULL, NULL) ); return 0; diff --git a/src/mme/mme_fd_path.c b/src/mme/mme_fd_path.c index 15b4493c35..16cc166e70 100644 --- a/src/mme/mme_fd_path.c +++ b/src/mme/mme_fd_path.c @@ -101,6 +101,10 @@ void mme_s6a_send_air(mme_ue_t *mme_ue) val.os.len = PLMN_ID_LEN; CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + + /* Set Vendor-Specific-Application-Id AVP */ + CHECK_FCT_DO( fd_message_vendor_specific_appid_set( + req, S6A_APPLICATION_ID), goto out ); CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); @@ -436,6 +440,10 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue) CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + /* Set Vendor-Specific-Application-Id AVP */ + CHECK_FCT_DO( fd_message_vendor_specific_appid_set( + req, S6A_APPLICATION_ID), goto out ); + CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out ); /* Keep a pointer to the session data for debug purpose, diff --git a/src/pcrf/pcrf_fd_path.c b/src/pcrf/pcrf_fd_path.c index 237c472ab4..aebc53742d 100644 --- a/src/pcrf/pcrf_fd_path.c +++ b/src/pcrf/pcrf_fd_path.c @@ -71,7 +71,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, CHECK_FCT_DO( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp), goto out ); CHECK_FCT_DO( fd_msg_avp_new(gx_cc_request_number, 0, &avp), goto out ); - val.i32 = 0; + val.i32 = 1; CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); CHECK_FCT_DO( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp), goto out ); @@ -104,174 +104,205 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, goto out; } - /* Set Charging-Rule-Install */ - CHECK_FCT( fd_msg_avp_new(gx_charging_rule_install, 0, &avp) ); - - for (i = 0; i < cca_message.num_of_pcc_rule; i++) + if (cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) { - pcc_rule_t *pcc_rule = &cca_message.pcc_rule[i]; + /* Set Charging-Rule-Install */ + if (cca_message.num_of_pcc_rule) + CHECK_FCT( fd_msg_avp_new(gx_charging_rule_install, 0, &avp) ); - CHECK_FCT( fd_msg_avp_new(gx_charging_rule_definition, 0, &avpch1) ); - - CHECK_FCT( fd_msg_avp_new(gx_charging_rule_name, 0, &avpch2) ); - /* Charing-Rule-Name is automatically configured by order */ - sprintf(pcc_rule->name, "%s%d", apn, i+1); - val.os.data = (c_uint8_t *)pcc_rule->name; - val.os.len = strlen(pcc_rule->name); - CHECK_FCT( fd_msg_avp_setvalue(avpch2, &val) ); - CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - - for (j = 0; j < pcc_rule->num_of_flow; j++) + for (i = 0; i < cca_message.num_of_pcc_rule; i++) { - flow_t *flow = &pcc_rule->flow[j]; + pcc_rule_t *pcc_rule = &cca_message.pcc_rule[i]; - CHECK_FCT( fd_msg_avp_new(gx_flow_information, 0, &avpch2) ); + CHECK_FCT( fd_msg_avp_new(gx_charging_rule_definition, 0, + &avpch1) ); - CHECK_FCT( fd_msg_avp_new(gx_flow_direction, 0, &avpch3) ); - val.i32 = flow->direction; - CHECK_FCT( fd_msg_avp_setvalue(avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add(avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + CHECK_FCT( fd_msg_avp_new(gx_charging_rule_name, 0, &avpch2) ); + /* Charing-Rule-Name is automatically configured by order */ + sprintf(pcc_rule->name, "%s%d", apn, i+1); + val.os.data = (c_uint8_t *)pcc_rule->name; + val.os.len = strlen(pcc_rule->name); + CHECK_FCT( fd_msg_avp_setvalue(avpch2, &val) ); + CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - CHECK_FCT( fd_msg_avp_new(gx_flow_description, 0, &avpch3) ); - val.os.data = (c_uint8_t *)flow->description; - val.os.len = strlen(flow->description); - CHECK_FCT( fd_msg_avp_setvalue(avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add(avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + for (j = 0; j < pcc_rule->num_of_flow; j++) + { + flow_t *flow = &pcc_rule->flow[j]; + + CHECK_FCT( fd_msg_avp_new(gx_flow_information, 0, &avpch2) ); + + CHECK_FCT( fd_msg_avp_new(gx_flow_direction, 0, &avpch3) ); + val.i32 = flow->direction; + CHECK_FCT( fd_msg_avp_setvalue(avpch3, &val) ); + CHECK_FCT( fd_msg_avp_add(avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + + CHECK_FCT( fd_msg_avp_new(gx_flow_description, 0, &avpch3) ); + val.os.data = (c_uint8_t *)flow->description; + val.os.len = strlen(flow->description); + CHECK_FCT( fd_msg_avp_setvalue(avpch3, &val) ); + CHECK_FCT( fd_msg_avp_add(avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + + CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); + } + + CHECK_FCT( fd_msg_avp_new(gx_flow_status, 0, &avpch2) ); + val.i32 = GX_FLOW_STATUS_ENABLED; + CHECK_FCT( fd_msg_avp_setvalue(avpch2, &val) ); + CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); + + CHECK_FCT( fd_msg_avp_new(gx_qos_information, 0, &avpch2) ) + + CHECK_FCT( fd_msg_avp_new(gx_qos_class_identifier, 0, &avpch3) ); + val.u32 = pcc_rule->qos.qci; + CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + + CHECK_FCT( fd_msg_avp_new(gx_allocation_retention_priority, 0, + &avpch3) ); + + CHECK_FCT( fd_msg_avp_new(gx_priority_level, 0, &avpch4) ); + val.u32 = pcc_rule->qos.arp.priority_level; + CHECK_FCT( fd_msg_avp_setvalue (avpch4, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch3, MSG_BRW_LAST_CHILD, avpch4) ); + + CHECK_FCT( fd_msg_avp_new(gx_pre_emption_capability, 0, &avpch4) ); + val.u32 = pcc_rule->qos.arp.pre_emption_capability; + CHECK_FCT( fd_msg_avp_setvalue (avpch4, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch3, MSG_BRW_LAST_CHILD, avpch4) ); + + CHECK_FCT( fd_msg_avp_new(gx_pre_emption_vulnerability, 0, + &avpch4) ); + val.u32 = pcc_rule->qos.arp.pre_emption_vulnerability; + CHECK_FCT( fd_msg_avp_setvalue (avpch4, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch3, MSG_BRW_LAST_CHILD, avpch4) ); + + CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + + if (pcc_rule->qos.mbr.uplink) + { + CHECK_FCT( + fd_msg_avp_new(gx_max_requested_bandwidth_ul, 0, &avpch3) ); + val.u32 = pcc_rule->qos.mbr.uplink; + CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); + CHECK_FCT( + fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + } + + if (pcc_rule->qos.mbr.downlink) + { + CHECK_FCT( + fd_msg_avp_new(gx_max_requested_bandwidth_dl, 0, &avpch3) ); + val.u32 = pcc_rule->qos.mbr.downlink; + CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); + CHECK_FCT( + fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + } + + if (pcc_rule->qos.gbr.uplink) + { + CHECK_FCT( + fd_msg_avp_new(gx_guaranteed_bitrate_ul, 0, &avpch3) ); + val.u32 = pcc_rule->qos.gbr.uplink; + CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); + CHECK_FCT( + fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + } + + if (pcc_rule->qos.gbr.downlink) + { + CHECK_FCT( + fd_msg_avp_new(gx_guaranteed_bitrate_dl, 0, &avpch3) ); + val.u32 = pcc_rule->qos.gbr.downlink; + CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); + CHECK_FCT( + fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); + } CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - } - CHECK_FCT( fd_msg_avp_new(gx_flow_status, 0, &avpch2) ); - val.i32 = GX_FLOW_STATUS_ENABLED; - CHECK_FCT( fd_msg_avp_setvalue(avpch2, &val) ); - CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); + CHECK_FCT( fd_msg_avp_new(gx_precedence, 0, &avpch2) ) + val.u32 = i + 1; /* Precendence is automatically configured by order */ + CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); + CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - CHECK_FCT( fd_msg_avp_new(gx_qos_information, 0, &avpch2) ) - - CHECK_FCT( fd_msg_avp_new(gx_qos_class_identifier, 0, &avpch3) ); - val.u32 = pcc_rule->qos.qci; - CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); - - CHECK_FCT( fd_msg_avp_new(gx_allocation_retention_priority, 0, &avpch3) ); - - CHECK_FCT( fd_msg_avp_new(gx_priority_level, 0, &avpch4) ); - val.u32 = pcc_rule->qos.arp.priority_level; - CHECK_FCT( fd_msg_avp_setvalue (avpch4, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch3, MSG_BRW_LAST_CHILD, avpch4) ); - - CHECK_FCT( fd_msg_avp_new(gx_pre_emption_capability, 0, &avpch4) ); - val.u32 = pcc_rule->qos.arp.pre_emption_capability; - CHECK_FCT( fd_msg_avp_setvalue (avpch4, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch3, MSG_BRW_LAST_CHILD, avpch4) ); - - CHECK_FCT( fd_msg_avp_new(gx_pre_emption_vulnerability, 0, &avpch4) ); - val.u32 = pcc_rule->qos.arp.pre_emption_vulnerability; - CHECK_FCT( fd_msg_avp_setvalue (avpch4, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch3, MSG_BRW_LAST_CHILD, avpch4) ); - - CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); - - if (pcc_rule->qos.mbr.uplink) - { - CHECK_FCT( fd_msg_avp_new(gx_max_requested_bandwidth_ul, 0, - &avpch3) ); - val.u32 = pcc_rule->qos.mbr.uplink; - CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); - } - - if (pcc_rule->qos.mbr.downlink) - { - CHECK_FCT( fd_msg_avp_new(gx_max_requested_bandwidth_dl, 0, - &avpch3) ); - val.u32 = pcc_rule->qos.mbr.downlink; - CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); - } - - if (pcc_rule->qos.gbr.uplink) - { - CHECK_FCT( fd_msg_avp_new(gx_guaranteed_bitrate_ul, 0, &avpch3) ); - val.u32 = pcc_rule->qos.gbr.uplink; - CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); - } - - if (pcc_rule->qos.gbr.downlink) - { - CHECK_FCT( fd_msg_avp_new(gx_guaranteed_bitrate_dl, 0, &avpch3) ); - val.u32 = pcc_rule->qos.gbr.downlink; - CHECK_FCT( fd_msg_avp_setvalue (avpch3, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3) ); - } - - CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - - CHECK_FCT( fd_msg_avp_new(gx_precedence, 0, &avpch2) ) - val.u32 = i + 1; /* Precendence is automatically configured by order */ - CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); - CHECK_FCT( fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - - CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1) ); - } - CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); - - /* Set QoS-Information */ - if (cca_message.pdn.ambr.downlink || cca_message.pdn.ambr.uplink) - { - CHECK_FCT( fd_msg_avp_new(gx_qos_information, 0, &avp) ); - - if (cca_message.pdn.ambr.uplink) - { - CHECK_FCT( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_ul, 0, - &avpch1) ); - val.u32 = cca_message.pdn.ambr.uplink; - CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); - CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1) ); } - if (cca_message.pdn.ambr.downlink) + if (cca_message.num_of_pcc_rule) + CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); + + /* Set QoS-Information */ + if (cca_message.pdn.ambr.downlink || cca_message.pdn.ambr.uplink) { - CHECK_FCT( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_dl, 0, - &avpch1) ); - val.u32 = cca_message.pdn.ambr.downlink; - CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); - CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + CHECK_FCT( fd_msg_avp_new(gx_qos_information, 0, &avp) ); + + if (cca_message.pdn.ambr.uplink) + { + CHECK_FCT( + fd_msg_avp_new(gx_apn_aggregate_max_bitrate_ul, 0, &avpch1) ); + val.u32 = cca_message.pdn.ambr.uplink; + CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); + CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + } + + if (cca_message.pdn.ambr.downlink) + { + CHECK_FCT( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_dl, 0, + &avpch1) ); + val.u32 = cca_message.pdn.ambr.downlink; + CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); + CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + } + + CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); } + /* Set Default-EPS-Bearer-QoS */ + CHECK_FCT( fd_msg_avp_new(gx_default_eps_bearer_qos, 0, &avp) ); + + CHECK_FCT( fd_msg_avp_new(gx_qos_class_identifier, 0, &avpch1) ); + val.u32 = cca_message.pdn.qos.qci; + CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); + CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + + CHECK_FCT( + fd_msg_avp_new(gx_allocation_retention_priority, 0, &avpch1) ); + + CHECK_FCT( fd_msg_avp_new(gx_priority_level, 0, &avpch2) ); + val.u32 = cca_message.pdn.qos.arp.priority_level; + CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2) ); + + CHECK_FCT( fd_msg_avp_new(gx_pre_emption_capability, 0, &avpch2) ); + val.u32 = cca_message.pdn.qos.arp.pre_emption_capability; + CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2) ); + + CHECK_FCT( fd_msg_avp_new(gx_pre_emption_vulnerability, 0, &avpch2) ); + val.u32 = cca_message.pdn.qos.arp.pre_emption_vulnerability; + CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); + CHECK_FCT( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2) ); + + CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + + CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); + + /* Set Supported Features */ + CHECK_FCT( fd_msg_avp_new(gx_supported_features, 0, &avp) ); + + CHECK_FCT( fd_msg_avp_new(gx_feature_list_id, 0, &avpch1) ); + val.i32 = 1; + CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); + CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + + CHECK_FCT( fd_msg_avp_new(gx_feature_list, 0, &avpch1) ); + val.u32 = 0x0000000b; + CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); + CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); + CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); } - /* Set Default-EPS-Bearer-QoS */ - CHECK_FCT( fd_msg_avp_new(gx_default_eps_bearer_qos, 0, &avp) ); - - CHECK_FCT( fd_msg_avp_new(gx_qos_class_identifier, 0, &avpch1) ); - val.u32 = cca_message.pdn.qos.qci; - CHECK_FCT( fd_msg_avp_setvalue (avpch1, &val) ); - CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); - - CHECK_FCT( fd_msg_avp_new(gx_allocation_retention_priority, 0, &avpch1) ); - - CHECK_FCT( fd_msg_avp_new(gx_priority_level, 0, &avpch2) ); - val.u32 = cca_message.pdn.qos.arp.priority_level; - CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - - CHECK_FCT( fd_msg_avp_new(gx_pre_emption_capability, 0, &avpch2) ); - val.u32 = cca_message.pdn.qos.arp.pre_emption_capability; - CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - - CHECK_FCT( fd_msg_avp_new(gx_pre_emption_vulnerability, 0, &avpch2) ); - val.u32 = cca_message.pdn.qos.arp.pre_emption_vulnerability; - CHECK_FCT( fd_msg_avp_setvalue (avpch2, &val) ); - CHECK_FCT( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2) ); - - CHECK_FCT( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1) ); - - CHECK_FCT( fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp) ); - /* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */ CHECK_FCT( fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1) ); diff --git a/src/pgw/pgw_fd_path.c b/src/pgw/pgw_fd_path.c index 403dc7f178..e802c299f9 100644 --- a/src/pgw/pgw_fd_path.c +++ b/src/pgw/pgw_fd_path.c @@ -80,7 +80,7 @@ void pgw_gx_send_ccr(gtp_xact_t *xact, pgw_sess_t *sess, CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); CHECK_FCT_DO( fd_msg_avp_new(gx_cc_request_number, 0, &avp), goto out ); - val.i32 = 0; + val.i32 = 1; CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); @@ -103,160 +103,169 @@ void pgw_gx_send_ccr(gtp_xact_t *xact, pgw_sess_t *sess, CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - /* Set Supported-Features */ - CHECK_FCT_DO( fd_msg_avp_new(gx_supported_features, 0, &avp), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_feature_list_id, 0, &avpch1), - goto out ); - val.i32 = 1; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_feature_list, 0, &avpch1), - goto out ); - val.u32 = 0x0000000b; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), goto out ); - - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - - /* Set Network-Request-Support */ - CHECK_FCT_DO( fd_msg_avp_new(gx_network_request_support, 0, &avp), - goto out ); - val.i32 = 1; - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - - /* Set Framed-IP-Address */ - CHECK_FCT_DO( fd_msg_avp_new(gx_framed_ip_address, 0, &avp), - goto out ); - val.os.data = (c_uint8_t*)&sess->ip_pool->ue_addr; - val.os.len = sizeof(sess->ip_pool->ue_addr); - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - - /* Set IP-Can-Type */ - CHECK_FCT_DO( fd_msg_avp_new(gx_ip_can_type, 0, &avp), - goto out ); - val.i32 = GX_IP_CAN_TYPE_3GPP_EPS; - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - - /* Set RAT-Type */ - CHECK_FCT_DO( fd_msg_avp_new(gx_rat_type, 0, &avp), - goto out ); - val.i32 = GX_RAT_TYPE_EUTRAN; - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - - /* Set QoS-Information */ - if (sess->pdn.ambr.downlink || sess->pdn.ambr.uplink) + if (cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) { - CHECK_FCT_DO( fd_msg_avp_new(gx_qos_information, 0, &avp), + /* Set Supported-Features */ + CHECK_FCT_DO( fd_msg_avp_new(gx_supported_features, 0, &avp), goto out ); - if (sess->pdn.ambr.uplink) + CHECK_FCT_DO( fd_msg_avp_new(gx_feature_list_id, 0, &avpch1), + goto out ); + val.i32 = 1; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + goto out ); + + CHECK_FCT_DO( fd_msg_avp_new(gx_feature_list, 0, &avpch1), + goto out ); + val.u32 = 0x0000000b; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + goto out ); + + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), + goto out ); + + /* Set Network-Request-Support */ + CHECK_FCT_DO( fd_msg_avp_new(gx_network_request_support, 0, &avp), + goto out ); + val.i32 = 1; + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + + /* Set Framed-IP-Address */ + CHECK_FCT_DO( fd_msg_avp_new(gx_framed_ip_address, 0, &avp), + goto out ); + val.os.data = (c_uint8_t*)&sess->ip_pool->ue_addr; + val.os.len = sizeof(sess->ip_pool->ue_addr); + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + + /* Set IP-Can-Type */ + CHECK_FCT_DO( fd_msg_avp_new(gx_ip_can_type, 0, &avp), + goto out ); + val.i32 = GX_IP_CAN_TYPE_3GPP_EPS; + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + + /* Set RAT-Type */ + CHECK_FCT_DO( fd_msg_avp_new(gx_rat_type, 0, &avp), + goto out ); + val.i32 = GX_RAT_TYPE_EUTRAN; + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + + /* Set QoS-Information */ + if (sess->pdn.ambr.downlink || sess->pdn.ambr.uplink) { - CHECK_FCT_DO( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_ul, 0, - &avpch1), goto out ); - val.u32 = sess->pdn.ambr.uplink; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + CHECK_FCT_DO( fd_msg_avp_new(gx_qos_information, 0, &avp), goto out ); - } - - if (sess->pdn.ambr.downlink) - { - CHECK_FCT_DO( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_dl, 0, - &avpch1), goto out ); - val.u32 = sess->pdn.ambr.downlink; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + + if (sess->pdn.ambr.uplink) + { + CHECK_FCT_DO( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_ul, + 0, &avpch1), goto out ); + val.u32 = sess->pdn.ambr.uplink; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + goto out ); + } + + if (sess->pdn.ambr.downlink) + { + CHECK_FCT_DO( fd_msg_avp_new(gx_apn_aggregate_max_bitrate_dl, 0, + &avpch1), goto out ); + val.u32 = sess->pdn.ambr.downlink; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + goto out ); + } + + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); } - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - } - - /* Set Default-EPS-Bearer-QoS */ - CHECK_FCT_DO( fd_msg_avp_new(gx_default_eps_bearer_qos, 0, &avp), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_qos_class_identifier, 0, &avpch1), - goto out ); - val.u32 = sess->pdn.qos.qci; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_allocation_retention_priority, 0, &avpch1), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_priority_level, 0, &avpch2), goto out ); - val.u32 = sess->pdn.qos.arp.priority_level; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch2, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_pre_emption_capability, 0, &avpch2), - goto out ); - val.u32 = sess->pdn.qos.arp.pre_emption_capability; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch2, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_new(gx_pre_emption_vulnerability, 0, &avpch2), - goto out ); - val.u32 = sess->pdn.qos.arp.pre_emption_vulnerability; - CHECK_FCT_DO( fd_msg_avp_setvalue (avpch2, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), - goto out ); - - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - - /* Set 3GPP-User-Location-Info */ - { - struct gx_uli_t { - c_uint8_t type; - tai_t tai; - e_cgi_t e_cgi; - } gx_uli; - - memset(&gx_uli, 0, sizeof(gx_uli)); - gx_uli.type = GX_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI; - memcpy(&gx_uli.tai.plmn_id, &sess->tai.plmn_id, - sizeof(sess->tai.plmn_id)); - gx_uli.tai.tac = htons(sess->tai.tac); - memcpy(&gx_uli.e_cgi.plmn_id, &sess->e_cgi.plmn_id, - sizeof(sess->e_cgi.plmn_id)); - gx_uli.e_cgi.cell_id = htonl(sess->e_cgi.cell_id); - - CHECK_FCT_DO( fd_msg_avp_new(gx_3gpp_user_location_info, 0, &avp), + /* Set Default-EPS-Bearer-QoS */ + CHECK_FCT_DO( fd_msg_avp_new(gx_default_eps_bearer_qos, 0, &avp), goto out ); - val.os.data = (c_uint8_t*)&gx_uli; - val.os.len = sizeof(gx_uli); - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); - } - /* Set 3GPP-MS-Timezone */ - { - gtp_ue_timezone_t ue_timezone; - memset(&ue_timezone, 0, sizeof(ue_timezone)); - ue_timezone.timezone = 0x40; - ue_timezone.daylight_saving_time = - GTP_UE_TIME_ZONE_NO_ADJUSTMENT_FOR_DAYLIGHT_SAVING_TIME; - - CHECK_FCT_DO( fd_msg_avp_new(gx_3gpp_ms_timezone, 0, &avp), + CHECK_FCT_DO( fd_msg_avp_new(gx_qos_class_identifier, 0, &avpch1), goto out ); - val.os.data = (c_uint8_t*)&ue_timezone; - val.os.len = sizeof(ue_timezone); - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + val.u32 = sess->pdn.qos.qci; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch1, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + goto out ); + + CHECK_FCT_DO( fd_msg_avp_new(gx_allocation_retention_priority, 0, + &avpch1), goto out ); + + CHECK_FCT_DO( fd_msg_avp_new(gx_priority_level, 0, &avpch2), goto out ); + val.u32 = sess->pdn.qos.arp.priority_level; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch2, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2), + goto out ); + + CHECK_FCT_DO( fd_msg_avp_new(gx_pre_emption_capability, 0, &avpch2), + goto out ); + val.u32 = sess->pdn.qos.arp.pre_emption_capability; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch2, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2), + goto out ); + + CHECK_FCT_DO( fd_msg_avp_new(gx_pre_emption_vulnerability, 0, &avpch2), + goto out ); + val.u32 = sess->pdn.qos.arp.pre_emption_vulnerability; + CHECK_FCT_DO( fd_msg_avp_setvalue (avpch2, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2), + goto out ); + + CHECK_FCT_DO( fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1), + goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); + + /* Set 3GPP-User-Location-Info */ + { + struct gx_uli_t { + c_uint8_t type; + tai_t tai; + e_cgi_t e_cgi; + } gx_uli; + + memset(&gx_uli, 0, sizeof(gx_uli)); + gx_uli.type = GX_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI; + memcpy(&gx_uli.tai.plmn_id, &sess->tai.plmn_id, + sizeof(sess->tai.plmn_id)); + gx_uli.tai.tac = htons(sess->tai.tac); + memcpy(&gx_uli.e_cgi.plmn_id, &sess->e_cgi.plmn_id, + sizeof(sess->e_cgi.plmn_id)); + gx_uli.e_cgi.cell_id = htonl(sess->e_cgi.cell_id); + + CHECK_FCT_DO( fd_msg_avp_new(gx_3gpp_user_location_info, 0, &avp), + goto out ); + val.os.data = (c_uint8_t*)&gx_uli; + val.os.len = sizeof(gx_uli); + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), + goto out ); + } + + /* Set 3GPP-MS-Timezone */ + { + gtp_ue_timezone_t ue_timezone; + memset(&ue_timezone, 0, sizeof(ue_timezone)); + ue_timezone.timezone = 0x40; + ue_timezone.daylight_saving_time = + GTP_UE_TIME_ZONE_NO_ADJUSTMENT_FOR_DAYLIGHT_SAVING_TIME; + + CHECK_FCT_DO( fd_msg_avp_new(gx_3gpp_ms_timezone, 0, &avp), + goto out ); + val.os.data = (c_uint8_t*)&ue_timezone; + val.os.len = sizeof(ue_timezone); + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), + goto out ); + } } /* Set Called-Station-Id */