forked from acouzens/open5gs
Compare commits
2 Commits
9a515e9b1d
...
c06303ec54
Author | SHA1 | Date |
---|---|---|
Pau Espin | c06303ec54 | |
Pau Espin | 5b1edb816a |
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/* 3GPP TS 29.273 section 9
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
|
@ -35,7 +35,8 @@ extern struct dict_object *ogs_diam_s6b_application;
|
||||||
extern struct dict_object *ogs_diam_s6b_mip6_feature_vector;
|
extern struct dict_object *ogs_diam_s6b_mip6_feature_vector;
|
||||||
|
|
||||||
typedef struct ogs_diam_s6b_message_s {
|
typedef struct ogs_diam_s6b_message_s {
|
||||||
#define OGS_DIAM_S6B_CMD_SESSION_TERMINATION 1
|
#define OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION 1
|
||||||
|
#define OGS_DIAM_S6B_CMD_SESSION_TERMINATION 2
|
||||||
uint16_t cmd_code;
|
uint16_t cmd_code;
|
||||||
uint32_t result_code;
|
uint32_t result_code;
|
||||||
uint32_t *err;
|
uint32_t *err;
|
||||||
|
|
|
@ -228,6 +228,8 @@ typedef struct smf_sess_s {
|
||||||
uint32_t gx_cca_init_err; /* Gx CCA RXed error code */
|
uint32_t gx_cca_init_err; /* Gx CCA RXed error code */
|
||||||
bool gy_ccr_init_in_flight; /* Waiting for Gy CCA */
|
bool gy_ccr_init_in_flight; /* Waiting for Gy CCA */
|
||||||
uint32_t gy_cca_init_err; /* Gy CCA RXed error code */
|
uint32_t gy_cca_init_err; /* Gy CCA RXed error code */
|
||||||
|
bool s6b_aar_in_flight; /* Waiting for S6B AAR */
|
||||||
|
uint32_t s6b_aaa_err; /* S6B AAA RXed error code */
|
||||||
bool gx_ccr_term_in_flight; /* Waiting for Gx CCA */
|
bool gx_ccr_term_in_flight; /* Waiting for Gx CCA */
|
||||||
uint32_t gx_cca_term_err; /* Gx CCA RXed error code */
|
uint32_t gx_cca_term_err; /* Gx CCA RXed error code */
|
||||||
bool gy_ccr_term_in_flight; /* Waiting for Gy CCA */
|
bool gy_ccr_term_in_flight; /* Waiting for Gy CCA */
|
||||||
|
@ -333,6 +335,7 @@ typedef struct smf_sess_s {
|
||||||
struct {
|
struct {
|
||||||
uint8_t version; /* GTPC version */
|
uint8_t version; /* GTPC version */
|
||||||
ogs_tlv_octet_t ue_pco;
|
ogs_tlv_octet_t ue_pco;
|
||||||
|
ogs_tlv_octet_t ue_apco;
|
||||||
ogs_tlv_octet_t ue_epco;
|
ogs_tlv_octet_t ue_epco;
|
||||||
ogs_tlv_octet_t user_location_information;
|
ogs_tlv_octet_t user_location_information;
|
||||||
ogs_tlv_octet_t ue_timezone;
|
ogs_tlv_octet_t ue_timezone;
|
||||||
|
|
|
@ -182,8 +182,10 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
|
||||||
switch (e->h.id) {
|
switch (e->h.id) {
|
||||||
case OGS_FSM_ENTRY_SIG:
|
case OGS_FSM_ENTRY_SIG:
|
||||||
/* reset state: */
|
/* reset state: */
|
||||||
|
sess->sm_data.s6b_aar_in_flight = false;
|
||||||
sess->sm_data.gx_ccr_init_in_flight = false;
|
sess->sm_data.gx_ccr_init_in_flight = false;
|
||||||
sess->sm_data.gy_ccr_init_in_flight = false;
|
sess->sm_data.gy_ccr_init_in_flight = false;
|
||||||
|
sess->sm_data.s6b_aaa_err = ER_DIAMETER_SUCCESS;
|
||||||
sess->sm_data.gx_cca_init_err = ER_DIAMETER_SUCCESS;
|
sess->sm_data.gx_cca_init_err = ER_DIAMETER_SUCCESS;
|
||||||
sess->sm_data.gy_cca_init_err = ER_DIAMETER_SUCCESS;
|
sess->sm_data.gy_cca_init_err = ER_DIAMETER_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
@ -229,7 +231,9 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
|
||||||
break;
|
break;
|
||||||
case OGS_GTP2_RAT_TYPE_WLAN:
|
case OGS_GTP2_RAT_TYPE_WLAN:
|
||||||
smf_s6b_send_aar(sess, e->gtp_xact);
|
smf_s6b_send_aar(sess, e->gtp_xact);
|
||||||
|
sess->sm_data.s6b_aar_in_flight = true;
|
||||||
OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_initial);
|
OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_initial);
|
||||||
|
/* Gx/Gy Init Req is done after s6b AAR + AAA */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
|
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
|
||||||
|
@ -327,6 +331,7 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
|
||||||
{
|
{
|
||||||
smf_sess_t *sess = NULL;
|
smf_sess_t *sess = NULL;
|
||||||
|
|
||||||
|
ogs_diam_s6b_message_t *s6b_message = NULL;
|
||||||
ogs_diam_gy_message_t *gy_message = NULL;
|
ogs_diam_gy_message_t *gy_message = NULL;
|
||||||
ogs_diam_gx_message_t *gx_message = NULL;
|
ogs_diam_gx_message_t *gx_message = NULL;
|
||||||
uint32_t diam_err;
|
uint32_t diam_err;
|
||||||
|
@ -340,6 +345,22 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
switch (e->h.id) {
|
switch (e->h.id) {
|
||||||
|
case SMF_EVT_S6B_MESSAGE:
|
||||||
|
s6b_message = e->s6b_message;
|
||||||
|
ogs_assert(s6b_message);
|
||||||
|
|
||||||
|
switch(s6b_message->cmd_code) {
|
||||||
|
case OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION:
|
||||||
|
sess->sm_data.s6b_aar_in_flight = false;
|
||||||
|
sess->sm_data.s6b_aaa_err = s6b_message->result_code;
|
||||||
|
if (s6b_message->result_code == ER_DIAMETER_SUCCESS) {
|
||||||
|
send_ccr_init_req_gx_gy(sess, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
goto test_can_proceed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SMF_EVT_GX_MESSAGE:
|
case SMF_EVT_GX_MESSAGE:
|
||||||
gx_message = e->gx_message;
|
gx_message = e->gx_message;
|
||||||
ogs_assert(gx_message);
|
ogs_assert(gx_message);
|
||||||
|
@ -382,9 +403,12 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
|
||||||
|
|
||||||
test_can_proceed:
|
test_can_proceed:
|
||||||
/* First wait for both Gx and Gy requests to be done: */
|
/* First wait for both Gx and Gy requests to be done: */
|
||||||
if (!sess->sm_data.gx_ccr_init_in_flight &&
|
if (!sess->sm_data.s6b_aar_in_flight &&
|
||||||
|
!sess->sm_data.gx_ccr_init_in_flight &&
|
||||||
!sess->sm_data.gy_ccr_init_in_flight) {
|
!sess->sm_data.gy_ccr_init_in_flight) {
|
||||||
diam_err = ER_DIAMETER_SUCCESS;
|
diam_err = ER_DIAMETER_SUCCESS;
|
||||||
|
if (sess->sm_data.s6b_aaa_err != ER_DIAMETER_SUCCESS)
|
||||||
|
diam_err = sess->sm_data.s6b_aaa_err;
|
||||||
if (sess->sm_data.gx_cca_init_err != ER_DIAMETER_SUCCESS)
|
if (sess->sm_data.gx_cca_init_err != ER_DIAMETER_SUCCESS)
|
||||||
diam_err = sess->sm_data.gx_cca_init_err;
|
diam_err = sess->sm_data.gx_cca_init_err;
|
||||||
if (sess->sm_data.gy_cca_init_err != ER_DIAMETER_SUCCESS)
|
if (sess->sm_data.gy_cca_init_err != ER_DIAMETER_SUCCESS)
|
||||||
|
|
|
@ -47,6 +47,8 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
||||||
int len;
|
int len;
|
||||||
uint8_t pco_buf[OGS_MAX_PCO_LEN];
|
uint8_t pco_buf[OGS_MAX_PCO_LEN];
|
||||||
int16_t pco_len;
|
int16_t pco_len;
|
||||||
|
uint8_t apco_buf[OGS_MAX_PCO_LEN];
|
||||||
|
int16_t apco_len;
|
||||||
uint8_t *epco_buf = NULL;
|
uint8_t *epco_buf = NULL;
|
||||||
int16_t epco_len;
|
int16_t epco_len;
|
||||||
|
|
||||||
|
@ -145,6 +147,17 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
||||||
rsp->protocol_configuration_options.len = pco_len;
|
rsp->protocol_configuration_options.len = pco_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* APCO */
|
||||||
|
if (sess->gtp.ue_apco.presence &&
|
||||||
|
sess->gtp.ue_apco.len && sess->gtp.ue_apco.data) {
|
||||||
|
apco_len = smf_pco_build(
|
||||||
|
apco_buf, sess->gtp.ue_apco.data, sess->gtp.ue_apco.len);
|
||||||
|
ogs_assert(apco_len > 0);
|
||||||
|
rsp->additional_protocol_configuration_options.presence = 1;
|
||||||
|
rsp->additional_protocol_configuration_options.data = apco_buf;
|
||||||
|
rsp->additional_protocol_configuration_options.len = apco_len;
|
||||||
|
}
|
||||||
|
|
||||||
/* ePCO */
|
/* ePCO */
|
||||||
if (sess->gtp.ue_epco.presence &&
|
if (sess->gtp.ue_epco.presence &&
|
||||||
sess->gtp.ue_epco.len && sess->gtp.ue_epco.data) {
|
sess->gtp.ue_epco.len && sess->gtp.ue_epco.data) {
|
||||||
|
|
|
@ -378,6 +378,12 @@ uint8_t smf_s5c_handle_create_session_request(
|
||||||
&req->protocol_configuration_options);
|
&req->protocol_configuration_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* APCO */
|
||||||
|
if (req->additional_protocol_configuration_options.presence) {
|
||||||
|
OGS_TLV_STORE_DATA(&sess->gtp.ue_apco,
|
||||||
|
&req->additional_protocol_configuration_options);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set User Location Information */
|
/* Set User Location Information */
|
||||||
if (req->user_location_information.presence) {
|
if (req->user_location_information.presence) {
|
||||||
OGS_TLV_STORE_DATA(&sess->gtp.user_location_information,
|
OGS_TLV_STORE_DATA(&sess->gtp.user_location_information,
|
||||||
|
@ -452,6 +458,8 @@ uint8_t smf_s5c_handle_delete_session_request(
|
||||||
OGS_TLV_CLEAR_DATA(&sess->gtp.ue_pco);
|
OGS_TLV_CLEAR_DATA(&sess->gtp.ue_pco);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* APCO not present in Session deletion procedure, hence no need to clear it here. */
|
||||||
|
|
||||||
if (req->extended_protocol_configuration_options.presence) {
|
if (req->extended_protocol_configuration_options.presence) {
|
||||||
OGS_TLV_STORE_DATA(&sess->gtp.ue_epco,
|
OGS_TLV_STORE_DATA(&sess->gtp.ue_epco,
|
||||||
&req->extended_protocol_configuration_options);
|
&req->extended_protocol_configuration_options);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/* 3GPP TS 29.273 section 9
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
|
@ -344,11 +344,11 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
|
||||||
unsigned long dur;
|
unsigned long dur;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int new;
|
int new;
|
||||||
int result_code = 0;
|
|
||||||
int exp_result_code = 0;
|
|
||||||
|
|
||||||
smf_sess_t *sess = NULL;
|
smf_sess_t *sess = NULL;
|
||||||
ogs_gtp_xact_t *xact = NULL;
|
ogs_gtp_xact_t *xact = NULL;
|
||||||
|
smf_event_t *e = NULL;
|
||||||
|
ogs_diam_s6b_message_t *s6b_message = NULL;
|
||||||
|
|
||||||
ogs_debug("[AA-Answer]");
|
ogs_debug("[AA-Answer]");
|
||||||
|
|
||||||
|
@ -374,15 +374,20 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
|
||||||
xact = sess_data->xact;
|
xact = sess_data->xact;
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
|
|
||||||
|
s6b_message = ogs_calloc(1, sizeof(ogs_diam_s6b_message_t));
|
||||||
|
ogs_assert(s6b_message);
|
||||||
|
/* Set Session Termination Command */
|
||||||
|
s6b_message->cmd_code = OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION;
|
||||||
|
|
||||||
/* Value of Result Code */
|
/* Value of Result Code */
|
||||||
ret = fd_msg_search_avp(*msg, ogs_diam_result_code, &avp);
|
ret = fd_msg_search_avp(*msg, ogs_diam_result_code, &avp);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
if (avp) {
|
if (avp) {
|
||||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
result_code = hdr->avp_value->i32;
|
s6b_message->result_code = hdr->avp_value->i32;
|
||||||
if (result_code != ER_DIAMETER_SUCCESS) {
|
if (s6b_message->result_code != ER_DIAMETER_SUCCESS) {
|
||||||
ogs_error("Result Code: %d", result_code);
|
ogs_error("Result Code: %d", s6b_message->result_code);
|
||||||
error++;
|
error++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -397,8 +402,8 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
|
||||||
if (avpch1) {
|
if (avpch1) {
|
||||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
exp_result_code = hdr->avp_value->i32;
|
s6b_message->result_code = hdr->avp_value->i32;
|
||||||
ogs_error("Experimental Result Code: %d", exp_result_code);
|
ogs_error("Experimental Result Code: %d", s6b_message->result_code);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("no Result-Code");
|
ogs_error("no Result-Code");
|
||||||
|
@ -431,9 +436,22 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
|
||||||
error++;
|
error++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error) {
|
e = smf_event_new(SMF_EVT_S6B_MESSAGE);
|
||||||
smf_gx_send_ccr(sess, xact,
|
ogs_assert(e);
|
||||||
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
|
|
||||||
|
if (error && s6b_message->result_code == ER_DIAMETER_SUCCESS)
|
||||||
|
s6b_message->result_code = error;
|
||||||
|
|
||||||
|
e->sess = sess;
|
||||||
|
e->gtp_xact = xact;
|
||||||
|
e->s6b_message = s6b_message;
|
||||||
|
ret = ogs_queue_push(ogs_app()->queue, e);
|
||||||
|
if (ret != OGS_OK) {
|
||||||
|
ogs_error("ogs_queue_push() failed:%d", (int)ret);
|
||||||
|
ogs_free(s6b_message);
|
||||||
|
ogs_event_free(e);
|
||||||
|
} else {
|
||||||
|
ogs_pollset_notify(ogs_app()->pollset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the message */
|
/* Free the message */
|
||||||
|
|
|
@ -365,6 +365,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
switch(s6b_message->cmd_code) {
|
switch(s6b_message->cmd_code) {
|
||||||
|
case OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION:
|
||||||
case OGS_DIAM_S6B_CMD_SESSION_TERMINATION:
|
case OGS_DIAM_S6B_CMD_SESSION_TERMINATION:
|
||||||
ogs_fsm_dispatch(&sess->sm, e);
|
ogs_fsm_dispatch(&sess->sm, e);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue