[SMF] Inegrate session setup cycle into sess->sm (#1489)

It allows for much better control on the lifecycle of the session, and
already shows some missing tear down paths in case of errors.
It also clarifies the existence of "sess" pointer in several paths.

The code also becomes clearer overall, since all the transitions and
logic to send next messages are put together.

Tear down of the session will be integrated into gsm-sm in a follow-up
patch.

The 5gc session setup is only partially moved to gsm-sm, and left as an
exercise for users wishin to improve 5gc support.
This commit is contained in:
Pau Espin 2022-04-14 03:30:58 +02:00 committed by GitHub
parent e3da7c9934
commit e61b469489
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 432 additions and 336 deletions

View File

@ -21,6 +21,7 @@
#define SMF_EVENT_H
#include "ogs-core.h"
#include "ogs-gtp.h"
#ifdef __cplusplus
extern "C" {
@ -81,6 +82,11 @@ typedef struct smf_event_s {
ogs_pfcp_xact_t *pfcp_xact;
ogs_pfcp_message_t *pfcp_message;
union {
ogs_gtp1_message_t *gtp1_message;
ogs_gtp2_message_t *gtp2_message;
};
union {
ogs_diam_gx_message_t *gx_message;
ogs_diam_gy_message_t *gy_message;

View File

@ -46,7 +46,7 @@ void smf_gn_handle_echo_response(
/* Not Implemented */
}
void smf_gn_handle_create_pdp_context_request(
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)
{
@ -65,6 +65,7 @@ void smf_gn_handle_create_pdp_context_request(
ogs_gtp1_qos_profile_decoded_t qos_pdec;
uint8_t qci = 9;
ogs_assert(sess);
ogs_assert(xact);
ogs_assert(req);
@ -101,23 +102,14 @@ void smf_gn_handle_create_pdp_context_request(
cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_error("No Context");
cause_value = OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND;
} 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 (!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_CREATE_PDP_CONTEXT_RESPONSE_TYPE, cause_value);
return;
}
if (cause_value != OGS_GTP1_CAUSE_REQUEST_ACCEPTED)
return cause_value;
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
@ -133,12 +125,9 @@ void smf_gn_handle_create_pdp_context_request(
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (ogs_gtp1_parse_uli(&uli, &req->user_location_information) == 0) {
ogs_gtp1_send_error_message(xact, sess->sgw_s5c_teid,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT);
return;
}
if (ogs_gtp1_parse_uli(&uli, &req->user_location_information) == 0)
return OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT;
/* TODO: Copy uli->cgi/sai/rai into sess-> */
switch (uli.geo_loc_type) {
case OGS_GTP1_GEO_LOC_TYPE_CGI:
@ -155,12 +144,8 @@ void smf_gn_handle_create_pdp_context_request(
/* Set Bearer QoS */
rv = ogs_gtp1_parse_qos_profile(&qos_pdec,
&req->quality_of_service_profile);
if(rv < 0) {
ogs_gtp1_send_error_message(xact, sess->sgw_s5c_teid,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT);
return;
}
if(rv < 0)
return OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT;
/* 3GPP TS 23.060 section 9.2.1A: "The QoS profiles of the PDP context and EPS bearer are mapped as specified in TS 23.401"
* 3GPP TS 23.401 Annex E: "Mapping between EPS and Release 99 QoS parameters"
@ -205,12 +190,9 @@ void smf_gn_handle_create_pdp_context_request(
ogs_assert(eua);
rv = ogs_gtp1_eua_to_ip(eua, req->end_user_address.len, &sess->session.ue_ip,
&sess->ue_session_type);
if(rv != OGS_OK) {
ogs_gtp1_send_error_message(xact, sess->sgw_s5c_teid,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT);
return;
}
if(rv != OGS_OK)
return OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT;
/* Initially Set Session Type from UE */
sess->session.session_type = sess->ue_session_type;
@ -240,19 +222,12 @@ void smf_gn_handle_create_pdp_context_request(
/* Check if selected PGW is associated with SMF */
ogs_assert(sess->pfcp_node);
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) {
ogs_gtp1_send_error_message(xact, sess->sgw_s5c_teid,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE);
return;
}
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated))
return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
if ((pfcp_cause = smf_sess_set_ue_ip(sess)) != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
cause_value = gtp_cause_from_pfcp(pfcp_cause, 1);
ogs_gtp1_send_error_message(xact, sess->sgw_s5c_teid,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
cause_value);
return;
return cause_value;
}
ogs_info("UE IMSI[%s] APN[%s] IPv4[%s] IPv6[%s]",
@ -261,8 +236,7 @@ void smf_gn_handle_create_pdp_context_request(
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
smf_gx_send_ccr(sess, xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
return cause_value;
}
void smf_gn_handle_delete_pdp_context_request(

View File

@ -32,7 +32,7 @@ void smf_gn_handle_echo_request(
void smf_gn_handle_echo_response(
ogs_gtp_xact_t *xact, ogs_gtp1_echo_response_t *req);
void smf_gn_handle_create_pdp_context_request(
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(

View File

@ -17,7 +17,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "binding.h"
#include "sbi-path.h"
#include "gn-handler.h"
#include "gx-handler.h"
#include "gy-handler.h"
#include "n4-handler.h"
#include "s5c-handler.h"
#include "nnrf-handler.h"
#include "nsmf-handler.h"
#include "nudm-handler.h"
@ -25,18 +31,262 @@
#include "namf-handler.h"
#include "gsm-handler.h"
#include "ngap-handler.h"
#include "gtp-path.h"
#include "pfcp-path.h"
#include "ngap-path.h"
#include "fd-path.h"
static uint8_t gtp_cause_from_diameter(uint8_t gtp_version,
const uint32_t dia_err, const uint32_t *dia_exp_err)
{
switch (gtp_version) {
case 1:
switch (dia_err) {
case OGS_DIAM_UNKNOWN_SESSION_ID:
return OGS_GTP1_CAUSE_APN_ACCESS_DENIED;
}
break;
case 2:
switch (dia_err) {
case OGS_DIAM_UNKNOWN_SESSION_ID:
return OGS_GTP2_CAUSE_APN_ACCESS_DENIED_NO_SUBSCRIPTION;
}
break;
}
ogs_error("Unexpected Diameter Result Code %d/%d, defaulting to severe "
"network failure",
dia_err, dia_exp_err ? *dia_exp_err : -1);
switch (gtp_version) {
case 1:
return OGS_GTP1_CAUSE_USER_AUTHENTICATION_FAILED;
case 2:
default:
return OGS_GTP2_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER;
}
}
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,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE, gtp_cause);
else
ogs_gtp2_send_error_message(gtp_xact, sess->sgw_s5c_teid,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, gtp_cause);
}
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;
uint8_t gtp1_cause, gtp2_cause;
OGS_FSM_TRAN(s, &smf_gsm_state_operational);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (!sess->gtp_rat_type) /* 5gc */
OGS_FSM_TRAN(s, &smf_gsm_state_operational);
break;
case SMF_EVT_GN_MESSAGE:
switch(e->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,
&e->gtp1_message->create_pdp_context_request);
if (gtp1_cause != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) {
send_gtp_create_err_msg(sess, e->gtp_xact, gtp1_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_auth);
smf_gx_send_ccr(sess, e->gtp_xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
}
break;
case SMF_EVT_S5C_MESSAGE:
switch(e->gtp2_message->h.type) {
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
gtp2_cause = smf_s5c_handle_create_session_request(sess,
e->gtp_xact,
&e->gtp2_message->create_session_request);
if (gtp2_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
send_gtp_create_err_msg(sess, e->gtp_xact, gtp2_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_auth);
switch (sess->gtp_rat_type) {
case OGS_GTP2_RAT_TYPE_EUTRAN:
smf_gx_send_ccr(sess, e->gtp_xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
break;
case OGS_GTP2_RAT_TYPE_WLAN:
smf_s6b_send_aar(sess, e->gtp_xact);
break;
default:
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
ogs_assert_if_reached();
}
break;
}
break;
}
}
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)
{
ogs_assert(e && e->sess);
smf_sess_t *sess = e->sess;
uint32_t diam_err;
uint8_t gtp_cause;
switch (e->id) {
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_INITIAL_REQUEST:
ogs_assert(e->gtp_xact);
diam_err = smf_gx_handle_cca_initial_request(sess,
e->gx_message, e->gtp_xact);
if (diam_err != ER_DIAMETER_SUCCESS) {
uint8_t gtp_cause = gtp_cause_from_diameter(
e->gtp_xact->gtp_version,
diam_err, e->gx_message->exp_err);
send_gtp_create_err_msg(sess, e->gtp_xact, gtp_cause);
return;
}
switch(smf_use_gy_iface()) {
case 1:
/* Gy is available, set up session for the bearer before accepting it towards the UE */
/* OGS_FSM_TRAN: keep current state, we handle Gy here. */
smf_gy_send_ccr(sess, e->gtp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST);
return;
case 0:
/* Not using Gy, jump directly to PFCP Session Establishment Request */
OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_pfcp_establishment);
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_establishment_request(sess, e->gtp_xact));
return;
case -1:
ogs_error("No Gy Diameter Peer");
/* TODO: drop Gx connection here, possibly move to another "releasing" state! */
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_create_err_msg(sess, e->gtp_xact, gtp_cause);
return;
}
break;
}
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_INITIAL_REQUEST:
ogs_assert(e->gtp_xact);
diam_err = smf_gy_handle_cca_initial_request(sess,
e->gy_message, e->gtp_xact);
if (diam_err != ER_DIAMETER_SUCCESS) {
/* FIXME: tear down Gx session */
gtp_cause = gtp_cause_from_diameter(e->gtp_xact->gtp_version,
diam_err, e->gy_message->exp_err);
send_gtp_create_err_msg(sess, e->gtp_xact, gtp_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_initial_wait_pfcp_establishment);
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_establishment_request(sess, e->gtp_xact));
return;
}
break;
}
break;
}
}
void smf_gsm_state_initial_wait_pfcp_establishment(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;
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_gtp_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(sess->smf_ue);
smf_sess_t *eutran_sess = smf_sess_find_by_apn(
sess->smf_ue, sess->session.name, OGS_GTP2_RAT_TYPE_EUTRAN);
if (eutran_sess) {
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_modification_request(
eutran_sess, NULL,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
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(&param, 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, &param);
#endif
}
OGS_FSM_TRAN(s, &smf_gsm_state_operational);
break;
}
break;
}
}
void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
@ -52,6 +302,9 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
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;
int state = 0;
ogs_assert(s);
@ -69,6 +322,30 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
case OGS_FSM_EXIT_SIG:
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(&param, 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, &param);
break;
}
break;
case SMF_EVT_SBI_SERVER:
sbi_message = e->sbi.message;
ogs_assert(sbi_message);
@ -495,3 +772,7 @@ void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e)
break;
}
}
void smf_gsm_state_final(ogs_fsm_t *s, smf_event_t *e)
{
}

View File

@ -25,25 +25,8 @@
#include "gx-handler.h"
#include "binding.h"
static uint8_t gtp_cause_from_diameter(
const uint32_t *dia_err, const uint32_t *dia_exp_err)
{
if (dia_exp_err) {
}
if (dia_err) {
switch (*dia_err) {
case OGS_DIAM_UNKNOWN_SESSION_ID:
return OGS_GTP2_CAUSE_APN_ACCESS_DENIED_NO_SUBSCRIPTION;
}
}
ogs_error("Unexpected Diameter Result Code %d/%d, defaulting to severe "
"network failure",
dia_err ? *dia_err : -1, dia_exp_err ? *dia_exp_err : -1);
return OGS_GTP2_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER;
}
void smf_gx_handle_cca_initial_request(
/* Returns ER_DIAMETER_SUCCESS on success, Diameter error code on failue. */
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)
{
@ -68,18 +51,10 @@ void smf_gx_handle_cca_initial_request(
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (gx_message->result_code != ER_DIAMETER_SUCCESS) {
uint8_t cause_value = gtp_cause_from_diameter(
gx_message->err, gx_message->exp_err);
if (gx_message->result_code != ER_DIAMETER_SUCCESS)
return gx_message->err ? *gx_message->err :
ER_DIAMETER_AUTHENTICATION_REJECTED;
if (gtp_xact->gtp_version == 1)
ogs_gtp1_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE, cause_value);
else
ogs_gtp2_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
return;
}
sess->policy.num_of_pcc_rule = gx_message->session_data.num_of_pcc_rule;
for (i = 0; i < gx_message->session_data.num_of_pcc_rule; i++)
@ -272,30 +247,7 @@ void smf_gx_handle_cca_initial_request(
ogs_pfcp_pdr_associate_qer(dl_pdr, qer);
ogs_pfcp_pdr_associate_qer(ul_pdr, qer);
}
switch(smf_use_gy_iface()) {
case 1:
/* Gy is available, set up session for the bearer before accepting it towards the UE */
smf_gy_send_ccr(sess, gtp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST);
return;
case 0:
/* Not using Gy, jump directly to PFCP Session Establishment Request */
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_establishment_request(sess, gtp_xact));
return;
case -1:
ogs_error("No Gy Diameter Peer");
if (gtp_xact->gtp_version == 1)
ogs_gtp1_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE);
else
ogs_gtp2_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER);
return;
}
return ER_DIAMETER_SUCCESS;
}
void smf_gx_handle_cca_termination_request(

View File

@ -26,7 +26,7 @@
extern "C" {
#endif
void smf_gx_handle_cca_initial_request(
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(

View File

@ -24,24 +24,6 @@
#include "gy-handler.h"
#include "binding.h"
static uint8_t gtp_cause_from_diameter(
const uint32_t *dia_err, const uint32_t *dia_exp_err)
{
if (dia_exp_err) {
}
if (dia_err) {
switch (*dia_err) {
case OGS_DIAM_UNKNOWN_SESSION_ID:
return OGS_GTP2_CAUSE_APN_ACCESS_DENIED_NO_SUBSCRIPTION;
}
}
ogs_error("Unexpected Diameter Result Code %d/%d, defaulting to severe "
"network failure",
dia_err ? *dia_err : -1, dia_exp_err ? *dia_exp_err : -1);
return OGS_GTP2_CAUSE_UE_NOT_AUTHORISED_BY_OCS_OR_EXTERNAL_AAA_SERVER;
}
static void urr_enable_total_volume_threshold(smf_sess_t *sess, ogs_pfcp_urr_t *urr,
uint64_t total_volume_threshold)
{
@ -96,7 +78,8 @@ static void urr_update_time_threshold(ogs_pfcp_urr_t *urr, ogs_diam_gy_message_t
}
}
void smf_gy_handle_cca_initial_request(
/* Returns ER_DIAMETER_SUCCESS on success, Diameter error code on failue. */
uint32_t smf_gy_handle_cca_initial_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_gtp_xact_t *gtp_xact)
{
@ -110,18 +93,9 @@ void smf_gy_handle_cca_initial_request(
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (gy_message->result_code != ER_DIAMETER_SUCCESS) {
uint8_t cause_value = gtp_cause_from_diameter(
gy_message->err, gy_message->exp_err);
if (gtp_xact->gtp_version == 1)
ogs_gtp1_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE, cause_value);
else
ogs_gtp2_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
return;
}
if (gy_message->result_code != ER_DIAMETER_SUCCESS)
return gy_message->err ? *gy_message->err :
ER_DIAMETER_AUTHENTICATION_REJECTED;
bearer = smf_default_bearer_in_sess(sess);
ogs_assert(bearer);
@ -137,9 +111,7 @@ void smf_gy_handle_cca_initial_request(
/* Associate acconting URR each direction PDR: */
ogs_pfcp_pdr_associate_urr(bearer->ul_pdr, bearer->urr);
ogs_pfcp_pdr_associate_urr(bearer->dl_pdr, bearer->urr);
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_establishment_request(sess, gtp_xact));
return ER_DIAMETER_SUCCESS;
}
void smf_gy_handle_cca_update_request(

View File

@ -27,7 +27,7 @@
extern "C" {
#endif
void smf_gy_handle_cca_initial_request(
uint32_t smf_gy_handle_cca_initial_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_gtp_xact_t *gtp_xact);
void smf_gy_handle_cca_update_request(

View File

@ -141,20 +141,21 @@ static int sbi_status_from_pfcp(uint8_t pfcp_cause)
return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
}
void smf_5gc_n4_handle_session_establishment_response(
/* 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)
{
int i;
smf_n1_n2_message_transfer_param_t param;
ogs_sbi_stream_t *stream = NULL;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t offending_ie_value = 0;
ogs_pfcp_f_seid_t *up_f_seid = NULL;
ogs_assert(sess);
ogs_assert(xact);
ogs_assert(rsp);
@ -165,41 +166,36 @@ void smf_5gc_n4_handle_session_establishment_response(
ogs_pfcp_xact_commit(xact);
if (!sess) {
ogs_warn("No Context");
return;
}
if (rsp->up_f_seid.presence == 0) {
ogs_error("No UP F-SEID");
return;
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->created_pdr[0].presence == 0) {
ogs_error("No Created PDR");
return;
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
return;
cause_value = rsp->cause.u8;
}
} else {
ogs_error("No Cause");
return;
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
ogs_assert(sess);
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
return cause_value;
pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_far_t *far = NULL;
pdr = ogs_pfcp_handle_created_pdr(
&sess->pfcp, &rsp->created_pdr[i],
&pfcp_cause_value, &offending_ie_value);
&cause_value, &offending_ie_value);
if (!pdr)
break;
@ -230,14 +226,14 @@ void smf_5gc_n4_handle_session_establishment_response(
}
}
if (pfcp_cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause [%d] : Not Accepted", pfcp_cause_value);
return;
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause [%d] : Not Accepted", cause_value);
return cause_value;
}
if (sess->upf_n3_addr == NULL && sess->upf_n3_addr6 == NULL) {
ogs_error("No UP F-TEID");
return;
return OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
/* UP F-SEID */
@ -245,15 +241,7 @@ void smf_5gc_n4_handle_session_establishment_response(
ogs_assert(up_f_seid);
sess->upf_n4_seid = be64toh(up_f_seid->seid);
memset(&param, 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, &param);
return OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
}
void smf_5gc_n4_handle_session_modification_response(
@ -723,18 +711,19 @@ void smf_5gc_n4_handle_session_deletion_response(
}
}
void smf_epc_n4_handle_session_establishment_response(
/* 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)
{
uint8_t cause_value = 0;
uint8_t resp_type = 0;
uint8_t cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
smf_bearer_t *bearer = NULL;
ogs_gtp_xact_t *gtp_xact = NULL;
ogs_pfcp_f_seid_t *up_f_seid = NULL;
ogs_assert(sess);
ogs_assert(xact);
ogs_assert(rsp);
@ -745,62 +734,37 @@ void smf_epc_n4_handle_session_establishment_response(
ogs_pfcp_xact_commit(xact);
if (gtp_xact->gtp_version == 1) {
cause_value = OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
resp_type = OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE;
} else {
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
resp_type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
}
if (!sess) {
ogs_warn("No Context");
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND :
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->up_f_seid.presence == 0) {
ogs_error("No UP F-SEID");
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->created_pdr[0].presence == 0) {
ogs_error("No Created PDR");
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
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_xact->gtp_version);
cause_value = rsp->cause.u8;
}
} else {
ogs_error("No Cause");
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
if ((gtp_xact->gtp_version == 1 && cause_value == OGS_GTP1_CAUSE_REQUEST_ACCEPTED) ||
(gtp_xact->gtp_version == 2 && cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED)) {
if (cause_value == OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
int i;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t offending_ie_value = 0;
ogs_assert(sess);
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_far_t *far = NULL;
pdr = ogs_pfcp_handle_created_pdr(
&sess->pfcp, &rsp->created_pdr[i],
&pfcp_cause_value, &offending_ie_value);
&cause_value, &offending_ie_value);
if (!pdr)
break;
@ -836,74 +800,25 @@ void smf_epc_n4_handle_session_establishment_response(
ogs_assert(OGS_ERROR != ogs_pfcp_setup_pdr_gtpu_node(pdr));
}
}
cause_value = gtp_cause_from_pfcp(pfcp_cause_value, gtp_xact->gtp_version);
}
if ((gtp_xact->gtp_version == 1 && cause_value != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) ||
(gtp_xact->gtp_version == 2 && cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)) {
ogs_gtp_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
resp_type, cause_value);
return;
}
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
return cause_value;
ogs_assert(sess);
bearer = smf_default_bearer_in_sess(sess);
ogs_assert(bearer);
if (bearer->pgw_s5u_addr == NULL && bearer->pgw_s5u_addr6 == NULL) {
ogs_error("No UP F-TEID");
ogs_gtp_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
resp_type,
(gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND : OGS_GTP2_CAUSE_GRE_KEY_NOT_FOUND);
return;
return OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
/* UP F-SEID */
up_f_seid = rsp->up_f_seid.data;
ogs_assert(up_f_seid);
sess->upf_n4_seid = be64toh(up_f_seid->seid);
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_gtp_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).
*/
smf_ue_t *smf_ue = NULL;
smf_sess_t *eutran_sess = NULL;
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
eutran_sess = smf_sess_find_by_apn(
smf_ue, sess->session.name, OGS_GTP2_RAT_TYPE_EUTRAN);
if (eutran_sess) {
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_modification_request(
eutran_sess, NULL,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_GTP2_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP));
}
}
smf_bearer_binding(sess);
return OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
}
void smf_epc_n4_handle_session_modification_response(

View File

@ -26,7 +26,7 @@
extern "C" {
#endif
void smf_5gc_n4_handle_session_establishment_response(
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);
void smf_5gc_n4_handle_session_modification_response(
@ -36,7 +36,7 @@ void smf_5gc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp);
void smf_epc_n4_handle_session_establishment_response(
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);
void smf_epc_n4_handle_session_modification_response(

View File

@ -187,6 +187,8 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
if (message->h.seid_presence && message->h.seid != 0)
sess = smf_sess_find_by_seid(message->h.seid);
if (sess)
e->sess = sess;
switch (message->h.type) {
case OGS_PFCP_HEARTBEAT_REQUEST_TYPE:
@ -210,17 +212,22 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
&message->pfcp_association_setup_response);
break;
case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE:
if (!message->h.seid_presence) {
if (!message->h.seid_presence)
ogs_error("No SEID");
break;
if (!sess) {
ogs_gtp_xact_t *gtp_xact = xact->assoc_xact;
ogs_assert(gtp_xact);
if (gtp_xact->gtp_version == 1)
ogs_gtp1_send_error_message(gtp_xact, 0,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
else
ogs_gtp2_send_error_message(gtp_xact, 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
return;
}
if (xact->epc)
smf_epc_n4_handle_session_establishment_response(
sess, xact, &message->pfcp_session_establishment_response);
else
smf_5gc_n4_handle_session_establishment_response(
sess, xact, &message->pfcp_session_establishment_response);
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE:

View File

@ -45,7 +45,7 @@ void smf_s5c_handle_echo_response(
/* Not Implemented */
}
void smf_s5c_handle_create_session_request(
uint8_t smf_s5c_handle_create_session_request(
smf_sess_t *sess, ogs_gtp_xact_t *xact,
ogs_gtp2_create_session_request_t *req)
{
@ -66,6 +66,7 @@ void smf_s5c_handle_create_session_request(
ogs_gtp2_ambr_t *ambr = NULL;
uint16_t decoded = 0;
ogs_assert(sess);
ogs_assert(xact);
ogs_assert(req);
@ -111,50 +112,41 @@ void smf_s5c_handle_create_session_request(
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_error("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;
}
switch (sess->gtp_rat_type) {
case OGS_GTP2_RAT_TYPE_EUTRAN:
if (req->bearer_contexts_to_be_created.
s5_s8_u_sgw_f_teid.presence == 0) {
ogs_error("No S5/S8 SGW GTP-U TEID");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (req->user_location_information.presence == 0) {
ogs_error("No UE Location Information");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
break;
case 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 (req->bearer_contexts_to_be_created.
s2b_u_epdg_f_teid_5.presence == 0) {
ogs_error("No S2b ePDG GTP-U TEID");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
break;
default:
ogs_error("Unknown RAT Type [%d]", req->rat_type.u8);
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;
}
switch (sess->gtp_rat_type) {
case OGS_GTP2_RAT_TYPE_EUTRAN:
if (req->bearer_contexts_to_be_created.
s5_s8_u_sgw_f_teid.presence == 0) {
ogs_error("No S5/S8 SGW GTP-U TEID");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (req->user_location_information.presence == 0) {
ogs_error("No UE Location Information");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
break;
case 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 (req->bearer_contexts_to_be_created.
s2b_u_epdg_f_teid_5.presence == 0) {
ogs_error("No S2b ePDG GTP-U TEID");
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
break;
default:
ogs_error("Unknown RAT Type [%d]", req->rat_type.u8);
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
return;
}
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
return cause_value;
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
@ -184,10 +176,7 @@ void smf_s5c_handle_create_session_request(
if (eutran_session_count < 1) {
ogs_error("Cannot handover to WLAN");
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_MULTIPLE_ACCESSES_TO_A_PDN_CONNECTION_NOT_ALLOWED);
return;
return OGS_GTP2_CAUSE_MULTIPLE_ACCESSES_TO_A_PDN_CONNECTION_NOT_ALLOWED;
}
}
}
@ -200,12 +189,8 @@ void smf_s5c_handle_create_session_request(
/* Check if selected PGW is associated with SMF */
ogs_assert(sess->pfcp_node);
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) {
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING);
return;
}
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated))
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
/* UE IP Address */
paa = req->pdn_address_allocation.data;
@ -316,18 +301,7 @@ void smf_s5c_handle_create_session_request(
OGS_TLV_STORE_DATA(&sess->gtp.ue_timezone, &req->ue_time_zone);
}
switch (sess->gtp_rat_type) {
case OGS_GTP2_RAT_TYPE_EUTRAN:
smf_gx_send_ccr(sess, xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
break;
case OGS_GTP2_RAT_TYPE_WLAN:
smf_s6b_send_aar(sess, xact);
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_delete_session_request(

View File

@ -31,7 +31,7 @@ void smf_s5c_handle_echo_request(
void smf_s5c_handle_echo_response(
ogs_gtp_xact_t *xact, ogs_gtp2_echo_response_t *req);
void smf_s5c_handle_create_session_request(
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(

View File

@ -100,6 +100,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp2_message = &gtp_message;
if (gtp_message.h.teid != 0) {
sess = smf_sess_find_by_teid(gtp_message.h.teid);
@ -118,6 +119,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp_xact = gtp_xact;
switch(gtp_message.h.type) {
case OGS_GTP2_ECHO_REQUEST_TYPE:
@ -133,8 +135,14 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
if (sess)
OGS_SETUP_GTP_NODE(sess, gnode);
}
smf_s5c_handle_create_session_request(
sess, gtp_xact, &gtp_message.create_session_request);
if (!sess) {
ogs_gtp1_send_error_message(gtp_xact, 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
smf_s5c_handle_delete_session_request(
@ -177,6 +185,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp1_message = &gtp1_message;
if (gtp1_message.h.teid != 0) {
sess = smf_sess_find_by_teid(gtp1_message.h.teid);
@ -195,6 +204,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp_xact = gtp_xact;
switch(gtp1_message.h.type) {
case OGS_GTP1_ECHO_REQUEST_TYPE:
@ -210,8 +220,14 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
if (sess)
OGS_SETUP_GTP_NODE(sess, gnode);
}
smf_gn_handle_create_pdp_context_request(
sess, gtp_xact, &gtp1_message.create_pdp_context_request);
if (!sess) {
ogs_gtp1_send_error_message(gtp_xact, 0,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE:
smf_gn_handle_delete_pdp_context_request(
@ -247,8 +263,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
switch(gx_message->cc_request_type) {
case OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
smf_gx_handle_cca_initial_request(
sess, gx_message, gtp_xact);
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
smf_gx_handle_cca_termination_request(
@ -284,9 +299,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
switch(gy_message->cc_request_type) {
case OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_assert(e->gtp_xact);
smf_gy_handle_cca_initial_request(
sess, gy_message, e->gtp_xact);
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST:
ogs_assert(e->pfcp_xact);

View File

@ -48,6 +48,8 @@ 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);