update it
This commit is contained in:
parent
ee770398c2
commit
c1848e03a1
|
@ -39,7 +39,8 @@ static struct disp_hdl *hdl_gx_ccr = NULL;
|
|||
|
||||
pool_declare(pcrf_gx_sess_pool, struct sess_state, MAX_POOL_OF_DIAMETER_SESS);
|
||||
|
||||
static status_t encode_pcc_rule_install(struct msg *msg, pcc_rule_t *pcc_rule);
|
||||
static status_t encode_pcc_rule_definition(
|
||||
struct avp *avp, pcc_rule_t *pcc_rule);
|
||||
static void pcrf_gx_raa_cb(void *data, struct msg **msg);
|
||||
|
||||
static __inline__ struct sess_state *new_state(os0_t sid)
|
||||
|
@ -324,16 +325,32 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST)
|
||||
{
|
||||
int charging_rule_install = 0;
|
||||
|
||||
for (i = 0; i < gx_message.num_of_pcc_rule; i++)
|
||||
{
|
||||
pcc_rule_t *pcc_rule = &gx_message.pcc_rule[i];
|
||||
if (pcc_rule->num_of_flow)
|
||||
{
|
||||
rv = encode_pcc_rule_install(ans, pcc_rule);
|
||||
if (charging_rule_install == 0)
|
||||
{
|
||||
ret = fd_msg_avp_new(gx_charging_rule_install, 0, &avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
||||
charging_rule_install = 1;
|
||||
}
|
||||
|
||||
rv = encode_pcc_rule_definition(avp, pcc_rule);
|
||||
d_assert(rv == CORE_OK, return EINVAL,);
|
||||
}
|
||||
}
|
||||
|
||||
if (charging_rule_install)
|
||||
{
|
||||
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
}
|
||||
|
||||
/* Set QoS-Information */
|
||||
if (gx_message.pdn.ambr.downlink || gx_message.pdn.ambr.uplink)
|
||||
{
|
||||
|
@ -526,6 +543,7 @@ status_t pcrf_gx_send_rar(
|
|||
size_t sidlen;
|
||||
|
||||
gx_message_t gx_message;
|
||||
int charging_rule_install = 0;
|
||||
|
||||
d_assert(gx_sid, return CORE_ERROR,);
|
||||
d_assert(rx_sid, return CORE_ERROR,);
|
||||
|
@ -678,11 +696,22 @@ status_t pcrf_gx_send_rar(
|
|||
pcc_rule->num_of_flow++;
|
||||
}
|
||||
|
||||
/* Encode PCC Rule */
|
||||
rv = encode_pcc_rule_install(req, pcc_rule);
|
||||
if (charging_rule_install == 0)
|
||||
{
|
||||
ret = fd_msg_avp_new(gx_charging_rule_install, 0, &avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
charging_rule_install = 1;
|
||||
}
|
||||
|
||||
rv = encode_pcc_rule_definition(avp, pcc_rule);
|
||||
d_assert(rv == CORE_OK, return EINVAL,);
|
||||
}
|
||||
|
||||
if (charging_rule_install == 1)
|
||||
{
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
}
|
||||
|
||||
/* Save Rx Session-Id */
|
||||
if (sess_data->rx_sid)
|
||||
|
@ -971,18 +1000,16 @@ void pcrf_gx_final(void)
|
|||
pool_final(&pcrf_gx_sess_pool);
|
||||
}
|
||||
|
||||
static status_t encode_pcc_rule_install(struct msg *msg, pcc_rule_t *pcc_rule)
|
||||
static status_t encode_pcc_rule_definition(
|
||||
struct avp *avp, pcc_rule_t *pcc_rule)
|
||||
{
|
||||
struct avp *avp, *avpch1, *avpch2, *avpch3, *avpch4;
|
||||
struct avp *avpch1, *avpch2, *avpch3, *avpch4;
|
||||
union avp_value val;
|
||||
int ret = 0, i;
|
||||
|
||||
d_assert(msg, return CORE_ERROR,);
|
||||
d_assert(avp, return CORE_ERROR,);
|
||||
d_assert(pcc_rule, return CORE_ERROR,);
|
||||
|
||||
ret = fd_msg_avp_new(gx_charging_rule_install, 0, &avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
||||
ret = fd_msg_avp_new(gx_charging_rule_definition, 0, &avpch1);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
ret = fd_msg_avp_new(gx_charging_rule_name, 0, &avpch2);
|
||||
|
@ -1129,8 +1156,5 @@ static status_t encode_pcc_rule_install(struct msg *msg, pcc_rule_t *pcc_rule)
|
|||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
||||
ret = fd_msg_avp_add(msg, MSG_BRW_LAST_CHILD, avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ struct sess_state {
|
|||
|
||||
pool_declare(pgw_gx_sess_pool, struct sess_state, MAX_POOL_OF_DIAMETER_SESS);
|
||||
|
||||
static status_t decode_pcc_rule_definition(
|
||||
pcc_rule_t *pcc_rule, struct avp *avpch1, int *perror);
|
||||
static void pgw_gx_cca_cb(void *data, struct msg **msg);
|
||||
|
||||
void state_cleanup(
|
||||
|
@ -36,7 +38,7 @@ void state_cleanup(
|
|||
pool_free_node(&pgw_gx_sess_pool, sess_data);
|
||||
}
|
||||
|
||||
void pgw_gx_send_ccr(gtp_xact_t *xact, pgw_sess_t *sess,
|
||||
void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
||||
pkbuf_t *gtpbuf, c_uint32_t cc_request_type)
|
||||
{
|
||||
int ret;
|
||||
|
@ -415,12 +417,13 @@ void pgw_gx_send_ccr(gtp_xact_t *xact, pgw_sess_t *sess,
|
|||
|
||||
static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
||||
{
|
||||
status_t rv;
|
||||
int ret;
|
||||
|
||||
struct sess_state *sess_data = NULL;
|
||||
struct timespec ts;
|
||||
struct session *session;
|
||||
struct avp *avp, *avpch1, *avpch2, *avpch3, *avpch4;
|
||||
struct avp *avp, *avpch1, *avpch2;
|
||||
struct avp_hdr *hdr;
|
||||
unsigned long dur;
|
||||
int error = 0;
|
||||
|
@ -568,197 +571,10 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
pcc_rule_t *pcc_rule =
|
||||
&gx_message->pcc_rule[gx_message->num_of_pcc_rule];
|
||||
|
||||
ret = fd_msg_browse(avpch1,
|
||||
MSG_BRW_FIRST_CHILD, &avpch2, NULL);
|
||||
d_assert(ret == 0, return,);
|
||||
while(avpch2)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case GX_AVP_CODE_CHARGING_RULE_NAME:
|
||||
{
|
||||
core_cpystrn(pcc_rule->name,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
c_min(hdr->avp_value->os.len,
|
||||
MAX_PCC_RULE_NAME_LEN)+1);
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_INFORMATION:
|
||||
{
|
||||
flow_t *flow =
|
||||
&pcc_rule->flow[pcc_rule->num_of_flow];
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_flow_direction, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr( avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
flow->direction = hdr->avp_value->i32;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_flow_description, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
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);
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_STATUS:
|
||||
{
|
||||
pcc_rule->flow_status = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_QOS_INFORMATION:
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_qos_class_identifier, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.qci = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_QCI");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_allocation_retention_priority, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_priority_level, &avpch4);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.arp.priority_level =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_Priority-Level");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_capability, &avpch4);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.arp.
|
||||
pre_emption_capability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_Preemption-Capability");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_vulnerability,
|
||||
&avpch4);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.arp.
|
||||
pre_emption_vulnerability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_Preemption-Vulnerability");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_ARP");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_ul, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.mbr.uplink =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_dl, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.mbr.downlink =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_ul, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.gbr.uplink =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_dl, &avpch3);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
pcc_rule->qos.gbr.downlink =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_PRECEDENCE:
|
||||
{
|
||||
pcc_rule->precedence = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not implemented(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
|
||||
}
|
||||
rv = decode_pcc_rule_definition(pcc_rule, avpch1, &error);
|
||||
d_assert(rv == CORE_OK, return,);
|
||||
|
||||
gx_message->num_of_pcc_rule++;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -810,31 +626,31 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
d_assert(ret == 0, return,);
|
||||
if (avpch1)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch1, gx_priority_level, &avpch4);
|
||||
ret = fd_avp_search_avp(avpch1, gx_priority_level, &avpch2);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch4)
|
||||
if (avpch2)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
gx_message->pdn.qos.arp.priority_level = hdr->avp_value->u32;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch1, gx_pre_emption_capability, &avpch4);
|
||||
ret = fd_avp_search_avp(avpch1, gx_pre_emption_capability, &avpch2);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch4)
|
||||
if (avpch2)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
gx_message->pdn.qos.arp.pre_emption_capability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch1,
|
||||
gx_pre_emption_vulnerability, &avpch4);
|
||||
gx_pre_emption_vulnerability, &avpch2);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avpch4)
|
||||
if (avpch2)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
gx_message->pdn.qos.arp.pre_emption_vulnerability =
|
||||
hdr->avp_value->u32;
|
||||
|
@ -846,12 +662,19 @@ out:
|
|||
if (!error)
|
||||
{
|
||||
event_set(&e, PGW_EVT_GX_MESSAGE);
|
||||
event_set_param1(&e, (c_uintptr_t)xact->index);
|
||||
event_set_param2(&e, (c_uintptr_t)sess->index);
|
||||
event_set_param3(&e, (c_uintptr_t)gxbuf);
|
||||
event_set_param1(&e, (c_uintptr_t)sess->index);
|
||||
event_set_param2(&e, (c_uintptr_t)gxbuf);
|
||||
event_set_param3(&e, (c_uintptr_t)xact->index);
|
||||
event_set_param4(&e, (c_uintptr_t)gtpbuf);
|
||||
pgw_event_send(&e);
|
||||
}
|
||||
else
|
||||
{
|
||||
gx_message_free(gx_message);
|
||||
pkbuf_free(gxbuf);
|
||||
|
||||
pkbuf_free(gtpbuf);
|
||||
}
|
||||
|
||||
/* Free the message */
|
||||
d_assert(pthread_mutex_lock(&fd_logger_self()->stats_lock) == 0,,);
|
||||
|
@ -920,35 +743,48 @@ static int pgw_gx_fb_cb(struct msg **msg, struct avp *avp,
|
|||
}
|
||||
|
||||
static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
||||
struct session *sess, void *opaque, enum disp_action *act)
|
||||
struct session *session, void *opaque, enum disp_action *act)
|
||||
{
|
||||
int ret;
|
||||
#if 0
|
||||
status_t rv;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
struct msg *ans;
|
||||
#if 0
|
||||
struct msg *ans, *qry;
|
||||
struct avp *avpch1, *avpch2, *avpch3, *avpch4;
|
||||
struct avp *avpch1;
|
||||
struct avp_hdr *hdr;
|
||||
#endif
|
||||
union avp_value val;
|
||||
struct sess_state *sess_data = NULL;
|
||||
|
||||
event_t e;
|
||||
c_uint16_t gxbuf_len = 0;
|
||||
pkbuf_t *gxbuf = NULL;
|
||||
pgw_sess_t *sess = NULL;
|
||||
gx_message_t *gx_message = NULL;
|
||||
|
||||
c_uint32_t result_code = FD_DIAMETER_UNKNOWN_SESSION_ID;
|
||||
|
||||
d_assert(msg, return EINVAL,);
|
||||
|
||||
gxbuf_len = sizeof(gx_message_t);
|
||||
d_assert(gxbuf_len < 8192, return EINVAL,
|
||||
"Not supported size:%d", gxbuf_len);
|
||||
gxbuf = pkbuf_alloc(0, gxbuf_len);
|
||||
d_assert(gxbuf, return EINVAL, "Null param");
|
||||
gx_message = gxbuf->payload;
|
||||
d_assert(gx_message, return EINVAL, "Null param");
|
||||
|
||||
d_trace(3, "[Gx] Re-Auth-Request : PGW <-- PCRF\n");
|
||||
|
||||
/* Set Credit Control Command */
|
||||
memset(gx_message, 0, gxbuf_len);
|
||||
gx_message->cmd_code = GX_CMD_RE_AUTH;
|
||||
|
||||
/* Create answer header */
|
||||
#if 0
|
||||
qry = *msg;
|
||||
#endif
|
||||
ret = fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
ans = *msg;
|
||||
|
||||
ret = fd_sess_state_retrieve(pgw_gx_reg, sess, &sess_data);
|
||||
ret = fd_sess_state_retrieve(pgw_gx_reg, session, &sess_data);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
if (!sess_data)
|
||||
{
|
||||
|
@ -956,6 +792,49 @@ static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Get Session Information */
|
||||
sess = sess_data->sess;
|
||||
d_assert(sess, return EINVAL,);
|
||||
|
||||
ret = fd_msg_search_avp(qry, gx_charging_rule_install, &avp);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
if (avp)
|
||||
{
|
||||
ret = fd_msg_browse(avp, 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 GX_AVP_CODE_CHARGING_RULE_DEFINITION:
|
||||
{
|
||||
pcc_rule_t *pcc_rule =
|
||||
&gx_message->pcc_rule[gx_message->num_of_pcc_rule];
|
||||
|
||||
rv = decode_pcc_rule_definition(pcc_rule, avpch1, NULL);
|
||||
d_assert(rv == CORE_OK, return EINVAL,);
|
||||
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send Gx Event to PGW State Machine */
|
||||
event_set(&e, PGW_EVT_GX_MESSAGE);
|
||||
event_set_param1(&e, (c_uintptr_t)sess->index);
|
||||
event_set_param2(&e, (c_uintptr_t)gxbuf);
|
||||
pgw_event_send(&e);
|
||||
|
||||
/* Set the Auth-Application-Id AVP */
|
||||
ret = fd_msg_avp_new(fd_auth_application_id, 0, &avp);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
|
@ -970,13 +849,13 @@ static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
|||
d_assert(ret == 0, return EINVAL,);
|
||||
|
||||
/* Store this value in the session */
|
||||
ret = fd_sess_state_store(pgw_gx_reg, sess, &sess_data);
|
||||
ret = fd_sess_state_store(pgw_gx_reg, session, &sess_data);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
d_assert(sess_data == NULL,,);
|
||||
|
||||
/* Send the answer */
|
||||
ret = fd_msg_send(msg, NULL, NULL);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
d_assert(ret == 0,,);
|
||||
|
||||
/* Add this value to the stats */
|
||||
d_assert(pthread_mutex_lock(&fd_logger_self()->stats_lock) == 0,,);
|
||||
|
@ -999,13 +878,16 @@ out:
|
|||
}
|
||||
|
||||
/* Store this value in the session */
|
||||
ret = fd_sess_state_store(pgw_gx_reg, sess, &sess_data);
|
||||
ret = fd_sess_state_store(pgw_gx_reg, session, &sess_data);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
d_assert(sess_data == NULL,,);
|
||||
|
||||
ret = fd_msg_send(msg, NULL, NULL);
|
||||
d_assert(ret == 0,,);
|
||||
|
||||
gx_message_free(gx_message);
|
||||
pkbuf_free(gxbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1068,3 +950,193 @@ void pgw_fd_final(void)
|
|||
|
||||
pool_final(&pgw_gx_sess_pool);
|
||||
}
|
||||
|
||||
static status_t decode_pcc_rule_definition(
|
||||
pcc_rule_t *pcc_rule, struct avp *avpch1, int *perror)
|
||||
{
|
||||
int ret = 0, error = 0;
|
||||
struct avp *avpch2, *avpch3, *avpch4;
|
||||
struct avp_hdr *hdr;
|
||||
|
||||
d_assert(pcc_rule, return CORE_ERROR,);
|
||||
d_assert(avpch1, return CORE_ERROR,);
|
||||
|
||||
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
while(avpch2)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case GX_AVP_CODE_CHARGING_RULE_NAME:
|
||||
{
|
||||
core_cpystrn(pcc_rule->name, (char*)hdr->avp_value->os.data,
|
||||
c_min(hdr->avp_value->os.len, MAX_PCC_RULE_NAME_LEN)+1);
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_INFORMATION:
|
||||
{
|
||||
flow_t *flow =
|
||||
&pcc_rule->flow[pcc_rule->num_of_flow];
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, gx_flow_direction, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr( avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
flow->direction = hdr->avp_value->i32;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, gx_flow_description, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
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);
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_STATUS:
|
||||
{
|
||||
pcc_rule->flow_status = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_QOS_INFORMATION:
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_qos_class_identifier, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.qci = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_QCI");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_allocation_retention_priority, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch3, gx_priority_level, &avpch4);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.arp.priority_level = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_Priority-Level");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_capability, &avpch4);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.arp.pre_emption_capability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_Preemption-Capability");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_vulnerability, &avpch4);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_Preemption-Vulnerability");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("no_ARP");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_ul, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.mbr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_dl, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.mbr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_ul, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.gbr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_dl, &avpch3);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
pcc_rule->qos.gbr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_PRECEDENCE:
|
||||
{
|
||||
pcc_rule->precedence = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not implemented(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
|
||||
}
|
||||
|
||||
if (perror)
|
||||
*perror = error;
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ typedef struct _gtp_xact_t gtp_xact_t;
|
|||
CORE_DECLARE(status_t) pgw_fd_init(void);
|
||||
CORE_DECLARE(void) pgw_fd_final(void);
|
||||
|
||||
CORE_DECLARE(void) pgw_gx_send_ccr(gtp_xact_t *xact, pgw_sess_t *sess,
|
||||
CORE_DECLARE(void) pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
||||
pkbuf_t *gtpbuf, c_uint32_t cc_request_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "pgw_ipfw.h"
|
||||
|
||||
void pgw_gx_handle_cca_initial_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess,
|
||||
gx_message_t *gx_message, gtp_create_session_request_t *req)
|
||||
pgw_sess_t *sess, gx_message_t *gx_message,
|
||||
gtp_xact_t *xact, gtp_create_session_request_t *req)
|
||||
{
|
||||
status_t rv;
|
||||
gtp_header_t h;
|
||||
|
@ -18,9 +18,9 @@ void pgw_gx_handle_cca_initial_request(
|
|||
int i = 0, j = 0;
|
||||
pgw_bearer_t *bearer = NULL;
|
||||
|
||||
d_assert(xact, return, "Null param");
|
||||
d_assert(sess, return, "Null param");
|
||||
d_assert(gx_message, return, "Null param");
|
||||
d_assert(xact, return, "Null param");
|
||||
d_assert(req, return, "Null param");
|
||||
|
||||
/* Send Create Session Request with Creating Default Bearer */
|
||||
|
@ -103,8 +103,8 @@ void pgw_gx_handle_cca_initial_request(
|
|||
}
|
||||
|
||||
void pgw_gx_handle_cca_termination_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess,
|
||||
gx_message_t *gx_message, gtp_delete_session_request_t *req)
|
||||
pgw_sess_t *sess, gx_message_t *gx_message,
|
||||
gtp_xact_t *xact, gtp_delete_session_request_t *req)
|
||||
{
|
||||
status_t rv;
|
||||
gtp_header_t h;
|
||||
|
|
|
@ -10,11 +10,11 @@ extern "C" {
|
|||
#endif /* __cplusplus */
|
||||
|
||||
CORE_DECLARE(void) pgw_gx_handle_cca_initial_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess,
|
||||
gx_message_t *gx_message, gtp_create_session_request_t *req);
|
||||
pgw_sess_t *sess, gx_message_t *gx_message,
|
||||
gtp_xact_t *xact, gtp_create_session_request_t *req);
|
||||
CORE_DECLARE(void) pgw_gx_handle_cca_termination_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess,
|
||||
gx_message_t *gx_message, gtp_delete_session_request_t *req);
|
||||
pgw_sess_t *sess, gx_message_t *gx_message,
|
||||
gtp_xact_t *xact, gtp_delete_session_request_t *req);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "pgw_s5c_handler.h"
|
||||
|
||||
void pgw_s5c_handle_create_session_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess, gtp_create_session_request_t *req)
|
||||
pgw_sess_t *sess, gtp_xact_t *xact, gtp_create_session_request_t *req)
|
||||
{
|
||||
status_t rv;
|
||||
gtp_f_teid_t *sgw_s5c_teid, *sgw_s5u_teid;
|
||||
|
@ -124,12 +124,12 @@ void pgw_s5c_handle_create_session_request(
|
|||
}
|
||||
|
||||
void pgw_s5c_handle_delete_session_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess, gtp_delete_session_request_t *req)
|
||||
pgw_sess_t *sess, gtp_xact_t *xact, gtp_delete_session_request_t *req)
|
||||
{
|
||||
}
|
||||
|
||||
void pgw_s5c_handle_create_bearer_response(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess, gtp_create_bearer_response_t *req)
|
||||
pgw_sess_t *sess, gtp_xact_t *xact, gtp_create_bearer_response_t *req)
|
||||
{
|
||||
status_t rv;
|
||||
gtp_f_teid_t *sgw_s5u_teid, *pgw_s5u_teid;
|
||||
|
|
|
@ -10,11 +10,11 @@ extern "C" {
|
|||
#endif /* __cplusplus */
|
||||
|
||||
CORE_DECLARE(void) pgw_s5c_handle_create_session_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess, gtp_create_session_request_t *req);
|
||||
pgw_sess_t *sess, gtp_xact_t *xact, gtp_create_session_request_t *req);
|
||||
CORE_DECLARE(void) pgw_s5c_handle_delete_session_request(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess, gtp_delete_session_request_t *req);
|
||||
pgw_sess_t *sess, gtp_xact_t *xact, gtp_delete_session_request_t *req);
|
||||
CORE_DECLARE(void) pgw_s5c_handle_create_bearer_response(
|
||||
gtp_xact_t *xact, pgw_sess_t *sess, gtp_create_bearer_response_t *req);
|
||||
pgw_sess_t *sess, gtp_xact_t *xact, gtp_create_bearer_response_t *req);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -111,19 +111,19 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
|||
{
|
||||
case GTP_CREATE_SESSION_REQUEST_TYPE:
|
||||
pgw_s5c_handle_create_session_request(
|
||||
xact, sess, &message->create_session_request);
|
||||
pgw_gx_send_ccr(xact, sess, copybuf,
|
||||
sess, xact, &message->create_session_request);
|
||||
pgw_gx_send_ccr(sess, xact, copybuf,
|
||||
GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
|
||||
break;
|
||||
case GTP_DELETE_SESSION_REQUEST_TYPE:
|
||||
pgw_s5c_handle_delete_session_request(
|
||||
xact, sess, &message->delete_session_request);
|
||||
pgw_gx_send_ccr(xact, sess, copybuf,
|
||||
sess, xact, &message->delete_session_request);
|
||||
pgw_gx_send_ccr(sess, xact, copybuf,
|
||||
GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
|
||||
break;
|
||||
case GTP_CREATE_BEARER_RESPONSE_TYPE:
|
||||
pgw_s5c_handle_create_bearer_response(
|
||||
xact, sess, &message->create_bearer_response);
|
||||
sess, xact, &message->create_bearer_response);
|
||||
pkbuf_free(copybuf);
|
||||
break;
|
||||
default:
|
||||
|
@ -141,18 +141,10 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
|||
}
|
||||
case PGW_EVT_GX_MESSAGE:
|
||||
{
|
||||
index_t xact_index = event_get_param1(e);
|
||||
gtp_xact_t *xact = NULL;
|
||||
index_t sess_index = event_get_param2(e);
|
||||
index_t sess_index = event_get_param1(e);
|
||||
pgw_sess_t *sess = NULL;
|
||||
pkbuf_t *gxbuf = (pkbuf_t *)event_get_param3(e);
|
||||
pkbuf_t *gxbuf = (pkbuf_t *)event_get_param2(e);
|
||||
gx_message_t *gx_message = NULL;
|
||||
pkbuf_t *gtpbuf = (pkbuf_t *)event_get_param4(e);
|
||||
gtp_message_t *message = NULL;
|
||||
|
||||
d_assert(xact_index, return, "Null param");
|
||||
xact = gtp_xact_find(xact_index);
|
||||
d_assert(xact, return, "Null param");
|
||||
|
||||
d_assert(sess_index, return, "Null param");
|
||||
sess = pgw_sess_find(sess_index);
|
||||
|
@ -162,16 +154,26 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
|||
gx_message = gxbuf->payload;
|
||||
d_assert(gx_message, return, "Null param");
|
||||
|
||||
d_assert(gtpbuf, return, "Null param");
|
||||
message = gtpbuf->payload;
|
||||
|
||||
switch(gx_message->cmd_code)
|
||||
{
|
||||
case GX_CMD_CODE_CREDIT_CONTROL:
|
||||
{
|
||||
index_t xact_index = event_get_param3(e);
|
||||
gtp_xact_t *xact = NULL;
|
||||
|
||||
pkbuf_t *gtpbuf = (pkbuf_t *)event_get_param4(e);
|
||||
gtp_message_t *message = NULL;
|
||||
|
||||
d_assert(xact_index, return, "Null param");
|
||||
xact = gtp_xact_find(xact_index);
|
||||
d_assert(xact, return, "Null param");
|
||||
|
||||
d_assert(gtpbuf, return, "Null param");
|
||||
message = gtpbuf->payload;
|
||||
|
||||
if (gx_message->result_code != ER_DIAMETER_SUCCESS)
|
||||
{
|
||||
d_error("Not implemented(%d)", gx_message->result_code);
|
||||
d_error("Diameter Error(%d)", gx_message->result_code);
|
||||
break;
|
||||
}
|
||||
switch(gx_message->cc_request_type)
|
||||
|
@ -179,14 +181,14 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
|||
case GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
|
||||
{
|
||||
pgw_gx_handle_cca_initial_request(
|
||||
xact, sess, gx_message,
|
||||
sess, gx_message, xact,
|
||||
&message->create_session_request);
|
||||
break;
|
||||
}
|
||||
case GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
|
||||
{
|
||||
pgw_gx_handle_cca_termination_request(
|
||||
xact, sess, gx_message,
|
||||
sess, gx_message, xact,
|
||||
&message->delete_session_request);
|
||||
break;
|
||||
}
|
||||
|
@ -196,7 +198,15 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
|||
break;
|
||||
}
|
||||
}
|
||||
gx_message_free(gx_message);
|
||||
|
||||
pkbuf_free(gtpbuf);
|
||||
break;
|
||||
}
|
||||
case GX_CMD_RE_AUTH:
|
||||
{
|
||||
#if 0
|
||||
pgw_gx_handle_re_auth_request( sess, gx_message);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -206,8 +216,8 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
|||
}
|
||||
}
|
||||
|
||||
gx_message_free(gx_message);
|
||||
pkbuf_free(gxbuf);
|
||||
pkbuf_free(gtpbuf);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue