diff --git a/README.md b/README.md
index e4f6126c0..b07b522f0 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ If you find Open5GS useful for work, please consider supporting this Open Source
-
+
|
@@ -21,7 +21,7 @@ If you find Open5GS useful for work, please consider supporting this Open Source
-
+
|
diff --git a/src/smf/context.c b/src/smf/context.c
index ab2ecc070..07e05e8c1 100644
--- a/src/smf/context.c
+++ b/src/smf/context.c
@@ -1053,6 +1053,9 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type)
sess->gtp_rat_type = rat_type;
ogs_assert(sess->gtp_rat_type);
+ /* Set EPC */
+ sess->epc = true;
+
memset(&e, 0, sizeof(e));
e.sess = sess;
ogs_fsm_create(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final);
diff --git a/src/smf/context.h b/src/smf/context.h
index a9b0e5b3d..eabd28619 100644
--- a/src/smf/context.h
+++ b/src/smf/context.h
@@ -228,6 +228,8 @@ typedef struct smf_sess_s {
uint32_t s6b_sta_err; /* S6B CCA RXed error code */
} sm_data;
+ bool epc; /**< EPC or 5GC */
+
ogs_pfcp_sess_t pfcp; /* PFCP session context */
uint64_t smpolicycontrol_features; /* SBI features */
diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c
index 14302ae0e..6df57a3ca 100644
--- a/src/smf/gsm-sm.c
+++ b/src/smf/gsm-sm.c
@@ -66,7 +66,8 @@ static uint8_t gtp_cause_from_diameter(uint8_t gtp_version,
}
}
-static void send_gtp_create_err_msg(const smf_sess_t *sess, ogs_gtp_xact_t *gtp_xact, uint8_t gtp_cause)
+static void send_gtp_create_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,
@@ -76,7 +77,8 @@ 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)
+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,
@@ -92,10 +94,11 @@ static bool send_ccr_init_req_gx_gy(smf_sess_t *sess, smf_event_t *e)
if (use_gy == -1) {
ogs_error("No Gy Diameter Peer");
- /* TODO: drop Gx connection here, possibly move to another "releasing" state! */
+ /* 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;
+ OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE :
+ OGS_GTP2_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER;
send_gtp_create_err_msg(sess, e->gtp_xact, gtp_cause);
return false;
}
@@ -105,7 +108,8 @@ static bool send_ccr_init_req_gx_gy(smf_sess_t *sess, smf_event_t *e)
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
if (use_gy == 1) {
- /* Gy is available, set up session for the bearer before accepting it towards the UE */
+ /* Gy is available,
+ * set up session for the bearer before accepting it towards the UE */
sess->sm_data.gy_ccr_init_in_flight = true;
smf_gy_send_ccr(sess, e->gtp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST);
@@ -121,10 +125,11 @@ static bool send_ccr_termination_req_gx_gy_s6b(smf_sess_t *sess, smf_event_t *e)
if (use_gy == -1) {
ogs_error("No Gy Diameter Peer");
- /* TODO: drop Gx connection here, possibly move to another "releasing" state! */
+ /* 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;
+ 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;
}
@@ -140,7 +145,8 @@ static bool send_ccr_termination_req_gx_gy_s6b(smf_sess_t *sess, smf_event_t *e)
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 */
+ /* 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);
@@ -148,15 +154,83 @@ static bool send_ccr_termination_req_gx_gy_s6b(smf_sess_t *sess, smf_event_t *e)
return true;
}
+static bool send_sbi_message_from_delete_trigger(
+ smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger)
+{
+ ogs_sbi_message_t sendmsg;
+ ogs_sbi_response_t *response = NULL;
+
+ if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) {
+ ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
+
+ n1smbuf = gsm_build_pdu_session_release_command(
+ sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
+ ogs_assert(n1smbuf);
+
+ n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
+ sess, SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED,
+ NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
+ ogs_assert(n2smbuf);
+
+ ogs_assert(stream);
+ smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
+ n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD, n2smbuf);
+ } else if (trigger == OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
+ trigger == OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
+ memset(&sendmsg, 0, sizeof(sendmsg));
+
+ response = ogs_sbi_build_response(
+ &sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
+ ogs_assert(response);
+
+ ogs_assert(stream);
+ ogs_assert(true == ogs_sbi_server_send_response(stream, response));
+ } else if (trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
+ smf_n1_n2_message_transfer_param_t param;
+
+ memset(¶m, 0, sizeof(param));
+ param.state = SMF_NETWORK_REQUESTED_PDU_SESSION_RELEASE;
+ param.n2smbuf =
+ ngap_build_pdu_session_resource_release_command_transfer(
+ sess, SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED,
+ NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
+ ogs_assert(param.n2smbuf);
+
+ param.skip_ind = true;
+
+ smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m);
+ } else {
+ ogs_fatal("Unknown trigger [%d]", trigger);
+ ogs_assert_if_reached();
+ }
+
+ return true;
+}
+
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
- ogs_assert(s);
- ogs_assert(e && e->sess);
- smf_sess_t *sess = e->sess;
+ int rv;
+ char *strerror = NULL;
+ smf_ue_t *smf_ue = NULL;
+ smf_sess_t *sess = NULL;
+
+ ogs_gtp1_message_t *gtp1_message = NULL;
+ ogs_gtp2_message_t *gtp2_message = NULL;
uint8_t gtp1_cause, gtp2_cause;
+ ogs_nas_5gs_message_t *nas_message = NULL;
+
+ ogs_sbi_stream_t *stream = NULL;
+ ogs_sbi_message_t *sbi_message = NULL;
+
+ ogs_assert(s);
+ ogs_assert(e);
+
smf_sm_debug(e);
+ sess = e->sess;
+ ogs_assert(sess);
+
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
/* reset state: */
@@ -164,12 +238,16 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
sess->sm_data.gy_ccr_init_in_flight = false;
sess->sm_data.gx_cca_init_err = ER_DIAMETER_SUCCESS;
sess->sm_data.gy_cca_init_err = ER_DIAMETER_SUCCESS;
- if (!sess->gtp_rat_type) /* 5gc */
- OGS_FSM_TRAN(s, &smf_gsm_state_operational);
+ break;
+
+ case OGS_FSM_EXIT_SIG:
break;
case SMF_EVT_GN_MESSAGE:
- switch(e->gtp1_message->h.type) {
+ gtp1_message = e->gtp1_message;
+ ogs_assert(gtp1_message);
+
+ switch(gtp1_message->h.type) {
case OGS_GTP1_CREATE_PDP_CONTEXT_REQUEST_TYPE:
gtp1_cause = smf_gn_handle_create_pdp_context_request(sess,
e->gtp_xact,
@@ -179,12 +257,15 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
return;
}
if (send_ccr_init_req_gx_gy(sess, e) == true)
- OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_auth);
+ OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_initial);
}
break;
case SMF_EVT_S5C_MESSAGE:
- switch(e->gtp2_message->h.type) {
+ gtp2_message = e->gtp2_message;
+ ogs_assert(gtp2_message);
+
+ switch(gtp2_message->h.type) {
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
gtp2_cause = smf_s5c_handle_create_session_request(sess,
e->gtp_xact,
@@ -196,39 +277,134 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
switch (sess->gtp_rat_type) {
case OGS_GTP2_RAT_TYPE_EUTRAN:
if (send_ccr_init_req_gx_gy(sess, e) == true)
- OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_auth);
+ OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_initial);
break;
case OGS_GTP2_RAT_TYPE_WLAN:
smf_s6b_send_aar(sess, e->gtp_xact);
- OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_auth);
+ OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_initial);
break;
default:
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
ogs_assert_if_reached();
}
break;
+
+ default:
+ ogs_error("Not implmeneted(type:%d)", gtp2_message->h.type);
}
break;
+
+ case SMF_EVT_SBI_SERVER:
+ sbi_message = e->sbi.message;
+ ogs_assert(sbi_message);
+ stream = e->sbi.data;
+ ogs_assert(stream);
+
+ SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
+ SWITCH(sbi_message->h.resource.component[2])
+ CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
+ CASE(OGS_SBI_RESOURCE_NAME_RELEASE)
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
+ "Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]));
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ break;
+ DEFAULT
+ if (smf_nsmf_handle_create_sm_context(
+ sess, stream, sbi_message) == false) {
+ ogs_error("smf_nsmf_handle_create_sm_context() failed");
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ }
+ END
+ break;
+
+ DEFAULT
+ ogs_error("Invalid API name [%s]", sbi_message->h.service.name);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
+ "Invalid API name", sbi_message->h.service.name));
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ END
+ break;
+
+ case SMF_EVT_5GSM_MESSAGE:
+ nas_message = e->nas.message;
+ ogs_assert(nas_message);
+ sess = e->sess;
+ ogs_assert(sess);
+ stream = e->sbi.data;
+ ogs_assert(stream);
+ smf_ue = sess->smf_ue;
+ ogs_assert(smf_ue);
+
+ switch (nas_message->gsm.h.message_type) {
+ case OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST:
+ rv = gsm_handle_pdu_session_establishment_request(sess, stream,
+ &nas_message->gsm.pdu_session_establishment_request);
+ if (rv != OGS_OK) {
+ ogs_error("[%s:%d] Cannot handle NAS message",
+ smf_ue->supi, sess->psi);
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ break;
+ }
+
+ OGS_FSM_TRAN(s, smf_gsm_state_wait_5gc_sm_policy_association);
+ break;
+
+ default:
+ strerror = ogs_msprintf("Unknown message [%d]",
+ nas_message->gsm.h.message_type);
+ ogs_assert(strerror);
+
+ ogs_error("%s", strerror);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL));
+ ogs_free(strerror);
+
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ }
+ break;
+ default:
+ ogs_error("No handler for event %s", smf_event_get_name(e));
+ break;
}
}
-void smf_gsm_state_initial_wait_auth(ogs_fsm_t *s, smf_event_t *e)
+void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
{
- ogs_assert(e && e->sess);
- smf_sess_t *sess = e->sess;
+ smf_sess_t *sess = NULL;
+
+ ogs_diam_gy_message_t *gy_message = NULL;
+ ogs_diam_gx_message_t *gx_message = NULL;
uint32_t diam_err;
+ ogs_assert(s);
+ ogs_assert(e);
+
smf_sm_debug(e);
+ sess = e->sess;
+ ogs_assert(sess);
+
switch (e->id) {
case SMF_EVT_GX_MESSAGE:
- switch(e->gx_message->cmd_code) {
+ gx_message = e->gx_message;
+ ogs_assert(gx_message);
+
+ switch(gx_message->cmd_code) {
case OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL:
- switch(e->gx_message->cc_request_type) {
+ switch(gx_message->cc_request_type) {
case OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_assert(e->gtp_xact);
diam_err = smf_gx_handle_cca_initial_request(sess,
- e->gx_message, e->gtp_xact);
+ gx_message, e->gtp_xact);
sess->sm_data.gx_ccr_init_in_flight = false;
sess->sm_data.gx_cca_init_err = diam_err;
goto test_can_proceed;
@@ -238,13 +414,16 @@ void smf_gsm_state_initial_wait_auth(ogs_fsm_t *s, smf_event_t *e)
break;
case SMF_EVT_GY_MESSAGE:
- switch(e->gy_message->cmd_code) {
+ gy_message = e->gy_message;
+ ogs_assert(gy_message);
+
+ switch(gy_message->cmd_code) {
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
- switch(e->gy_message->cc_request_type) {
+ switch(gy_message->cc_request_type) {
case OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_assert(e->gtp_xact);
diam_err = smf_gy_handle_cca_initial_request(sess,
- e->gy_message, e->gtp_xact);
+ gy_message, e->gtp_xact);
sess->sm_data.gy_ccr_init_in_flight = false;
sess->sm_data.gy_cca_init_err = diam_err;
goto test_can_proceed;
@@ -266,112 +445,29 @@ test_can_proceed:
diam_err = sess->sm_data.gy_cca_init_err;
if (diam_err == ER_DIAMETER_SUCCESS) {
- OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_pfcp_establishment);
+ OGS_FSM_TRAN(s, &smf_gsm_state_wait_pfcp_establishment);
ogs_assert(OGS_OK ==
- smf_epc_pfcp_send_session_establishment_request(sess, e->gtp_xact));
+ smf_epc_pfcp_send_session_establishment_request(
+ sess, e->gtp_xact));
} else {
- /* FIXME: tear down Gx/Gy session if its sm_data.*init_err == ER_DIAMETER_SUCCESS */
- uint8_t gtp_cause = gtp_cause_from_diameter(e->gtp_xact->gtp_version,
- diam_err, NULL);
+ /* FIXME: tear down Gx/Gy session
+ * if its sm_data.*init_err == ER_DIAMETER_SUCCESS */
+ uint8_t gtp_cause = gtp_cause_from_diameter(
+ e->gtp_xact->gtp_version, diam_err, NULL);
send_gtp_create_err_msg(sess, e->gtp_xact, gtp_cause);
}
}
}
-void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
+void smf_gsm_state_wait_5gc_sm_policy_association(ogs_fsm_t *s, smf_event_t *e)
{
- ogs_assert(e && e->sess);
- 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) {
- case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE:
- if (e->pfcp_xact->epc) {
- ogs_gtp_xact_t *gtp_xact = e->pfcp_xact->assoc_xact;
- pfcp_cause = smf_epc_n4_handle_session_establishment_response(
- sess, e->pfcp_xact,
- &e->pfcp_message->pfcp_session_establishment_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_create_err_msg(sess, e->gtp_xact, gtp_cause);
- return;
- }
- switch (gtp_xact->gtp_version) {
- case 1:
- ogs_assert(OGS_OK ==
- smf_gtp1_send_create_pdp_context_response(
- sess, gtp_xact));
- break;
- case 2:
- ogs_assert(OGS_OK ==
- smf_gtp2_send_create_session_response(
- sess, gtp_xact));
- break;
- }
- if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
- /*
- * TS23.214
- * 6.3.1.7 Procedures with modification of bearer
- * p50
- * 2. ...
- * For "PGW/MME initiated bearer deactivation procedure",
- * PGW-C shall indicate PGW-U to stop counting and stop
- * forwarding downlink packets for the affected bearer(s).
- */
- ogs_assert(OGS_OK ==
- smf_epc_pfcp_send_deactivation(sess,
- OGS_GTP2_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP));
- }
- smf_bearer_binding(sess);
- } else {
-#if 0
- /* This is currently not happening, since 5gc isn't yet properly integrated and moves directly to operational state */
- smf_n1_n2_message_transfer_param_t param;
- pfcp_cause = smf_5gc_n4_handle_session_establishment_response(
- sess, e->pfcp_xact,
- &e->pfcp_message->pfcp_session_establishment_response);
- if (pfcp_cause != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
- return;
- memset(¶m, 0, sizeof(param));
- param.state = SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT;
- param.n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
- ogs_assert(param.n1smbuf);
- param.n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(
- sess);
- ogs_assert(param.n2smbuf);
- smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m);
-#endif
- }
- OGS_FSM_TRAN(s, &smf_gsm_state_operational);
- break;
- }
- break;
- }
-}
-
-void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
-{
- int rv, ngap_state;
char *strerror = NULL;
smf_ue_t *smf_ue = NULL;
smf_sess_t *sess = NULL;
- ogs_pkbuf_t *pkbuf = NULL;
-
- ogs_nas_5gs_message_t *nas_message = NULL;
ogs_sbi_stream_t *stream = NULL;
ogs_sbi_message_t *sbi_message = NULL;
- smf_n1_n2_message_transfer_param_t param;
- uint8_t pfcp_cause;
- uint8_t gtp1_cause, gtp2_cause;
- bool release;
-
int state = 0;
ogs_assert(s);
@@ -385,110 +481,9 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
break;
-
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:
- /* This is left here for 5gc sessions to properly receive messages,
- since startup transitions are not implemented yet for 5gc
- sessions. See #if0 in smf_gsm_state_initial_wait_pfcp_establishment() */
- assert(!e->pfcp_xact->epc);
- pfcp_cause = smf_5gc_n4_handle_session_establishment_response(
- sess, e->pfcp_xact,
- &e->pfcp_message->pfcp_session_establishment_response);
- if (pfcp_cause != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
- return;
- memset(¶m, 0, sizeof(param));
- param.state = SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT;
- param.n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
- ogs_assert(param.n1smbuf);
- param.n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(
- sess);
- ogs_assert(param.n2smbuf);
- smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m);
- 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;
-
- case SMF_EVT_SBI_SERVER:
- sbi_message = e->sbi.message;
- ogs_assert(sbi_message);
- stream = e->sbi.data;
- ogs_assert(stream);
-
- SWITCH(sbi_message->h.service.name)
- CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
- SWITCH(sbi_message->h.resource.component[2])
- CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
- smf_nsmf_handle_update_sm_context(sess, stream, sbi_message);
- break;
- CASE(OGS_SBI_RESOURCE_NAME_RELEASE)
- smf_nsmf_handle_release_sm_context(sess, stream, sbi_message);
- break;
- DEFAULT
- smf_nsmf_handle_create_sm_context(sess, stream, sbi_message);
- break;
- END
- break;
-
- DEFAULT
- ogs_error("Invalid API name [%s]", sbi_message->h.service.name);
- ogs_assert(true ==
- ogs_sbi_server_send_error(stream,
- OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
- "Invalid API name", sbi_message->h.service.name));
- END
- break;
-
case SMF_EVT_SBI_CLIENT:
sbi_message = e->sbi.message;
ogs_assert(sbi_message);
@@ -522,8 +517,9 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
}
if (smf_nudm_sdm_handle_get(
- sess, stream, sbi_message) != true) {
- OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
+ sess, stream, sbi_message) == false) {
+ ogs_error("smf_nudm_sdm_handle_get() failed");
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
}
break;
@@ -539,6 +535,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
sbi_message, strerror, NULL));
ogs_free(strerror);
+
OGS_FSM_TRAN(s, smf_gsm_state_exception);
END
break;
@@ -549,7 +546,23 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_SM_POLICIES)
- if (!sbi_message->h.resource.component[1]) {
+ if (sbi_message->h.resource.component[1]) {
+ strerror = ogs_msprintf("[%s:%d] "
+ "Unknown resource name [%s]",
+ smf_ue->supi, sess->psi,
+ sbi_message->h.resource.component[1]);
+ ogs_assert(strerror);
+
+ ogs_error("%s", strerror);
+ if (stream)
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST,
+ sbi_message, strerror, NULL));
+ ogs_free(strerror);
+
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ } else {
ogs_assert(stream);
if (sbi_message->res_status !=
OGS_SBI_HTTP_STATUS_CREATED) {
@@ -565,11 +578,299 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
sbi_message->res_status,
sbi_message, strerror, NULL));
ogs_free(strerror);
+
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
break;
}
- smf_npcf_smpolicycontrol_handle_create(
- sess, stream, state, sbi_message);
+ if (smf_npcf_smpolicycontrol_handle_create(
+ sess, stream, state, sbi_message) == true) {
+ OGS_FSM_TRAN(s,
+ &smf_gsm_state_wait_pfcp_establishment);
+ } else {
+ ogs_error(
+ "smf_npcf_smpolicycontrol_handle_create() failed");
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ }
+ }
+ break;
+
+ DEFAULT
+ strerror = ogs_msprintf("[%s:%d] Invalid resource name [%s]",
+ smf_ue->supi, sess->psi,
+ sbi_message->h.resource.component[0]);
+ ogs_assert(strerror);
+
+ ogs_error("%s", strerror);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST,
+ sbi_message, strerror, NULL));
+ ogs_free(strerror);
+
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ END
+ break;
+
+ DEFAULT
+ ogs_error("[%s:%d] Invalid API name [%s]",
+ smf_ue->supi, sess->psi, sbi_message->h.service.name);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ default:
+ ogs_error("No handler for event %s", smf_event_get_name(e));
+ break;
+ }
+}
+
+
+void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
+{
+ smf_sess_t *sess = NULL;
+ uint8_t pfcp_cause, gtp_cause;
+ smf_n1_n2_message_transfer_param_t param;
+
+ ogs_pfcp_xact_t *pfcp_xact = NULL;
+ ogs_pfcp_message_t *pfcp_message = NULL;
+
+ ogs_assert(s);
+ ogs_assert(e);
+
+ smf_sm_debug(e);
+
+ sess = e->sess;
+ ogs_assert(sess);
+
+ switch (e->id) {
+ case SMF_EVT_N4_MESSAGE:
+ pfcp_xact = e->pfcp_xact;
+ ogs_assert(pfcp_xact);
+ pfcp_message = e->pfcp_message;
+ ogs_assert(pfcp_message);
+
+ switch (pfcp_message->h.type) {
+ case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE:
+ if (pfcp_xact->epc) {
+ ogs_gtp_xact_t *gtp_xact = pfcp_xact->assoc_xact;
+ ogs_assert(gtp_xact);
+
+ pfcp_cause = smf_epc_n4_handle_session_establishment_response(
+ sess, pfcp_xact,
+ &pfcp_message->pfcp_session_establishment_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_create_err_msg(sess, e->gtp_xact, gtp_cause);
+ return;
+ }
+ switch (gtp_xact->gtp_version) {
+ case 1:
+ ogs_assert(OGS_OK ==
+ smf_gtp1_send_create_pdp_context_response(
+ sess, gtp_xact));
+ break;
+ case 2:
+ ogs_assert(OGS_OK ==
+ smf_gtp2_send_create_session_response(
+ sess, gtp_xact));
+ break;
+ }
+ if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
+ /*
+ * TS23.214
+ * 6.3.1.7 Procedures with modification of bearer
+ * p50
+ * 2. ...
+ * For "PGW/MME initiated bearer deactivation procedure",
+ * PGW-C shall indicate PGW-U to stop counting and stop
+ * forwarding downlink packets for the affected bearer(s).
+ */
+ ogs_assert(OGS_OK ==
+ smf_epc_pfcp_send_deactivation(sess,
+ OGS_GTP2_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP));
+ }
+ smf_bearer_binding(sess);
+ } else {
+ pfcp_cause = smf_5gc_n4_handle_session_establishment_response(
+ sess, pfcp_xact,
+ &pfcp_message->pfcp_session_establishment_response);
+ if (pfcp_cause != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
+ return;
+ memset(¶m, 0, sizeof(param));
+ param.state = SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT;
+ param.n1smbuf =
+ gsm_build_pdu_session_establishment_accept(sess);
+ ogs_assert(param.n1smbuf);
+ param.n2smbuf =
+ ngap_build_pdu_session_resource_setup_request_transfer(
+ sess);
+ ogs_assert(param.n2smbuf);
+ smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m);
+ }
+
+ OGS_FSM_TRAN(s, &smf_gsm_state_operational);
+ break;
+
+ default:
+ ogs_error("cannot handle PFCP message type[%d]",
+ pfcp_message->h.type);
+ }
+ }
+}
+
+void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
+{
+ int rv, ngap_state;
+ char *strerror = NULL;
+ smf_ue_t *smf_ue = NULL;
+ smf_sess_t *sess = NULL;
+ ogs_pkbuf_t *pkbuf = NULL;
+
+ ogs_nas_5gs_message_t *nas_message = NULL;
+
+ ogs_sbi_stream_t *stream = NULL;
+ ogs_sbi_message_t *sbi_message = NULL;
+
+ ogs_gtp1_message_t *gtp1_message = NULL;
+ ogs_gtp2_message_t *gtp2_message = NULL;
+ uint8_t gtp1_cause, gtp2_cause;
+ bool release;
+
+ ogs_assert(s);
+ ogs_assert(e);
+
+ smf_sm_debug(e);
+
+ sess = e->sess;
+ ogs_assert(sess);
+
+ switch (e->id) {
+ case OGS_FSM_ENTRY_SIG:
+ break;
+
+ case OGS_FSM_EXIT_SIG:
+ break;
+
+ case SMF_EVT_GN_MESSAGE:
+ gtp1_message = e->gtp1_message;
+ ogs_assert(gtp1_message);
+
+ switch(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,
+ >p1_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_wait_pfcp_deletion);
+ }
+ break;
+
+ case SMF_EVT_S5C_MESSAGE:
+ gtp2_message = e->gtp2_message;
+ ogs_assert(gtp2_message);
+
+ switch(gtp2_message->h.type) {
+ case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
+ gtp2_cause = smf_s5c_handle_delete_session_request(
+ sess, e->gtp_xact,
+ >p2_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_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_wait_pfcp_deletion);
+ }
+ break;
+
+ default:
+ ogs_error("Not implmeneted(type:%d)", gtp2_message->h.type);
+ }
+ break;
+
+ case SMF_EVT_SBI_SERVER:
+ sbi_message = e->sbi.message;
+ ogs_assert(sbi_message);
+ stream = e->sbi.data;
+ ogs_assert(stream);
+
+ SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
+ SWITCH(sbi_message->h.resource.component[2])
+ CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
+ smf_nsmf_handle_update_sm_context(sess, stream, sbi_message);
+ break;
+ CASE(OGS_SBI_RESOURCE_NAME_RELEASE)
+ smf_nsmf_handle_release_sm_context(sess, stream, sbi_message);
+ break;
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
+ "Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]));
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ END
+ break;
+
+ DEFAULT
+ ogs_error("Invalid API name [%s]", sbi_message->h.service.name);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
+ "Invalid API name", sbi_message->h.service.name));
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ END
+ break;
+
+ case SMF_EVT_SBI_CLIENT:
+ sbi_message = e->sbi.message;
+ ogs_assert(sbi_message);
+
+ sess = e->sess;
+ ogs_assert(sess);
+ smf_ue = sess->smf_ue;
+ ogs_assert(smf_ue);
+
+ SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL)
+ stream = e->sbi.data;
+
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_SM_POLICIES)
+ if (!sbi_message->h.resource.component[1]) {
+ ogs_assert(stream);
+ strerror = ogs_msprintf(
+ "[%s:%d] HTTP response error [%d]",
+ smf_ue->supi, sess->psi,
+ sbi_message->res_status);
+ ogs_assert(strerror);
+
+ ogs_error("%s", strerror);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(
+ stream, sbi_message->res_status,
+ sbi_message, strerror, NULL));
+ ogs_free(strerror);
+
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ break;
} else {
SWITCH(sbi_message->h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_DELETE)
@@ -582,10 +883,12 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(strerror);
ogs_error("%s", strerror);
ogs_free(strerror);
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ break;
}
- smf_npcf_smpolicycontrol_handle_delete(
- sess, stream, state, sbi_message);
+ OGS_FSM_TRAN(&sess->sm,
+ &smf_gsm_state_wait_pfcp_deletion);
break;
DEFAULT
@@ -602,6 +905,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
sbi_message, strerror, NULL));
ogs_free(strerror);
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
END
}
break;
@@ -618,6 +922,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
sbi_message, strerror, NULL));
ogs_free(strerror);
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
END
break;
@@ -654,16 +959,6 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(smf_ue);
switch (nas_message->gsm.h.message_type) {
- case OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST:
- rv = gsm_handle_pdu_session_establishment_request(sess, stream,
- &nas_message->gsm.pdu_session_establishment_request);
- if (rv != OGS_OK) {
- ogs_error("[%s:%d] Cannot handle NAS message",
- smf_ue->supi, sess->psi);
- OGS_FSM_TRAN(s, smf_gsm_state_exception);
- }
- break;
-
case OGS_NAS_5GS_PDU_SESSION_MODIFICATION_REQUEST:
rv = gsm_handle_pdu_session_modification_request(sess, stream,
&nas_message->gsm.pdu_session_modification_request);
@@ -773,12 +1068,6 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_FSM_TRAN(s, smf_gsm_state_exception);
- } else if (
- ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED ||
- ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED) {
-
- ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
-
} else if (ngap_state ==
SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN) {
smf_n1_n2_message_transfer_param_t param;
@@ -838,11 +1127,20 @@ 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_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
{
+ int status;
+
smf_sess_t *sess = NULL;
+
+ ogs_sbi_stream_t *stream = NULL;
+
+ ogs_pfcp_xact_t *pfcp_xact = NULL;
+ ogs_pfcp_message_t *pfcp_message = NULL;
+
uint8_t pfcp_cause, gtp_cause;
- ogs_gtp_xact_t *gtp_xact;
+ ogs_gtp_xact_t *gtp_xact = NULL;
+
ogs_assert(s);
ogs_assert(e);
@@ -853,8 +1151,21 @@ void smf_gsm_state_release_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
- ogs_assert(OGS_OK ==
- smf_epc_pfcp_send_session_deletion_request(sess, e->gtp_xact));
+ /* Since `pfcp_xact->epc` is not avaiable,
+ * we'll use `sess->epc` */
+ if (sess->epc) {
+ /* EPC */
+ ogs_assert(OGS_OK ==
+ smf_epc_pfcp_send_session_deletion_request(sess, e->gtp_xact));
+ } else {
+ /* 5GC */
+ stream = e->sbi.data;
+ ogs_assert(stream);
+
+ ogs_assert(OGS_OK ==
+ smf_5gc_pfcp_send_session_deletion_request(
+ sess, stream, e->sbi.state));
+ }
break;
case OGS_FSM_EXIT_SIG:
@@ -865,50 +1176,99 @@ void smf_gsm_state_release_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
break; /* ignore */
case SMF_EVT_N4_MESSAGE:
- gtp_xact = e->pfcp_xact->assoc_xact;
- switch (e->pfcp_message->h.type) {
+ pfcp_xact = e->pfcp_xact;
+ ogs_assert(pfcp_xact);
+ pfcp_message = e->pfcp_message;
+ ogs_assert(pfcp_message);
+
+ switch (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_xact->epc) {
+ gtp_xact = pfcp_xact->assoc_xact;
+
+ pfcp_cause = smf_epc_n4_handle_session_deletion_response(
+ sess, pfcp_xact,
+ &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);
+ ogs_assert(gtp_xact);
+ gtp_cause = gtp_cause_from_pfcp(
+ pfcp_cause, gtp_xact->gtp_version);
send_gtp_delete_err_msg(sess, gtp_xact, gtp_cause);
- return;
+ break;
}
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);
+ OGS_FSM_TRAN(s, &smf_gsm_state_wait_epc_auth_release);
/* 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
+ int trigger;
+
+ stream = pfcp_xact->assoc_stream;
+ trigger = pfcp_xact->delete_trigger;
+ ogs_assert(trigger);
+
+ ogs_pfcp_xact_commit(pfcp_xact);
+
+ status = smf_5gc_n4_handle_session_deletion_response(
+ sess, stream, trigger,
+ &pfcp_message->pfcp_session_deletion_response);
+ if (status != OGS_SBI_HTTP_STATUS_OK) {
+ ogs_error(
+ "smf_5gc_n4_handle_session_deletion_response() failed");
+ break;
+ }
+
+ if (send_sbi_message_from_delete_trigger(
+ sess, stream, trigger) == true) {
+
+ if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED ||
+ trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
+
+ OGS_FSM_TRAN(s, smf_gsm_state_wait_5gc_n1_n2_release);
+
+ } else if (trigger ==
+ OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
+ trigger ==
+ OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
+
+ OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
+
+ } else if (trigger ==
+ OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
+
+ } else {
+ ogs_fatal("Unknown trigger [%d]", trigger);
+ ogs_assert_if_reached();
+ }
+ }
}
break;
- }
- return;
- default:
- ogs_error("Unknown event %s", smf_event_get_name(e));
- break;
+ default:
+ ogs_error("cannot handle PFCP message type[%d]",
+ pfcp_message->h.type);
+ }
}
}
-void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e)
+void smf_gsm_state_wait_epc_auth_release(ogs_fsm_t *s, smf_event_t *e)
{
- ogs_assert(e && e->sess);
- smf_sess_t *sess = e->sess;
+ smf_sess_t *sess = NULL;
+
+ ogs_diam_gx_message_t *gx_message = NULL;
+ ogs_diam_gy_message_t *gy_message = NULL;
+ ogs_diam_s6b_message_t *s6b_message = NULL;
uint32_t diam_err;
+ ogs_assert(s);
+ ogs_assert(e);
+
smf_sm_debug(e);
+ sess = e->sess;
+ ogs_assert(sess);
+
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
/* reset state: */
@@ -923,12 +1283,15 @@ void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e)
break; /* ignore */
case SMF_EVT_GX_MESSAGE:
- switch(e->gx_message->cmd_code) {
+ gx_message = e->gx_message;
+ ogs_assert(gx_message);
+
+ switch(gx_message->cmd_code) {
case OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL:
- switch(e->gx_message->cc_request_type) {
+ switch(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);
+ 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;
@@ -938,13 +1301,16 @@ void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e)
break;
case SMF_EVT_GY_MESSAGE:
- switch(e->gy_message->cmd_code) {
+ gy_message = e->gy_message;
+ ogs_assert(gy_message);
+
+ switch(gy_message->cmd_code) {
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
- switch(e->gy_message->cc_request_type) {
+ switch(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);
+ 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;
@@ -954,7 +1320,10 @@ void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e)
break;
case SMF_EVT_S6B_MESSAGE:
- switch(e->s6b_message->cmd_code) {
+ s6b_message = e->s6b_message;
+ ogs_assert(s6b_message);
+
+ switch(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: */
@@ -987,15 +1356,19 @@ test_can_proceed:
*/
switch (e->gtp_xact->gtp_version) {
case 1:
- ogs_assert(OGS_OK == smf_gtp1_send_delete_pdp_context_response(sess, e->gtp_xact));
+ ogs_assert(OGS_OK ==
+ smf_gtp1_send_delete_pdp_context_response(
+ sess, e->gtp_xact));
break;
case 2:
- ogs_assert(OGS_OK == smf_gtp2_send_delete_session_response(sess, e->gtp_xact));
+ ogs_assert(OGS_OK ==
+ smf_gtp2_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);
+ 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);
}
}
@@ -1003,6 +1376,176 @@ test_can_proceed:
}
}
+void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e)
+{
+ int ngap_state;
+ char *strerror = NULL;
+
+ smf_ue_t *smf_ue = NULL;
+ smf_sess_t *sess = NULL;
+ ogs_pkbuf_t *pkbuf = NULL;
+
+ ogs_nas_5gs_message_t *nas_message = NULL;
+
+ ogs_sbi_stream_t *stream = NULL;
+ ogs_sbi_message_t *sbi_message = NULL;
+
+ ogs_assert(s);
+ ogs_assert(e);
+
+ smf_sm_debug(e);
+
+ sess = e->sess;
+ ogs_assert(sess);
+
+ switch (e->id) {
+ case OGS_FSM_ENTRY_SIG:
+ break;
+ case OGS_FSM_EXIT_SIG:
+ break;
+
+ case SMF_EVT_SBI_SERVER:
+ sbi_message = e->sbi.message;
+ ogs_assert(sbi_message);
+ stream = e->sbi.data;
+ ogs_assert(stream);
+
+ SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
+ SWITCH(sbi_message->h.resource.component[2])
+ CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
+ smf_nsmf_handle_update_sm_context(sess, stream, sbi_message);
+ break;
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
+ "Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]));
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ END
+ break;
+
+ DEFAULT
+ ogs_error("Invalid API name [%s]", sbi_message->h.service.name);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message,
+ "Invalid API name", sbi_message->h.service.name));
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+ END
+ break;
+
+ case SMF_EVT_SBI_CLIENT:
+ sbi_message = e->sbi.message;
+ ogs_assert(sbi_message);
+
+ sess = e->sess;
+ ogs_assert(sess);
+ smf_ue = sess->smf_ue;
+ ogs_assert(smf_ue);
+
+ SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
+ smf_namf_comm_handle_n1_n2_message_transfer(
+ sess, e->sbi.state, sbi_message);
+ break;
+
+ DEFAULT
+ ogs_error("[%s:%d] Invalid resource name [%s]",
+ smf_ue->supi, sess->psi,
+ sbi_message->h.resource.component[0]);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ DEFAULT
+ ogs_error("[%s:%d] Invalid API name [%s]",
+ smf_ue->supi, sess->psi, sbi_message->h.service.name);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ case SMF_EVT_NGAP_MESSAGE:
+ sess = e->sess;
+ ogs_assert(sess);
+ stream = e->sbi.data;
+ ogs_assert(stream);
+ smf_ue = sess->smf_ue;
+ ogs_assert(smf_ue);
+ pkbuf = e->pkbuf;
+ ogs_assert(pkbuf);
+ ogs_assert(e->ngap.type);
+
+ switch (e->ngap.type) {
+ case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP:
+ ngap_state = sess->ngap_state.pdu_session_resource_release;
+
+ if (ngap_state == SMF_NGAP_STATE_NONE) {
+ strerror = ogs_msprintf(
+ "[%s:%d] No PDUSessionResourceReleaseRequest",
+ smf_ue->supi, sess->psi);
+ ogs_assert(strerror);
+
+ ogs_error("%s", strerror);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL));
+ ogs_free(strerror);
+
+ OGS_FSM_TRAN(s, smf_gsm_state_exception);
+
+ } else if (
+ ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED ||
+ ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED) {
+
+ ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
+
+ } else {
+ ogs_fatal("Invalid state [%d]", ngap_state);
+ ogs_assert_if_reached();
+ }
+ break;
+ default:
+ ogs_error("Unknown message[%d]", e->ngap.type);
+ }
+ break;
+
+ case SMF_EVT_5GSM_MESSAGE:
+ nas_message = e->nas.message;
+ ogs_assert(nas_message);
+ sess = e->sess;
+ ogs_assert(sess);
+ stream = e->sbi.data;
+ ogs_assert(stream);
+ smf_ue = sess->smf_ue;
+ ogs_assert(smf_ue);
+
+ switch (nas_message->gsm.h.message_type) {
+ case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE:
+ ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
+ ogs_assert(true == smf_sbi_send_sm_context_status_notify(sess));
+ OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release);
+ break;
+ default:
+ strerror = ogs_msprintf("Unknown message [%d]",
+ nas_message->gsm.h.message_type);
+ ogs_assert(strerror);
+
+ ogs_error("%s", strerror);
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL));
+ ogs_free(strerror);
+ }
+ break;
+ }
+}
+
void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e)
{
smf_sess_t *sess = NULL;
@@ -1030,7 +1573,9 @@ 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)
{
+ smf_ue_t *smf_ue = NULL;
smf_sess_t *sess = NULL;
+
ogs_assert(s);
ogs_assert(e);
@@ -1038,9 +1583,13 @@ void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e)
sess = e->sess;
ogs_assert(sess);
+ smf_ue = sess->smf_ue;
+ ogs_assert(smf_ue);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
+ ogs_error("[%s:%d] State machine exception", smf_ue->supi, sess->psi);
+ SMF_SESS_CLEAR(sess);
break;
case OGS_FSM_EXIT_SIG:
diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c
index 67066f18c..33f63e536 100644
--- a/src/smf/n4-handler.c
+++ b/src/smf/n4-handler.c
@@ -141,7 +141,8 @@ static int sbi_status_from_pfcp(uint8_t pfcp_cause)
return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
}
-/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success, other cause value on failure */
+/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success,
+ * other cause value on failure */
uint8_t smf_5gc_n4_handle_session_establishment_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_establishment_response_t *rsp)
@@ -599,29 +600,17 @@ void smf_5gc_n4_handle_session_modification_response(
}
}
-void smf_5gc_n4_handle_session_deletion_response(
- smf_sess_t *sess, ogs_pfcp_xact_t *xact,
+int smf_5gc_n4_handle_session_deletion_response(
+ smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger,
ogs_pfcp_session_deletion_response_t *rsp)
{
int status = 0;
- int trigger;
-
- ogs_sbi_stream_t *stream = NULL;
-
- ogs_sbi_message_t sendmsg;
- ogs_sbi_response_t *response = NULL;
-
- ogs_assert(xact);
- ogs_assert(rsp);
ogs_debug("Session Deletion Response [5gc]");
- stream = xact->assoc_stream;
- trigger = xact->delete_trigger;
+ ogs_assert(rsp);
ogs_assert(trigger);
- ogs_pfcp_xact_commit(xact);
-
status = OGS_SBI_HTTP_STATUS_OK;
if (!sess) {
@@ -662,59 +651,16 @@ void smf_5gc_n4_handle_session_deletion_response(
ogs_error("%s", strerror);
ogs_free(strerror);
- return;
+ return status;
}
ogs_assert(sess);
- if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) {
- ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
-
- n1smbuf = gsm_build_pdu_session_release_command(
- sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
- ogs_assert(n1smbuf);
-
- n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
- sess, SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED,
- NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
- ogs_assert(n2smbuf);
-
- ogs_assert(stream);
- smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
- n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD, n2smbuf);
- } else if (trigger == OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
- trigger == OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
- memset(&sendmsg, 0, sizeof(sendmsg));
-
- response = ogs_sbi_build_response(
- &sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
- ogs_assert(response);
-
- ogs_assert(stream);
- ogs_assert(true == ogs_sbi_server_send_response(stream, response));
-
- 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;
-
- memset(¶m, 0, sizeof(param));
- param.state = SMF_NETWORK_REQUESTED_PDU_SESSION_RELEASE;
- param.n2smbuf =
- ngap_build_pdu_session_resource_release_command_transfer(
- sess, SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED,
- NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
- ogs_assert(param.n2smbuf);
-
- param.skip_ind = true;
-
- smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m);
- } else {
- ogs_fatal("Unknown trigger [%d]", trigger);
- ogs_assert_if_reached();
- }
+ return status;
}
-/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success, other cause value on failure */
+/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success,
+ * other cause value on failure */
uint8_t smf_epc_n4_handle_session_establishment_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_establishment_response_t *rsp)
@@ -1109,7 +1055,8 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
bearer = smf_default_bearer_in_sess(sess);
for (i = 0; i < OGS_ARRAY_SIZE(rsp->usage_report); i++) {
- ogs_pfcp_tlv_usage_report_session_deletion_response_t *use_rep = &rsp->usage_report[i];
+ ogs_pfcp_tlv_usage_report_session_deletion_response_t *use_rep =
+ &rsp->usage_report[i];
uint32_t urr_id;
ogs_pfcp_volume_measurement_t volume;
if (use_rep->presence == 0)
@@ -1119,7 +1066,8 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
urr_id = use_rep->urr_id.u32;
if (!bearer || !bearer->urr || bearer->urr->id != urr_id)
continue;
- ogs_pfcp_parse_volume_measurement(&volume, &use_rep->volume_measurement);
+ ogs_pfcp_parse_volume_measurement(
+ &volume, &use_rep->volume_measurement);
if (volume.ulvol)
sess->gy.ul_octets += volume.uplink_volume;
if (volume.dlvol)
@@ -1270,7 +1218,8 @@ void smf_n4_handle_session_report_request(
if (report_type.usage_report) {
bearer = smf_default_bearer_in_sess(sess);
for (i = 0; i < OGS_ARRAY_SIZE(pfcp_req->usage_report); i++) {
- ogs_pfcp_tlv_usage_report_session_report_request_t *use_rep = &pfcp_req->usage_report[i];
+ ogs_pfcp_tlv_usage_report_session_report_request_t *use_rep =
+ &pfcp_req->usage_report[i];
uint32_t urr_id;
ogs_pfcp_volume_measurement_t volume;
if (use_rep->presence == 0)
@@ -1280,7 +1229,8 @@ void smf_n4_handle_session_report_request(
urr_id = use_rep->urr_id.u32;
if (!bearer || !bearer->urr || bearer->urr->id != urr_id)
continue;
- ogs_pfcp_parse_volume_measurement(&volume, &use_rep->volume_measurement);
+ ogs_pfcp_parse_volume_measurement(
+ &volume, &use_rep->volume_measurement);
if (volume.ulvol)
sess->gy.ul_octets += volume.uplink_volume;
if (volume.dlvol)
@@ -1289,7 +1239,8 @@ void smf_n4_handle_session_report_request(
}
switch(smf_use_gy_iface()) {
case 1:
- smf_gy_send_ccr(sess, pfcp_xact, OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST);
+ smf_gy_send_ccr(sess, pfcp_xact,
+ OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST);
break;
case -1:
ogs_error("No Gy Diameter Peer");
diff --git a/src/smf/n4-handler.h b/src/smf/n4-handler.h
index 00b53009b..40c38c70a 100644
--- a/src/smf/n4-handler.h
+++ b/src/smf/n4-handler.h
@@ -32,8 +32,8 @@ uint8_t smf_5gc_n4_handle_session_establishment_response(
void smf_5gc_n4_handle_session_modification_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_modification_response_t *rsp);
-void smf_5gc_n4_handle_session_deletion_response(
- smf_sess_t *sess, ogs_pfcp_xact_t *xact,
+int smf_5gc_n4_handle_session_deletion_response(
+ smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger,
ogs_pfcp_session_deletion_response_t *rsp);
uint8_t smf_epc_n4_handle_session_establishment_response(
diff --git a/src/smf/npcf-handler.c b/src/smf/npcf-handler.c
index 7a7849724..8258edaa1 100644
--- a/src/smf/npcf-handler.c
+++ b/src/smf/npcf-handler.c
@@ -590,20 +590,6 @@ cleanup:
return false;
}
-bool smf_npcf_smpolicycontrol_handle_delete(
- smf_sess_t *sess, ogs_sbi_stream_t *stream, int state,
- ogs_sbi_message_t *recvmsg)
-{
- int trigger = state;
-
- ogs_assert(trigger);
-
- ogs_assert(OGS_OK ==
- smf_5gc_pfcp_send_session_deletion_request(sess, stream, trigger));
-
- return true;
-}
-
bool smf_npcf_smpolicycontrol_handle_update_notify(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
diff --git a/src/smf/npcf-handler.h b/src/smf/npcf-handler.h
index babe698b1..d9426ebee 100644
--- a/src/smf/npcf-handler.h
+++ b/src/smf/npcf-handler.h
@@ -29,9 +29,6 @@ extern "C" {
bool smf_npcf_smpolicycontrol_handle_create(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int state,
ogs_sbi_message_t *recvmsg);
-bool smf_npcf_smpolicycontrol_handle_delete(
- smf_sess_t *sess, ogs_sbi_stream_t *stream, int state,
- ogs_sbi_message_t *recvmsg);
bool smf_npcf_smpolicycontrol_handle_update_notify(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
bool smf_npcf_smpolicycontrol_handle_terminate_notify(
diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c
index e42ae0fba..297ef6dcf 100644
--- a/src/smf/smf-sm.c
+++ b/src/smf/smf-sm.c
@@ -245,7 +245,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
sess, gtp_xact, >p1_message.update_pdp_context_request);
break;
case OGS_GTP1_ERROR_INDICATION_TYPE:
- /* TS 29.060 10.1.1.4 dst port shall be the user plane port (2152) */
+ /* TS 29.060 10.1.1.4 dst port shall be the userplane port (2152) */
ogs_error("Rx unexpected Error Indication in GTPC port");
break;
default:
@@ -514,10 +514,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
e->sess = sess;
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&sess->sm, e);
- if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
- ogs_error("[%s] State machine exception", smf_ue->supi);
- SMF_SESS_CLEAR(sess);
- }
}
break;
@@ -743,10 +739,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&sess->sm, e);
- if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
- ogs_error("[%s] State machine exception", smf_ue->supi);
- SMF_SESS_CLEAR(sess);
- }
break;
DEFAULT
@@ -830,22 +822,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(sess);
ogs_assert(OGS_FSM_STATE(&sess->sm));
- sess->pti = nas_message.gsm.h.procedure_transaction_identity;
-
- switch (nas_message.gsm.h.message_type) {
- case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE:
- ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
- ogs_assert(true == smf_sbi_send_sm_context_status_notify(sess));
- SMF_SESS_CLEAR(sess);
- break;
- default:
- e->nas.message = &nas_message;
- ogs_fsm_dispatch(&sess->sm, e);
- if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
- ogs_error("State machine exception");
- SMF_SESS_CLEAR(sess);
- }
- }
+ e->nas.message = &nas_message;
+ ogs_fsm_dispatch(&sess->sm, e);
ogs_pkbuf_free(pkbuf);
break;
@@ -863,10 +841,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(OGS_FSM_STATE(&sess->sm));
ogs_fsm_dispatch(&sess->sm, e);
- if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
- ogs_error("State machine exception");
- SMF_SESS_CLEAR(sess);
- }
ogs_pkbuf_free(pkbuf);
break;
diff --git a/src/smf/smf-sm.h b/src/smf/smf-sm.h
index a580bd9c7..68dffdd7a 100644
--- a/src/smf/smf-sm.h
+++ b/src/smf/smf-sm.h
@@ -43,11 +43,13 @@ 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_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e);
+void smf_gsm_state_wait_5gc_sm_policy_association(ogs_fsm_t *s, smf_event_t *e);
+void smf_gsm_state_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_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e);
+void smf_gsm_state_wait_epc_auth_release(ogs_fsm_t *s, smf_event_t *e);
+void smf_gsm_state_wait_5gc_n1_n2_release(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);
diff --git a/src/upf/rule-match.h b/src/upf/rule-match.h
index 3a40d6cf2..c920338ce 100644
--- a/src/upf/rule-match.h
+++ b/src/upf/rule-match.h
@@ -27,8 +27,6 @@ extern "C" {
#endif
upf_sess_t *upf_sess_find_by_ue_ip_address(ogs_pkbuf_t *pkbuf);
-ogs_pfcp_rule_t *upf_pdr_rule_find_by_packet(
- ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *pkbuf);
#ifdef __cplusplus
}