initial code for CCR/CCA for Diameter Gx

This commit is contained in:
Sukchan Lee 2017-08-19 13:29:09 +09:00
parent ac4571ed52
commit 3a36d458e5
14 changed files with 256 additions and 111 deletions

View File

@ -23,11 +23,23 @@ extern "C" {
((__ptr_e)->param3 = (c_uintptr_t)(__param))
#define event_set_param4(__ptr_e, __param) \
((__ptr_e)->param4 = (c_uintptr_t)(__param))
#define event_set_param5(__ptr_e, __param) \
((__ptr_e)->param5 = (c_uintptr_t)(__param))
#define event_set_param6(__ptr_e, __param) \
((__ptr_e)->param6 = (c_uintptr_t)(__param))
#define event_set_param7(__ptr_e, __param) \
((__ptr_e)->param7 = (c_uintptr_t)(__param))
#define event_set_param8(__ptr_e, __param) \
((__ptr_e)->param8 = (c_uintptr_t)(__param))
#define event_get_param1(__ptr_e) ((__ptr_e)->param1)
#define event_get_param2(__ptr_e) ((__ptr_e)->param2)
#define event_get_param3(__ptr_e) ((__ptr_e)->param3)
#define event_get_param4(__ptr_e) ((__ptr_e)->param4)
#define event_get_param5(__ptr_e) ((__ptr_e)->param5)
#define event_get_param6(__ptr_e) ((__ptr_e)->param6)
#define event_get_param7(__ptr_e) ((__ptr_e)->param7)
#define event_get_param8(__ptr_e) ((__ptr_e)->param8)
#define event_timer(__tm_service, __ptr_e, __duration, __param) \
event_timer_create((__tm_service), TIMER_TYPE_ONE_SHOT, \
@ -43,6 +55,10 @@ typedef struct {
c_uintptr_t param2;
c_uintptr_t param3;
c_uintptr_t param4;
c_uintptr_t param5;
c_uintptr_t param6;
c_uintptr_t param7;
c_uintptr_t param8;
} event_t;
extern char *FSM_NAME_INIT_SIG;

View File

@ -288,7 +288,7 @@ out:
return CORE_ERROR;
}
static gtp_xact_t *gtp_xact_find(
static gtp_xact_t *gtp_xact_find_by_sqn(
gtp_node_t *gnode, c_uint8_t type, c_uint32_t sqn)
{
char buf[INET_ADDRSTRLEN];
@ -369,7 +369,7 @@ status_t gtp_xact_receive(
h = pkbuf->payload;
d_assert(h, goto out1, "Null param");
new = gtp_xact_find(gnode, h->type, h->sqn);
new = gtp_xact_find_by_sqn(gnode, h->type, h->sqn);
if (!new)
{
new = gtp_xact_remote_create(context, sock, gnode, h->sqn);
@ -442,3 +442,10 @@ out1:
pkbuf_free(pkbuf);
return CORE_ERROR;
}
gtp_xact_t *gtp_xact_find(index_t index)
{
d_assert(index, return NULL, "Invalid Index");
return index_find(&gtp_xact_pool, index);
}

View File

@ -71,6 +71,8 @@ CORE_DECLARE(status_t) gtp_xact_receive(
c_uint8_t *type, c_uint32_t *teid, gtp_message_t *gtp_message,
pkbuf_t *pkbuf);
CORE_DECLARE(gtp_xact_t *) gtp_xact_find(index_t index);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -257,7 +257,7 @@ void emm_state_operational(fsm_t *s, event_t *e)
c_uint32_t result_code = event_get_param3(e);
if (result_code != ER_DIAMETER_SUCCESS)
{
/* TODO */
d_error("Not impleneted");
return;
}
@ -284,6 +284,11 @@ void emm_state_operational(fsm_t *s, event_t *e)
break;
}
default:
{
d_error("Invalid type(%d)", event_get_param2(e));
break;
}
}
break;
}

View File

@ -27,22 +27,24 @@ static int pcrf_ccr_cb( struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
{
struct msg *ans, *qry;
#if 0
struct avp_hdr *hdr;
#endif
union avp_value val;
c_uint32_t cc_request_type = 0;
c_uint32_t result_code = 0;
d_assert(msg, return EINVAL,);
printf("pcrf received message\n");
/* Create answer header */
qry = *msg;
CHECK_FCT( fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0) );
ans = *msg;
/* Get CC-Request-Type */
CHECK_FCT( fd_msg_search_avp(qry, gx_cc_request_type, &avp) );
CHECK_FCT( fd_msg_avp_hdr(avp, &hdr) );
cc_request_type = hdr->avp_value->i32;
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
CHECK_FCT( fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1) );
@ -52,9 +54,9 @@ static int pcrf_ccr_cb( struct msg **msg, struct avp *avp,
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 );
/* Set CCR AVP */
/* Set CC-Request-Type, CC-Request-Number */
CHECK_FCT_DO( fd_msg_avp_new(gx_cc_request_type, 0, &avp), goto out );
val.i32 = GX_CC_REQUEST_TYPE_INITIAL_REQUEST;
val.i32 = cc_request_type;
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 );

View File

@ -4,11 +4,9 @@ noinst_LTLIBRARIES = libpgw.la
libpgw_la_SOURCES = \
pgw_event.h pgw_context.h pgw_sm.h \
pgw_gtp_path.h pgw_s5c_handler.h \
pgw_gx_handler.h \
pgw_gtp_path.h pgw_s5c_handler.h pgw_gx_handler.h \
pgw_init.c pgw_event.c pgw_context.c pgw_sm.c \
pgw_gtp_path.c pgw_s5c_handler.c \
pgw_gx_handler.c
pgw_gtp_path.c pgw_s5c_handler.c pgw_gx_handler.c
libpgw_la_DEPENDENCIES = \
$(top_srcdir)/lib/core/src/libcore.la \

View File

@ -69,6 +69,9 @@ typedef struct _pgw_sess_t {
c_uint32_t sgw_s5c_teid;
c_uint32_t sgw_s5c_addr;
/* Last Received GTP Messasge */
gtp_message_t last_gtp_message;
c_int8_t apn[MAX_APN_LEN];
paa_t paa;
pgw_ip_pool_t* ip_pool;

View File

@ -20,6 +20,9 @@ char* pgw_event_get_name(event_t *e)
case PGW_EVT_TRANSACTION_T3:
return "PGW_EVT_TRANSACTION_T3";
case PGW_EVT_S5C_SESSION_FROM_GX:
return "PGW_EVT_S5C_SESSION_FROM_GX";
default:
break;
}

View File

@ -7,12 +7,16 @@
extern "C" {
#endif /* __cplusplus */
#define GX_CMD_CREDIT_CONTROL 272
typedef enum {
PGW_EVT_BASE = FSM_USER_SIG,
PGW_EVT_S5C_SESSION_MSG,
PGW_EVT_TRANSACTION_T3,
PGW_EVT_S5C_SESSION_FROM_GX,
PGW_EVT_TOP,
} event_e;

View File

@ -6,6 +6,7 @@
#include "fd_lib.h"
#include "gx_lib.h"
#include "pgw_event.h"
#include "pgw_gx_handler.h"
#define MAX_NUM_SESSION_STATE 32
@ -13,6 +14,7 @@
static struct session_handler *pgw_gx_reg = NULL;
struct sess_state {
gtp_xact_t *xact;
pgw_sess_t *sess;
struct timespec ts; /* Time of sending the message */
};
@ -21,7 +23,8 @@ pool_declare(pgw_gx_sess_pool, struct sess_state, MAX_NUM_SESSION_STATE);
static void pgw_gx_cca_cb(void *data, struct msg **msg);
void pgw_gx_send_ccr(pgw_sess_t *sess)
void pgw_gx_send_ccr(
gtp_xact_t *xact, pgw_sess_t *sess, c_uint32_t cc_request_type)
{
struct msg *req = NULL;
struct avp *avp;
@ -38,6 +41,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess)
pool_alloc_node(&pgw_gx_sess_pool, &mi);
d_assert(mi, return, "malloc failed: %s", strerror(errno));
mi->xact = xact;
mi->sess = sess;
/* Create the request */
@ -66,9 +70,9 @@ void pgw_gx_send_ccr(pgw_sess_t *sess)
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 CCR AVP */
/* Set CC-Request-Type, CC-Request-Number */
CHECK_FCT_DO( fd_msg_avp_new(gx_cc_request_type, 0, &avp), goto out );
val.i32 = GX_CC_REQUEST_TYPE_INITIAL_REQUEST;
val.i32 = cc_request_type;
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 );
@ -94,10 +98,8 @@ void pgw_gx_send_ccr(pgw_sess_t *sess)
fd_logger_self()->stats.nb_sent++;
CHECK_POSIX_DO( pthread_mutex_unlock(&fd_logger_self()->stats_lock), );
#if 0
d_trace(3, "[S6A] Authentication-Information-Request : UE[%s] --> HSS\n",
mme_ue->imsi_bcd);
#endif
d_trace(3, "[Gx] Credit-Control-Request : PGW[%d] --> PCRF\n",
sess->pgw_s5c_teid);
out:
pool_free_node(&pgw_gx_sess_pool, mi);
@ -117,11 +119,11 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
unsigned long dur;
int error = 0;
c_uint32_t result_code = 0;
c_uint32_t cc_request_type = 0;
int new;
#if 0
event_t e;
#endif
gtp_xact_t *xact = NULL;
pgw_sess_t *sess = NULL;
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
@ -134,13 +136,13 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
CHECK_FCT_DO( fd_sess_state_retrieve(pgw_gx_reg, session, &mi), return );
d_assert(mi && (void *)mi == data, return, );
xact = mi->xact;
d_assert(xact, return, );
sess = mi->sess;
d_assert(sess, return, );
#if 0
d_trace(3, "[Gx] Credit-Information-Answer : UE[%s] <-- HSS\n",
mme_ue->imsi_bcd);
#endif
d_trace(3, "[Gx] Credit-Control-Answer : PGW[%d] <-- PCRF\n",
sess->pgw_s5c_teid);
/* Value of Result Code */
CHECK_FCT_DO( fd_msg_search_avp(*msg, fd_result_code, &avp), return );
@ -207,14 +209,24 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
goto out;
}
CHECK_FCT_DO(
fd_msg_search_avp(*msg, gx_cc_request_type, &avp), return );
if (avp)
{
CHECK_FCT_DO( fd_msg_avp_hdr(avp, &hdr), return );
cc_request_type = hdr->avp_value->i32;
}
else
error++;
out:
#if 0
event_set(&e, MME_EVT_EMM_UE_FROM_S6A);
event_set_param1(&e, (c_uintptr_t)mme_ue->index);
event_set_param2(&e, (c_uintptr_t)S6A_CMD_AUTHENTICATION_INFORMATION);
event_set_param3(&e, (c_uintptr_t)result_code);
mme_event_send(&e);
#endif
event_set(&e, PGW_EVT_S5C_SESSION_FROM_GX);
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)GX_CMD_CREDIT_CONTROL);
event_set_param4(&e, (c_uintptr_t)cc_request_type);
event_set_param5(&e, (c_uintptr_t)result_code);
pgw_event_send(&e);
/* Free the message */
CHECK_POSIX_DO( pthread_mutex_lock(&fd_logger_self()->stats_lock), );

View File

@ -12,7 +12,8 @@ extern "C" {
CORE_DECLARE(int) pgw_gx_init(void);
CORE_DECLARE(void) pgw_gx_final(void);
CORE_DECLARE(void) pgw_gx_send_ccr(pgw_sess_t *sess);
CORE_DECLARE(void) pgw_gx_send_ccr(
gtp_xact_t *xact, pgw_sess_t *sess, c_uint32_t cc_request_type);
#ifdef __cplusplus
}

View File

@ -8,7 +8,6 @@
#include "pgw_context.h"
#include "pgw_gtp_path.h"
#include "pgw_s5c_handler.h"
#include "pgw_gx_handler.h"
c_int16_t pgw_pco_build(c_uint8_t *pco_buf, tlv_pco_t *tlv_pco)
{
@ -97,33 +96,20 @@ c_int16_t pgw_pco_build(c_uint8_t *pco_buf, tlv_pco_t *tlv_pco)
return size;
}
void pgw_handle_create_session_request(
gtp_xact_t *xact, gtp_create_session_request_t *req)
gtp_xact_t *xact, pgw_sess_t *sess, gtp_create_session_request_t *req)
{
status_t rv;
pkbuf_t *pkbuf;
gtp_message_t gtp_message;
c_uint8_t type = GTP_CREATE_SESSION_RESPONSE_TYPE;
gtp_create_session_response_t *rsp = &gtp_message.create_session_response;
gtp_cause_t cause;
gtp_f_teid_t *sgw_s5c_teid, *sgw_s5u_teid;
gtp_f_teid_t pgw_s5c_teid, pgw_s5u_teid;
c_int8_t apn[MAX_APN_LEN];
c_uint8_t pco_buf[MAX_PCO_LEN];
c_int16_t pco_len;
pgw_sess_t *sess = NULL;
pgw_bearer_t *bearer = NULL;
d_assert(xact, return, "Null param");
d_assert(sess, return, "Null param");
d_assert(req, return, "Null param");
bearer = pgw_default_bearer_in_sess(sess);
d_assert(bearer, return, "Null param");
if (req->access_point_name.presence == 0)
{
d_error("No APN");
return;
}
if (req->sender_f_teid_for_control_plane.presence == 0)
{
d_error("No TEID");
@ -145,27 +131,6 @@ void pgw_handle_create_session_request(
return;
}
/* Generate Control Plane(UL) : PGW-S5C */
memcpy(apn, req->access_point_name.data, req->access_point_name.len);
apn[req->access_point_name.len] = 0;
sess = pgw_sess_find_by_apn(apn);
if (!sess)
{
bearer = pgw_sess_add(apn,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
d_assert(bearer, return, "No Bearer Context");
sess = bearer->sess;
}
d_assert(sess, return, "No Session Context");
memset(&gtp_message, 0, sizeof(gtp_message_t));
memset(&cause, 0, sizeof(cause));
cause.value = GTP_CAUSE_REQUEST_ACCEPTED;
rsp->cause.presence = 1;
rsp->cause.len = sizeof(cause);
rsp->cause.data = &cause;
/* Receive Control Plane(DL) : SGW-S5C */
sgw_s5c_teid = req->sender_f_teid_for_control_plane.data;
sess->sgw_s5c_teid = ntohl(sgw_s5c_teid->teid);
@ -178,6 +143,40 @@ void pgw_handle_create_session_request(
d_trace(3, "[GTP] Create Session Reqeust : "
"SGW[%d] --> PGW[%d]\n", sess->sgw_s5c_teid, sess->pgw_s5c_teid);
}
void pgw_handle_create_session_response(gtp_xact_t *xact, pgw_sess_t *sess)
{
status_t rv;
pkbuf_t *pkbuf;
pgw_bearer_t *bearer = NULL;
gtp_message_t gtp_message;
c_uint8_t type = GTP_CREATE_SESSION_RESPONSE_TYPE;
gtp_create_session_request_t *req = NULL;
gtp_create_session_response_t *rsp = NULL;
gtp_cause_t cause;
gtp_f_teid_t pgw_s5c_teid, pgw_s5u_teid;
c_uint8_t pco_buf[MAX_PCO_LEN];
c_int16_t pco_len;
d_assert(xact, return, "Null param");
d_assert(sess, return, "Null param");
bearer = pgw_default_bearer_in_sess(sess);
d_assert(bearer, return, "Null param");
req = &sess->last_gtp_message.create_session_request;
rsp = &gtp_message.create_session_response;
memset(&gtp_message, 0, sizeof(gtp_message_t));
/* Set Cause */
memset(&cause, 0, sizeof(cause));
cause.value = GTP_CAUSE_REQUEST_ACCEPTED;
rsp->cause.presence = 1;
rsp->cause.len = sizeof(cause);
rsp->cause.data = &cause;
/* Send Control Plane(UL) : PGW-S5C */
memset(&pgw_s5c_teid, 0, sizeof(gtp_f_teid_t));
@ -192,7 +191,7 @@ void pgw_handle_create_session_request(
rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
len = GTP_F_TEID_IPV4_LEN;
d_assert(sess->ip_pool, pgw_sess_remove(sess); return, "No IP Pool");
d_assert(sess->ip_pool, return, "No IP Pool");
sess->paa.pdn_type = GTP_PDN_TYPE_IPV4;
sess->paa.ipv4_addr = sess->ip_pool->ue_addr;
@ -206,7 +205,7 @@ void pgw_handle_create_session_request(
if (req->protocol_configuration_options.presence == 1)
{
pco_len = pgw_pco_build(pco_buf, &req->protocol_configuration_options);
d_assert(pco_len > 0, pgw_sess_remove(sess); return, "pco build failed");
d_assert(pco_len > 0, return, "pco build failed");
rsp->protocol_configuration_options.presence = 1;
rsp->protocol_configuration_options.data = pco_buf;
rsp->protocol_configuration_options.len = pco_len;
@ -227,24 +226,27 @@ void pgw_handle_create_session_request(
rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.len =
GTP_F_TEID_IPV4_LEN;
#if 0
pgw_gx_send_ccr(sess);
#endif
rv = gtp_build_msg(&pkbuf, type, &gtp_message);
d_assert(rv == CORE_OK, pgw_sess_remove(sess); return, "gtp build failed");
d_assert(rv == CORE_OK, return, "gtp build failed");
pgw_s5c_send_to_sgw(xact, type, sess->sgw_s5c_teid, pkbuf);
}
void pgw_handle_delete_session_request(
gtp_xact_t *xact, pgw_sess_t *sess, gtp_delete_session_request_t *req)
{
}
void pgw_handle_delete_session_response(gtp_xact_t *xact, pgw_sess_t *sess)
{
status_t rv;
pkbuf_t *pkbuf;
gtp_message_t gtp_message;
c_uint8_t type = GTP_DELETE_SESSION_RESPONSE_TYPE;
gtp_delete_session_response_t *rsp = &gtp_message.delete_session_response;
gtp_delete_session_request_t *req = NULL;
gtp_delete_session_response_t *rsp = NULL;
c_uint32_t sgw_s5c_teid;
gtp_cause_t cause;
@ -252,29 +254,20 @@ void pgw_handle_delete_session_request(
c_int16_t pco_len;
d_assert(xact, return, "Null param");
/* sess can be NULL */
d_assert(req, return, "Null param");
d_assert(sess, return, "Null param");
req = &sess->last_gtp_message.delete_session_request;
rsp = &gtp_message.delete_session_response;
/* prepare cause */
memset(&cause, 0, sizeof(cause));
cause.value = GTP_CAUSE_REQUEST_ACCEPTED;
/* Remove a pgw session */
if (sess)
{
/* backup sgw_s5c_teid in session context */
sgw_s5c_teid = sess->sgw_s5c_teid;
/* backup sgw_s5c_teid in session context */
sgw_s5c_teid = sess->sgw_s5c_teid;
if (pgw_sess_remove(sess) != CORE_OK)
{
d_error("Error on PGW session %d removal", sess->index);
cause.value = GTP_CAUSE_CONTEXT_NOT_FOUND;
}
}
else
{
cause.value = GTP_CAUSE_INVALID_PEER;
}
/* Remove a pgw session */
pgw_sess_remove(sess);
memset(&gtp_message, 0, sizeof(gtp_message_t));

View File

@ -1,19 +1,25 @@
#ifndef __PGW_HANDLER_H__
#define __PGW_HANDLER_H__
#ifndef __PGW_S5C_HANDLER_H__
#define __PGW_S5C_HANDLER_H__
#include "gtp_tlv.h"
#include "pgw_context.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(void) pgw_handle_create_session_request(
gtp_xact_t *xact, gtp_create_session_request_t *req);
gtp_xact_t *xact, pgw_sess_t *sess, gtp_create_session_request_t *req);
CORE_DECLARE(void) pgw_handle_create_session_response(
gtp_xact_t *xact, pgw_sess_t *sess);
CORE_DECLARE(void) pgw_handle_delete_session_request(
gtp_xact_t *xact, pgw_sess_t *sess, gtp_delete_session_request_t *req);
CORE_DECLARE(void) pgw_handle_delete_session_response(
gtp_xact_t *xact, pgw_sess_t *sess);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PGW_HANDLER_H__ */
#endif /* __PGW_S5C_HANDLER_H__ */

View File

@ -1,11 +1,16 @@
#define TRACE_MODULE _pgw_sm
#include "core_debug.h"
#include "fd_lib.h"
#include "gx_lib.h"
#include "pgw_sm.h"
#include "pgw_context.h"
#include "pgw_event.h"
#include "pgw_gtp_path.h"
#include "pgw_s5c_handler.h"
#include "pgw_gx_handler.h"
void pgw_state_initial(fsm_t *s, event_t *e)
{
@ -77,21 +82,55 @@ void pgw_state_operational(fsm_t *s, event_t *e)
if (type == GTP_CREATE_SESSION_REQUEST_TYPE)
{
pgw_handle_create_session_request(
xact, &gtp_message.create_session_request);
pkbuf_free(pkbuf);
gtp_create_session_request_t *req =
&gtp_message.create_session_request;
c_int8_t apn[MAX_APN_LEN];
break;
if (req->access_point_name.presence == 0)
{
d_error("No APN");
pkbuf_free(pkbuf);
break;
}
memcpy(apn,
req->access_point_name.data, req->access_point_name.len);
apn[req->access_point_name.len] = 0;
sess = pgw_sess_find_by_apn(apn);
if (!sess)
{
pgw_bearer_t *bearer = NULL;
bearer = pgw_sess_add(apn,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
d_assert(bearer, pkbuf_free(pkbuf); break,
"No Bearer Context");
sess = bearer->sess;
}
}
else
{
sess = pgw_sess_find_by_teid(teid);
}
d_assert(sess, pkbuf_free(pkbuf); break, "No Session Context");
/* Store Last GTP Message for Session */
memcpy(&sess->last_gtp_message,
&gtp_message, sizeof(gtp_message_t));
sess = pgw_sess_find_by_teid(teid);
d_assert(sess, pkbuf_free(pkbuf); break,
"No Session Context(TEID:%d)", teid);
switch(type)
{
case GTP_CREATE_SESSION_REQUEST_TYPE:
pgw_handle_create_session_request(
xact, sess, &gtp_message.create_session_request);
pgw_gx_send_ccr(xact, sess,
GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
break;
case GTP_DELETE_SESSION_REQUEST_TYPE:
pgw_handle_delete_session_request(
xact, sess, &gtp_message.delete_session_request);
pgw_gx_send_ccr(xact, sess,
GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
break;
default:
d_warn("Not implmeneted(type:%d)", type);
@ -105,6 +144,60 @@ void pgw_state_operational(fsm_t *s, event_t *e)
gtp_xact_timeout(event_get_param1(e));
break;
}
case PGW_EVT_S5C_SESSION_FROM_GX:
{
index_t xact_index = event_get_param1(e);
gtp_xact_t *xact = NULL;
index_t sess_index = event_get_param2(e);
pgw_sess_t *sess = 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);
d_assert(sess, return, "Null param");
switch(event_get_param3(e))
{
case GX_CMD_CREDIT_CONTROL:
{
c_uint32_t result_code = event_get_param5(e);
if (result_code != ER_DIAMETER_SUCCESS)
{
d_error("Not impleneted");
return;
}
switch(event_get_param4(e))
{
case GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
{
pgw_handle_create_session_response(xact, sess);
break;
}
case GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
{
pgw_handle_delete_session_response(xact, sess);
break;
}
default:
{
d_error("Not implemented(%d)", event_get_param4(e));
break;
}
}
break;
}
default:
{
d_error("Invalid type(%d)", event_get_param3(e));
break;
}
}
break;
}
default:
{
d_error("No handler for event %s", pgw_event_get_name(e));