change s1ap_send_ue_release_command with delay parameter

This commit is contained in:
Sukchan Lee 2017-09-18 19:30:03 +09:00
parent 5663f64cbb
commit 8862741a8d
12 changed files with 133 additions and 110 deletions

View File

@ -66,20 +66,20 @@ status_t event_timedrecv(msgq_id queue_id, event_t *e, c_time_t timeout)
return rv;
}
void* event_timer_expire_func(c_uintptr_t queue_id, c_uintptr_t event,
c_uintptr_t param1, c_uintptr_t param2, c_uintptr_t param3,
c_uintptr_t param4, c_uintptr_t param5)
void* event_timer_expire_func(c_uintptr_t queue_id, c_uintptr_t param1,
c_uintptr_t param2, c_uintptr_t param3, c_uintptr_t param4,
c_uintptr_t param5, c_uintptr_t param6)
{
event_t e;
status_t rv;
d_assert(queue_id, return NULL, "Null param");
event_set(&e, event);
event_set_param1(&e, param1);
event_set_param2(&e, param2);
event_set_param3(&e, param3);
event_set_param4(&e, param4);
event_set_param5(&e, param5);
event_set(&e, param1);
event_set_param1(&e, param2);
event_set_param2(&e, param3);
event_set_param3(&e, param4);
event_set_param4(&e, param5);
event_set_param5(&e, param6);
rv = event_send(queue_id, &e);
if (rv != CORE_OK)

View File

@ -356,7 +356,8 @@ void emm_state_default_esm(fsm_t *s, event_t *e)
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(
enb_ue, &cause, 0);
d_assert(rv == CORE_OK, return, "s1ap send error");
FSM_TRAN(s, &emm_state_attached);
break;

View File

@ -309,8 +309,6 @@ struct _mme_ue_t {
#define GTP_COUNTER_DELETE_SESSION 0
#define GTP_COUNTER_MODIFY_BEARER_BY_PATH_SWITCH 1
#define GTP_COUNTER_MODIFY_BEARER_BY_HANDOVER_NOTIFY 2
#define GTP_COUNTER_DELETE_INDIRECT_TUNNEL_BY_HANDOVER_NOTIFY 3
#define GTP_COUNTER_DELETE_INDIRECT_TUNNEL_BY_HANDOVER_CANCEL 4
struct {
c_uint8_t request;
c_uint8_t response;

View File

@ -18,6 +18,8 @@ char* mme_event_get_name(event_t *e)
case MME_EVT_S1AP_MESSAGE:
return "MME_EVT_S1AP_MESSAGE";
case MME_EVT_S1AP_DELAYED_SEND:
return "MME_EVT_S1AP_DELAYED_SEND";
case MME_EVT_S1AP_LO_ACCEPT:
return "MME_EVT_S1AP_LO_ACCEPT";
case MME_EVT_S1AP_LO_CONNREFUSED:

View File

@ -14,6 +14,7 @@ typedef enum {
MME_EVT_BASE = FSM_USER_SIG,
MME_EVT_S1AP_MESSAGE,
MME_EVT_S1AP_DELAYED_SEND,
MME_EVT_S1AP_LO_ACCEPT,
MME_EVT_S1AP_LO_CONNREFUSED,

View File

@ -110,6 +110,8 @@ void mme_s11_handle_modify_bearer_response(
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_modify_bearer_response_t *rsp)
{
status_t rv;
S1ap_Cause_t cause;
enb_ue_t *source_ue = NULL, *target_ue = NULL;
d_assert(xact, return, "Null param");
d_assert(mme_ue, return, "Null param");
@ -127,11 +129,16 @@ void mme_s11_handle_modify_bearer_response(
);
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_MODIFY_BEARER_BY_HANDOVER_NOTIFY,
GTP_COUNTER_INCREMENT(mme_ue,
GTP_COUNTER_DELETE_INDIRECT_TUNNEL_BY_HANDOVER_NOTIFY);
rv = mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
mme_ue);
d_assert(rv == CORE_OK, return, "gtp send error");
target_ue = mme_ue->enb_ue;
d_assert(target_ue, return, "Null param");
source_ue = target_ue->source_ue;
d_assert(source_ue, return, "Null param");
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(source_ue, &cause, 300);
d_assert(rv == CORE_OK, return, "s1ap send error");
);
}
@ -308,7 +315,7 @@ void mme_s11_handle_release_access_bearers_response(
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause, 0);
d_assert(rv == CORE_OK,, "s1ap send error");
}
@ -415,11 +422,8 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
{
status_t rv;
S1ap_Cause_t cause;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
enb_ue_t *source_ue = NULL, *target_ue = NULL;
d_assert(xact, return, "Null param");
d_assert(mme_ue, return, "Null param");
@ -449,35 +453,4 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
}
sess = mme_sess_next(sess);
}
GTP_COUNTER_CHECK(mme_ue,
GTP_COUNTER_DELETE_INDIRECT_TUNNEL_BY_HANDOVER_NOTIFY,
target_ue = mme_ue->enb_ue;
d_assert(target_ue, return, "Null param");
source_ue = target_ue->source_ue;
d_assert(source_ue, return, "Null param");
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(source_ue, &cause);
d_assert(rv == CORE_OK, return, "s1ap send error");
);
GTP_COUNTER_CHECK(mme_ue,
GTP_COUNTER_DELETE_INDIRECT_TUNNEL_BY_HANDOVER_CANCEL,
source_ue = mme_ue->enb_ue;
d_assert(source_ue, return, "Null param");
target_ue = source_ue->target_ue;
d_assert(target_ue, return, "Null param");
mme_ue_deassociate_target_ue(target_ue);
cause.present = S1ap_Cause_PR_radioNetwork;
cause.choice.nas = S1ap_CauseRadioNetwork_handover_cancelled;
rv = s1ap_send_ue_context_release_commmand(target_ue, &cause);
d_assert(rv == CORE_OK, return, "s1ap send error");
);
}

View File

@ -147,6 +147,27 @@ void mme_state_operational(fsm_t *s, event_t *e)
pkbuf_free(pkbuf);
break;
}
case MME_EVT_S1AP_DELAYED_SEND:
{
mme_enb_t *enb = NULL;
pkbuf_t *pkbuf = NULL;
tm_block_id timer = 0;
enb = mme_enb_find(event_get_param1(e));
d_assert(enb, break,);
pkbuf = (pkbuf_t *)event_get_param2(e);
d_assert(pkbuf, break,);
timer = event_get_param3(e);
d_assert(timer, pkbuf_free(pkbuf);break,);
rv = s1ap_send_to_enb(enb, pkbuf);
d_assert(rv == CORE_OK, pkbuf_free(pkbuf),);
tm_delete(timer);
break;
}
case MME_EVT_EMM_MESSAGE:
{
nas_message_t message;

View File

@ -134,7 +134,7 @@ status_t nas_send_attach_reject(mme_ue_t *mme_ue,
/* FIXME : delay is needed */
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = s1ap_cause_nas;;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause, 0);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -201,7 +201,7 @@ status_t nas_send_detach_accept(mme_ue_t *mme_ue)
/* FIXME : delay is needed */
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_detach;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause, 0);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
return CORE_OK;
@ -338,7 +338,7 @@ status_t nas_send_tau_accept(mme_ue_t *mme_ue)
* that UE receive DL NAS ? */
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause, 0);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
}
else
@ -385,7 +385,7 @@ status_t nas_send_tau_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
* that UE receive DL NAS ? */
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause, 0);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
return CORE_OK;
@ -418,7 +418,7 @@ status_t nas_send_service_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
* that UE receive DL NAS ? */
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause, 0);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
return CORE_OK;

View File

@ -417,7 +417,8 @@ void s1ap_handle_ue_context_release_request(
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_normal_release;
rv = s1ap_send_ue_context_release_commmand(enb_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(
enb_ue, &cause, 0);
d_assert(rv == CORE_OK, return, "s1ap send error");
}
}
@ -451,9 +452,14 @@ void s1ap_handle_ue_context_release_request(
void s1ap_handle_ue_context_release_complete(
mme_enb_t *enb, s1ap_message_t *message)
{
status_t rv;
char buf[INET_ADDRSTRLEN];
enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
int need_to_delete_indirect_tunnel = 0;
S1ap_UEContextReleaseComplete_IEs_t *ies = NULL;
ies = &message->s1ap_UEContextReleaseComplete_IEs;
@ -461,6 +467,8 @@ void s1ap_handle_ue_context_release_complete(
enb_ue = enb_ue_find_by_mme_ue_s1ap_id(ies->mme_ue_s1ap_id);
d_assert(enb_ue, return, "No UE Context[%d]", ies->mme_ue_s1ap_id);
mme_ue = enb_ue->mme_ue;
d_assert(mme_ue, return,);
d_trace(3, "[S1AP] UE Context Release Complete : "
"UE[mME-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
@ -469,6 +477,30 @@ void s1ap_handle_ue_context_release_complete(
enb->enb_id);
enb_ue_remove(enb_ue);
sess = mme_sess_first(mme_ue);
while(sess)
{
bearer = mme_bearer_first(sess);
while(bearer)
{
if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) ||
MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer))
{
need_to_delete_indirect_tunnel = 1;
}
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
if (need_to_delete_indirect_tunnel)
{
rv = mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
mme_ue);
d_assert(rv == CORE_OK, return, "gtp send error");
}
}
void s1ap_handle_paging(mme_ue_t *mme_ue)
@ -828,7 +860,7 @@ void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message)
cause.present = S1ap_Cause_PR_radioNetwork;
cause.choice.nas = S1ap_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system;
rv = s1ap_send_ue_context_release_commmand(target_ue, &cause);
rv = s1ap_send_ue_context_release_commmand(target_ue, &cause, 0);
d_assert(rv == CORE_OK, return, "s1ap send error");
d_trace(3, "[S1AP] Handover Failure : "
@ -844,10 +876,7 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message)
char buf[INET_ADDRSTRLEN];
enb_ue_t *source_ue = NULL;
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
int need_to_delete_indirect_tunnel = 0;
enb_ue_t *target_ue = NULL;
S1ap_HandoverCancelIEs_t *ies = NULL;
S1ap_Cause_t cause;
@ -867,53 +896,19 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message)
"Conflict MME-UE-S1AP-ID : %d != %d\n",
source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
mme_ue = source_ue->mme_ue;
d_assert(mme_ue, return,);
target_ue = source_ue->target_ue;
d_assert(target_ue, return,);
sess = mme_sess_first(mme_ue);
while(sess)
{
bearer = mme_bearer_first(sess);
while(bearer)
{
if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) ||
MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer))
{
need_to_delete_indirect_tunnel = 1;
}
rv = s1ap_send_handover_cancel_ack(source_ue);
d_assert(rv == CORE_OK,, "s1ap send error");
bearer = mme_bearer_next(bearer);
}
sess = mme_sess_next(sess);
}
mme_ue_deassociate_target_ue(target_ue);
cause.present = S1ap_Cause_PR_radioNetwork;
cause.choice.nas = S1ap_CauseRadioNetwork_handover_cancelled;
if (need_to_delete_indirect_tunnel)
{
GTP_COUNTER_INCREMENT(mme_ue,
GTP_COUNTER_DELETE_INDIRECT_TUNNEL_BY_HANDOVER_CANCEL);
rv = mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
mme_ue);
d_assert(rv == CORE_OK, return, "gtp send error");
}
else
{
enb_ue_t *target_ue = NULL;
rv = s1ap_send_handover_cancel_ack(source_ue);
d_assert(rv == CORE_OK,, "s1ap send error");
target_ue = source_ue->target_ue;
d_assert(target_ue, return,);
mme_ue_deassociate_target_ue(target_ue);
cause.present = S1ap_Cause_PR_radioNetwork;
cause.choice.nas = S1ap_CauseRadioNetwork_handover_cancelled;
rv = s1ap_send_ue_context_release_commmand(target_ue, &cause);
d_assert(rv == CORE_OK, return, "s1ap send error");
}
rv = s1ap_send_ue_context_release_commmand(target_ue, &cause, 0);
d_assert(rv == CORE_OK, return, "s1ap send error");
d_trace(3, "[S1AP] Handover Cancel : "
"UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",

View File

@ -215,6 +215,34 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
return rv;
}
status_t s1ap_delayed_send_to_enb(
mme_enb_t *enb, pkbuf_t *pkbuf, c_uint32_t duration)
{
tm_block_id timer = 0;
d_assert(enb, return CORE_ERROR,);
d_assert(pkbuf, return CORE_ERROR,);
if (duration)
{
timer = timer_create(
&mme_self()->tm_service, MME_EVT_S1AP_DELAYED_SEND, duration);
d_assert(timer, return CORE_ERROR,);
timer_set_param1(timer, (c_uintptr_t)enb->index);
timer_set_param2(timer, (c_uintptr_t)pkbuf);
timer_set_param3(timer, timer);
tm_start(timer);
return CORE_OK;
}
else
{
return s1ap_send_to_enb(enb, pkbuf);
}
}
status_t s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf)
{
event_t e;
@ -380,7 +408,7 @@ status_t s1ap_send_initial_context_setup_request(mme_ue_t *mme_ue)
}
status_t s1ap_send_ue_context_release_commmand(
enb_ue_t *enb_ue, S1ap_Cause_t *cause)
enb_ue_t *enb_ue, S1ap_Cause_t *cause, c_uint32_t delay)
{
status_t rv;
mme_enb_t *enb = NULL;
@ -394,7 +422,7 @@ status_t s1ap_send_ue_context_release_commmand(
rv = s1ap_build_ue_context_release_commmand(&s1apbuf, enb_ue, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_delayed_send_to_enb(enb, s1apbuf, delay);
d_assert(rv == CORE_OK,, "s1ap send error");
return CORE_OK;

View File

@ -16,6 +16,8 @@ CORE_DECLARE(status_t) s1ap_close();
CORE_DECLARE(status_t) s1ap_send(net_sock_t *s, pkbuf_t *pkb);
CORE_DECLARE(status_t) s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkb);
CORE_DECLARE(status_t) s1ap_delayed_send_to_enb(mme_enb_t *enb,
pkbuf_t *pkbuf, c_uint32_t duration);
CORE_DECLARE(status_t) s1ap_send_to_nas(
enb_ue_t *enb_ue, S1ap_NAS_PDU_t *nasPdu);
CORE_DECLARE(status_t) s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf);
@ -23,7 +25,7 @@ CORE_DECLARE(status_t) s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf);
CORE_DECLARE(status_t) s1ap_send_initial_context_setup_request(
mme_ue_t *mme_ue);
CORE_DECLARE(status_t) s1ap_send_ue_context_release_commmand(
enb_ue_t *enb_ue, S1ap_Cause_t *cause);
enb_ue_t *enb_ue, S1ap_Cause_t *cause, c_uint32_t delay);
CORE_DECLARE(status_t) s1ap_send_path_switch_ack(mme_ue_t *mme_ue);
CORE_DECLARE(status_t) s1ap_send_path_switch_failure(mme_enb_t *enb,

View File

@ -694,6 +694,7 @@ static void handover_test2(abts_case *tc, void *data)
ABTS_INT_NEQUAL(tc, 0, rc);
pkbuf_free(recvbuf);
#if 0
/* Send Handover Cancel */
rv = tests1ap_build_handover_cancel(&sendbuf, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -713,6 +714,7 @@ static void handover_test2(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, CORE_OK, rv);
core_sleep(time_from_msec(300));
#endif
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8("001010123456815"));