initial code for CCR/CCA for Diameter Gx
This commit is contained in:
parent
ac4571ed52
commit
3a36d458e5
|
@ -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;
|
||||
|
|
|
@ -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(>p_xact_pool, index);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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), );
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 = >p_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(>p_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 = >p_message.create_session_response;
|
||||
|
||||
memset(>p_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, >p_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 = >p_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 = >p_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(>p_message, 0, sizeof(gtp_message_t));
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
107
src/pgw/pgw_sm.c
107
src/pgw/pgw_sm.c
|
@ -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, >p_message.create_session_request);
|
||||
pkbuf_free(pkbuf);
|
||||
gtp_create_session_request_t *req =
|
||||
>p_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,
|
||||
>p_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, >p_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, >p_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));
|
||||
|
|
Loading…
Reference in New Issue