[SMF] Integrate session tear down cycle into sess->sm (#1500)

* [SMF] smf_sm.c Fix indentation

* [SMF] gsm-sm: log fsm events

* [SMF] Integrate session tear down cycle into sess->sm
This commit is contained in:
Pau Espin 2022-04-20 14:42:18 +02:00 committed by GitHub
parent 79de674fd8
commit 2de12e32f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 458 additions and 295 deletions

View File

@ -34,6 +34,14 @@ extern struct dict_object *ogs_diam_s6b_application;
extern struct dict_object *ogs_diam_s6b_mip6_feature_vector;
typedef struct ogs_diam_s6b_message_s {
#define OGS_DIAM_S6B_CMD_SESSION_TERMINATION 1
uint16_t cmd_code;
uint32_t result_code;
uint32_t *err;
uint32_t *exp_err;
} ogs_diam_s6b_message_t;
int ogs_diam_s6b_init(void);
#ifdef __cplusplus

View File

@ -214,7 +214,13 @@ typedef struct smf_sess_s {
bool gx_ccr_init_in_flight; /* Waiting for Gx CCA */
uint32_t gx_cca_init_err; /* Gx CCA RXed error code */
bool gy_ccr_init_in_flight; /* Waiting for Gy CCA */
uint32_t gy_cca_init_err; /* Gx CCA RXed error code */
uint32_t gy_cca_init_err; /* Gy CCA RXed error code */
bool gx_ccr_term_in_flight; /* Waiting for Gx CCA */
uint32_t gx_cca_term_err; /* Gx CCA RXed error code */
bool gy_ccr_term_in_flight; /* Waiting for Gy CCA */
uint32_t gy_cca_term_err; /* Gy CCA RXed error code */
bool s6b_str_in_flight; /* Waiting for S6B CCA */
uint32_t s6b_sta_err; /* S6B CCA RXed error code */
} sm_data;
ogs_pfcp_sess_t pfcp; /* PFCP session context */

View File

@ -64,6 +64,8 @@ const char *smf_event_get_name(smf_event_t *e)
case SMF_EVT_S5C_MESSAGE:
return "SMF_EVT_S5C_MESSAGE";
case SMF_EVT_S6B_MESSAGE:
return "SMF_EVT_S6B_MESSAGE";
case SMF_EVT_GN_MESSAGE:
return "SMF_EVT_GN_MESSAGE";
case SMF_EVT_GX_MESSAGE:

View File

@ -34,6 +34,7 @@ typedef struct ogs_pfcp_xact_s ogs_pfcp_xact_t;
typedef struct ogs_pfcp_message_s ogs_pfcp_message_t;
typedef struct ogs_diam_gx_message_s ogs_diam_gx_message_t;
typedef struct ogs_diam_gy_message_s ogs_diam_gy_message_t;
typedef struct ogs_diam_s6b_message_s ogs_diam_s6b_message_t;
typedef struct smf_sess_s smf_sess_t;
typedef struct smf_upf_s smf_upf_t;
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
@ -48,6 +49,7 @@ typedef enum {
SMF_EVT_BASE = OGS_FSM_USER_SIG,
SMF_EVT_S5C_MESSAGE,
SMF_EVT_S6B_MESSAGE,
SMF_EVT_GN_MESSAGE,
SMF_EVT_GX_MESSAGE,
SMF_EVT_GY_MESSAGE,
@ -90,6 +92,7 @@ typedef struct smf_event_s {
union {
ogs_diam_gx_message_t *gx_message;
ogs_diam_gy_message_t *gy_message;
ogs_diam_s6b_message_t *s6b_message;
};
struct {

View File

@ -239,39 +239,20 @@ uint8_t smf_gn_handle_create_pdp_context_request(
return cause_value;
}
void smf_gn_handle_delete_pdp_context_request(
uint8_t smf_gn_handle_delete_pdp_context_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp1_delete_pdp_context_request_t *req)
{
uint8_t cause_value = 0;
ogs_debug("Delete PDP Context Request");
ogs_assert(xact);
ogs_assert(req);
cause_value = OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP1_CAUSE_NON_EXISTENT;
} else {
if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
cause_value = OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
}
}
if (cause_value != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp1_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, cause_value);
return;
if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
smf_gx_send_ccr(sess, xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
return OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
}
void smf_gn_handle_update_pdp_context_request(

View File

@ -35,7 +35,7 @@ void smf_gn_handle_echo_response(
uint8_t smf_gn_handle_create_pdp_context_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp1_create_pdp_context_request_t *req);
void smf_gn_handle_delete_pdp_context_request(
uint8_t smf_gn_handle_delete_pdp_context_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp1_delete_pdp_context_request_t *req);
void smf_gn_handle_update_pdp_context_request(

View File

@ -76,6 +76,16 @@ static void send_gtp_create_err_msg(const smf_sess_t *sess, ogs_gtp_xact_t *gtp_
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, gtp_cause);
}
static void send_gtp_delete_err_msg(const smf_sess_t *sess, ogs_gtp_xact_t *gtp_xact, uint8_t gtp_cause)
{
if (gtp_xact->gtp_version == 1)
ogs_gtp1_send_error_message(gtp_xact, sess->sgw_s5c_teid,
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, gtp_cause);
else
ogs_gtp2_send_error_message(gtp_xact, sess->sgw_s5c_teid,
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp_cause);
}
static bool send_ccr_init_req_gx_gy(smf_sess_t *sess, smf_event_t *e)
{
int use_gy = smf_use_gy_iface();
@ -103,6 +113,41 @@ static bool send_ccr_init_req_gx_gy(smf_sess_t *sess, smf_event_t *e)
return true;
}
static bool send_ccr_termination_req_gx_gy_s6b(smf_sess_t *sess, smf_event_t *e)
{
/* TODO: we should take into account here whether "sess" has an active Gy
session created, not whether one was supposedly created as per policy */
int use_gy = smf_use_gy_iface();
if (use_gy == -1) {
ogs_error("No Gy Diameter Peer");
/* TODO: drop Gx connection here, possibly move to another "releasing" state! */
uint8_t gtp_cause = (e->gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE :
OGS_GTP2_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER;
send_gtp_delete_err_msg(sess, e->gtp_xact, gtp_cause);
return false;
}
if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
sess->sm_data.s6b_str_in_flight = true;
smf_s6b_send_str(sess, e->gtp_xact,
OGS_DIAM_TERMINATION_CAUSE_DIAMETER_LOGOUT);
}
sess->sm_data.gx_ccr_term_in_flight = true;
smf_gx_send_ccr(sess, e->gtp_xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
if (use_gy == 1) {
/* Gy is available, set up session for the bearer before accepting it towards the UE */
sess->sm_data.gy_ccr_term_in_flight = true;
smf_gy_send_ccr(sess, e->gtp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST);
}
return true;
}
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
ogs_assert(s);
@ -110,6 +155,8 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
smf_sess_t *sess = e->sess;
uint8_t gtp1_cause, gtp2_cause;
smf_sm_debug(e);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
/* reset state: */
@ -171,6 +218,8 @@ void smf_gsm_state_initial_wait_auth(ogs_fsm_t *s, smf_event_t *e)
smf_sess_t *sess = e->sess;
uint32_t diam_err;
smf_sm_debug(e);
switch (e->id) {
case SMF_EVT_GX_MESSAGE:
switch(e->gx_message->cmd_code) {
@ -235,6 +284,8 @@ void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
smf_sess_t *sess = e->sess;
uint8_t pfcp_cause, gtp_cause;
smf_sm_debug(e);
switch (e->id) {
case SMF_EVT_N4_MESSAGE:
switch (e->pfcp_message->h.type) {
@ -322,6 +373,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
smf_n1_n2_message_transfer_param_t param;
uint8_t pfcp_cause;
uint8_t gtp1_cause, gtp2_cause;
bool release;
int state = 0;
@ -340,6 +393,44 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
case OGS_FSM_EXIT_SIG:
break;
case SMF_EVT_GN_MESSAGE:
switch(e->gtp1_message->h.type) {
case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE:
gtp1_cause = smf_gn_handle_delete_pdp_context_request(sess,
e->gtp_xact,
&e->gtp1_message->delete_pdp_context_request);
if (gtp1_cause != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp1_send_error_message(e->gtp_xact, sess->sgw_s5c_teid,
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, gtp1_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_release_wait_pfcp_deletion);
}
break;
case SMF_EVT_S5C_MESSAGE:
switch(e->gtp2_message->h.type) {
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
gtp2_cause = smf_s5c_handle_delete_session_request(sess, e->gtp_xact,
&e->gtp2_message->delete_session_request);
if (gtp2_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(e->gtp_xact, sess->sgw_s5c_teid,
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp2_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_release_wait_pfcp_deletion);
break;
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
release = smf_s5c_handle_delete_bearer_response(
sess, e->gtp_xact, &e->gtp2_message->delete_bearer_response);
if (release) {
e->gtp_xact = NULL;
OGS_FSM_TRAN(s, &smf_gsm_state_release_wait_pfcp_deletion);
}
break;
}
break;
case SMF_EVT_N4_MESSAGE:
switch (e->pfcp_message->h.type) {
case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE:
@ -361,6 +452,14 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
break;
case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE:
/* This is left here for 5gc sessions to properly receive messages,
since tear down transitions are not implemented yet for 5gc
sessions. See #if0 in smf_gsm_state_initial_wait_pfcp_deletion() */
assert(!e->pfcp_xact->epc);
smf_5gc_n4_handle_session_deletion_response(sess,
e->pfcp_xact, &e->pfcp_message->pfcp_session_deletion_response);
break;
}
break;
@ -743,6 +842,171 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
}
}
void smf_gsm_state_release_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
{
smf_sess_t *sess = NULL;
uint8_t pfcp_cause, gtp_cause;
ogs_gtp_xact_t *gtp_xact;
ogs_assert(s);
ogs_assert(e);
smf_sm_debug(e);
sess = e->sess;
ogs_assert(sess);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_deletion_request(sess, e->gtp_xact));
break;
case OGS_FSM_EXIT_SIG:
break;
case SMF_EVT_GN_MESSAGE:
case SMF_EVT_S5C_MESSAGE:
break; /* ignore */
case SMF_EVT_N4_MESSAGE:
gtp_xact = e->pfcp_xact->assoc_xact;
switch (e->pfcp_message->h.type) {
case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE:
if (e->pfcp_xact->epc) {
gtp_xact = e->pfcp_xact->assoc_xact;
pfcp_cause = smf_epc_n4_handle_session_deletion_response(sess,
e->pfcp_xact, &e->pfcp_message->pfcp_session_deletion_response);
if (pfcp_cause != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
/* FIXME: tear down Gy and Gx */
gtp_cause = gtp_cause_from_pfcp(pfcp_cause, gtp_xact->gtp_version);
send_gtp_delete_err_msg(sess, gtp_xact, gtp_cause);
return;
}
e->gtp_xact = gtp_xact;
if (send_ccr_termination_req_gx_gy_s6b(sess, e) == true)
OGS_FSM_TRAN(s, &smf_gsm_state_release_wait_auth);
/* else: free session? */
} else {
#if 0
/* This is currently not happening, since 5gc isn't yet properly
integrated and doesn't move to this state */
smf_5gc_n4_handle_session_deletion_response(sess,
e->pfcp_xact, &message->pfcp_session_deletion_response);
return; /* TODO: implement handling of errors here */
#endif
}
break;
}
return;
default:
ogs_error("Unknown event %s", smf_event_get_name(e));
break;
}
}
void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e)
{
ogs_assert(e && e->sess);
smf_sess_t *sess = e->sess;
uint32_t diam_err;
smf_sm_debug(e);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
/* reset state: */
sess->sm_data.gx_cca_term_err = ER_DIAMETER_SUCCESS;
sess->sm_data.gy_cca_term_err = ER_DIAMETER_SUCCESS;
sess->sm_data.s6b_sta_err = ER_DIAMETER_SUCCESS;
break;
case SMF_EVT_GN_MESSAGE:
case SMF_EVT_S5C_MESSAGE:
case SMF_EVT_N4_MESSAGE:
break; /* ignore */
case SMF_EVT_GX_MESSAGE:
switch(e->gx_message->cmd_code) {
case OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL:
switch(e->gx_message->cc_request_type) {
case OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
diam_err = smf_gx_handle_cca_termination_request(sess,
e->gx_message, e->gtp_xact);
sess->sm_data.gx_ccr_term_in_flight = false;
sess->sm_data.gx_cca_term_err = diam_err;
goto test_can_proceed;
}
break;
}
break;
case SMF_EVT_GY_MESSAGE:
switch(e->gy_message->cmd_code) {
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
switch(e->gy_message->cc_request_type) {
case OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST:
ogs_assert(e->gtp_xact);
diam_err = smf_gy_handle_cca_termination_request(sess,
e->gy_message, e->gtp_xact);
sess->sm_data.gy_ccr_term_in_flight = false;
sess->sm_data.gy_cca_term_err = diam_err;
goto test_can_proceed;
}
break;
}
break;
case SMF_EVT_S6B_MESSAGE:
switch(e->s6b_message->cmd_code) {
case OGS_DIAM_S6B_CMD_SESSION_TERMINATION:
sess->sm_data.s6b_str_in_flight = false;
/* TODO: validate error code from message below: */
sess->sm_data.s6b_sta_err = ER_DIAMETER_SUCCESS;
goto test_can_proceed;
}
break;
}
return;
test_can_proceed:
/* First wait for both Gx and Gy requests to be done: */
if (!sess->sm_data.gx_ccr_term_in_flight &&
!sess->sm_data.gy_ccr_term_in_flight &&
!sess->sm_data.s6b_str_in_flight) {
diam_err = ER_DIAMETER_SUCCESS;
if (sess->sm_data.gx_cca_term_err != ER_DIAMETER_SUCCESS)
diam_err = sess->sm_data.gx_cca_term_err;
if (sess->sm_data.gy_cca_term_err != ER_DIAMETER_SUCCESS)
diam_err = sess->sm_data.gy_cca_term_err;
if (sess->sm_data.s6b_sta_err != ER_DIAMETER_SUCCESS)
diam_err = sess->sm_data.s6b_sta_err;
/* Initiated by peer request, let's answer: */
if (e->gtp_xact) {
if (diam_err == ER_DIAMETER_SUCCESS) {
/*
* 1. MME sends Delete Session Request to SGW/SMF.
* 2. SMF sends Delete Session Response to SGW/MME.
*/
switch (e->gtp_xact->gtp_version) {
case 1:
ogs_assert(OGS_OK == smf_gtp1_send_delete_pdp_context_response(sess, e->gtp_xact));
break;
case 2:
ogs_assert(OGS_OK == smf_gtp_send_delete_session_response(sess, e->gtp_xact));
break;
}
} else {
uint8_t gtp_cause = gtp_cause_from_diameter(e->gtp_xact->gtp_version,
diam_err, NULL);
send_gtp_delete_err_msg(sess, e->gtp_xact, gtp_cause);
}
}
OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release);
}
}
void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e)
{
smf_sess_t *sess = NULL;
@ -756,6 +1020,7 @@ void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
SMF_SESS_CLEAR(sess);
break;
case OGS_FSM_EXIT_SIG:

View File

@ -243,26 +243,18 @@ uint32_t smf_gx_handle_cca_initial_request(
return ER_DIAMETER_SUCCESS;
}
void smf_gx_handle_cca_termination_request(
uint32_t smf_gx_handle_cca_termination_request(
smf_sess_t *sess, ogs_diam_gx_message_t *gx_message,
ogs_gtp_xact_t *gtp_xact)
{
ogs_assert(sess);
ogs_assert(gx_message);
ogs_assert(gtp_xact);
ogs_debug("[SMF] Delete Session Response");
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
/*
* << 'gtp_xact' is NOT NULL >>
*
* 1. MME sends Delete Session Request to SGW/SMF.
* 2. SMF sends Delete Session Response to SGW/MME.
*/
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_deletion_request(sess, gtp_xact));
return ER_DIAMETER_SUCCESS;
}
void smf_gx_handle_re_auth_request(

View File

@ -29,7 +29,7 @@ extern "C" {
uint32_t smf_gx_handle_cca_initial_request(
smf_sess_t *sess, ogs_diam_gx_message_t *gx_message,
ogs_gtp_xact_t *gtp_xact);
void smf_gx_handle_cca_termination_request(
uint32_t smf_gx_handle_cca_termination_request(
smf_sess_t *sess, ogs_diam_gx_message_t *gx_message,
ogs_gtp_xact_t *gtp_xact);
void smf_gx_handle_re_auth_request(

View File

@ -93,7 +93,6 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
struct sockaddr_in6 sin6;
uint32_t charing_id;
ogs_assert(xact);
ogs_assert(sess);
ogs_assert(sess->ipv4 || sess->ipv6);
@ -742,7 +741,6 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
ogs_debug(" CC-Request-Number[%d]", cc_request_number);
xact = sess_data->xact[cc_request_number];
ogs_assert(xact);
sess = sess_data->sess;
ogs_assert(sess);

View File

@ -182,7 +182,7 @@ void smf_gy_handle_cca_update_request(
}
}
void smf_gy_handle_cca_termination_request(
uint32_t smf_gy_handle_cca_termination_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_gtp_xact_t *gtp_xact)
{
@ -194,36 +194,7 @@ void smf_gy_handle_cca_termination_request(
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (gtp_xact) {
/*
* 1. MME sends Delete Session Request to SGW/SMF.
* 2. SMF sends Delete Session Response to SGW/MME.
*/
switch (gtp_xact->gtp_version) {
case 1:
ogs_assert(OGS_OK == smf_gtp1_send_delete_pdp_context_response(sess, gtp_xact));
break;
case 2:
ogs_assert(OGS_OK == smf_gtp_send_delete_session_response(sess, gtp_xact));
break;
}
} else {
/*
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
* 2. MME sends Delete Bearer Response to SGW/SMF.
*
* OR
*
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
*
* Note that the following messages are not processed here.
* - Bearer Resource Command
* - Delete Bearer Request/Response with DEDICATED BEARER.
*/
}
SMF_SESS_CLEAR(sess);
return;
return ER_DIAMETER_SUCCESS;
}
void smf_gy_handle_re_auth_request(

View File

@ -33,7 +33,7 @@ uint32_t smf_gy_handle_cca_initial_request(
void smf_gy_handle_cca_update_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_pfcp_xact_t *gtp_xact);
void smf_gy_handle_cca_termination_request(
uint32_t smf_gy_handle_cca_termination_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_gtp_xact_t *gtp_xact);
void smf_gy_handle_re_auth_request(

View File

@ -693,7 +693,7 @@ void smf_5gc_n4_handle_session_deletion_response(
ogs_assert(stream);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
SMF_SESS_CLEAR(sess);
OGS_FSM_TRAN(&sess->sm, smf_gsm_state_session_will_release);
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
smf_n1_n2_message_transfer_param_t param;
@ -1045,61 +1045,28 @@ void smf_epc_n4_handle_session_modification_response(
}
}
void smf_epc_n4_handle_session_deletion_response(
uint8_t smf_epc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp)
{
uint8_t cause_value = 0;
uint8_t resp_type = 0;
ogs_gtp_xact_t *gtp_xact = NULL;
smf_bearer_t *bearer = NULL;
unsigned int i;
ogs_assert(sess);
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Deletion Response [epc]");
gtp_xact = xact->assoc_xact;
ogs_pfcp_xact_commit(xact);
/* If !gtp_xact, set it to whatever valid, nothing is sent in the end anyway */
uint8_t gtp_version = gtp_xact ? gtp_xact->gtp_version : 2;
if (gtp_version == 1) {
resp_type = OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE;
cause_value = OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
} else {
resp_type = OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE;
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
}
if (!sess) {
ogs_warn("No Context");
cause_value = (gtp_version == 1) ?
OGS_GTP1_CAUSE_NON_EXISTENT :
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_warn("PFCP Cause[%d] : Not Accepted", rsp->cause.u8);
cause_value = gtp_cause_from_pfcp(rsp->cause.u8, gtp_version);
}
} else {
if (!rsp->cause.presence) {
ogs_error("No Cause");
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
return OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
if (gtp_xact &&
((gtp_version == 1 && cause_value != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) ||
(gtp_version == 2 && cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED))) {
ogs_gtp_send_error_message(gtp_xact, sess->sgw_s5c_teid, resp_type,
cause_value);
return;
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_warn("PFCP Cause[%d] : Not Accepted", rsp->cause.u8);
return rsp->cause.u8;
}
ogs_assert(sess);
@ -1124,48 +1091,7 @@ void smf_epc_n4_handle_session_deletion_response(
sess->gy.duration += use_rep->duration_measurement.u32;
}
switch(smf_use_gy_iface()) {
case 1:
/* Gy is available, terminate the Gy session before terminating it towards the UE */
smf_gy_send_ccr(sess, gtp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST);
return;
case -1:
ogs_error("No Gy Diameter Peer");
break; /* continue below */
/* default: continue below */
}
if (gtp_xact) {
/*
* 1. MME sends Delete Session Request to SGW/SMF.
* 2. SMF sends Delete Session Response to SGW/MME.
*/
switch (gtp_version) {
case 1:
ogs_assert(OGS_OK == smf_gtp1_send_delete_pdp_context_response(sess, gtp_xact));
break;
case 2:
ogs_assert(OGS_OK == smf_gtp_send_delete_session_response(sess, gtp_xact));
break;
}
} else {
/*
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
* 2. MME sends Delete Bearer Response to SGW/SMF.
*
* OR
*
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
*
* Note that the following messages are not processed here.
* - Bearer Resource Command
* - Delete Bearer Request/Response with DEDICATED BEARER.
*/
}
SMF_SESS_CLEAR(sess);
return OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
}
void smf_n4_handle_session_report_request(

View File

@ -42,7 +42,7 @@ uint8_t smf_epc_n4_handle_session_establishment_response(
void smf_epc_n4_handle_session_modification_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_modification_response_t *rsp);
void smf_epc_n4_handle_session_deletion_response(
uint8_t smf_epc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp);

View File

@ -245,17 +245,9 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
break;
case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE:
if (!message->h.seid_presence) {
if (!message->h.seid_presence)
ogs_error("No SEID");
break;
}
if (xact->epc)
smf_epc_n4_handle_session_deletion_response(
sess, xact, &message->pfcp_session_deletion_response);
else
smf_5gc_n4_handle_session_deletion_response(
sess, xact, &message->pfcp_session_deletion_response);
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE:

View File

@ -304,58 +304,31 @@ uint8_t smf_s5c_handle_create_session_request(
return OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
}
void smf_s5c_handle_delete_session_request(
uint8_t smf_s5c_handle_delete_session_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_delete_session_request_t *req)
{
uint8_t cause_value = 0;
ogs_debug("Delete Session Request");
ogs_assert(xact);
ogs_assert(req);
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
cause_value = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
if (!ogs_diam_app_connected(OGS_DIAM_S6B_APPLICATION_ID)) {
ogs_error("No S6b Diameter Peer");
cause_value = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
}
if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
return;
if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
if (!ogs_diam_app_connected(OGS_DIAM_S6B_APPLICATION_ID)) {
ogs_error("No S6b Diameter Peer");
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
switch (sess->gtp_rat_type) {
case OGS_GTP2_RAT_TYPE_EUTRAN:
smf_gx_send_ccr(sess, xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
break;
case OGS_GTP2_RAT_TYPE_WLAN:
smf_s6b_send_str(sess, xact,
OGS_DIAM_TERMINATION_CAUSE_DIAMETER_LOGOUT);
break;
default:
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
ogs_assert_if_reached();
}
return OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
}
void smf_s5c_handle_modify_bearer_request(
@ -664,7 +637,8 @@ void smf_s5c_handle_update_bearer_response(
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
}
void smf_s5c_handle_delete_bearer_response(
/* return true if entire session must be released */
bool smf_s5c_handle_delete_bearer_response(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_delete_bearer_response_t *rsp)
{
@ -717,66 +691,64 @@ void smf_s5c_handle_delete_bearer_response(
ogs_error("No Cause");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
/* Release entire session: */
return true;
}
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_deletion_request(
sess, NULL));
/*
* 1. MME sends Bearer Resource Command to SGW/SMF.
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME
* 3. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF
*
* OR
*
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF
*/
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
} else {
/*
* 1. MME sends Bearer Resource Command to SGW/SMF.
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME
* 3. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF
*
* OR
*
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF
*/
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->cause.presence) {
ogs_gtp2_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
if (rsp->cause.presence) {
ogs_gtp2_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
cause_value = cause->value;
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
ogs_error("No Cause");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
ogs_debug("Delete Bearer Response : SGW[0x%x] --> SMF[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_bearer_modification_request(
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
} else {
ogs_error("No Cause");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
ogs_debug("Delete Bearer Response : SGW[0x%x] --> SMF[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_bearer_modification_request(
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
return false;
}
static int reconfigure_packet_filter(smf_pf_t *pf, ogs_gtp2_tft_t *tft, int i)

View File

@ -34,7 +34,7 @@ void smf_s5c_handle_echo_response(
uint8_t smf_s5c_handle_create_session_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_create_session_request_t *req);
void smf_s5c_handle_delete_session_request(
uint8_t smf_s5c_handle_delete_session_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_delete_session_request_t *req);
void smf_s5c_handle_modify_bearer_request(
@ -46,7 +46,7 @@ void smf_s5c_handle_create_bearer_response(
void smf_s5c_handle_update_bearer_response(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_update_bearer_response_t *req);
void smf_s5c_handle_delete_bearer_response(
bool smf_s5c_handle_delete_bearer_response(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_delete_bearer_response_t *req);
void smf_s5c_handle_bearer_resource_command(

View File

@ -20,7 +20,7 @@
#include "fd-path.h"
static struct session_handler *smf_s6b_reg = NULL;
static struct disp_hdl *hdl_s6b_fb = NULL;
static struct disp_hdl *hdl_s6b_fb = NULL;
struct sess_state {
smf_sess_t *sess;
@ -62,12 +62,12 @@ static void state_cleanup(struct sess_state *sess_data, os0_t sid, void *opaque)
ogs_thread_mutex_unlock(&sess_state_mutex);
}
static int smf_s6b_fb_cb(struct msg **msg, struct avp *avp,
static int smf_s6b_fb_cb(struct msg **msg, struct avp *avp,
struct session *sess, void *opaque, enum disp_action *act)
{
/* This CB should never be called */
ogs_warn("Unexpected message received!");
return ENOTSUP;
}
@ -488,7 +488,7 @@ void smf_s6b_send_str(smf_sess_t *sess, ogs_gtp_xact_t *xact, uint32_t cause)
smf_ue_t *smf_ue = NULL;
char *user_name = NULL;
ogs_assert(xact);
//ogs_assert(xact);
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
@ -603,6 +603,7 @@ void smf_s6b_send_str(smf_sess_t *sess, ogs_gtp_xact_t *xact, uint32_t cause)
static void smf_s6b_sta_cb(void *data, struct msg **msg)
{
int ret;
int rv;
struct sess_state *sess_data = NULL;
struct timespec ts;
@ -612,11 +613,10 @@ static void smf_s6b_sta_cb(void *data, struct msg **msg)
unsigned long dur;
int error = 0;
int new;
int result_code = 0;
int exp_result_code = 0;
smf_event_t *e = NULL;
smf_sess_t *sess = NULL;
ogs_gtp_xact_t *xact = NULL;
ogs_diam_s6b_message_t *s6b_message = NULL;
ogs_debug("[Session-Termination-Answer]");
@ -638,9 +638,11 @@ static void smf_s6b_sta_cb(void *data, struct msg **msg)
ogs_debug(" Retrieve its data: [%s]", sess_data->s6b_sid);
sess = sess_data->sess;
ogs_assert(sess);
xact = sess_data->xact;
ogs_assert(xact);
s6b_message = ogs_calloc(1, sizeof(ogs_diam_s6b_message_t));
ogs_assert(s6b_message);
/* Set Session Termination Command */
s6b_message->cmd_code = OGS_DIAM_S6B_CMD_SESSION_TERMINATION;
/* Value of Result Code */
ret = fd_msg_search_avp(*msg, ogs_diam_result_code, &avp);
@ -648,9 +650,10 @@ static void smf_s6b_sta_cb(void *data, struct msg **msg)
if (avp) {
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
result_code = hdr->avp_value->i32;
if (result_code != ER_DIAMETER_SUCCESS) {
ogs_error("Result Code: %d", result_code);
s6b_message->result_code = hdr->avp_value->i32;
s6b_message->err = &s6b_message->result_code;
if (s6b_message->result_code != ER_DIAMETER_SUCCESS) {
ogs_error("Result Code: %d", s6b_message->result_code);
error++;
}
} else {
@ -665,8 +668,10 @@ static void smf_s6b_sta_cb(void *data, struct msg **msg)
if (avpch1) {
ret = fd_msg_avp_hdr(avpch1, &hdr);
ogs_assert(ret == 0);
exp_result_code = hdr->avp_value->i32;
ogs_error("Experimental Result Code: %d", exp_result_code);
s6b_message->result_code = hdr->avp_value->i32;
s6b_message->exp_err = &s6b_message->result_code;
ogs_error("Experimental Result Code: %d",
s6b_message->result_code);
}
} else {
ogs_error("no Result-Code");
@ -700,8 +705,21 @@ static void smf_s6b_sta_cb(void *data, struct msg **msg)
}
if (!error) {
smf_gx_send_ccr(sess, xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
e = smf_event_new(SMF_EVT_S6B_MESSAGE);
ogs_assert(e);
e->sess = sess;
e->s6b_message = s6b_message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
ogs_free(s6b_message);
smf_event_free(e);
} else {
ogs_pollset_notify(ogs_app()->pollset);
}
} else {
ogs_free(s6b_message);
}
/* Free the message */

View File

@ -62,6 +62,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_diam_gx_message_t *gx_message = NULL;
ogs_diam_gy_message_t *gy_message = NULL;
ogs_diam_s6b_message_t *s6b_message = NULL;
ogs_pfcp_node_t *pfcp_node = NULL;
ogs_pfcp_xact_t *pfcp_xact = NULL;
@ -145,8 +146,14 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
smf_s5c_handle_delete_session_request(
sess, gtp_xact, &gtp2_message.delete_session_request);
if (!sess) {
ogs_gtp2_send_error_message(gtp_xact, 0,
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
smf_s5c_handle_modify_bearer_request(
@ -161,8 +168,12 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
sess, gtp_xact, &gtp2_message.update_bearer_response);
break;
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
smf_s5c_handle_delete_bearer_response(
sess, gtp_xact, &gtp2_message.delete_bearer_response);
if (!sess) {
/* TODO: NACK the message */
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
smf_s5c_handle_bearer_resource_command(
@ -230,8 +241,14 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE:
smf_gn_handle_delete_pdp_context_request(
sess, gtp_xact, &gtp1_message.delete_pdp_context_request);
if (!sess) {
ogs_gtp1_send_error_message(gtp_xact, 0,
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_NON_EXISTENT);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP1_UPDATE_PDP_CONTEXT_REQUEST_TYPE:
smf_gn_handle_update_pdp_context_request(
@ -258,16 +275,12 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
switch(gx_message->cmd_code) {
case OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL:
gtp_xact = e->gtp_xact;
ogs_assert(gtp_xact);
switch(gx_message->cc_request_type) {
case OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
smf_gx_handle_cca_termination_request(
sess, gx_message, gtp_xact);
ogs_fsm_dispatch(&sess->sm, e);
break;
default:
ogs_error("Not implemented(%d)", gx_message->cc_request_type);
@ -302,14 +315,12 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST:
ogs_assert(e->pfcp_xact);
smf_gy_handle_cca_update_request(
sess, gy_message, e->pfcp_xact);
ogs_assert(e->pfcp_xact);
smf_gy_handle_cca_update_request(
sess, gy_message, e->pfcp_xact);
break;
case OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST:
ogs_assert(e->gtp_xact);
smf_gy_handle_cca_termination_request(
sess, gy_message, e->gtp_xact);
ogs_fsm_dispatch(&sess->sm, e);
break;
default:
ogs_error("Not implemented(%d)", gy_message->cc_request_type);
@ -328,6 +339,25 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_free(gy_message);
break;
case SMF_EVT_S6B_MESSAGE:
ogs_assert(e);
s6b_message = e->s6b_message;
ogs_assert(s6b_message);
sess = e->sess;
ogs_assert(sess);
switch(s6b_message->cmd_code) {
case OGS_DIAM_S6B_CMD_SESSION_TERMINATION:
ogs_fsm_dispatch(&sess->sm, e);
break;
default:
ogs_error("Invalid type(%d)", s6b_message->cmd_code);
break;
}
ogs_free(s6b_message);
break;
case SMF_EVT_N4_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;
@ -716,9 +746,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
ogs_error("[%s] State machine exception", smf_ue->supi);
SMF_SESS_CLEAR(sess);
} else if (OGS_FSM_CHECK(
&sess->sm, smf_gsm_state_session_will_release)) {
SMF_SESS_CLEAR(sess);
}
break;

View File

@ -43,13 +43,15 @@ void smf_nf_state_exception(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_final(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial_wait_auth(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_release_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e);
void smf_pfcp_state_initial(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial_wait_auth(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e);
void smf_pfcp_state_final(ogs_fsm_t *s, smf_event_t *e);
void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e);
void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e);