diff --git a/lib/fd/Makefile.am b/lib/fd/Makefile.am index 628c0f68f..362a06826 100644 --- a/lib/fd/Makefile.am +++ b/lib/fd/Makefile.am @@ -13,7 +13,7 @@ libfd_la_SOURCES = \ gx/dict_init.c gx/gx_message.c \ \ rx/rx_dict.h rx/rx_message.h \ - rx/dict_init.c \ + rx/dict_init.c rx/rx_message.c \ $(NULL) libfd_la_DEPENDENCIES = \ diff --git a/lib/fd/fd_message.h b/lib/fd/fd_message.h index eb3dd373e..3e11a7307 100644 --- a/lib/fd/fd_message.h +++ b/lib/fd/fd_message.h @@ -10,6 +10,9 @@ extern "C" { #endif /* __cplusplus */ +#define FD_AVP_CODE_FRAME_IP_ADDRESS 8 +#define FD_AVP_CODE_FRAME_IPV6_PREFIX 97 + /* Result-Code AVP */ #define FD_DIAMETER_AVP_UNSUPPORTED 5001 #define FD_DIAMETER_UNKNOWN_SESSION_ID 5002 diff --git a/lib/fd/gx/gx_message.h b/lib/fd/gx/gx_message.h index 3a33abdf3..dba417f23 100644 --- a/lib/fd/gx/gx_message.h +++ b/lib/fd/gx/gx_message.h @@ -8,7 +8,8 @@ extern "C" { #include "3gpp_types.h" typedef struct _gx_message_t { -#define GX_CMD_CODE_CREDIT_CONTROL 272 +#define GX_CMD_CODE_CREDIT_CONTROL 272 +#define GX_CMD_RE_AUTH 258 c_uint16_t cmd_code; /* Experimental-Result-Codes */ @@ -24,10 +25,10 @@ typedef struct _gx_message_t { #define GX_DIAMETER_ERROR_NBIFOM_NOT_AUTHORIZED 5149 c_uint32_t result_code; -#define GX_CC_REQUEST_TYPE_INITIAL_REQUEST 1 -#define GX_CC_REQUEST_TYPE_UPDATE_REQUEST 2 -#define GX_CC_REQUEST_TYPE_TERMINATION_REQUEST 3 -#define GX_CC_REQUEST_TYPE_EVENT_REQUEST 4 +#define GX_CC_REQUEST_TYPE_INITIAL_REQUEST 1 +#define GX_CC_REQUEST_TYPE_UPDATE_REQUEST 2 +#define GX_CC_REQUEST_TYPE_TERMINATION_REQUEST 3 +#define GX_CC_REQUEST_TYPE_EVENT_REQUEST 4 c_uint32_t cc_request_type; pdn_t pdn; @@ -35,7 +36,7 @@ typedef struct _gx_message_t { int num_of_pcc_rule; } gx_message_t; -CORE_DECLARE(void) gx_message_free(gx_message_t *message); +CORE_DECLARE(void) gx_message_free(gx_message_t *gx_message); #ifdef __cplusplus } diff --git a/lib/fd/rx/rx_dict.h b/lib/fd/rx/rx_dict.h index 781d9e467..069bbf08d 100644 --- a/lib/fd/rx/rx_dict.h +++ b/lib/fd/rx/rx_dict.h @@ -10,6 +10,20 @@ extern "C" { #define RX_APPLICATION_ID 16777236 +#define RX_AVP_CODE_SUBSCRIPTION_ID (443) +#define RX_AVP_CODE_SPECIFIC_ACTION (513) + +#define RX_AVP_CODE_MEDIA_COMPONENT_DESCRIPTION (517) +#define RX_AVP_CODE_MEDIA_TYPE (520) +#define RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_DL (515) +#define RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_UL (516) +#define RX_AVP_CODE_MEDIA_COMPONENT_NUMBER (518) + +#define RX_AVP_CODE_MEDIA_SUB_COMPONENT (519) +#define RX_AVP_CODE_FLOW_DESCRIPTION (507) +#define RX_AVP_CODE_FLOW_NUMBER (509) +#define RX_AVP_CODE_FLOW_USAGE (512) + extern struct dict_object *rx_application; extern struct dict_object *rx_cmd_aar; @@ -17,14 +31,6 @@ extern struct dict_object *rx_cmd_aaa; extern struct dict_object *rx_media_component_description; extern struct dict_object *rx_media_component_number; -#define RX_MEDIA_TYPE_AUDIO 0 -#define RX_MEDIA_TYPE_VIDEO 1 -#define RX_MEDIA_TYPE_DATA 2 -#define RX_MEDIA_TYPE_APPLICATION 3 -#define RX_MEDIA_TYPE_CONTROL 4 -#define RX_MEDIA_TYPE_TEXT 5 -#define RX_MEDIA_TYPE_MESSAGE 6 -#define RX_MEDIA_TYPE_OTHER 0xFFFFFFFF extern struct dict_object *rx_media_type; extern struct dict_object *rx_max_requested_bandwidth_ul; extern struct dict_object *rx_max_requested_bandwidth_dl; @@ -40,9 +46,6 @@ extern struct dict_object *rx_flow_status; extern struct dict_object *rx_codec_data; extern struct dict_object *rx_media_sub_component; extern struct dict_object *rx_flow_number; -#define RX_FLOW_USAGE_NO_INFORMATION 0 -#define RX_FLOW_USAGE_RTCP 1 -#define RX_FLOW_USAGE_AF_SIGNALLING 2 extern struct dict_object *rx_flow_usage; extern struct dict_object *rx_flow_description; extern struct dict_object *rx_subscription_id; diff --git a/lib/fd/rx/rx_message.c b/lib/fd/rx/rx_message.c new file mode 100644 index 000000000..66f09f293 --- /dev/null +++ b/lib/fd/rx/rx_message.c @@ -0,0 +1,29 @@ +#define TRACE_MODULE _rx_message + +#include "core_debug.h" +#include "core_pkbuf.h" + +#include "rx_message.h" + +void rx_message_free(rx_message_t *rx_message) +{ + int i, j; + + d_assert(rx_message, return, "Null param"); + + for (i = 0; i < rx_message->num_of_media_component; i++) + { + rx_media_component_t *media_component = + &rx_message->media_component[i]; + + for (j = 0; j < media_component->num_of_flow; j++) + { + flow_t *flow = &media_component->flow[j]; + + if (flow->description) + core_free(flow->description); + else + d_assert(0,, "Null param"); + } + } +} diff --git a/lib/fd/rx/rx_message.h b/lib/fd/rx/rx_message.h index fcf13795b..bab2d53f5 100644 --- a/lib/fd/rx/rx_message.h +++ b/lib/fd/rx/rx_message.h @@ -7,6 +7,28 @@ extern "C" { #include "3gpp_types.h" +typedef struct _rx_media_component_t { +#define RX_MEDIA_TYPE_AUDIO 0 +#define RX_MEDIA_TYPE_VIDEO 1 +#define RX_MEDIA_TYPE_DATA 2 +#define RX_MEDIA_TYPE_APPLICATION 3 +#define RX_MEDIA_TYPE_CONTROL 4 +#define RX_MEDIA_TYPE_TEXT 5 +#define RX_MEDIA_TYPE_MESSAGE 6 +#define RX_MEDIA_TYPE_OTHER 0xFFFFFFFF + c_uint32_t media_type; + + bitrate_t mbr; /* Maxmimum Bit Rate (MBR) */ + bitrate_t gbr; /* Guaranteed Bit Rate (GBR) */ + +#define RX_FLOW_USAGE_NO_INFORMATION 0 +#define RX_FLOW_USAGE_RTCP 1 +#define RX_FLOW_USAGE_AF_SIGNALLING 2 + c_uint32_t flow_usage; + flow_t flow[MAX_NUM_OF_FLOW]; + int num_of_flow; +} rx_media_component_t; + typedef struct _rx_message_t { #define RX_CMD_CODE_AA 265 c_uint16_t cmd_code; @@ -22,8 +44,13 @@ typedef struct _rx_message_t { #define RX_DIAMETER_TEMPORARY_NETWORK_FAILURE 5068 c_uint32_t result_code; +#define MAX_NUM_OF_MEDIA_COMPONENT 16 + rx_media_component_t media_component[MAX_NUM_OF_MEDIA_COMPONENT]; + int num_of_media_component; } rx_message_t; +CORE_DECLARE(void) rx_message_free(rx_message_t *rx_message); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/pcrf/pcrf_rx_path.c b/src/pcrf/pcrf_rx_path.c index 84a16bfd1..aded29caa 100644 --- a/src/pcrf/pcrf_rx_path.c +++ b/src/pcrf/pcrf_rx_path.c @@ -4,6 +4,7 @@ #include "core_pool.h" #include "core_pkbuf.h" #include "core_network.h" +#include "core_lib.h" #include "fd/fd_lib.h" #include "fd/rx/rx_dict.h" @@ -65,22 +66,17 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp, int ret; struct msg *ans, *qry; -#if 0 - struct avp *avpch1, *avpch2, *avpch3, *avpch4; -#endif + struct avp *avpch1, *avpch2, *avpch3; struct avp_hdr *hdr; union avp_value val; struct sess_state *sess_data = NULL; size_t sidlen; + rx_message_t rx_message; #if 0 - gx_cca_message_t cca_message; - c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1]; - c_int8_t apn[MAX_APN_LEN+1]; int i, j; - - c_uint32_t cc_request_type = 0; #endif + char buf[CORE_ADDRSTRLEN]; os0_t rx_sid = NULL; os0_t gx_sid = NULL; @@ -100,10 +96,8 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp, d_assert(sess_data, return EINVAL,); } -#if 0 /* Initialize Message */ - memset(&cca_message, 0, sizeof(gx_cca_message_t)); -#endif + memset(&rx_message, 0, sizeof(rx_message_t)); /* Create answer header */ qry = *msg; @@ -174,6 +168,126 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp, goto out; } + ret = fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avpch1, NULL); + d_assert(ret == 0, return EINVAL,); + while(avpch1) + { + ret = fd_msg_avp_hdr(avpch1, &hdr); + d_assert(ret == 0, return EINVAL,); + switch(hdr->avp_code) + { + case AC_SESSION_ID: + case AC_ORIGIN_HOST: + case AC_ORIGIN_REALM: + case AC_DESTINATION_REALM: + case AC_ROUTE_RECORD: + case AC_PROXY_INFO: + case AC_AUTH_APPLICATION_ID: + case FD_AVP_CODE_FRAME_IP_ADDRESS: + case FD_AVP_CODE_FRAME_IPV6_PREFIX: + case RX_AVP_CODE_SUBSCRIPTION_ID: + break; + /* Gwt Specific-Action */ + case RX_AVP_CODE_SPECIFIC_ACTION: + break; + /* Gwt Media-Component-Description */ + case RX_AVP_CODE_MEDIA_COMPONENT_DESCRIPTION: + { + rx_media_component_t *media_component = &rx_message. + media_component[rx_message.num_of_media_component]; + + ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL); + d_assert(ret == 0, return EINVAL,); + while(avpch2) + { + ret = fd_msg_avp_hdr(avpch2, &hdr); + d_assert(ret == 0, return EINVAL,); + switch(hdr->avp_code) + { + case RX_AVP_CODE_MEDIA_COMPONENT_NUMBER: + break; + case RX_AVP_CODE_MEDIA_TYPE: + { + media_component->media_type = hdr->avp_value->i32; + break; + } + case RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_DL: + { + media_component->mbr.downlink = hdr->avp_value->i32; + break; + } + case RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_UL: + { + media_component->mbr.uplink = hdr->avp_value->i32; + break; + } + case RX_AVP_CODE_MEDIA_SUB_COMPONENT: + { + ret = fd_msg_browse(avpch2, MSG_BRW_FIRST_CHILD, + &avpch3, NULL); + d_assert(ret == 0, return EINVAL,); + while(avpch3) + { + ret = fd_msg_avp_hdr(avpch3, &hdr); + d_assert(ret == 0, return EINVAL,); + switch(hdr->avp_code) + { + case RX_AVP_CODE_FLOW_NUMBER: + break; + case RX_AVP_CODE_FLOW_USAGE: + { + media_component->flow_usage = + hdr->avp_value->i32; + break; + } + case RX_AVP_CODE_FLOW_DESCRIPTION: + { + flow_t *flow = &media_component->flow + [media_component->num_of_flow]; + + flow->description = core_malloc( + hdr->avp_value->os.len+1); + core_cpystrn( + flow->description, + (char*)hdr->avp_value->os.data, + hdr->avp_value->os.len+1); + media_component->num_of_flow++; + break; + } + default: + { + d_error("Not supported(%d)", + hdr->avp_code); + break; + } + } + fd_msg_browse(avpch3, MSG_BRW_NEXT, &avpch3, NULL); + } + + break; + } + default: + { + d_warn("Not supported(%d)", hdr->avp_code); + break; + } + } + + fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL); + } + + rx_message.num_of_media_component++; + break; + } + default: + { + d_warn("Not supported(%d)", hdr->avp_code); + break; + } + } + fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL); + } + /* Associate Gx-session with Rx-session */ rv = pcrf_sess_gx_associate_rx(gx_sid, rx_sid); d_assert(rv == CORE_OK, goto out, "Cannot Associate Gx/Rx Session"); @@ -184,6 +298,24 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp, sess_data->gx_sid = (os0_t)core_strdup((char *)gx_sid); d_assert(sess_data->gx_sid, goto out,); + /* Set IP-Can-Type */ + ret = fd_msg_avp_new(rx_ip_can_type, 0, &avp); + d_assert(ret == 0, return EINVAL,); + val.i32 = RX_IP_CAN_TYPE_3GPP_EPS; + ret = fd_msg_avp_setvalue(avp, &val); + d_assert(ret == 0, return EINVAL,); + ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp); + d_assert(ret == 0, return EINVAL,); + + /* Set RAT-Type */ + ret = fd_msg_avp_new(rx_rat_type, 0, &avp); + d_assert(ret == 0, return EINVAL,); + val.i32 = RX_RAT_TYPE_EUTRAN; + ret = fd_msg_avp_setvalue(avp, &val); + d_assert(ret == 0, return EINVAL,); + ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp); + d_assert(ret == 0, return EINVAL,); + /* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */ ret = fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1); d_assert(ret == 0, return EINVAL,); @@ -202,10 +334,7 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp, fd_logger_self()->stats.nb_echoed++; d_assert(pthread_mutex_unlock(&fd_logger_self()->stats_lock) == 0,,); -#if 0 - gx_cca_message_free(&cca_message); -#endif - + rx_message_free(&rx_message); pcrf_gx_send_rar(gx_sid); @@ -245,9 +374,7 @@ out: d_assert(ret == 0,,); state_cleanup(sess_data, NULL, NULL); -#if 0 - gx_cca_message_free(&cca_message); -#endif + rx_message_free(&rx_message); return 0; } diff --git a/src/pgw/pgw_fd_path.c b/src/pgw/pgw_fd_path.c index f297d4f31..48bb12d28 100644 --- a/src/pgw/pgw_fd_path.c +++ b/src/pgw/pgw_fd_path.c @@ -573,7 +573,6 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg) d_assert(ret == 0, return,); while(avpch2) { - ret = fd_msg_avp_hdr(avpch2, &hdr); d_assert(ret == 0, return,); switch(hdr->avp_code) diff --git a/test/rx/pcscf_fd_path.c b/test/rx/pcscf_fd_path.c index 6f96a68ea..3f1a45ab0 100644 --- a/test/rx/pcscf_fd_path.c +++ b/test/rx/pcscf_fd_path.c @@ -10,6 +10,7 @@ #include "fd/fd_lib.h" #include "fd/rx/rx_dict.h" +#include "fd/rx/rx_message.h" #include "pcscf_fd_path.h"