Update state machine

This commit is contained in:
James Park 2017-09-08 15:56:42 -07:00
parent 98e56968ee
commit f4e4697430
6 changed files with 122 additions and 10 deletions

View File

@ -297,3 +297,22 @@ status_t emm_build_tau_reject(pkbuf_t **emmbuf, nas_emm_cause_t emm_cause,
return CORE_OK;
}
status_t emm_build_service_reject(pkbuf_t **emmbuf, nas_emm_cause_t emm_cause,
mme_ue_t *mme_ue)
{
nas_message_t message;
nas_service_reject_t *service_reject = &message.emm.service_reject;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_SERVICE_REJECT;
service_reject->emm_cause = emm_cause;
d_assert(nas_plain_encode(emmbuf, &message) == CORE_OK && *emmbuf,,);
return CORE_OK;
}

View File

@ -18,6 +18,8 @@ CORE_DECLARE(status_t) emm_build_attach_reject(
CORE_DECLARE(status_t) emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue);
CORE_DECLARE(status_t) emm_build_tau_reject(pkbuf_t **emmbuf,
nas_emm_cause_t emm_cause,mme_ue_t *mme_ue);
CORE_DECLARE(status_t) emm_build_service_reject(pkbuf_t **emmbuf,
nas_emm_cause_t emm_cause, mme_ue_t *mme_ue);
#ifdef __cplusplus
}

View File

@ -394,19 +394,47 @@ void emm_handle_service_request(
d_assert(mme_ue, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
sess = mme_sess_first(mme_ue);
d_assert(sess, return, "Null param");
/* Update Kenb */
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, mme_ue->kenb);
if (!MME_UE_HAVE_IMSI(mme_ue))
{
/* Unknown UE. Send Service_reject to force UE to attach */
nas_send_service_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return;
}
else
{
sess = mme_sess_first(mme_ue);
d_assert(sess, return, "Null param");
CLEAR_PAGING_INFO(mme_ue);
CLEAR_PAGING_INFO(mme_ue);
rv = s1ap_build_initial_context_setup_request(&s1apbuf, sess, NULL);
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
/* Update Kenb */
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, mme_ue->kenb);
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,, "s1ap send error");
rv = s1ap_build_initial_context_setup_request(&s1apbuf, sess, NULL);
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,, "s1ap send error");
}
else
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
rv = mme_gtp_send_delete_all_sessions(mme_ue);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_delete_all_sessions failed");
}
else
{
mme_s6a_send_air(mme_ue);
}
FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
}
}
}
void emm_handle_emm_status(mme_ue_t *mme_ue, nas_emm_status_t *emm_status)
@ -539,8 +567,16 @@ void emm_handle_tau_request(
if (!MME_UE_HAVE_IMSI(mme_ue))
{
#if 0 /* FIXME : TAU message does not have PDC_CONNECTIVTY message.
So even if ininiate the attach-like procedure, it failed.
*/
/* Unknown GUTI */
FSM_TRAN(&mme_ue->sm, &emm_state_identity);
#else
/* Send TAU reject */
nas_send_tau_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
#endif
}
else
{

View File

@ -60,6 +60,14 @@ void emm_state_detached(fsm_t *s, event_t *e)
nas_message_t *message = (nas_message_t *)event_get_param4(e);
d_assert(message, break, "Null param");
if (message->emm.h.security_header_type
== NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE)
{
emm_handle_service_request(
mme_ue, &message->emm.service_request);
break;
}
switch(message->emm.h.message_type)
{
case NAS_ATTACH_REQUEST:
@ -68,6 +76,18 @@ void emm_state_detached(fsm_t *s, event_t *e)
mme_ue, &message->emm.attach_request);
break;
}
case NAS_TRACKING_AREA_UPDATE_REQUEST:
{
emm_handle_tau_request(
mme_ue, &message->emm.tracking_area_update_request);
break;
}
default:
{
d_warn("Unknown message type = %d",
message->emm.h.message_type);
break;
}
}
break;
}

View File

@ -266,7 +266,40 @@ status_t nas_send_tau_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
/* Build TAU reject */
if (emm_build_tau_reject(&emmbuf, emm_cause, mme_ue) != CORE_OK)
{
d_error("emm_build_tau_accept error");
d_error("emm_build_tau_reject error");
pkbuf_free(emmbuf);
return CORE_ERROR;
}
/* Send Dl NAS to UE */
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
/* FIXME : delay required before sending UE context release to make sure
* 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);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
return CORE_OK;
}
status_t nas_send_service_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
{
status_t rv;
enb_ue_t *enb_ue = NULL;
pkbuf_t *emmbuf = NULL;
S1ap_Cause_t cause;
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param");
/* Build TAU reject */
if (emm_build_service_reject(&emmbuf, emm_cause, mme_ue) != CORE_OK)
{
d_error("emm_build_service_reject error");
pkbuf_free(emmbuf);
return CORE_ERROR;
}

View File

@ -27,6 +27,8 @@ CORE_DECLARE(status_t) nas_send_deactivate_bearer_context_request(
CORE_DECLARE(status_t) nas_send_tau_accept(mme_ue_t *mme_ue);
CORE_DECLARE(status_t) nas_send_tau_reject(mme_ue_t *mme_ue,
nas_esm_cause_t emm_cause);
CORE_DECLARE(status_t) nas_send_service_reject(mme_ue_t *mme_ue,
nas_emm_cause_t emm_cause);
#ifdef __cplusplus
}