Support VoLTE service in ECM-IDLE

This commit is contained in:
Sukchan Lee 2020-11-07 17:27:12 -05:00
parent 2d3b8eed81
commit f1a207fd9b
53 changed files with 2170 additions and 860 deletions

View File

@ -293,7 +293,7 @@ pool:
# nf_instance:
# heartbeat: 10
#
# o Message Wait Duration (Default : 2000ms = 2 seconds)
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:

View File

@ -169,7 +169,7 @@ pool:
# nf_instance:
# heartbeat: 10
#
# o Message Wait Duration (Default : 2000ms = 2 seconds)
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:

View File

@ -398,3 +398,13 @@ pool:
# o usrsctp_udp_port : 9899
#
sctp:
#
# time:
#
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:
# duration: 3000
time:

View File

@ -145,7 +145,7 @@ pool:
# subscription:
# validity: 3600
#
# o Message Wait Duration (Default : 2000ms = 2 seconds)
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:

View File

@ -162,3 +162,13 @@ max:
# big: 8
#
pool:
#
# time:
#
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:
# duration: 3000
time:

View File

@ -153,3 +153,13 @@ max:
# big: 8
#
pool:
#
# time:
#
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:
# duration: 3000
time:

View File

@ -346,7 +346,7 @@ pool:
# nf_instance:
# heartbeat: 10
#
# o Message Wait Duration (Default : 2000ms = 2 seconds)
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:

View File

@ -169,7 +169,7 @@ pool:
# nf_instance:
# heartbeat: 10
#
# o Message Wait Duration (Default : 2000ms = 2 seconds)
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:

View File

@ -171,7 +171,7 @@ pool:
# nf_instance:
# heartbeat: 10
#
# o Message Wait Duration (Default : 2000ms = 2 seconds)
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:

View File

@ -238,3 +238,13 @@ max:
# big: 8
#
pool:
#
# time:
#
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
#
# o Message Wait Duration (3000 ms)
# message:
# duration: 3000
time:

View File

@ -193,8 +193,15 @@ static void app_context_prepare(void)
/* 86400 seconds = 1 day */
self.time.subscription.validity_duration = 86400;
/* Message Wait Duration : 2 seconds */
self.time.message.duration = ogs_time_from_sec(2);
/*
* Message Wait Duration : 10 seconds (Default)
*
* The paging retry timer is 2 seconds and the retry count is 3.
*
* It is recomended to set at least 9 seconds to reflect
* the paging failure result to GTPv2-C or HTTP2(SBI).
*/
self.time.message.duration = ogs_time_from_sec(10);
regenerate_all_timer_duration();
}

View File

@ -155,6 +155,11 @@ ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint32_t sqn)
return xact;
}
ogs_gtp_xact_t *ogs_gtp_xact_cycle(ogs_gtp_xact_t *xact)
{
return ogs_pool_cycle(&pool, xact);
}
void ogs_gtp_xact_delete_all(ogs_gtp_node_t *gnode)
{
ogs_gtp_xact_t *xact = NULL, *next_xact = NULL;

View File

@ -87,12 +87,16 @@ typedef struct ogs_gtp_xact_s {
#define OGS_GTP_MODIFY_QOS_UPDATE ((uint64_t)1<<1)
uint64_t update_flags;
#define OGS_GTP_DELETE_SEND_AUTHENTICATION_REUQEST 1
#define OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST 1
#define OGS_GTP_DELETE_SEND_DETACH_ACCEPT 2
#define OGS_GTP_DELETE_SEND_DEACTIVATE_BEARER_CONTEXT_REQUEST 3
#define OGS_GTP_DELETE_SEND_UE_CONTEXT_RELEASE_COMMAND 4
#define OGS_GTP_DELETE_HANDLE_PDN_CONNECTIVITY_REQUEST 5
int delete_action;
#define OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND 1
#define OGS_GTP_RELEASE_S1_CONTEXT_REMOVE 2
int release_action;
} ogs_gtp_xact_t;
int ogs_gtp_xact_init(void);
@ -103,6 +107,7 @@ ogs_gtp_xact_t *ogs_gtp_xact_local_create(ogs_gtp_node_t *gnode,
void (*cb)(ogs_gtp_xact_t *xact, void *data), void *data);
ogs_gtp_xact_t *ogs_gtp_xact_remote_create(
ogs_gtp_node_t *gnode, uint32_t sqn);
ogs_gtp_xact_t *ogs_gtp_xact_cycle(ogs_gtp_xact_t *xact);
void ogs_gtp_xact_delete_all(ogs_gtp_node_t *gnode);
int ogs_gtp_xact_update_tx(ogs_gtp_xact_t *xact,

View File

@ -153,6 +153,11 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
return xact;
}
ogs_pfcp_xact_t *ogs_pfcp_xact_cycle(ogs_pfcp_xact_t *xact)
{
return ogs_pool_cycle(&pool, xact);
}
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node)
{
ogs_pfcp_xact_t *xact = NULL, *next_xact = NULL;

View File

@ -99,6 +99,7 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
void (*cb)(ogs_pfcp_xact_t *xact, void *data), void *data);
ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
ogs_pfcp_node_t *node, uint32_t sqn);
ogs_pfcp_xact_t *ogs_pfcp_xact_cycle(ogs_pfcp_xact_t *xact);
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node);
int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,

View File

@ -601,8 +601,9 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
gnb = amf_gnb_find_by_addr(addr);
if (gnb) {
ogs_info("gNB-N1[%s] connection refused!!!",
OGS_ADDR(addr, buf));
ogs_info("gNB-N1[%s] connection refused!!!", OGS_ADDR(addr, buf));
amf_sbi_send_deactivate_all_ue_in_gnb(
gnb, AMF_UPDATE_SM_CONTEXT_NG_RESET);
amf_gnb_remove(gnb);
} else {
ogs_warn("gNB-N1[%s] connection refused, Already Removed!",

View File

@ -885,8 +885,6 @@ int amf_gnb_remove(amf_gnb_t *gnb)
ogs_hash_set(self.gnb_addr_hash, gnb->addr, sizeof(ogs_sockaddr_t), NULL);
ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), NULL);
ran_ue_remove_in_gnb(gnb);
if (gnb->sock_type == SOCK_STREAM) {
ogs_pollset_remove(gnb->poll);
ogs_sctp_destroy(gnb->sock);
@ -1001,20 +999,6 @@ void ran_ue_remove(ran_ue_t *ran_ue)
stats_remove_ran_ue();
}
void ran_ue_remove_in_gnb(amf_gnb_t *gnb)
{
ran_ue_t *ran_ue = NULL, *next_ran_ue = NULL;
ran_ue = ran_ue_first_in_gnb(gnb);
while (ran_ue) {
next_ran_ue = ran_ue_next_in_gnb(ran_ue);
ran_ue_remove(ran_ue);
ran_ue = next_ran_ue;
}
}
void ran_ue_switch_to_gnb(ran_ue_t *ran_ue, amf_gnb_t *new_gnb)
{
ogs_assert(ran_ue);
@ -1036,12 +1020,9 @@ ran_ue_t *ran_ue_find_by_ran_ue_ngap_id(
{
ran_ue_t *ran_ue = NULL;
ran_ue = ran_ue_first_in_gnb(gnb);
while (ran_ue) {
ogs_list_for_each(&gnb->ran_ue_list, ran_ue) {
if (ran_ue_ngap_id == ran_ue->ran_ue_ngap_id)
break;
ran_ue = ran_ue_next_in_gnb(ran_ue);
}
return ran_ue;
@ -1058,16 +1039,6 @@ ran_ue_t *ran_ue_find_by_amf_ue_ngap_id(uint64_t amf_ue_ngap_id)
return ran_ue_find(amf_ue_ngap_id);
}
ran_ue_t *ran_ue_first_in_gnb(amf_gnb_t *gnb)
{
return ogs_list_first(&gnb->ran_ue_list);
}
ran_ue_t *ran_ue_next_in_gnb(ran_ue_t *ran_ue)
{
return ogs_list_next(ran_ue);
}
ran_ue_t *ran_ue_cycle(ran_ue_t *ran_ue)
{
return ogs_pool_cycle(&ran_ue_pool, ran_ue);

View File

@ -477,14 +477,11 @@ int amf_gnb_sock_type(ogs_sock_t *sock);
ran_ue_t *ran_ue_add(amf_gnb_t *gnb, uint32_t ran_ue_ngap_id);
void ran_ue_remove(ran_ue_t *ran_ue);
void ran_ue_remove_in_gnb(amf_gnb_t *gnb);
void ran_ue_switch_to_gnb(ran_ue_t *ran_ue, amf_gnb_t *new_gnb);
ran_ue_t *ran_ue_find_by_ran_ue_ngap_id(
amf_gnb_t *gnb, uint32_t ran_ue_ngap_id);
ran_ue_t *ran_ue_find(uint32_t index);
ran_ue_t *ran_ue_find_by_amf_ue_ngap_id(uint64_t amf_ue_ngap_id);
ran_ue_t *ran_ue_first_in_gnb(amf_gnb_t *gnb);
ran_ue_t *ran_ue_next_in_gnb(ran_ue_t *ran_ue);
ran_ue_t *ran_ue_cycle(ran_ue_t *ran_ue);
amf_ue_t *amf_ue_add(ran_ue_t *ran_ue);

View File

@ -907,13 +907,9 @@ void ngap_handle_initial_context_setup_failure(
if (amf_ue) {
old_xact_count = amf_sess_xact_count(amf_ue);
#if 0 /* change buffering instead of deletion */
amf_sbi_send_release_all_sessions(amf_ue,
AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE);
#else
amf_sbi_send_deactivate_all_sessions(
amf_ue, Cause->present, (int)Cause->choice.radioNetwork);
#endif
amf_ue, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
Cause->present, (int)Cause->choice.radioNetwork);
new_xact_count = amf_sess_xact_count(amf_ue);
}
@ -1045,7 +1041,8 @@ void ngap_handle_ue_context_release_request(
if (!PDUSessionList) {
amf_sbi_send_deactivate_all_sessions(
amf_ue, Cause->present, (int)Cause->choice.radioNetwork);
amf_ue, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
Cause->present, (int)Cause->choice.radioNetwork);
} else {
for (i = 0; i < PDUSessionList->list.count; i++) {
PDUSessionItem = (NGAP_PDUSessionResourceItemCxtRelReq_t *)
@ -1072,8 +1069,8 @@ void ngap_handle_ue_context_release_request(
PDUSessionItem->pDUSessionID);
if (SESSION_CONTEXT_IN_SMF(sess)) {
amf_sbi_send_deactivate_session(
sess, Cause->present,
(int)Cause->choice.radioNetwork);
sess, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
Cause->present, (int)Cause->choice.radioNetwork);
}
}
}

View File

@ -318,6 +318,27 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
sess->n1_released = true;
} else if (state == AMF_UPDATE_SM_CONTEXT_NG_RESET) {
/*
* 1. NG RESET
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
* 3. PFCP Session Modifcation Request (Apply:Buff & NOCP)
* 4. PFCP Session Modifcation Response
* 5. NG RESET ACKNOWLEDGE
*/
/* Nothing to do */
if (SESSION_SYNC_DONE(amf_ue)) {
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
if (ran_ue) {
ogs_debug(" SUPI[%s]", amf_ue->supi);
ran_ue_remove(ran_ue);
} else {
ogs_warn("[%s] RAN-NG Context has already been removed",
amf_ue->supi);
}
}
} else {
ogs_error("Invalid STATE[%d]", state);
}
@ -336,7 +357,6 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
amf_nsmf_pdu_session_handle_release_sm_context(
sess, AMF_RELEASE_SM_CONTEXT_NO_STATE);
}
}
} else {
amf_ue_t *amf_ue = NULL;

View File

@ -183,7 +183,7 @@ void amf_sbi_send_activating_session(amf_sess_t *sess)
}
void amf_sbi_send_deactivate_session(
amf_sess_t *sess, int group, int cause)
amf_sess_t *sess, int state, int group, int cause)
{
amf_nsmf_pdu_session_update_sm_context_param_t param;
@ -198,12 +198,11 @@ void amf_sbi_send_deactivate_session(
/* UPDATE_UpCnxState - DEACTIVATED */
amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF,
sess, AMF_UPDATE_SM_CONTEXT_DEACTIVATED, &param,
amf_nsmf_pdu_session_build_update_sm_context);
sess, state, &param, amf_nsmf_pdu_session_build_update_sm_context);
}
void amf_sbi_send_deactivate_all_sessions(
amf_ue_t *amf_ue, int group, int cause)
amf_ue_t *amf_ue, int state, int group, int cause)
{
amf_sess_t *sess = NULL;
@ -211,7 +210,32 @@ void amf_sbi_send_deactivate_all_sessions(
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_deactivate_session(sess, group, cause);
amf_sbi_send_deactivate_session(sess, state, group, cause);
}
}
void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state)
{
amf_ue_t *amf_ue = NULL;
ran_ue_t *ran_ue = NULL, *ran_ue_next;
ogs_list_for_each_safe(&gnb->ran_ue_list, ran_ue_next, ran_ue) {
int old_xact_count = 0, new_xact_count = 0;
amf_ue = ran_ue->amf_ue;
ogs_assert(amf_ue);
old_xact_count = amf_sess_xact_count(amf_ue);
amf_sbi_send_deactivate_all_sessions(
amf_ue, state, NGAP_Cause_PR_radioNetwork,
NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure);
new_xact_count = amf_sess_xact_count(amf_ue);
if (old_xact_count == new_xact_count) {
ran_ue_remove(ran_ue);
}
}
}

View File

@ -43,6 +43,7 @@ void amf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
#define AMF_UPDATE_SM_CONTEXT_SUSPENDED 4
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6
#define AMF_UPDATE_SM_CONTEXT_NG_RESET 7
void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
amf_sess_t *sess, int state, void *data,
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data));
@ -50,9 +51,10 @@ void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
void amf_sbi_send_activating_session(amf_sess_t *sess);
void amf_sbi_send_deactivate_session(
amf_sess_t *sess, int group, int cause);
amf_sess_t *sess, int state, int group, int cause);
void amf_sbi_send_deactivate_all_sessions(
amf_ue_t *amf_ue, int group, int cause);
amf_ue_t *amf_ue, int state, int group, int cause);
void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state);
#define AMF_RELEASE_SM_CONTEXT_NO_STATE 0
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 1

View File

@ -153,6 +153,14 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
break;
}
if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) {
ogs_warn("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd);
nas_eps_send_service_reject(mme_ue,
EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED);
OGS_FSM_TRAN(s, &emm_state_exception);
break;
}
s1ap_send_initial_context_setup_request(mme_ue);
OGS_FSM_TRAN(s, &emm_state_registered);
break;
@ -181,7 +189,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
mme_gtp_send_delete_all_sessions(mme_ue,
OGS_GTP_DELETE_SEND_AUTHENTICATION_REUQEST);
OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST);
} else {
mme_s6a_send_air(mme_ue, NULL);
}
@ -224,7 +232,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
} else {
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
mme_gtp_send_delete_all_sessions(mme_ue,
OGS_GTP_DELETE_SEND_AUTHENTICATION_REUQEST);
OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST);
} else {
mme_s6a_send_air(mme_ue, NULL);
}
@ -258,6 +266,14 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
break;
}
if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) {
ogs_warn("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd);
nas_eps_send_service_reject(mme_ue,
EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED);
OGS_FSM_TRAN(s, &emm_state_exception);
break;
}
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
mme_s6a_send_air(mme_ue, NULL);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
@ -469,10 +485,13 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3413);
mme_send_after_paging(mme_ue, OGS_GTP_CAUSE_UNABLE_TO_PAGE_UE);
if (CS_CALL_SERVICE_INDICATOR(mme_ue) ||
SMS_SERVICE_INDICATOR(mme_ue)) {
sgsap_send_ue_unreachable(mme_ue,
SGSAP_SGS_CAUSE_UE_UNREACHABLE);
}
CLEAR_SERVICE_INDICATOR(mme_ue);
@ -892,7 +911,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
}
mme_gtp_send_delete_all_sessions(mme_ue,
OGS_GTP_DELETE_SEND_AUTHENTICATION_REUQEST);
OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST);
OGS_FSM_TRAN(s, &emm_state_authentication);
break;
case OGS_NAS_EPS_EMM_STATUS:
@ -1008,7 +1027,7 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
} else {
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
mme_gtp_send_delete_all_sessions(mme_ue,
OGS_GTP_DELETE_SEND_AUTHENTICATION_REUQEST);
OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST);
} else {
mme_s6a_send_air(mme_ue, NULL);
}

View File

@ -136,7 +136,8 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
/* Check if Initial Context Setup Response or
* E-RAB Setup Response is received */
if (MME_HAVE_ENB_S1U_PATH(bearer)) {
mme_gtp_send_create_bearer_response(bearer);
mme_gtp_send_create_bearer_response(
bearer, OGS_GTP_CAUSE_REQUEST_ACCEPTED);
}
OGS_FSM_TRAN(s, esm_state_active);
@ -235,14 +236,16 @@ void esm_state_active(ogs_fsm_t *s, mme_event_t *e)
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
mme_gtp_send_update_bearer_response(bearer);
mme_gtp_send_update_bearer_response(
bearer, OGS_GTP_CAUSE_REQUEST_ACCEPTED);
break;
case OGS_NAS_EPS_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT:
ogs_debug("Deactivate EPS bearer "
"context accept");
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
mme_gtp_send_delete_bearer_response(bearer);
mme_gtp_send_delete_bearer_response(
bearer, OGS_GTP_CAUSE_REQUEST_ACCEPTED);
OGS_FSM_TRAN(s, esm_state_bearer_deactivated);
break;
case OGS_NAS_EPS_BEARER_RESOURCE_ALLOCATION_REQUEST:

View File

@ -1931,8 +1931,6 @@ int mme_enb_remove(mme_enb_t *enb)
ogs_hash_set(self.enb_addr_hash, enb->addr, sizeof(ogs_sockaddr_t), NULL);
ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL);
enb_ue_remove_in_enb(enb);
if (enb->sock_type == SOCK_STREAM) {
ogs_pollset_remove(enb->poll);
ogs_sctp_destroy(enb->sock);
@ -2050,20 +2048,6 @@ void enb_ue_remove(enb_ue_t *enb_ue)
stats_remove_enb_ue();
}
void enb_ue_remove_in_enb(mme_enb_t *enb)
{
enb_ue_t *enb_ue = NULL, *next_enb_ue = NULL;
enb_ue = enb_ue_first_in_enb(enb);
while (enb_ue) {
next_enb_ue = enb_ue_next_in_enb(enb_ue);
enb_ue_remove(enb_ue);
enb_ue = next_enb_ue;
}
}
void enb_ue_switch_to_enb(enb_ue_t *enb_ue, mme_enb_t *new_enb)
{
ogs_assert(enb_ue);
@ -2085,12 +2069,9 @@ enb_ue_t *enb_ue_find_by_enb_ue_s1ap_id(
{
enb_ue_t *enb_ue = NULL;
enb_ue = enb_ue_first_in_enb(enb);
while (enb_ue) {
ogs_list_for_each(&enb->enb_ue_list, enb_ue) {
if (enb_ue_s1ap_id == enb_ue->enb_ue_s1ap_id)
break;
enb_ue = enb_ue_next_in_enb(enb_ue);
}
return enb_ue;
@ -2107,16 +2088,6 @@ enb_ue_t *enb_ue_find_by_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id)
return enb_ue_find(mme_ue_s1ap_id);
}
enb_ue_t *enb_ue_first_in_enb(mme_enb_t *enb)
{
return ogs_list_first(&enb->enb_ue_list);
}
enb_ue_t *enb_ue_next_in_enb(enb_ue_t *enb_ue)
{
return ogs_list_next(enb_ue);
}
enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue)
{
return ogs_pool_cycle(&enb_ue_pool, enb_ue);
@ -2551,47 +2522,56 @@ int mme_ue_set_imsi(mme_ue_t *mme_ue, char *imsi_bcd)
return OGS_OK;
}
int mme_ue_have_indirect_tunnel(mme_ue_t *mme_ue)
bool mme_ue_have_indirect_tunnel(mme_ue_t *mme_ue)
{
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
sess = mme_sess_first(mme_ue);
while (sess) {
mme_bearer_t *bearer = mme_bearer_first(sess);
while (bearer) {
ogs_assert(mme_ue);
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
if (MME_HAVE_ENB_DL_INDIRECT_TUNNEL(bearer) ||
MME_HAVE_ENB_UL_INDIRECT_TUNNEL(bearer) ||
MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) ||
MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) {
return 1;
return true;
}
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
return 0;
return false;
}
int mme_ue_clear_indirect_tunnel(mme_ue_t *mme_ue)
void mme_ue_clear_indirect_tunnel(mme_ue_t *mme_ue)
{
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
ogs_assert(mme_ue);
sess = mme_sess_first(mme_ue);
while (sess) {
mme_bearer_t *bearer = mme_bearer_first(sess);
while (bearer) {
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
CLEAR_INDIRECT_TUNNEL(bearer);
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
}
bool mme_ue_have_active_eps_bearers(mme_ue_t *mme_ue)
{
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
ogs_assert(mme_ue);
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
if (OGS_FSM_CHECK(&bearer->sm, esm_state_active))
return true;
}
}
return OGS_OK;
return false;
}
void mme_ue_associate_enb_ue(mme_ue_t *mme_ue, enb_ue_t *enb_ue)
@ -3076,23 +3056,9 @@ mme_bearer_t *mme_bearer_next(mme_bearer_t *bearer)
return ogs_list_next(bearer);
}
int mme_bearer_set_inactive(mme_ue_t *mme_ue)
mme_bearer_t *mme_bearer_cycle(mme_bearer_t *bearer)
{
mme_sess_t *sess = NULL;
ogs_assert(mme_ue);
sess = mme_sess_first(mme_ue);
while (sess) {
mme_bearer_t *bearer = mme_bearer_first(sess);
while (bearer) {
CLEAR_ENB_S1U_PATH(bearer);
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
return OGS_OK;
return ogs_pool_cycle(&mme_bearer_pool, bearer);
}
void mme_pdn_remove_all(mme_ue_t *mme_ue)

View File

@ -406,13 +406,13 @@ struct mme_ue_s {
} while(0)
OGS_POOL(ebi_pool, uint8_t);
/* Paging Info */
#define ECM_CONNECTED(__mME) \
((__mME) && ((__mME)->enb_ue != NULL) && enb_ue_cycle((__mME)->enb_ue))
#define ECM_IDLE(__mME) \
((__mME) && \
(((__mME)->enb_ue == NULL) || (enb_ue_cycle((__mME)->enb_ue) == NULL)))
/* S1 UE context */
enb_ue_t *enb_ue;
enb_ue_t *enb_ue; /* S1 UE context */
/* Save PDN Connectivity Request */
ogs_nas_esm_message_container_t pdn_connectivity_request;
@ -507,17 +507,6 @@ struct mme_ue_s {
mme_csmap_t *csmap;
};
#define MME_HAVE_SGW_S1U_PATH(__sESS) \
((__sESS) && (mme_bearer_first(__sESS)) && \
((mme_default_bearer_in_sess(__sESS)->sgw_s1u_teid)))
#define CLEAR_SGW_S1U_PATH(__sESS) \
do { \
mme_bearer_t *__bEARER = NULL; \
ogs_assert((__sESS)); \
__bEARER = mme_default_bearer_in_sess(__sESS); \
__bEARER->sgw_s1u_teid = 0; \
} while(0)
#define SESSION_CONTEXT_IS_AVAILABLE(__mME) \
((__mME) && ((__mME)->sgw_s11_teid))
@ -530,6 +519,9 @@ struct mme_ue_s {
(__mME)->sgw_s11_teid = 0; \
(__mME)->session_context_will_deleted = 0; \
} while(0)
#define ACTIVE_EPS_BEARERS_IS_AVAIABLE(__mME) \
(mme_ue_have_active_eps_bearers(__mME))
typedef struct mme_sess_s {
ogs_lnode_t lnode;
@ -556,9 +548,6 @@ typedef struct mme_sess_s {
ogs_tlv_octet_t pgw_pco;
} mme_sess_t;
#define CLEAR_BEARER_CONTEXT(__mME) \
mme_bearer_set_inactive(__mME)
#define MME_HAVE_ENB_S1U_PATH(__bEARER) \
((__bEARER) && ((__bEARER)->enb_s1u_teid))
#define CLEAR_ENB_S1U_PATH(__bEARER) \
@ -567,6 +556,17 @@ typedef struct mme_sess_s {
(__bEARER)->enb_s1u_teid = 0; \
} while(0)
#define MME_HAVE_SGW_S1U_PATH(__sESS) \
((__sESS) && (mme_bearer_first(__sESS)) && \
((mme_default_bearer_in_sess(__sESS)->sgw_s1u_teid)))
#define CLEAR_SGW_S1U_PATH(__sESS) \
do { \
mme_bearer_t *__bEARER = NULL; \
ogs_assert((__sESS)); \
__bEARER = mme_default_bearer_in_sess(__sESS); \
__bEARER->sgw_s1u_teid = 0; \
} while(0)
#define MME_HAVE_ENB_DL_INDIRECT_TUNNEL(__bEARER) \
((__bEARER) && ((__bEARER)->enb_dl_teid))
#define MME_HAVE_ENB_UL_INDIRECT_TUNNEL(__bEARER) \
@ -678,14 +678,11 @@ int mme_enb_sock_type(ogs_sock_t *sock);
enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id);
void enb_ue_remove(enb_ue_t *enb_ue);
void enb_ue_remove_in_enb(mme_enb_t *enb);
void enb_ue_switch_to_enb(enb_ue_t *enb_ue, mme_enb_t *new_enb);
enb_ue_t *enb_ue_find_by_enb_ue_s1ap_id(
mme_enb_t *enb, uint32_t enb_ue_s1ap_id);
enb_ue_t *enb_ue_find(uint32_t index);
enb_ue_t *enb_ue_find_by_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id);
enb_ue_t *enb_ue_first_in_enb(mme_enb_t *enb);
enb_ue_t *enb_ue_next_in_enb(enb_ue_t *enb_ue);
enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue);
mme_ue_t *mme_ue_add(enb_ue_t *enb_ue);
@ -703,8 +700,10 @@ mme_ue_t *mme_ue_find_by_teid(uint32_t teid);
mme_ue_t *mme_ue_find_by_message(ogs_nas_eps_message_t *message);
int mme_ue_set_imsi(mme_ue_t *mme_ue, char *imsi_bcd);
int mme_ue_have_indirect_tunnel(mme_ue_t *mme_ue);
int mme_ue_clear_indirect_tunnel(mme_ue_t *mme_ue);
bool mme_ue_have_indirect_tunnel(mme_ue_t *mme_ue);
void mme_ue_clear_indirect_tunnel(mme_ue_t *mme_ue);
bool mme_ue_have_active_eps_bearers(mme_ue_t *mme_ue);
/*
* o RECV Initial UE-Message : S-TMSI
@ -785,9 +784,7 @@ mme_bearer_t *mme_default_bearer_in_sess(mme_sess_t *sess);
mme_bearer_t *mme_linked_bearer(mme_bearer_t *bearer);
mme_bearer_t *mme_bearer_first(mme_sess_t *sess);
mme_bearer_t *mme_bearer_next(mme_bearer_t *bearer);
int mme_bearer_is_inactive(mme_ue_t *mme_ue);
int mme_bearer_set_inactive(mme_ue_t *mme_ue);
mme_bearer_t *mme_bearer_cycle(mme_bearer_t *bearer);
void mme_pdn_remove_all(mme_ue_t *mme_ue);
ogs_pdn_t *mme_pdn_find_by_apn(mme_ue_t *mme_ue, char *apn);

View File

@ -79,18 +79,45 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
uint8_t type = 0;
ogs_assert(xact);
type = xact->seq[0].type;
switch (type) {
case OGS_GTP_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
case OGS_GTP_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
case OGS_GTP_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
mme_ue = data;
ogs_assert(mme_ue);
break;
case OGS_GTP_CREATE_SESSION_REQUEST_TYPE:
case OGS_GTP_DELETE_SESSION_REQUEST_TYPE:
sess = data;
ogs_assert(sess);
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
break;
case OGS_GTP_MODIFY_BEARER_REQUEST_TYPE:
case OGS_GTP_BEARER_RESOURCE_COMMAND_TYPE:
bearer = data;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
break;
default:
ogs_fatal("Invalid type [%d]", type);
ogs_assert_if_reached();
break;
}
ogs_assert(mme_ue);
switch (type) {
case OGS_GTP_DELETE_SESSION_REQUEST_TYPE:
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
if (enb_ue) {
s1ap_send_ue_context_release_command(enb_ue,
@ -100,9 +127,10 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
ogs_warn("No S1 Context");
}
break;
case OGS_GTP_BEARER_RESOURCE_COMMAND_TYPE:
/* Nothing to do */
break;
default:
mme_ue = data;
ogs_assert(mme_ue);
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
break;
}
@ -182,7 +210,7 @@ void mme_gtp_send_create_session_request(mme_sess_t *sess)
pkbuf = mme_s11_build_create_session_request(h.type, sess);
ogs_expect_or_return(pkbuf);
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, mme_ue);
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, sess);
ogs_expect_or_return(xact);
rv = ogs_gtp_xact_commit(xact);
@ -211,7 +239,7 @@ void mme_gtp_send_modify_bearer_request(
pkbuf = mme_s11_build_modify_bearer_request(h.type, bearer, uli_presence);
ogs_expect_or_return(pkbuf);
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, mme_ue);
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, bearer);
ogs_expect_or_return(xact);
rv = ogs_gtp_xact_commit(xact);
@ -283,7 +311,8 @@ void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action)
}
}
void mme_gtp_send_create_bearer_response(mme_bearer_t *bearer)
void mme_gtp_send_create_bearer_response(
mme_bearer_t *bearer, uint8_t cause_value)
{
int rv;
@ -296,14 +325,14 @@ void mme_gtp_send_create_bearer_response(mme_bearer_t *bearer)
ogs_assert(bearer);
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
xact = bearer->xact;
xact = ogs_gtp_xact_cycle(bearer->xact);
ogs_assert(xact);
memset(&h, 0, sizeof(ogs_gtp_header_t));
h.type = OGS_GTP_CREATE_BEARER_RESPONSE_TYPE;
h.teid = mme_ue->sgw_s11_teid;
pkbuf = mme_s11_build_create_bearer_response(h.type, bearer);
pkbuf = mme_s11_build_create_bearer_response(h.type, bearer, cause_value);
ogs_expect_or_return(pkbuf);
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
@ -313,7 +342,8 @@ void mme_gtp_send_create_bearer_response(mme_bearer_t *bearer)
ogs_expect(rv == OGS_OK);
}
void mme_gtp_send_update_bearer_response(mme_bearer_t *bearer)
void mme_gtp_send_update_bearer_response(
mme_bearer_t *bearer, uint8_t cause_value)
{
int rv;
@ -326,14 +356,14 @@ void mme_gtp_send_update_bearer_response(mme_bearer_t *bearer)
ogs_assert(bearer);
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
xact = bearer->xact;
xact = ogs_gtp_xact_cycle(bearer->xact);
ogs_assert(xact);
memset(&h, 0, sizeof(ogs_gtp_header_t));
h.type = OGS_GTP_UPDATE_BEARER_RESPONSE_TYPE;
h.teid = mme_ue->sgw_s11_teid;
pkbuf = mme_s11_build_update_bearer_response(h.type, bearer);
pkbuf = mme_s11_build_update_bearer_response(h.type, bearer, cause_value);
ogs_expect_or_return(pkbuf);
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
@ -343,7 +373,8 @@ void mme_gtp_send_update_bearer_response(mme_bearer_t *bearer)
ogs_expect(rv == OGS_OK);
}
void mme_gtp_send_delete_bearer_response(mme_bearer_t *bearer)
void mme_gtp_send_delete_bearer_response(
mme_bearer_t *bearer, uint8_t cause_value)
{
int rv;
@ -356,14 +387,14 @@ void mme_gtp_send_delete_bearer_response(mme_bearer_t *bearer)
ogs_assert(bearer);
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
xact = bearer->xact;
xact = ogs_gtp_xact_cycle(bearer->xact);
ogs_assert(xact);
memset(&h, 0, sizeof(ogs_gtp_header_t));
h.type = OGS_GTP_DELETE_BEARER_RESPONSE_TYPE;
h.teid = mme_ue->sgw_s11_teid;
pkbuf = mme_s11_build_delete_bearer_response(h.type, bearer);
pkbuf = mme_s11_build_delete_bearer_response(h.type, bearer, cause_value);
ogs_expect_or_return(pkbuf);
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
@ -373,13 +404,14 @@ void mme_gtp_send_delete_bearer_response(mme_bearer_t *bearer)
ogs_expect(rv == OGS_OK);
}
void mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue)
void mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action)
{
int rv;
ogs_gtp_header_t h;
ogs_pkbuf_t *pkbuf = NULL;
ogs_gtp_xact_t *xact = NULL;
ogs_assert(action);
ogs_assert(mme_ue);
memset(&h, 0, sizeof(ogs_gtp_header_t));
@ -391,11 +423,57 @@ void mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue)
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, mme_ue);
ogs_expect_or_return(xact);
xact->release_action = action;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}
void mme_gtp_send_release_all_ue_in_enb(mme_enb_t *enb, int action)
{
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_list_for_each(&enb->enb_ue_list, enb_ue) {
mme_ue = enb_ue->mme_ue;
ogs_assert(mme_ue);
mme_gtp_send_release_access_bearers_request(mme_ue, action);
}
}
void mme_gtp_send_downlink_data_notification_ack(
mme_bearer_t *bearer, uint8_t cause_value)
{
int rv;
mme_ue_t *mme_ue = NULL;
ogs_gtp_xact_t *xact = NULL;
ogs_gtp_header_t h;
ogs_pkbuf_t *s11buf = NULL;
ogs_assert(bearer);
xact = ogs_gtp_xact_cycle(bearer->xact);
ogs_assert(xact);
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
/* Build Downlink data notification ack */
memset(&h, 0, sizeof(ogs_gtp_header_t));
h.type = OGS_GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE;
h.teid = mme_ue->sgw_s11_teid;
s11buf = mme_s11_build_downlink_data_notification_ack(h.type, cause_value);
ogs_expect_or_return(s11buf);
rv = ogs_gtp_xact_update_tx(xact, &h, s11buf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}
void mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
mme_ue_t *mme_ue)
{

View File

@ -34,10 +34,17 @@ void mme_gtp_send_modify_bearer_request(
mme_bearer_t *bearer, int uli_presence);
void mme_gtp_send_delete_session_request(mme_sess_t *sess, int action);
void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action);
void mme_gtp_send_create_bearer_response(mme_bearer_t *bearer);
void mme_gtp_send_update_bearer_response(mme_bearer_t *bearer);
void mme_gtp_send_delete_bearer_response(mme_bearer_t *bearer);
void mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue);
void mme_gtp_send_create_bearer_response(
mme_bearer_t *bearer, uint8_t cause_value);
void mme_gtp_send_update_bearer_response(
mme_bearer_t *bearer, uint8_t cause_value);
void mme_gtp_send_delete_bearer_response(
mme_bearer_t *bearer, uint8_t cause_value);
void mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action);
void mme_gtp_send_release_all_ue_in_enb(mme_enb_t *enb, int action);
void mme_gtp_send_downlink_data_notification_ack(
mme_bearer_t *bearer, uint8_t cause_value);
void mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
mme_ue_t *mme_ue);

View File

@ -61,7 +61,8 @@ void mme_send_release_access_bearer_or_ue_context_release(enb_ue_t *enb_ue)
mme_ue = enb_ue->mme_ue;
if (mme_ue) {
ogs_debug("[%s] Release access bearer request", mme_ue->imsi_bcd);
mme_gtp_send_release_access_bearers_request(mme_ue);
mme_gtp_send_release_access_bearers_request(
mme_ue, OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND);
} else {
ogs_debug("[%s] No UE Context", mme_ue->imsi_bcd);
s1ap_send_ue_context_release_command(enb_ue,
@ -69,3 +70,66 @@ void mme_send_release_access_bearer_or_ue_context_release(enb_ue_t *enb_ue)
S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE, 0);
}
}
void mme_send_after_paging(mme_ue_t *mme_ue, uint8_t cause_value)
{
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
ogs_assert(mme_ue);
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
ogs_gtp_xact_t *xact = NULL;
uint8_t type;
xact = ogs_gtp_xact_cycle(bearer->xact);
if (xact) {
/*
* It may conflict with GTP transaction already used.
* To avoid this, check `xact->step` to see if
* the transaction has already been committed.
*/
type = xact->seq[xact->step-1].type;
switch (type) {
case OGS_GTP_DOWNLINK_DATA_NOTIFICATION_TYPE:
mme_gtp_send_downlink_data_notification_ack(
bearer, cause_value);
break;
case OGS_GTP_CREATE_BEARER_REQUEST_TYPE:
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
nas_eps_send_activate_dedicated_bearer_context_request(
bearer);
} else {
mme_gtp_send_create_bearer_response(
bearer, cause_value);
}
break;
case OGS_GTP_UPDATE_BEARER_REQUEST_TYPE:
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
nas_eps_send_modify_bearer_context_request(bearer,
(xact->update_flags &
OGS_GTP_MODIFY_QOS_UPDATE) ? 1 : 0,
(xact->update_flags &
OGS_GTP_MODIFY_TFT_UPDATE) ? 1 : 0);
} else {
mme_gtp_send_update_bearer_response(
bearer, cause_value);
}
break;
case OGS_GTP_DELETE_BEARER_REQUEST_TYPE:
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
nas_eps_send_deactivate_bearer_context_request(bearer);
} else {
mme_gtp_send_delete_bearer_response(
bearer, cause_value);
}
break;
default:
break;
}
}
}
}
}

View File

@ -30,6 +30,8 @@ void mme_send_delete_session_or_detach(mme_ue_t *mme_ue);
void mme_send_delete_session_or_mme_ue_context_release(mme_ue_t *mme_ue);
void mme_send_release_access_bearer_or_ue_context_release(enb_ue_t *enb_ue);
void mme_send_after_paging(mme_ue_t *mme_ue, uint8_t cause_value);
#ifdef __cplusplus
}
#endif

View File

@ -51,7 +51,7 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
ogs_debug("[MME] Create Session Request");
ogs_debug("Create Session Request");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
memset(&gtp_message, 0, sizeof(ogs_gtp_message_t));
@ -286,7 +286,7 @@ ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
ogs_debug("[MME] Modifty Bearer Request");
ogs_debug("Modifty Bearer Request");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d]",
@ -347,7 +347,7 @@ ogs_pkbuf_t *mme_s11_build_delete_session_request(
bearer = mme_default_bearer_in_sess(sess);
ogs_assert(bearer);
ogs_debug("[MME] Delete Session Request");
ogs_debug("Delete Session Request");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
@ -379,7 +379,7 @@ ogs_pkbuf_t *mme_s11_build_delete_session_request(
}
ogs_pkbuf_t *mme_s11_build_create_bearer_response(
uint8_t type, mme_bearer_t *bearer)
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value)
{
int rv;
ogs_gtp_message_t gtp_message;
@ -400,7 +400,7 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
ogs_debug("[MME] Create Bearer Response");
ogs_debug("Create Bearer Response");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
@ -408,40 +408,42 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
/* Set Cause */
memset(&cause, 0, sizeof(cause));
cause.value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
cause.value = cause_value;
rsp->cause.presence = 1;
rsp->cause.len = sizeof(cause);
rsp->cause.data = &cause;
/* Bearer Context : EBI */
rsp->bearer_contexts.presence = 1;
rsp->bearer_contexts.eps_bearer_id.presence = 1;
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
/* Bearer Context : EBI */
rsp->bearer_contexts.presence = 1;
rsp->bearer_contexts.eps_bearer_id.presence = 1;
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
/* Data Plane(DL) : ENB-S1U */
memset(&enb_s1u_teid, 0, sizeof(ogs_gtp_f_teid_t));
enb_s1u_teid.interface_type = OGS_GTP_F_TEID_S1_U_ENODEB_GTP_U;
enb_s1u_teid.teid = htobe32(bearer->enb_s1u_teid);
rv = ogs_gtp_ip_to_f_teid(&bearer->enb_s1u_ip, &enb_s1u_teid, &len);
ogs_assert(rv == OGS_OK);
rsp->bearer_contexts.s1_u_enodeb_f_teid.presence = 1;
rsp->bearer_contexts.s1_u_enodeb_f_teid.data = &enb_s1u_teid;
rsp->bearer_contexts.s1_u_enodeb_f_teid.len = len;
/* Data Plane(UL) : SGW-S1U */
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp_f_teid_t));
sgw_s1u_teid.interface_type = OGS_GTP_F_TEID_S1_U_SGW_GTP_U;
sgw_s1u_teid.teid = htobe32(bearer->sgw_s1u_teid);
rv = ogs_gtp_ip_to_f_teid(&bearer->sgw_s1u_ip, &sgw_s1u_teid, &len);
ogs_assert(rv == OGS_OK);
rsp->bearer_contexts.s4_u_sgsn_f_teid.presence = 1;
rsp->bearer_contexts.s4_u_sgsn_f_teid.data = &sgw_s1u_teid;
rsp->bearer_contexts.s4_u_sgsn_f_teid.len = OGS_GTP_F_TEID_IPV4_LEN;
/* Data Plane(DL) : ENB-S1U */
memset(&enb_s1u_teid, 0, sizeof(ogs_gtp_f_teid_t));
enb_s1u_teid.interface_type = OGS_GTP_F_TEID_S1_U_ENODEB_GTP_U;
enb_s1u_teid.teid = htobe32(bearer->enb_s1u_teid);
rv = ogs_gtp_ip_to_f_teid(&bearer->enb_s1u_ip, &enb_s1u_teid, &len);
ogs_assert(rv == OGS_OK);
rsp->bearer_contexts.s1_u_enodeb_f_teid.presence = 1;
rsp->bearer_contexts.s1_u_enodeb_f_teid.data = &enb_s1u_teid;
rsp->bearer_contexts.s1_u_enodeb_f_teid.len = len;
/* Bearer Context : Cause */
rsp->bearer_contexts.cause.presence = 1;
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
/* Data Plane(UL) : SGW-S1U */
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp_f_teid_t));
sgw_s1u_teid.interface_type = OGS_GTP_F_TEID_S1_U_SGW_GTP_U;
sgw_s1u_teid.teid = htobe32(bearer->sgw_s1u_teid);
rv = ogs_gtp_ip_to_f_teid(&bearer->sgw_s1u_ip, &sgw_s1u_teid, &len);
ogs_assert(rv == OGS_OK);
rsp->bearer_contexts.s4_u_sgsn_f_teid.presence = 1;
rsp->bearer_contexts.s4_u_sgsn_f_teid.data = &sgw_s1u_teid;
rsp->bearer_contexts.s4_u_sgsn_f_teid.len = OGS_GTP_F_TEID_IPV4_LEN;
/* Bearer Context : Cause */
rsp->bearer_contexts.cause.presence = 1;
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
}
/* User Location Information(ULI) */
memset(&uli, 0, sizeof(ogs_gtp_uli_t));
@ -477,7 +479,7 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
}
ogs_pkbuf_t *mme_s11_build_update_bearer_response(
uint8_t type, mme_bearer_t *bearer)
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value)
{
ogs_gtp_message_t gtp_message;
ogs_gtp_update_bearer_response_t *rsp = &gtp_message.update_bearer_response;
@ -495,7 +497,7 @@ ogs_pkbuf_t *mme_s11_build_update_bearer_response(
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
ogs_debug("[MME] Update Bearer Response");
ogs_debug("Update Bearer Response");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
@ -503,20 +505,22 @@ ogs_pkbuf_t *mme_s11_build_update_bearer_response(
/* Set Cause */
memset(&cause, 0, sizeof(cause));
cause.value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
cause.value = cause_value;
rsp->cause.presence = 1;
rsp->cause.len = sizeof(cause);
rsp->cause.data = &cause;
/* Bearer Context : EBI */
rsp->bearer_contexts.presence = 1;
rsp->bearer_contexts.eps_bearer_id.presence = 1;
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
/* Bearer Context : EBI */
rsp->bearer_contexts.presence = 1;
rsp->bearer_contexts.eps_bearer_id.presence = 1;
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
/* Bearer Context : Cause */
rsp->bearer_contexts.cause.presence = 1;
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
/* Bearer Context : Cause */
rsp->bearer_contexts.cause.presence = 1;
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
}
/* User Location Information(ULI) */
memset(&uli, 0, sizeof(ogs_gtp_uli_t));
@ -552,7 +556,7 @@ ogs_pkbuf_t *mme_s11_build_update_bearer_response(
}
ogs_pkbuf_t *mme_s11_build_delete_bearer_response(
uint8_t type, mme_bearer_t *bearer)
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value)
{
ogs_gtp_message_t gtp_message;
ogs_gtp_delete_bearer_response_t *rsp = &gtp_message.delete_bearer_response;
@ -570,7 +574,7 @@ ogs_pkbuf_t *mme_s11_build_delete_bearer_response(
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
ogs_debug("[MME] Delete Bearer Response");
ogs_debug("Delete Bearer Response");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
@ -578,20 +582,22 @@ ogs_pkbuf_t *mme_s11_build_delete_bearer_response(
/* Set Cause */
memset(&cause, 0, sizeof(cause));
cause.value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
cause.value = cause_value;
rsp->cause.presence = 1;
rsp->cause.len = sizeof(cause);
rsp->cause.data = &cause;
/* Bearer Context : EBI */
rsp->bearer_contexts.presence = 1;
rsp->bearer_contexts.eps_bearer_id.presence = 1;
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
/* Bearer Context : EBI */
rsp->bearer_contexts.presence = 1;
rsp->bearer_contexts.eps_bearer_id.presence = 1;
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
/* Bearer Context : Cause */
rsp->bearer_contexts.cause.presence = 1;
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
/* Bearer Context : Cause */
rsp->bearer_contexts.cause.presence = 1;
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
}
/* User Location Information(ULI) */
memset(&uli, 0, sizeof(ogs_gtp_uli_t));
@ -632,7 +638,7 @@ ogs_pkbuf_t *mme_s11_build_release_access_bearers_request(uint8_t type)
ogs_gtp_release_access_bearers_request_t *req =
&gtp_message.release_access_bearers_request;
ogs_debug("[MME] Release Access Bearers Request");
ogs_debug("Release Access Bearers Request");
memset(&gtp_message, 0, sizeof(ogs_gtp_message_t));
req->originating_node.presence = 1;
@ -642,7 +648,8 @@ ogs_pkbuf_t *mme_s11_build_release_access_bearers_request(uint8_t type)
return ogs_gtp_build_msg(&gtp_message);
}
ogs_pkbuf_t *mme_s11_build_downlink_data_notification_ack(uint8_t type)
ogs_pkbuf_t *mme_s11_build_downlink_data_notification_ack(
uint8_t type, uint8_t cause_value)
{
ogs_gtp_message_t gtp_message;
ogs_gtp_downlink_data_notification_acknowledge_t *ack =
@ -650,12 +657,12 @@ ogs_pkbuf_t *mme_s11_build_downlink_data_notification_ack(uint8_t type)
ogs_gtp_cause_t cause;
ogs_debug("[MME] Downlink Data Notification Ackknowledge");
ogs_debug("Downlink Data Notification Ackknowledge");
memset(&gtp_message, 0, sizeof(ogs_gtp_message_t));
memset(&cause, 0, sizeof(cause));
cause.value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
cause.value = cause_value;
ack->cause.presence = 1;
ack->cause.data = &cause;
@ -684,7 +691,7 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request(
ogs_assert(mme_ue);
ogs_debug("[MME] Create Indirect Data Forwarding Tunnel Request");
ogs_debug("Create Indirect Data Forwarding Tunnel Request");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
@ -779,15 +786,14 @@ ogs_pkbuf_t *mme_s11_build_bearer_resource_command(
tad = &modification->traffic_flow_aggregate;
break;
default:
ogs_error("Invalid NAS ESM Type[%d]",
nas_message->esm.h.message_type);
ogs_error("Invalid NAS ESM Type[%d]", nas_message->esm.h.message_type);
return NULL;
}
linked_bearer = mme_linked_bearer(bearer);
ogs_assert(linked_bearer);
ogs_debug("[MME] Bearer Resource Command");
ogs_debug("Bearer Resource Command");
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);

View File

@ -31,13 +31,14 @@ ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
ogs_pkbuf_t *mme_s11_build_delete_session_request(
uint8_t type, mme_sess_t *sess);
ogs_pkbuf_t *mme_s11_build_create_bearer_response(
uint8_t type, mme_bearer_t *bearer);
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value);
ogs_pkbuf_t *mme_s11_build_update_bearer_response(
uint8_t type, mme_bearer_t *bearer);
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value);
ogs_pkbuf_t *mme_s11_build_delete_bearer_response(
uint8_t type, mme_bearer_t *bearer);
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value);
ogs_pkbuf_t *mme_s11_build_release_access_bearers_request(uint8_t type);
ogs_pkbuf_t *mme_s11_build_downlink_data_notification_ack(uint8_t type);
ogs_pkbuf_t *mme_s11_build_downlink_data_notification_ack(
uint8_t type, uint8_t cause_value);
ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request(
uint8_t type, mme_ue_t *mme_ue);

View File

@ -37,7 +37,7 @@ void mme_s11_handle_echo_request(
ogs_assert(xact);
ogs_assert(req);
ogs_debug("[MME] Receiving Echo Request");
ogs_debug("Receiving Echo Request");
/* FIXME : Before implementing recovery counter correctly,
* I'll re-use the recovery value in request message */
ogs_gtp_send_echo_response(xact, req->recovery.u8, 0);
@ -68,41 +68,13 @@ void mme_s11_handle_create_session_response(
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("[MME] Create Session Response");
ogs_debug("Create Session Response");
if (!mme_ue) {
ogs_warn("No Context in TEID");
mme_ue = xact->data;
ogs_assert(mme_ue);
}
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts_created.cause.presence) {
cause = rsp->bearer_contexts_created.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED)
ogs_warn("Cause[%d] : No Accepted", cause_value);
if (rsp->pdn_address_allocation.presence == 0) {
ogs_error("No PDN Address Allocation");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -125,6 +97,35 @@ void mme_s11_handle_create_session_response(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!mme_ue) {
ogs_warn("No Context in TEID");
mme_ue = xact->data;
ogs_assert(mme_ue);
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts_created.cause.presence) {
cause = rsp->bearer_contexts_created.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (sess && SESSION_CONTEXT_IN_ATTACH(sess)) {
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
@ -215,7 +216,12 @@ void mme_s11_handle_modify_bearer_response(
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("[MME] Modify Bearer Response");
ogs_debug("Modify Bearer Response");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (!mme_ue) {
ogs_warn("No Context in TEID");
@ -223,9 +229,6 @@ void mme_s11_handle_modify_bearer_response(
ogs_assert(mme_ue);
}
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
@ -233,16 +236,19 @@ void mme_s11_handle_modify_bearer_response(
cause_value = cause->value;
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED)
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
}
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_MODIFY_BEARER_BY_PATH_SWITCH,
s1ap_send_path_switch_ack(mme_ue);
);
@ -275,16 +281,16 @@ void mme_s11_handle_delete_session_response(
action = xact->delete_action;
ogs_assert(action);
ogs_debug("[MME] Delete Session Response");
ogs_debug("Delete Session Response");
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
sess = xact->data;
ogs_assert(sess);
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
@ -297,7 +303,7 @@ void mme_s11_handle_delete_session_response(
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
if (action == OGS_GTP_DELETE_SEND_AUTHENTICATION_REUQEST) {
if (action == OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST) {
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
mme_s6a_send_air(mme_ue, NULL);
}
@ -373,7 +379,7 @@ void mme_s11_handle_create_bearer_request(
ogs_assert(xact);
ogs_assert(req);
ogs_debug("[MME] Create Bearer Response");
ogs_debug("Create Bearer Response");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
@ -381,17 +387,6 @@ void mme_s11_handle_create_bearer_request(
ogs_error("No Linked EBI");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (mme_ue && cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
sess = mme_sess_find_by_ebi(mme_ue, req->linked_eps_bearer_id.u8);
if (sess) bearer = mme_bearer_add(sess);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -413,6 +408,16 @@ void mme_s11_handle_create_bearer_request(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (mme_ue && cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
sess = mme_sess_find_by_ebi(mme_ue, req->linked_eps_bearer_id.u8);
if (sess) bearer = mme_bearer_add(sess);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(xact, mme_ue ? mme_ue->sgw_s11_teid : 0,
OGS_GTP_CREATE_BEARER_RESPONSE_TYPE, cause_value);
@ -456,19 +461,30 @@ void mme_s11_handle_create_bearer_request(
/* Save Bearer TFT */
OGS_TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft);
/* Save Transaction. will be handled after EMM-attached */
/*
* Save Transaction. It will be handled after EMM-attached
*
* You should not remove OLD bearer->xact.
* If GTP-xact Holding timer is expired,
* OLD bearer->xact memory will be automatically removed.
*/
bearer->xact = xact;
/* Before Activate DEDICATED bearer, we'll check DEFAULT bearer status */
/* Before Activate DEDICATED bearer, check DEFAULT bearer status */
default_bearer = mme_default_bearer_in_sess(sess);
ogs_expect_or_return(default_bearer);
if (/* Check if Activate Default Bearer Accept is received */
OGS_FSM_CHECK(&default_bearer->sm, esm_state_active) &&
/* Check if Initial Context Setup Response or
* E-RAB Setup Response is received */
MME_HAVE_ENB_S1U_PATH(default_bearer)) {
nas_eps_send_activate_dedicated_bearer_context_request(bearer);
if (OGS_FSM_CHECK(&default_bearer->sm, esm_state_active)) {
if (ECM_IDLE(mme_ue)) {
s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
} else {
nas_eps_send_activate_dedicated_bearer_context_request(bearer);
}
} else {
/*
* After received Activate EPS default bearer context accept
* Invoke nas_eps_send_activate_all_dedicated_bearers()
*/
}
}
@ -484,7 +500,7 @@ void mme_s11_handle_update_bearer_request(
ogs_assert(xact);
ogs_assert(req);
ogs_debug("[MME] Update Bearer Request");
ogs_debug("Update Bearer Request");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
@ -526,60 +542,62 @@ void mme_s11_handle_update_bearer_request(
ogs_debug(" PTI[%d]", sess->pti);
}
/* Save Transaction. will be handled after EMM-attached */
/*
* Save Transaction. It will be handled after EMM-attached
*
* You should not remove OLD bearer->xact.
* If GTP-xact Holding timer is expired,
* OLD bearer->xact memory will be automatically removed.
*/
bearer->xact = xact;
if (/* Check if Activate Default/Dedicated Bearer Accept is received */
OGS_FSM_CHECK(&bearer->sm, esm_state_active) &&
/* Check if Initial Context Setup Response or
* E-RAB Setup Response is received */
MME_HAVE_ENB_S1U_PATH(bearer)) {
if (req->bearer_contexts.bearer_level_qos.presence == 1) {
/* Bearer QoS */
ogs_expect_or_return(ogs_gtp_parse_bearer_qos(&bearer_qos,
&req->bearer_contexts.bearer_level_qos) ==
req->bearer_contexts.bearer_level_qos.len);
bearer->qos.qci = bearer_qos.qci;
bearer->qos.arp.priority_level = bearer_qos.priority_level;
bearer->qos.arp.pre_emption_capability =
bearer_qos.pre_emption_capability;
bearer->qos.arp.pre_emption_vulnerability =
bearer_qos.pre_emption_vulnerability;
bearer->qos.mbr.downlink = bearer_qos.dl_mbr;
bearer->qos.mbr.uplink = bearer_qos.ul_mbr;
bearer->qos.gbr.downlink = bearer_qos.dl_gbr;
bearer->qos.gbr.uplink = bearer_qos.ul_gbr;
}
if (req->bearer_contexts.bearer_level_qos.presence == 1) {
/* Bearer QoS */
ogs_expect_or_return(ogs_gtp_parse_bearer_qos(&bearer_qos,
&req->bearer_contexts.bearer_level_qos) ==
req->bearer_contexts.bearer_level_qos.len);
bearer->qos.qci = bearer_qos.qci;
bearer->qos.arp.priority_level = bearer_qos.priority_level;
bearer->qos.arp.pre_emption_capability =
bearer_qos.pre_emption_capability;
bearer->qos.arp.pre_emption_vulnerability =
bearer_qos.pre_emption_vulnerability;
bearer->qos.mbr.downlink = bearer_qos.dl_mbr;
bearer->qos.mbr.uplink = bearer_qos.ul_mbr;
bearer->qos.gbr.downlink = bearer_qos.dl_gbr;
bearer->qos.gbr.uplink = bearer_qos.ul_gbr;
if (req->bearer_contexts.tft.presence == 1) {
/* Save Bearer TFT */
OGS_TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft);
}
xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE;
}
if (req->bearer_contexts.bearer_level_qos.presence == 1 ||
req->bearer_contexts.tft.presence == 1) {
nas_eps_send_modify_bearer_context_request(bearer,
if (req->bearer_contexts.tft.presence == 1) {
/* Save Bearer TFT */
OGS_TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft);
xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE;
}
if (req->bearer_contexts.bearer_level_qos.presence == 1 ||
req->bearer_contexts.tft.presence == 1) {
if (ECM_IDLE(mme_ue)) {
s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
} else {
nas_eps_send_modify_bearer_context_request(bearer,
req->bearer_contexts.bearer_level_qos.presence,
req->bearer_contexts.tft.presence);
} else {
ogs_warn("[IGNORE] Update Bearer Request : "
"Both QoS and TFT is NULL");
if (xact->xid & OGS_GTP_CMD_XACT_ID) {
/* MME recieved Bearer resource modification request */
nas_eps_send_bearer_resource_modification_reject(
bearer, ESM_CAUSE_SERVICE_OPTION_NOT_SUPPORTED);
}
mme_gtp_send_update_bearer_response(bearer);
}
} else {
if (!OGS_FSM_CHECK(&bearer->sm, esm_state_active)) {
ogs_assert_if_reached();
} else if (!MME_HAVE_ENB_S1U_PATH(bearer)) {
ogs_assert_if_reached();
} else
ogs_assert_if_reached();
ogs_warn("[IGNORE] Update Bearer Request : "
"Both QoS and TFT is NULL");
if (xact->xid & OGS_GTP_CMD_XACT_ID) {
/* MME received Bearer Resource Modification Request */
nas_eps_send_bearer_resource_modification_reject(
bearer, ESM_CAUSE_SERVICE_OPTION_NOT_SUPPORTED);
}
mme_gtp_send_update_bearer_response(
bearer, OGS_GTP_CAUSE_REQUEST_ACCEPTED);
}
}
@ -593,7 +611,7 @@ void mme_s11_handle_delete_bearer_request(
ogs_assert(xact);
ogs_assert(req);
ogs_debug("[MME] Delete Bearer Request");
ogs_debug("Delete Bearer Request");
if (mme_ue && req->linked_eps_bearer_id.presence == 1) {
bearer = mme_bearer_find_by_ue_ebi(
@ -632,25 +650,21 @@ void mme_s11_handle_delete_bearer_request(
ogs_debug(" PTI[%d]", sess->pti);
}
/* Save Transaction. will be handled after EMM-attached */
ogs_assert(bearer);
/*
* Save Transaction. It will be handled after EMM-attached
*
* You should not remove OLD bearer->xact.
* If GTP-xact Holding timer is expired,
* OLD bearer->xact memory will be automatically removed.
*/
bearer->xact = xact;
if (/* Check if Activate Default/Dedicated Bearer Accept is received */
OGS_FSM_CHECK(&bearer->sm, esm_state_active) &&
/* Check if Initial Context Setup Response or
* E-RAB Setup Response is received */
MME_HAVE_ENB_S1U_PATH(bearer)) {
nas_eps_send_deactivate_bearer_context_request(bearer);
if (ECM_IDLE(mme_ue)) {
s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
} else {
if (!OGS_FSM_CHECK(&bearer->sm, esm_state_active)) {
ogs_assert_if_reached();
} else if (!MME_HAVE_ENB_S1U_PATH(bearer)) {
ogs_assert_if_reached();
} else
ogs_assert_if_reached();
nas_eps_send_deactivate_bearer_context_request(bearer);
}
}
void mme_s11_handle_release_access_bearers_response(
@ -659,12 +673,18 @@ void mme_s11_handle_release_access_bearers_response(
{
int rv;
uint8_t cause_value = 0;
int action = 0;
enb_ue_t *enb_ue = NULL;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
ogs_assert(xact);
ogs_assert(rsp);
action = xact->release_action;
ogs_assert(action);
ogs_debug("[MME] Release Access Bearers Response");
ogs_debug("Release Access Bearers Response");
if (!mme_ue) {
ogs_warn("No Context in TEID");
@ -687,21 +707,31 @@ void mme_s11_handle_release_access_bearers_response(
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
CLEAR_ENB_S1U_PATH(bearer);
}
}
rv = CLEAR_BEARER_CONTEXT(mme_ue);
ogs_expect(rv == OGS_OK);
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
if (enb_ue) {
s1ap_send_ue_context_release_command(enb_ue,
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
S1AP_UE_CTX_REL_S1_REMOVE_AND_UNLINK, 0);
if (action == OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND) {
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
if (enb_ue) {
s1ap_send_ue_context_release_command(enb_ue,
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
S1AP_UE_CTX_REL_S1_REMOVE_AND_UNLINK, 0);
} else {
ogs_warn("ENB-S1 Context has already been removed");
}
} else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE) {
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
if (enb_ue) {
enb_ue_remove(enb_ue);
} else {
ogs_warn("ENB-S1 Context has already been removed");
}
} else {
ogs_warn("ENB-S1 Context has already been removed");
ogs_fatal("Invalid action = %d", action);
ogs_assert_if_reached();
}
}
@ -709,18 +739,40 @@ void mme_s11_handle_downlink_data_notification(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_downlink_data_notification_t *noti)
{
int rv;
uint8_t cause_value = 0;
ogs_gtp_header_t h;
ogs_pkbuf_t *s11buf = NULL;
mme_bearer_t *bearer = NULL;
ogs_assert(xact);
ogs_assert(noti);
ogs_debug("[MME] Downlink Data Notification");
ogs_debug("Downlink Data Notification");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (noti->eps_bearer_id.presence == 0) {
ogs_error("No Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!mme_ue) {
ogs_warn("OGS_GTP_CAUSE_CONTEXT_NOT_FOUND");
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = mme_bearer_find_by_ue_ebi(mme_ue, noti->eps_bearer_id.u8);
if (!bearer)
ogs_error("No Context for EPS Bearer ID[%d]",
noti->eps_bearer_id.u8);
}
if (!bearer) {
ogs_error("No context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(xact, mme_ue ? mme_ue->sgw_s11_teid : 0,
OGS_GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
OGS_GTP_CAUSE_CONTEXT_NOT_FOUND);
@ -728,22 +780,18 @@ void mme_s11_handle_downlink_data_notification(
}
ogs_assert(mme_ue);
ogs_assert(bearer);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
/* Build Downlink data notification ack */
memset(&h, 0, sizeof(ogs_gtp_header_t));
h.type = OGS_GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE;
h.teid = mme_ue->sgw_s11_teid;
s11buf = mme_s11_build_downlink_data_notification_ack(h.type);
ogs_expect_or_return(s11buf);
rv = ogs_gtp_xact_update_tx(xact, &h, s11buf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
/*
* Save Transaction. It will be handled after ECM-Connected
*
* You should not remove OLD bearer->xact.
* If GTP-xact Holding timer is expired,
* OLD bearer->xact memory will be automatically removed.
*/
bearer->xact = xact;
if (noti->cause.presence) {
ogs_gtp_cause_t *cause = noti->cause.data;
@ -805,6 +853,9 @@ void mme_s11_handle_downlink_data_notification(
s1ap_send_ue_context_release_command(enb_ue,
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
S1AP_UE_CTX_REL_S1_PAGING, 0);
} else {
mme_gtp_send_downlink_data_notification_ack(
bearer, OGS_GTP_CAUSE_UE_ALREADY_RE_ATTACHED);
}
}
}
@ -824,7 +875,7 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("[MME] Create Indirect Data Forwarding Tunnel Response");
ogs_debug("Create Indirect Data Forwarding Tunnel Response");
if (!mme_ue) {
ogs_warn("No Context in TEID");
@ -896,7 +947,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("[MME] Delete Indirect Data Forwarding Tunnel Response");
ogs_debug("Delete Indirect Data Forwarding Tunnel Response");
if (!mme_ue) {
ogs_warn("No Context in TEID");
@ -924,8 +975,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
rv = mme_ue_clear_indirect_tunnel(mme_ue);
ogs_expect(rv == OGS_OK);
mme_ue_clear_indirect_tunnel(mme_ue);
}
void mme_s11_handle_bearer_resource_failure_indication(
@ -941,7 +991,7 @@ void mme_s11_handle_bearer_resource_failure_indication(
bearer = xact->data;
ogs_assert(ind);
ogs_debug("[MME] Bearer Resource Failure Indication");
ogs_debug("Bearer Resource Failure Indication");
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);

View File

@ -225,6 +225,8 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
enb = mme_enb_find_by_addr(addr);
if (enb) {
ogs_info("eNB-S1[%s] connection refused!!!", OGS_ADDR(addr, buf));
mme_gtp_send_release_all_ue_in_enb(
enb, OGS_GTP_RELEASE_S1_CONTEXT_REMOVE);
mme_enb_remove(enb);
} else {
ogs_warn("eNB-S1[%s] connection refused, Already Removed!",

View File

@ -358,17 +358,52 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request(
&UEAggregateMaximumBitrate->uEaggregateMaximumBitRateDL,
subscription_data->ambr.downlink);
sess = mme_sess_first(mme_ue);
while (sess) {
bearer = mme_bearer_first(sess);
while (bearer) {
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *item = NULL;
S1AP_E_RABToBeSetupItemCtxtSUReq_t *e_rab = NULL;
S1AP_GBR_QosInformation_t *gbrQosInformation = NULL;
S1AP_NAS_PDU_t *nasPdu = NULL;
item = CALLOC(
1, sizeof(S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t));
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) {
/*
* For Attach Request,
* Delete Session Request/Response removes ALL session/bearers.
*
* Since all bearers are INACTIVE,
* we should not check the bearer activation.
*/
} else if (OGS_FSM_CHECK(&bearer->sm, esm_state_active)) {
/*
* For Service Request/TAU Request/Extended Service Request,
* Only the active EPS bearer can be included.
*
* If MME received Create Bearer Request and
* if MME does not receive Activate EPS Bearer Context Accept,
* We should not include the INACTIVE bearer.
*
* For example,
* 1. SGW->MME : Create Bearer Request
* 2. MME->UE : S1 Paging
* 3. UE->MME : Service Request
* 4. MME->UE : Initial Context Setup Request
* (We should not include INACTIVE BEARER)
* 5. UE->MME : Initial Context Setup Response
* 6. MME->UE : Activate dedicated EPS Bearer Context Request
* 7. UE->MME : Activate dedicated EPS Bearer Context Accept
* 8. MME->SGW : Create Bearer Response
*/
} else {
ogs_warn("No active EPS bearer [%d]", bearer->ebi);
ogs_warn(" IMSI[%s] NAS-EPS Type[%d] "
"ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
mme_ue->imsi_bcd, mme_ue->nas_eps.type,
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
continue;
}
item = CALLOC(1, sizeof(S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t));
ASN_SEQUENCE_ADD(&E_RABToBeSetupListCtxtSUReq->list, item);
item->id = S1AP_ProtocolIE_ID_id_E_RABToBeSetupItemCtxtSUReq;
@ -435,12 +470,11 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request(
* set emmbuf to NULL as shown below */
emmbuf = NULL;
}
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
ogs_assert(E_RABToBeSetupListCtxtSUReq->list.count);
ie = CALLOC(1, sizeof(S1AP_InitialContextSetupRequestIEs_t));
ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie);
@ -1600,10 +1634,9 @@ ogs_pkbuf_t *s1ap_build_handover_command(enb_ue_t *source_ue)
ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
source_ue->enb_ue_s1ap_id, source_ue->mme_ue_s1ap_id);
sess = mme_sess_first(mme_ue);
while (sess) {
bearer = mme_bearer_first(sess);
while (bearer) {
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
S1AP_E_RABDataForwardingItem_t *e_rab = NULL;
if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) ||
@ -1673,10 +1706,7 @@ ogs_pkbuf_t *s1ap_build_handover_command(enb_ue_t *source_ue)
bearer->sgw_ul_teid, e_rab->uL_GTP_TEID);
ogs_debug(" SGW-UL-TEID[%d]", bearer->sgw_dl_teid);
}
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
ie = CALLOC(1, sizeof(S1AP_HandoverCommandIEs_t));
@ -1915,10 +1945,9 @@ ogs_pkbuf_t *s1ap_build_handover_request(
&UEAggregateMaximumBitrate->uEaggregateMaximumBitRateDL,
subscription_data->ambr.downlink);
sess = mme_sess_first(mme_ue);
while (sess) {
bearer = mme_bearer_first(sess);
while (bearer) {
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
S1AP_E_RABToBeSetupItemHOReqIEs_t *item = NULL;
S1AP_E_RABToBeSetupItemHOReq_t *e_rab = NULL;
S1AP_GBR_QosInformation_t *gbrQosInformation = NULL;
@ -1976,10 +2005,7 @@ ogs_pkbuf_t *s1ap_build_handover_request(
ogs_asn_uint32_to_OCTET_STRING(
bearer->sgw_s1u_teid, &e_rab->gTP_TEID);
ogs_debug(" SGW-S1U-TEID[%d]", bearer->sgw_s1u_teid);
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
ogs_s1ap_buffer_to_OCTET_STRING(

View File

@ -580,18 +580,24 @@ void s1ap_handle_initial_context_setup_response(
ogs_debug(" EBI[%d] ENB-S1U-TEID[%d]",
bearer->ebi, bearer->enb_s1u_teid);
if (OGS_FSM_CHECK(&bearer->sm, esm_state_active)) {
ogs_debug(" NAS_EPS Type[%d]", mme_ue->nas_eps.type);
int uli_presence = 0;
if (mme_ue->nas_eps.type != MME_EPS_TYPE_ATTACH_REQUEST) {
ogs_debug(" ### ULI PRESENT ###");
uli_presence = 1;
}
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) {
/* For Attach Request, Nothing to do */
} else if (OGS_FSM_CHECK(&bearer->sm, esm_state_active)) {
int uli_presence = 1;
/*
* For Service Request/TAU Request/Extended Service Request,
* ULI is present if it's the active EPS bearer.
*
*/
ogs_debug(" ### ULI PRESENT ###");
mme_gtp_send_modify_bearer_request(bearer, uli_presence);
}
}
}
if (mme_ue->nas_eps.type != MME_EPS_TYPE_ATTACH_REQUEST)
mme_send_after_paging(mme_ue, OGS_GTP_CAUSE_REQUEST_ACCEPTED);
if (SMS_SERVICE_INDICATOR(mme_ue)) {
sgsap_send_service_request(mme_ue, SGSAP_EMM_CONNECTED_MODE);
}
@ -949,7 +955,8 @@ void s1ap_handle_e_rab_setup_response(
if (bearer->ebi == linked_bearer->ebi) {
mme_gtp_send_modify_bearer_request(bearer, 0);
} else {
mme_gtp_send_create_bearer_response(bearer);
mme_gtp_send_create_bearer_response(
bearer, OGS_GTP_CAUSE_REQUEST_ACCEPTED);
}
}
}
@ -1107,7 +1114,6 @@ void s1ap_handle_ue_context_release_complete(
void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
{
int rv;
mme_ue_t *mme_ue = NULL;
ogs_assert(enb_ue);
@ -1144,15 +1150,14 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
enb_ue_remove(enb_ue);
ogs_expect_or_return(mme_ue);
if (mme_ue_have_indirect_tunnel(mme_ue)) {
if (mme_ue_have_indirect_tunnel(mme_ue) == true) {
mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
mme_ue);
} else {
ogs_warn("Check your eNodeB");
ogs_warn(" There is no INDIRECT TUNNEL");
ogs_warn(" Packet could be dropped during S1-Handover");
rv = mme_ue_clear_indirect_tunnel(mme_ue);
ogs_expect(rv == OGS_OK);
mme_ue_clear_indirect_tunnel(mme_ue);
}
break;
case S1AP_UE_CTX_REL_S1_PAGING:
@ -1685,7 +1690,7 @@ void s1ap_handle_handover_request_ack(
OGS_ASN_STORE_DATA(&mme_ue->container,
Target_ToSource_TransparentContainer);
if (mme_ue_have_indirect_tunnel(mme_ue) == 1) {
if (mme_ue_have_indirect_tunnel(mme_ue) == true) {
mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
mme_ue);
} else {
@ -2094,7 +2099,8 @@ void s1ap_handle_s1_reset(
case S1AP_ResetType_PR_s1_Interface:
ogs_warn(" S1AP_ResetType_PR_s1_Interface");
enb_ue_remove_in_enb(enb);
mme_gtp_send_release_all_ue_in_enb(
enb, OGS_GTP_RELEASE_S1_CONTEXT_REMOVE);
break;
case S1AP_ResetType_PR_partOfS1_Interface:
ogs_warn(" S1AP_ResetType_PR_partOfS1_Interface");
@ -2106,6 +2112,7 @@ void s1ap_handle_s1_reset(
S1AP_UE_associatedLogicalS1_ConnectionItem_t *item = NULL;
enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = NULL;
ie2 = (S1AP_UE_associatedLogicalS1_ConnectionItemRes_t *)
partOfS1_Interface->list.array[i];
@ -2119,8 +2126,7 @@ void s1ap_handle_s1_reset(
item->eNB_UE_S1AP_ID ? (int)*item->eNB_UE_S1AP_ID : -1);
if (item->mME_UE_S1AP_ID)
enb_ue = enb_ue_find_by_mme_ue_s1ap_id(
*item->mME_UE_S1AP_ID);
enb_ue = enb_ue_find_by_mme_ue_s1ap_id( *item->mME_UE_S1AP_ID);
else if (item->eNB_UE_S1AP_ID)
enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb,
*item->eNB_UE_S1AP_ID);
@ -2133,7 +2139,11 @@ void s1ap_handle_s1_reset(
continue;
}
enb_ue_remove(enb_ue);
mme_ue = enb_ue->mme_ue;
ogs_assert(mme_ue);
mme_gtp_send_release_access_bearers_request(
mme_ue, OGS_GTP_RELEASE_S1_CONTEXT_REMOVE);
}
break;
default:
@ -2141,6 +2151,26 @@ void s1ap_handle_s1_reset(
break;
}
/*
* In the specification, eNB can send RESET ACK without waiting
* for resource release, but MME must send after releasing all resources.
*
* Why? Huh.. At this point, I implemented MME to send RESET ACK
* without waiting for resource release. If problems are found,
* I will fix them later.
*
* TS36.413
* 8.7.1.2.1 Reset Procedure Initiated from the MME
*
* The eNB does not need to wait for the release of radio resources
* to be completed before returning the RESET ACKNOWLEDGE message.
*
* 8.7.1.2.2 Reset Procedure Initiated from the E-UTRAN
* After the MME has released all assigned S1 resources and
* the UE S1AP IDs for all indicated UE associations which can be used
* for new UE-associated logical S1-connections over the S1 interface,
* the MME shall respond with the RESET ACKNOWLEDGE message.
*/
s1ap_send_s1_reset_ack(enb, partOfS1_Interface);
}

View File

@ -139,6 +139,32 @@ void sgwc_gtp_close(void)
ogs_socknode_remove_all(&sgwc_self()->gtpc_list6);
}
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
{
sgwc_bearer_t *bearer = data;
sgwc_sess_t *sess = NULL;
sgwc_ue_t *sgwc_ue = NULL;
uint8_t type = 0;
ogs_assert(xact);
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
type = xact->seq[0].type;
switch (type) {
case OGS_GTP_DOWNLINK_DATA_NOTIFICATION_TYPE:
ogs_error("[%s] No Downlink Data Notification ACK", sgwc_ue->imsi_bcd);
break;
default:
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
}
}
void sgwc_gtp_send_downlink_data_notification(
uint8_t cause_value, sgwc_bearer_t *bearer)
{
@ -171,7 +197,8 @@ void sgwc_gtp_send_downlink_data_notification(
pkbuf = sgwc_s11_build_downlink_data_notification(cause_value, bearer);
ogs_expect_or_return(pkbuf);
gtp_xact = ogs_gtp_xact_local_create(sgwc_ue->gnode, &h, pkbuf, NULL, sess);
gtp_xact = ogs_gtp_xact_local_create(
sgwc_ue->gnode, &h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(gtp_xact);
rv = ogs_gtp_xact_commit(gtp_xact);

View File

@ -22,7 +22,7 @@
#include "s11-handler.h"
static void timeout(ogs_gtp_xact_t *xact, void *data)
static void sess_timeout(ogs_gtp_xact_t *xact, void *data)
{
sgwc_sess_t *sess = data;
sgwc_ue_t *sgwc_ue = NULL;
@ -35,6 +35,33 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
type = xact->seq[0].type;
switch (type) {
case OGS_GTP_DELETE_SESSION_REQUEST_TYPE:
ogs_error("[%s] No Delete Session Response", sgwc_ue->imsi_bcd);
sgwc_pfcp_send_session_deletion_request(sess, NULL, NULL);
break;
default:
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
}
}
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
{
sgwc_bearer_t *bearer = data;
sgwc_sess_t *sess = NULL;
sgwc_ue_t *sgwc_ue = NULL;
uint8_t type = 0;
ogs_assert(xact);
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
type = xact->seq[0].type;
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
}
@ -106,11 +133,6 @@ void sgwc_s11_handle_create_session_request(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sgwc_ue) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->imsi.presence == 0) {
ogs_error("No IMSI");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -148,6 +170,11 @@ void sgwc_s11_handle_create_session_request(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sgwc_ue) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
@ -266,8 +293,17 @@ void sgwc_s11_handle_modify_bearer_request(
ogs_error("No EPS Bearer ID");
cause.value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.presence == 0) {
ogs_error("No eNB TEID");
cause.value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (sgwc_ue && cause.value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (!sgwc_ue) {
ogs_error("No Context");
cause.value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause.value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_ue_ebi(sgwc_ue,
req->bearer_contexts_to_be_modified.eps_bearer_id.u8);
if (!bearer)
@ -280,11 +316,6 @@ void sgwc_s11_handle_modify_bearer_request(
cause.value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.presence == 0) {
ogs_error("No eNB TEID");
cause.value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause.value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
@ -385,16 +416,28 @@ void sgwc_s11_handle_delete_session_request(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sgwc_ue) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->linked_eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sgwc_ue) {
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
sess = sgwc_sess_find_by_ebi(sgwc_ue, req->linked_eps_bearer_id.u8);
if (!sess)
ogs_error("Unknown EPS Bearer [IMSI:%s, EBI:%d]",
sgwc_ue->imsi_bcd, req->linked_eps_bearer_id.u8);
}
if (!sess) {
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
@ -403,17 +446,6 @@ void sgwc_s11_handle_delete_session_request(
}
ogs_assert(sgwc_ue);
sess = sgwc_sess_find_by_ebi(sgwc_ue, req->linked_eps_bearer_id.u8);
if (!sess) {
ogs_error("No Context [IMSI:%s, EBI:%d]",
sgwc_ue->imsi_bcd, req->linked_eps_bearer_id.u8);
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE,
OGS_GTP_CAUSE_CONTEXT_NOT_FOUND);
return;
}
ogs_assert(sess);
ogs_assert(sess->gnode);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
@ -428,7 +460,7 @@ void sgwc_s11_handle_delete_session_request(
ogs_expect_or_return(gtpbuf);
s5c_xact = ogs_gtp_xact_local_create(
sess->gnode, &message->h, gtpbuf, timeout, sess);
sess->gnode, &message->h, gtpbuf, sess_timeout, sess);
ogs_expect_or_return(s5c_xact);
ogs_gtp_xact_associate(s11_xact, s5c_xact);
@ -465,40 +497,11 @@ void sgwc_s11_handle_create_bearer_response(
ogs_debug("Create Bearer Response");
if (!sgwc_ue) {
sgwc_sess_t *sess = NULL;
ogs_warn("No Context in TEID");
sess = s11_xact->data;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
}
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -520,14 +523,57 @@ void sgwc_s11_handle_create_bearer_response(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (s11_xact->xid & OGS_GTP_CMD_XACT_ID)
/* MME received Bearer Resource Modification Request */
bearer = s5c_xact->data;
else
bearer = s11_xact->data;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
if (!sgwc_ue) {
ogs_warn("No Context in TEID");
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
sgwc_pfcp_send_bearer_modification_request(
bearer, NULL, NULL,
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE);
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_CREATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
ogs_assert(sgwc_ue);
/* Correlate with SGW-S1U-TEID */
sgw_s1u_teid = rsp->bearer_contexts.s4_u_sgsn_f_teid.data;
ogs_assert(sgw_s1u_teid);
@ -535,12 +581,8 @@ void sgwc_s11_handle_create_bearer_response(
/* Find the Tunnel by SGW-S1U-TEID */
ul_tunnel = sgwc_tunnel_find_by_teid(sgwc_ue, be32toh(sgw_s1u_teid->teid));
ogs_assert(ul_tunnel);
bearer = ul_tunnel->bearer;
ogs_assert(bearer);
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
ogs_assert(dl_tunnel);
sess = bearer->sess;
ogs_assert(sess);
/* Set EBI */
bearer->ebi = rsp->bearer_contexts.eps_bearer_id.u8;
@ -597,37 +639,58 @@ void sgwc_s11_handle_update_bearer_response(
ogs_gtp_xact_t *s5c_xact = NULL;
sgwc_sess_t *sess = NULL;
sgwc_bearer_t *bearer = NULL;
ogs_gtp_update_bearer_response_t *req = NULL;
ogs_gtp_update_bearer_response_t *rsp = NULL;
ogs_assert(s11_xact);
s5c_xact = s11_xact->assoc_xact;
ogs_assert(s5c_xact);
ogs_assert(message);
req = &message->update_bearer_response;
ogs_assert(req);
rsp = &message->update_bearer_response;
ogs_assert(rsp);
ogs_debug("Update Bearer Response");
if (!sgwc_ue) {
sgwc_sess_t *sess = NULL;
ogs_warn("No Context in TEID");
sess = s11_xact->data;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
}
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
if (req->cause.presence) {
ogs_gtp_cause_t *cause = req->cause.data;
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (s11_xact->xid & OGS_GTP_CMD_XACT_ID)
/* MME received Bearer Resource Modification Request */
bearer = s5c_xact->data;
else
bearer = s11_xact->data;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
if (!sgwc_ue) {
ogs_warn("No Context in TEID");
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (req->bearer_contexts.cause.presence) {
cause = req->bearer_contexts.cause.data;
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
@ -635,41 +698,20 @@ void sgwc_s11_handle_update_bearer_response(
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (req->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (sgwc_ue && cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_ue_ebi(
sgwc_ue, req->bearer_contexts.eps_bearer_id.u8);
}
if (!bearer) {
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
@ -698,38 +740,58 @@ void sgwc_s11_handle_delete_bearer_response(
sgwc_sess_t *sess = NULL;
sgwc_bearer_t *bearer = NULL;
ogs_gtp_delete_bearer_response_t *req = NULL;
ogs_gtp_delete_bearer_response_t *rsp = NULL;
ogs_assert(s11_xact);
s5c_xact = s11_xact->assoc_xact;
ogs_assert(s5c_xact);
ogs_assert(message);
req = &message->delete_bearer_response;
ogs_assert(req);
rsp = &message->delete_bearer_response;
ogs_assert(rsp);
ogs_debug("Delete Bearer Response");
if (!sgwc_ue) {
sgwc_sess_t *sess = NULL;
ogs_warn("No Context in TEID");
sess = s11_xact->data;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
}
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
if (req->cause.presence) {
ogs_gtp_cause_t *cause = req->cause.data;
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (s11_xact->xid & OGS_GTP_CMD_XACT_ID)
/* MME received Bearer Resource Modification Request */
bearer = s5c_xact->data;
else
bearer = s11_xact->data;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
if (!sgwc_ue) {
ogs_warn("No Context in TEID");
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (req->bearer_contexts.cause.presence) {
cause = req->bearer_contexts.cause.data;
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
@ -737,41 +799,14 @@ void sgwc_s11_handle_delete_bearer_response(
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (req->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (sgwc_ue && cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_ue_ebi(
sgwc_ue, req->bearer_contexts.eps_bearer_id.u8);
ogs_assert(bearer);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_DELETE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
sess = bearer->sess;
ogs_assert(sess);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
@ -833,6 +868,7 @@ void sgwc_s11_handle_downlink_data_notification_ack(
int rv;
uint8_t cause_value;
sgwc_bearer_t *bearer = NULL;
sgwc_sess_t *sess = NULL;
ogs_gtp_downlink_data_notification_acknowledge_t *ack = NULL;
@ -842,11 +878,15 @@ void sgwc_s11_handle_downlink_data_notification_ack(
ack = &message->downlink_data_notification_acknowledge;
ogs_assert(ack);
sess = s11_xact->data;
bearer = s11_xact->data;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
@ -1048,6 +1088,7 @@ void sgwc_s11_handle_bearer_resource_command(
ogs_gtp_xact_t *s5c_xact = NULL;
sgwc_sess_t *sess = NULL;
sgwc_bearer_t *bearer = NULL;
ogs_assert(s11_xact);
ogs_assert(message);
@ -1057,23 +1098,6 @@ void sgwc_s11_handle_bearer_resource_command(
cmd = &message->bearer_resource_command;
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sgwc_ue) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cmd->linked_eps_bearer_id.presence == 0) {
ogs_error("No Linked EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
} else {
sess = sgwc_sess_find_by_ebi(sgwc_ue, cmd->linked_eps_bearer_id.u8);
if (!sess) {
ogs_error("No Context for Linked EPS Bearer ID[%d]",
cmd->linked_eps_bearer_id.u8);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
}
if (cmd->procedure_transaction_id.presence == 0) {
ogs_error("No PTI");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -1082,6 +1106,28 @@ void sgwc_s11_handle_bearer_resource_command(
ogs_error("No Traffic aggregate description(TAD)");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cmd->linked_eps_bearer_id.presence == 0) {
ogs_error("No Linked EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sgwc_ue) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_ue_ebi(
sgwc_ue, cmd->linked_eps_bearer_id.u8);
if (!bearer)
ogs_error("No Context for Linked EPS Bearer ID[%d]",
cmd->linked_eps_bearer_id.u8);
}
if (!bearer) {
ogs_error("No context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(
@ -1090,6 +1136,8 @@ void sgwc_s11_handle_bearer_resource_command(
return;
}
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
ogs_assert(sess->gnode);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
@ -1104,7 +1152,7 @@ void sgwc_s11_handle_bearer_resource_command(
ogs_expect_or_return(pkbuf);
s5c_xact = ogs_gtp_xact_local_create(
sess->gnode, &message->h, pkbuf, timeout, sess);
sess->gnode, &message->h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(s5c_xact);
ogs_gtp_xact_associate(s11_xact, s5c_xact);

View File

@ -22,21 +22,35 @@
#include "s5c-handler.h"
static void timeout(ogs_gtp_xact_t *xact, void *data)
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
{
sgwc_sess_t *sess = data;
sgwc_bearer_t *bearer = data;
sgwc_sess_t *sess = NULL;
sgwc_ue_t *sgwc_ue = NULL;
uint8_t type = 0;
ogs_assert(xact);
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
type = xact->seq[0].type;
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
switch (type) {
case OGS_GTP_UPDATE_BEARER_REQUEST_TYPE:
ogs_error("[%s] No Update Bearer Response", sgwc_ue->imsi_bcd);
break;
case OGS_GTP_DELETE_BEARER_REQUEST_TYPE:
ogs_error("[%s] No Delete Bearer Response", sgwc_ue->imsi_bcd);
sgwc_pfcp_send_bearer_modification_request(
bearer, NULL, NULL, OGS_PFCP_MODIFY_REMOVE);
break;
default:
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
}
}
void sgwc_s5c_handle_create_session_response(
@ -67,47 +81,11 @@ void sgwc_s5c_handle_create_session_response(
ogs_debug("Create Session Response");
if (!sess) {
ogs_warn("No Context in TEID");
sess = s5c_xact->data;
ogs_assert(sess);
}
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(s5c_xact);
ogs_expect(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts_created.cause.presence) {
cause = rsp->bearer_contexts_created.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
/* Deliver PGW cause value to the MME */
ogs_warn("Cause[%d] : No Accepted", cause_value);
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE,
cause_value);
return;
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED)
ogs_warn("Cause[%d] : No Accepted", cause_value);
if (rsp->bearer_contexts_created.cause.presence == 0) {
ogs_error("No EPS Bearer Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -121,21 +99,6 @@ void sgwc_s5c_handle_create_session_response(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_sess_ebi(sess,
rsp->bearer_contexts_created.eps_bearer_id.u8);
ogs_assert(bearer);
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
ogs_assert(ul_tunnel);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
presence == 0) {
ogs_error("No GTP TEID");
@ -167,13 +130,62 @@ void sgwc_s5c_handle_create_session_response(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_warn("No Context in TEID");
sess = s5c_xact->data;
ogs_assert(sess);
}
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_sess_ebi(sess,
rsp->bearer_contexts_created.eps_bearer_id.u8);
if (!bearer)
ogs_error("No Context for EPS Bearer ID[%d]",
rsp->bearer_contexts_created.eps_bearer_id.u8);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts_created.cause.presence) {
cause = rsp->bearer_contexts_created.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
sgwc_pfcp_send_session_deletion_request(sess, NULL, NULL);
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE, cause_value);
return;
}
ogs_assert(bearer);
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
ogs_assert(ul_tunnel);
/* Receive Data Plane(UL) : PGW-S5U */
pgw_s5u_teid = rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.data;
ogs_assert(pgw_s5u_teid);
@ -233,14 +245,19 @@ void sgwc_s5c_handle_delete_session_response(
ogs_debug("Delete Session Response");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(s5c_xact);
ogs_expect(rv == OGS_OK);
if (!sess) {
ogs_warn("No Context in TEID");
sess = s5c_xact->data;
ogs_assert(sess);
}
rv = ogs_gtp_xact_commit(s5c_xact);
ogs_expect(rv == OGS_OK);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
@ -253,15 +270,13 @@ void sgwc_s5c_handle_delete_session_response(
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
sgwc_pfcp_send_session_deletion_request(sess, NULL, NULL);
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE, cause_value);
return;
}
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
/* Remove a pgw session */
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
@ -295,11 +310,6 @@ void sgwc_s5c_handle_create_bearer_request(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->linked_eps_bearer_id.presence == 0) {
ogs_error("No Linked EBI");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -317,6 +327,11 @@ void sgwc_s5c_handle_create_bearer_request(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_CREATE_BEARER_RESPONSE_TYPE, cause_value);
@ -373,6 +388,7 @@ void sgwc_s5c_handle_update_bearer_request(
ogs_gtp_update_bearer_request_t *req = NULL;
ogs_pkbuf_t *pkbuf = NULL;
sgwc_ue_t *sgwc_ue = NULL;
sgwc_bearer_t *bearer = NULL;
ogs_assert(s5c_xact);
ogs_assert(message);
@ -383,11 +399,6 @@ void sgwc_s5c_handle_update_bearer_request(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -397,16 +408,36 @@ void sgwc_s5c_handle_update_bearer_request(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_sess_ebi(
sess, req->bearer_contexts.eps_bearer_id.u8);
if (!bearer)
ogs_error("No Context for EPS Bearer ID[%d]",
req->bearer_contexts.eps_bearer_id.u8);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
ogs_assert(sess);
ogs_assert(bearer);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
ogs_assert(sgwc_ue->gnode);
ogs_debug(" EBI[%d]", bearer->ebi);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
@ -421,7 +452,7 @@ void sgwc_s5c_handle_update_bearer_request(
s11_xact = s5c_xact->assoc_xact;
if (!s11_xact) {
s11_xact = ogs_gtp_xact_local_create(
sgwc_ue->gnode, &message->h, pkbuf, timeout, sess);
sgwc_ue->gnode, &message->h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(s11_xact);
ogs_gtp_xact_associate(s5c_xact, s11_xact);
@ -446,6 +477,7 @@ void sgwc_s5c_handle_delete_bearer_request(
ogs_gtp_delete_bearer_request_t *req = NULL;
ogs_pkbuf_t *pkbuf = NULL;
sgwc_ue_t *sgwc_ue = NULL;
sgwc_bearer_t *bearer = NULL;
ogs_assert(s5c_xact);
ogs_assert(message);
@ -456,14 +488,25 @@ void sgwc_s5c_handle_delete_bearer_request(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (req->linked_eps_bearer_id.presence == 0 &&
req->eps_bearer_ids.presence == 0) {
ogs_error("No Linked EBI or EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->linked_eps_bearer_id.presence == 0 &&
req->eps_bearer_ids.presence == 0) {
ogs_error("No Linked EBI or EPS Bearer ID");
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = sgwc_bearer_find_by_sess_ebi(sess, req->eps_bearer_ids.u8);
if (!bearer)
ogs_error("No Context for EPS Bearer ID[%d]",
req->eps_bearer_ids.u8);
}
if (!bearer) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
@ -473,10 +516,13 @@ void sgwc_s5c_handle_delete_bearer_request(
return;
}
ogs_assert(sess);
ogs_assert(bearer);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
ogs_assert(sgwc_ue->gnode);
ogs_debug(" EBI[%d]", bearer->ebi);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
@ -491,7 +537,7 @@ void sgwc_s5c_handle_delete_bearer_request(
s11_xact = s5c_xact->assoc_xact;
if (!s11_xact) {
s11_xact = ogs_gtp_xact_local_create(
sgwc_ue->gnode, &message->h, pkbuf, timeout, sess);
sgwc_ue->gnode, &message->h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(s11_xact);
ogs_gtp_xact_associate(s5c_xact, s11_xact);

View File

@ -60,7 +60,7 @@ static uint8_t gtp_cause_from_pfcp(uint8_t pfcp_cause)
return OGS_GTP_CAUSE_SYSTEM_FAILURE;
}
static void timeout(ogs_gtp_xact_t *xact, void *data)
static void sess_timeout(ogs_gtp_xact_t *xact, void *data)
{
sgwc_sess_t *sess = data;
sgwc_ue_t *sgwc_ue = NULL;
@ -73,8 +73,44 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
type = xact->seq[0].type;
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
switch (type) {
case OGS_GTP_CREATE_SESSION_REQUEST_TYPE:
ogs_error("[%s] No Create Session Response", sgwc_ue->imsi_bcd);
sgwc_pfcp_send_session_deletion_request(sess, NULL, NULL);
break;
default:
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
}
}
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
{
sgwc_bearer_t *bearer = data;
sgwc_sess_t *sess = NULL;
sgwc_ue_t *sgwc_ue = NULL;
uint8_t type = 0;
ogs_assert(xact);
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
type = xact->seq[0].type;
switch (type) {
case OGS_GTP_CREATE_BEARER_REQUEST_TYPE:
ogs_error("[%s] No Create Bearer Response", sgwc_ue->imsi_bcd);
sgwc_pfcp_send_bearer_modification_request(
bearer, NULL, NULL,
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE);
break;
default:
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
sgwc_ue->imsi_bcd, type);
}
}
void sgwc_sxa_handle_session_establishment_response(
@ -269,7 +305,7 @@ void sgwc_sxa_handle_session_establishment_response(
ogs_assert(sess->gnode);
s5c_xact = ogs_gtp_xact_local_create(
sess->gnode, &gtp_message->h, pkbuf, timeout, sess);
sess->gnode, &gtp_message->h, pkbuf, sess_timeout, sess);
ogs_expect_or_return(s5c_xact);
ogs_gtp_xact_associate(s11_xact, s5c_xact);
@ -308,9 +344,38 @@ void sgwc_sxa_handle_session_modification_response(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
if (flags & OGS_PFCP_MODIFY_SESSION) {
if (!sess) {
ogs_warn("No Context");
sess = pfcp_xact->data;
ogs_assert(sess);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
} else {
bearer = pfcp_xact->data;
ogs_assert(bearer);
if (!sess) {
ogs_warn("No Context");
sess = bearer->sess;
ogs_assert(sess);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
sgwc_ue = bearer->sgwc_ue;
ogs_assert(sgwc_ue);
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
ogs_assert(dl_tunnel);
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
ogs_assert(ul_tunnel);
}
if (pfcp_rsp->cause.presence) {
@ -327,7 +392,6 @@ void sgwc_sxa_handle_session_modification_response(
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++) {
sgwc_tunnel_t *tunnel = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
@ -364,7 +428,6 @@ void sgwc_sxa_handle_session_modification_response(
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (sess) sgwc_ue = sess->sgwc_ue;
if (flags & OGS_PFCP_MODIFY_CREATE) {
s5c_xact = pfcp_xact->assoc_xact;
ogs_assert(s5c_xact);
@ -375,11 +438,14 @@ void sgwc_sxa_handle_session_modification_response(
} else if (flags & OGS_PFCP_MODIFY_REMOVE) {
s5c_xact = pfcp_xact->assoc_xact;
ogs_assert(s5c_xact);
ogs_gtp_send_error_message(
s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_DELETE_BEARER_RESPONSE_TYPE, cause_value);
if (s5c_xact) {
ogs_gtp_send_error_message(
s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP_DELETE_BEARER_RESPONSE_TYPE, cause_value);
}
sgwc_bearer_remove(bearer);
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
@ -414,24 +480,6 @@ void sgwc_sxa_handle_session_modification_response(
return;
}
if (flags & OGS_PFCP_MODIFY_SESSION) {
sess = pfcp_xact->data;
ogs_assert(sess);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
} else {
bearer = pfcp_xact->data;
ogs_assert(bearer);
sgwc_ue = bearer->sgwc_ue;
ogs_assert(sgwc_ue);
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
ogs_assert(dl_tunnel);
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
ogs_assert(ul_tunnel);
}
if (flags & OGS_PFCP_MODIFY_CREATE) {
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
ogs_gtp_create_bearer_request_t *gtp_req = NULL;
@ -467,8 +515,9 @@ void sgwc_sxa_handle_session_modification_response(
ogs_expect_or_return(pkbuf);
ogs_assert(sgwc_ue->gnode);
s11_xact = ogs_gtp_xact_local_create(
sgwc_ue->gnode, &recv_message->h, pkbuf, timeout, sess);
ogs_assert(bearer);
s11_xact = ogs_gtp_xact_local_create(sgwc_ue->gnode,
&recv_message->h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(s11_xact);
ogs_gtp_xact_associate(s5c_xact, s11_xact);
@ -720,20 +769,21 @@ void sgwc_sxa_handle_session_modification_response(
} else {
s5c_xact = pfcp_xact->assoc_xact;
ogs_assert(s5c_xact);
ogs_assert(recv_message);
recv_message->h.type = OGS_GTP_DELETE_BEARER_RESPONSE_TYPE;
recv_message->h.teid = sess->pgw_s5c_teid;
if (s5c_xact) {
ogs_assert(recv_message);
recv_message->h.type = OGS_GTP_DELETE_BEARER_RESPONSE_TYPE;
recv_message->h.teid = sess->pgw_s5c_teid;
pkbuf = ogs_gtp_build_msg(recv_message);
ogs_expect_or_return(pkbuf);
pkbuf = ogs_gtp_build_msg(recv_message);
ogs_expect_or_return(pkbuf);
rv = ogs_gtp_xact_update_tx(s5c_xact, &recv_message->h, pkbuf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_gtp_xact_update_tx(s5c_xact, &recv_message->h, pkbuf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_gtp_xact_commit(s5c_xact);
ogs_expect(rv == OGS_OK);
rv = ogs_gtp_xact_commit(s5c_xact);
ogs_expect(rv == OGS_OK);
}
sgwc_bearer_remove(bearer);
}
@ -928,9 +978,6 @@ void sgwc_sxa_handle_session_deletion_response(
ogs_assert(pfcp_xact);
ogs_assert(pfcp_rsp);
s11_xact = pfcp_xact->assoc_xact;
ogs_assert(s11_xact);
ogs_pfcp_xact_commit(pfcp_xact);
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
@ -950,11 +997,15 @@ void sgwc_sxa_handle_session_deletion_response(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
s11_xact = pfcp_xact->assoc_xact;
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (sess) sgwc_ue = sess->sgwc_ue;
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE, cause_value);
if (s11_xact) {
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP_DELETE_SESSION_RESPONSE_TYPE, cause_value);
}
return;
}
@ -962,17 +1013,19 @@ void sgwc_sxa_handle_session_deletion_response(
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);
gtp_message->h.type = OGS_GTP_DELETE_SESSION_RESPONSE_TYPE;
gtp_message->h.teid = sgwc_ue->mme_s11_teid;
if (s11_xact) {
gtp_message->h.type = OGS_GTP_DELETE_SESSION_RESPONSE_TYPE;
gtp_message->h.teid = sgwc_ue->mme_s11_teid;
pkbuf = ogs_gtp_build_msg(gtp_message);
ogs_expect_or_return(pkbuf);
pkbuf = ogs_gtp_build_msg(gtp_message);
ogs_expect_or_return(pkbuf);
rv = ogs_gtp_xact_update_tx(s11_xact, &gtp_message->h, pkbuf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_gtp_xact_update_tx(s11_xact, &gtp_message->h, pkbuf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
}
sgwc_sess_remove(sess);
}

View File

@ -23,17 +23,40 @@
#include "ipfw/ipfw2.h"
static void timeout(ogs_gtp_xact_t *xact, void *data)
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
{
smf_sess_t *sess = data;
smf_bearer_t *bearer = data;
smf_sess_t *sess = NULL;
smf_ue_t *smf_ue = NULL;
uint8_t type = 0;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
type = xact->seq[0].type;
ogs_debug("GTP Timeout : SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x] "
"Message-Type[%d]", sess->sgw_s5c_teid, sess->smf_n4_teid, type);
switch (type) {
case OGS_GTP_CREATE_BEARER_REQUEST_TYPE:
ogs_error("[%s] No Create Bearer Response", smf_ue->imsi_bcd);
smf_epc_pfcp_send_bearer_modification_request(
bearer, OGS_PFCP_MODIFY_REMOVE);
break;
case OGS_GTP_UPDATE_BEARER_REQUEST_TYPE:
ogs_error("[%s] No Update Bearer Response", smf_ue->imsi_bcd);
break;
case OGS_GTP_DELETE_BEARER_REQUEST_TYPE:
ogs_error("[%s] No Delete Bearer Response", smf_ue->imsi_bcd);
smf_epc_pfcp_send_bearer_modification_request(
bearer, OGS_PFCP_MODIFY_REMOVE);
break;
default:
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
smf_ue->imsi_bcd, type);
break;
}
}
/*
@ -378,7 +401,7 @@ void smf_bearer_binding(smf_sess_t *sess)
ogs_expect_or_return(pkbuf);
xact = ogs_gtp_xact_local_create(
sess->gnode, &h, pkbuf, timeout, sess);
sess->gnode, &h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(xact);
if (pcc_rule->num_of_flow)
@ -409,7 +432,7 @@ void smf_bearer_binding(smf_sess_t *sess)
ogs_expect_or_return(pkbuf);
xact = ogs_gtp_xact_local_create(
sess->gnode, &h, pkbuf, timeout, sess);
sess->gnode, &h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(xact);
rv = ogs_gtp_xact_commit(xact);
@ -444,7 +467,8 @@ void smf_gtp_send_create_bearer_request(smf_bearer_t *bearer)
pkbuf = smf_s5c_build_create_bearer_request(h.type, bearer, &tft);
ogs_expect_or_return(pkbuf);
xact = ogs_gtp_xact_local_create(sess->gnode, &h, pkbuf, timeout, sess);
xact = ogs_gtp_xact_local_create(
sess->gnode, &h, pkbuf, bearer_timeout, bearer);
ogs_expect_or_return(xact);
rv = ogs_gtp_xact_commit(xact);

View File

@ -68,15 +68,10 @@ void smf_s5c_handle_create_session_request(
ogs_assert(xact);
ogs_assert(req);
ogs_debug("[SMF] Create Session Reqeust");
ogs_debug("Create Session Reqeust");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (req->imsi.presence == 0) {
ogs_error("No IMSI");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -114,6 +109,11 @@ void smf_s5c_handle_create_session_request(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (!ogs_diam_peer_connected()) {
ogs_warn("No Diameter Peer");
cause_value = OGS_GTP_CAUSE_REMOTE_PEER_NOT_RESPONDING;
@ -239,7 +239,7 @@ void smf_s5c_handle_delete_session_request(
{
uint8_t cause_value = 0;
ogs_debug("[SMF] Delete Session Request");
ogs_debug("Delete Session Request");
ogs_assert(xact);
ogs_assert(req);
@ -274,6 +274,7 @@ void smf_s5c_handle_create_bearer_response(
ogs_gtp_create_bearer_response_t *rsp)
{
int rv;
uint8_t cause_value;
ogs_gtp_f_teid_t *sgw_s5u_teid, *pgw_s5u_teid;
smf_bearer_t *bearer = NULL;
ogs_pfcp_far_t *dl_far = NULL;
@ -281,43 +282,68 @@ void smf_s5c_handle_create_bearer_response(
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("[SMF] Create Bearer Response");
ogs_debug("Create Bearer Response");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
if (!sess) {
ogs_warn("No Context in TEID");
return;
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.s5_s8_u_pgw_f_teid.presence == 0) {
ogs_error("No SMF TEID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.s5_s8_u_sgw_f_teid.presence == 0) {
ogs_error("No SGW TEID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
bearer = xact->data;
ogs_assert(bearer);
if (!sess) {
ogs_warn("No Context in TEID");
sess = bearer->sess;
ogs_assert(sess);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
if (cause->value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_warn("GTP Failed [CAUSE:%d]", cause->value);
return;
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
return;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
return;
}
if (rsp->bearer_contexts.s5_s8_u_pgw_f_teid.presence == 0) {
ogs_error("No SMF TEID");
return;
}
if (rsp->bearer_contexts.s5_s8_u_sgw_f_teid.presence == 0) {
ogs_error("No SGW TEID");
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
smf_epc_pfcp_send_bearer_modification_request(
bearer, OGS_PFCP_MODIFY_REMOVE);
return;
}
@ -339,7 +365,7 @@ void smf_s5c_handle_create_bearer_response(
rv = ogs_gtp_f_teid_to_ip(sgw_s5u_teid, &bearer->sgw_s5u_ip);
ogs_assert(rv == OGS_OK);
ogs_debug("[SMF] Create Bearer Response : SGW[0x%x] --> SMF[0x%x]",
ogs_debug("Create Bearer Response : SGW[0x%x] --> SMF[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
/* Setup FAR */
@ -359,6 +385,7 @@ void smf_s5c_handle_update_bearer_response(
ogs_gtp_update_bearer_response_t *rsp)
{
int rv;
uint8_t cause_value;
uint64_t gtp_flags = 0;
uint64_t pfcp_flags = 0;
smf_bearer_t *bearer = NULL;
@ -368,43 +395,65 @@ void smf_s5c_handle_update_bearer_response(
gtp_flags = xact->update_flags;
ogs_assert(gtp_flags);
ogs_debug("[SMF] Update Bearer Response");
ogs_debug("Update Bearer Response");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
if (!sess) {
ogs_warn("No Context in TEID");
return;
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
bearer = xact->data;
ogs_assert(bearer);
if (!sess) {
ogs_warn("No Context in TEID");
sess = bearer->sess;
ogs_assert(sess);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
if (cause->value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_warn("GTP Failed [CAUSE:%d]", cause->value);
return;
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
return;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
return;
}
bearer = smf_bearer_find_by_ebi(
sess, rsp->bearer_contexts.eps_bearer_id.u8);
ogs_expect_or_return(bearer);
ogs_debug("[SMF] Update Bearer Response : SGW[0x%x] --> SMF[0x%x]",
ogs_debug("Update Bearer Response : SGW[0x%x] --> SMF[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (gtp_flags & OGS_GTP_MODIFY_TFT_UPDATE) {
@ -461,48 +510,67 @@ void smf_s5c_handle_delete_bearer_response(
ogs_gtp_delete_bearer_response_t *rsp)
{
int rv;
uint8_t cause_value;
smf_bearer_t *bearer = NULL;
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("[SMF] Delete Bearer Response");
ogs_debug("Delete Bearer Response");
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
if (!sess) {
ogs_warn("No Context in TEID");
return;
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
bearer = xact->data;
ogs_assert(bearer);
if (!sess) {
ogs_warn("No Context in TEID");
sess = bearer->sess;
ogs_assert(sess);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
if (cause->value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_warn("GTP Failed [CAUSE:%d]", cause->value);
return;
cause_value = cause->value;
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (rsp->bearer_contexts.cause.presence) {
cause = rsp->bearer_contexts.cause.data;
ogs_assert(cause);
cause_value = cause->value;
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
} else {
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
} else {
ogs_error("No Cause");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (rsp->bearer_contexts.presence == 0) {
ogs_error("No Bearer");
return;
}
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
ogs_error("No EPS Bearer ID");
return;
}
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
bearer = smf_bearer_find_by_ebi(
sess, rsp->bearer_contexts.eps_bearer_id.u8);
ogs_expect_or_return(bearer);
ogs_debug("[SMF] Delete Bearer Response : SGW[0x%x] --> SMF[0x%x]",
ogs_debug("Delete Bearer Response : SGW[0x%x] --> SMF[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
smf_epc_pfcp_send_bearer_modification_request(
@ -624,19 +692,6 @@ void smf_s5c_handle_bearer_resource_command(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (cmd->linked_eps_bearer_id.presence == 0) {
ogs_error("No Linked EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
} else {
bearer = smf_bearer_find_by_ebi(
sess, cmd->linked_eps_bearer_id.u8);
if (!bearer) {
ogs_error("No Context for Linked EPS Bearer ID[%d]",
cmd->linked_eps_bearer_id.u8);
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
}
if (cmd->procedure_transaction_id.presence == 0) {
ogs_error("No PTI");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -646,6 +701,28 @@ void smf_s5c_handle_bearer_resource_command(
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cmd->linked_eps_bearer_id.presence == 0) {
ogs_error("No Linked EPS Bearer ID");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
bearer = smf_bearer_find_by_ebi(sess, cmd->linked_eps_bearer_id.u8);
if (!bearer)
ogs_error("No Context for Linked EPS Bearer ID[%d]",
cmd->linked_eps_bearer_id.u8);
}
if (!bearer) {
ogs_error("No Context");
cause_value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
OGS_GTP_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
@ -852,6 +929,24 @@ void smf_s5c_handle_bearer_resource_command(
xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE;
}
/* IMPORTANT:
*
* When initiaited by Bearer Resource Command, there must be bearer context
* in the Transaction. Otherwise, the beare context cannot be found
* in GTP response message.
*
* For example,
* 1. MME sends Bearer Resource Command to SGW-C, SMF.
* 2. SMF sends Update/Delete Bearer Request to the SGW-C, MME.
* 3. MME sends Update/Delete Bearer Response to thw SGW-C, SMF.
*
* On number 3 step, if MME sends Response without Bearer Context,
* we need a way to find Bearer context.
*
* To do this, I saved Bearer Context in Transaction Context.
*/
xact->data = bearer;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}

View File

@ -982,6 +982,7 @@ static void test3_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
#if 0 /* WITHOUT checking NO active EPS bearers */
/* Receive Initial Context Setup Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
@ -1033,6 +1034,7 @@ static void test3_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id;
#endif
/* Receive Service Reject */
recvbuf = testenb_s1ap_read(s1ap);

View File

@ -101,3 +101,19 @@ void testesm_handle_activate_dedicated_eps_bearer_context_request(
bearer = test_bearer_add(sess, message->esm.h.eps_bearer_identity);
ogs_assert(bearer);
}
void testesm_handle_deactivate_eps_bearer_context_request(
test_ue_t *test_ue, ogs_nas_eps_message_t *message)
{
test_sess_t *sess = NULL;
test_bearer_t *bearer = NULL;
uint8_t ebi;
ogs_assert(message);
ebi = message->esm.h.eps_bearer_identity;
ogs_assert(ebi);
bearer = test_bearer_find_by_ue_ebi(test_ue, ebi);
ogs_assert(bearer);
}

View File

@ -28,6 +28,8 @@ void testesm_handle_activate_default_eps_bearer_context_request(
test_ue_t *test_ue, ogs_nas_eps_message_t *message);
void testesm_handle_activate_dedicated_eps_bearer_context_request(
test_ue_t *test_ue, ogs_nas_eps_message_t *message);
void testesm_handle_deactivate_eps_bearer_context_request(
test_ue_t *test_ue, ogs_nas_eps_message_t *message);
#ifdef __cplusplus
}

View File

@ -187,6 +187,7 @@ void testesm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
case OGS_NAS_EPS_MODIFY_EPS_BEARER_CONTEXT_REQUEST:
break;
case OGS_NAS_EPS_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST:
testesm_handle_deactivate_eps_bearer_context_request(test_ue, &message);
break;
case OGS_NAS_EPS_BEARER_RESOURCE_ALLOCATION_REJECT:
break;

View File

@ -489,10 +489,6 @@ ogs_pkbuf_t *test_s1ap_build_initial_context_setup_response(test_ue_t *test_ue)
S1AP_E_RABSetupItemCtxtSURes_t *e_rab = NULL;
ogs_assert(test_ue);
sess = ogs_list_first(&test_ue->sess_list);
ogs_assert(sess);
bearer = ogs_list_first(&sess->bearer_list);
ogs_assert(bearer);
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome;
@ -543,28 +539,32 @@ ogs_pkbuf_t *test_s1ap_build_initial_context_setup_response(test_ue_t *test_ue)
E_RABSetupListCtxtSURes = &ie->value.choice.E_RABSetupListCtxtSURes;
item = CALLOC(1, sizeof(S1AP_E_RABSetupItemCtxtSUResIEs_t));
ASN_SEQUENCE_ADD(&E_RABSetupListCtxtSURes->list, item);
ogs_list_for_each(&test_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
item = CALLOC(1, sizeof(S1AP_E_RABSetupItemCtxtSUResIEs_t));
ASN_SEQUENCE_ADD(&E_RABSetupListCtxtSURes->list, item);
item->id = S1AP_ProtocolIE_ID_id_E_RABSetupItemCtxtSURes;
item->criticality = S1AP_Criticality_ignore;
item->value.present =
S1AP_E_RABSetupItemCtxtSUResIEs__value_PR_E_RABSetupItemCtxtSURes;
item->id = S1AP_ProtocolIE_ID_id_E_RABSetupItemCtxtSURes;
item->criticality = S1AP_Criticality_ignore;
item->value.present =
S1AP_E_RABSetupItemCtxtSUResIEs__value_PR_E_RABSetupItemCtxtSURes;
e_rab = &item->value.choice.E_RABSetupItemCtxtSURes;
e_rab = &item->value.choice.E_RABSetupItemCtxtSURes;
e_rab->e_RAB_ID = bearer->ebi;
e_rab->e_RAB_ID = bearer->ebi;
rv = ogs_gtp_sockaddr_to_f_teid(
bearer->enb_s1u_addr, bearer->enb_s1u_addr6, &f_teid, &len);
ogs_assert(rv == OGS_OK);
rv = ogs_gtp_sockaddr_to_f_teid(
bearer->enb_s1u_addr, bearer->enb_s1u_addr6, &f_teid, &len);
ogs_assert(rv == OGS_OK);
rv = ogs_gtp_f_teid_to_ip(&f_teid, &ip);
ogs_assert(rv == OGS_OK);
rv = ogs_gtp_f_teid_to_ip(&f_teid, &ip);
ogs_assert(rv == OGS_OK);
rv = ogs_asn_ip_to_BIT_STRING(&ip, &e_rab->transportLayerAddress);
ogs_assert(rv == OGS_OK);
ogs_asn_uint32_to_OCTET_STRING(bearer->enb_s1u_teid, &e_rab->gTP_TEID);
rv = ogs_asn_ip_to_BIT_STRING(&ip, &e_rab->transportLayerAddress);
ogs_assert(rv == OGS_OK);
ogs_asn_uint32_to_OCTET_STRING(bearer->enb_s1u_teid, &e_rab->gTP_TEID);
}
}
return ogs_s1ap_encode(&pdu);
}

View File

@ -413,7 +413,7 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(100);
ogs_msleep(300);
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi));

View File

@ -1285,6 +1285,8 @@ static void test4_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
ogs_msleep(300);
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi));
ABTS_PTR_NOTNULL(tc, doc);

View File

@ -283,6 +283,8 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
ogs_msleep(300);
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi));
ABTS_PTR_NOTNULL(tc, doc);

View File

@ -572,6 +572,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* Send Detach Request */
emmbuf = testemm_build_detach_request(test_ue, 1);
ABTS_PTR_NOTNULL(tc, emmbuf);
@ -1047,6 +1050,9 @@ static void test2_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Session Remove */
test_sess_remove(sess);
/* Send UE Context Release Request */
sendbuf = test_s1ap_build_ue_context_release_request(test_ue,
S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity);
@ -1939,6 +1945,9 @@ static void test4_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Session Remove */
test_sess_remove(sess);
/* Send PDN Connectivity Request */
sess = test_sess_add_by_apn(test_ue, "internet");
ogs_assert(sess);
@ -2034,6 +2043,9 @@ static void test4_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed in deactivate EPS bearer */
ogs_msleep(100);
@ -2055,9 +2067,17 @@ static void test4_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Attach Request */
/* Test Session Remove */
sess = test_sess_find_by_apn(test_ue, "internet");
ogs_assert(sess);
test_sess_remove(sess);
sess = test_sess_find_by_apn(test_ue, "ims");
ogs_assert(sess);
test_sess_remove(sess);
/* Send Attach Request */
sess = test_sess_add_by_apn(test_ue, "internet");
ogs_assert(sess);
memset(&sess->pdn_connectivity_param,
0, sizeof(sess->pdn_connectivity_param));
@ -2178,6 +2198,612 @@ static void test4_func(abts_case *tc, void *data)
test_ue_remove(test_ue);
}
static void test5_func(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *s1ap;
ogs_socknode_t *gtpu;
ogs_pkbuf_t *emmbuf;
ogs_pkbuf_t *esmbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_s1ap_message_t message;
uint8_t *rx_sid = NULL;
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t *test_ue = NULL;
test_sess_t *sess = NULL;
test_bearer_t *bearer = NULL;
uint32_t enb_ue_s1ap_id;
uint64_t mme_ue_s1ap_id;
const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
uint8_t k[OGS_KEY_LEN];
const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca";
uint8_t opc[OGS_KEY_LEN];
mongoc_collection_t *collection = NULL;
bson_t *doc = NULL;
int64_t count = 0;
bson_error_t error;
const char *json =
"{"
"\"_id\" : { \"$oid\" : \"310014158b8861d7605378c6\" }, "
"\"imsi\" : \"001010123456819\", "
"\"pdn\" : ["
"{"
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd32\" },"
"\"apn\" : \"internet\","
"\"qos\" : {"
"\"qci\" : 9,"
"\"arp\" : {"
"\"priority_level\" : 8,"
"\"pre_emption_vulnerability\" : 1,"
"\"pre_emption_capability\" : 1"
"}"
"},"
"\"type\" : 2"
"},"
"{"
"\"_id\" : { \"$oid\" : \"310014158b8861d7605378c7\" }, "
"\"apn\" : \"ims\", "
"\"pcc_rule\" : ["
"{"
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2d\" },"
"\"qos\" : {"
"\"qci\" : 1,"
"\"gbr\" : {"
"\"downlink\" : { \"$numberLong\" : \"64\" },"
"\"uplink\" : { \"$numberLong\" : \"44\" }"
"},"
"\"mbr\" : {"
"\"downlink\" : { \"$numberLong\" : \"64\" },"
"\"uplink\" : { \"$numberLong\" : \"44\" }"
"},"
"\"arp\" : {"
"\"priority_level\" : 3,"
"\"pre_emption_vulnerability\" : 0,"
"\"pre_emption_capability\" : 0 }"
"}"
"}"
"],"
"\"ambr\" : {"
"\"uplink\" : { \"$numberLong\" : \"1000000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1000000\" } "
"},"
"\"qos\" : { "
"\"qci\" : 5, "
"\"arp\" : { "
"\"priority_level\" : 1,"
"\"pre_emption_vulnerability\" : 1, "
"\"pre_emption_capability\" : 1"
"} "
"}, "
"\"type\" : 2"
"}"
"],"
"\"ambr\" : { "
"\"uplink\" : { \"$numberLong\" : \"1000000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1000000\" } "
"},"
"\"subscribed_rau_tau_timer\" : 12,"
"\"network_access_mode\" : 2, "
"\"subscriber_status\" : 0, "
"\"access_restriction_data\" : 32, "
"\"security\" : { "
"\"k\" : \"465B5CE8 B199B49F AA5F0A2E E238A6BC\", "
"\"opc\" : \"E8ED289D EBA952E4 283B54E8 8E6183CA\", "
"\"amf\" : \"8000\", "
"\"sqn\" : { \"$numberLong\" : \"64\" } "
"}, "
"\"__v\" : 0 "
"}";
/* Setup Test UE & Session Context */
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
mobile_identity_suci.routing_indicator1 = 0;
mobile_identity_suci.routing_indicator2 = 0xf;
mobile_identity_suci.routing_indicator3 = 0xf;
mobile_identity_suci.routing_indicator4 = 0xf;
mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME;
mobile_identity_suci.home_network_pki_value = 0;
mobile_identity_suci.scheme_output[0] = 0x10;
mobile_identity_suci.scheme_output[1] = 0x32;
mobile_identity_suci.scheme_output[2] = 0x54;
mobile_identity_suci.scheme_output[3] = 0x86;
mobile_identity_suci.scheme_output[4] = 0x91;
test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13);
ogs_assert(test_ue);
test_ue->e_cgi.cell_id = 0x1079baf;
test_ue->nas.ksi = 0;
test_ue->nas.value = OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH;
OGS_HEX(_k_string, strlen(_k_string), test_ue->k);
OGS_HEX(_opc_string, strlen(_opc_string), test_ue->opc);
sess = test_sess_add_by_apn(test_ue, "internet");
ogs_assert(sess);
/* eNB connects to MME */
s1ap = tests1ap_client(AF_INET);
ABTS_PTR_NOTNULL(tc, s1ap);
/* eNB connects to SGW */
gtpu = test_gtpu_server(1, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu);
/* Send S1-Setup Reqeust */
sendbuf = test_s1ap_build_s1_setup_request(
S1AP_ENB_ID_PR_macroENB_ID, 0x54f64);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive S1-Setup Response */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(NULL, recvbuf);
/********** Insert Subscriber in Database */
collection = mongoc_client_get_collection(
ogs_mongoc()->client, ogs_mongoc()->name, "subscribers");
ABTS_PTR_NOTNULL(tc, collection);
doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi));
ABTS_PTR_NOTNULL(tc, doc);
count = mongoc_collection_count (
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
if (count) {
ABTS_TRUE(tc, mongoc_collection_remove(collection,
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
}
bson_destroy(doc);
doc = bson_new_from_json((const uint8_t *)json, -1, &error);;
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_insert(collection,
MONGOC_INSERT_NONE, doc, NULL, &error));
bson_destroy(doc);
doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi));
ABTS_PTR_NOTNULL(tc, doc);
do {
count = mongoc_collection_count (
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
} while (count == 0);
bson_destroy(doc);
collection = mongoc_client_get_collection(
ogs_mongoc()->client, ogs_mongoc()->name, "subscribers");
ABTS_PTR_NOTNULL(tc, collection);
/* Send Attach Request */
memset(&sess->pdn_connectivity_param,
0, sizeof(sess->pdn_connectivity_param));
sess->pdn_connectivity_param.eit = 1;
esmbuf = testesm_build_pdn_connectivity_request(sess);
ABTS_PTR_NOTNULL(tc, esmbuf);
memset(&test_ue->attach_request_param,
0, sizeof(test_ue->attach_request_param));
test_ue->attach_request_param.integrity_protected = 1;
test_ue->attach_request_param.drx_parameter = 1;
test_ue->attach_request_param.ms_network_capability = 1;
test_ue->attach_request_param.tmsi_status = 1;
test_ue->attach_request_param.mobile_station_classmark_2 = 1;
test_ue->attach_request_param.ue_usage_setting = 1;
emmbuf = testemm_build_attach_request(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, emmbuf);
memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param));
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Authentication Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Authentication response */
emmbuf = testemm_build_authentication_response(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Security mode complete */
test_ue->mobile_identity_imeisv_presence = true;
emmbuf = testemm_build_security_mode_complete(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive ESM Information Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send ESM Information Response */
sess->esm_information_param.pco = 1;
esmbuf = testesm_build_esm_information_response(sess);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial Context Setup Request +
* Attach Accept +
* Activate Default Bearer Context Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UE Capability Info Indication */
sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Initial Context Setup Response */
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Attach Complete + Activate default EPS bearer cotext accept */
test_ue->nr_cgi.cell_id = 0x1234502;
bearer = test_bearer_find_by_ue_ebi(test_ue, 5);
ogs_assert(bearer);
esmbuf = testesm_build_activate_default_eps_bearer_context_accept(
bearer, false);
ABTS_PTR_NOTNULL(tc, esmbuf);
emmbuf = testemm_build_attach_complete(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive EMM information */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, bearer, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send PDN Connectivity Request */
sess = test_sess_add_by_apn(test_ue, "ims");
ogs_assert(sess);
sess->pti = 7;
sess->pdn_connectivity_param.integrity_protected = 1;
sess->pdn_connectivity_param.ciphered = 1;
sess->pdn_connectivity_param.apn = 1;
sess->pdn_connectivity_param.pco = 1;
esmbuf = testesm_build_pdn_connectivity_request(sess);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive E-RAB Setup Request +
* Activate default EPS bearer context request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send E-RAB Setup Response */
bearer = test_bearer_find_by_ue_ebi(test_ue, 6);
ogs_assert(bearer);
sendbuf = test_s1ap_build_e_rab_setup_response(bearer);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Activate default EPS bearer context accept */
esmbuf = testesm_build_activate_default_eps_bearer_context_accept(
bearer, true);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, bearer, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send UE Context Release Request */
sendbuf = test_s1ap_build_ue_context_release_request(test_ue,
S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send AA-Request */
pcscf_rx_send_aar_audio(&rx_sid, sess,
OGS_DIAM_RX_SUBSCRIPTION_ID_TYPE_END_USER_IMSI, 1, 1);
/* Receive S1-Paging */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Service Request */
emmbuf = testemm_build_service_request(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Data, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial Context Setup Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Initial Context Setup Response */
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive E-RAB Setup Request +
* Activate dedicated EPS bearer context request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send E-RAB Setup Response */
bearer = test_bearer_find_by_ue_ebi(test_ue, 7);
ogs_assert(bearer);
sendbuf = test_s1ap_build_e_rab_setup_response(bearer);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Activate dedicated EPS bearer context accept */
esmbuf = testesm_build_activate_dedicated_eps_bearer_context_accept(bearer);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* DELAY is needed in dedicated EPS bearer */
ogs_msleep(100);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, bearer, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send UE Context Release Request */
sendbuf = test_s1ap_build_ue_context_release_request(test_ue,
S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send AA-Request without Flow */
pcscf_rx_send_aar_audio(&rx_sid, sess,
OGS_DIAM_RX_SUBSCRIPTION_ID_TYPE_END_USER_IMSI, 2, 1);
/* Receive S1-Paging */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Service Request */
emmbuf = testemm_build_service_request(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Data, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial Context Setup Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Initial Context Setup Response */
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive E-RAB Modify Request +
* Modify EPS bearer context request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send E-RAB Modify Response */
sendbuf = test_s1ap_build_e_rab_modify_response(bearer);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Modify EPS bearer context accept */
esmbuf = testesm_build_modify_eps_bearer_context_accept(bearer);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(100);
/* Send UE Context Release Request */
sendbuf = test_s1ap_build_ue_context_release_request(test_ue,
S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Session-Termination-Request */
pcscf_rx_send_str(rx_sid);
/* Receive S1-Paging */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Service Request */
emmbuf = testemm_build_service_request(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Data, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial Context Setup Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Initial Context Setup Response */
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive E-RAB Release Command +
* Dectivate EPS bearer context request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send E-RAB Release Response */
sendbuf = test_s1ap_build_e_rab_release_response(bearer);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Deactivate EPS bearer context accept */
esmbuf = testesm_build_deactivate_eps_bearer_context_accept(bearer);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
ogs_msleep(100);
/* Send UE Context Release Request */
sendbuf = test_s1ap_build_ue_context_release_request(test_ue,
S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(300);
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi));
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_remove(collection,
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
bson_destroy(doc);
mongoc_collection_destroy(collection);
/* eNB disonncect from MME */
testenb_s1ap_close(s1ap);
/* eNB disonncect from SGW */
test_gtpu_close(gtpu);
test_ue_remove(test_ue);
}
abts_suite *test_rx(abts_suite *suite)
{
suite = ADD_SUITE(suite)
@ -2186,6 +2812,7 @@ abts_suite *test_rx(abts_suite *suite)
abts_run_test(suite, test2_func, NULL);
abts_run_test(suite, test3_func, NULL);
abts_run_test(suite, test4_func, NULL);
abts_run_test(suite, test5_func, NULL);
return suite;
}

View File

@ -422,6 +422,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Session Remove */
test_sess_remove(sess);
/* Send INVALID PDN Connectivity Request */
sess = test_sess_add_by_apn(test_ue, "ims2");
ogs_assert(sess);

View File

@ -494,6 +494,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before Session-Termination-Request */
ogs_msleep(100);
@ -524,6 +527,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before AA-Request */
ogs_msleep(100);
@ -638,6 +644,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before Session-Termination-Request */
ogs_msleep(100);
@ -668,6 +677,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before AA-Request */
ogs_msleep(100);
@ -782,6 +794,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before Session-Termination-Request */
ogs_msleep(100);
@ -812,6 +827,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before AA-Request */
ogs_msleep(100);
@ -926,6 +944,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before Session-Termination-Request */
ogs_msleep(100);
@ -956,6 +977,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before AA-Request */
ogs_msleep(100);
@ -1070,6 +1094,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before Session-Termination-Request */
ogs_msleep(100);
@ -1100,6 +1127,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before AA-Request */
ogs_msleep(100);
@ -1214,6 +1244,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
/* DELAY is needed before Session-Termination-Request */
ogs_msleep(100);
@ -1244,6 +1277,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Test Bearer Remove */
test_bearer_remove(bearer);
ogs_msleep(300);
/********** Remove Subscriber in Database */