refine attached/detached state handler
This commit is contained in:
parent
f94553bc8a
commit
7d43bd870e
697
src/mme/emm_sm.c
697
src/mme/emm_sm.c
|
@ -34,33 +34,48 @@ void emm_state_final(fsm_t *s, event_t *e)
|
|||
mme_sm_trace(3, e);
|
||||
}
|
||||
|
||||
static void emm_state_detached_attached(fsm_t *s, event_t *e);
|
||||
|
||||
void emm_state_detached(fsm_t *s, event_t *e)
|
||||
{
|
||||
status_t rv;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
d_assert(s, return, "Null param");
|
||||
d_assert(e, return, "Null param");
|
||||
|
||||
mme_sm_trace(3, e);
|
||||
|
||||
mme_ue = mme_ue_find(event_get_param1(e));
|
||||
emm_state_detached_attached(s, e);
|
||||
}
|
||||
|
||||
void emm_state_attached(fsm_t *s, event_t *e)
|
||||
{
|
||||
d_assert(s, return, "Null param");
|
||||
d_assert(e, return, "Null param");
|
||||
|
||||
mme_sm_trace(3, e);
|
||||
|
||||
emm_state_detached_attached(s, e);
|
||||
}
|
||||
|
||||
static void emm_state_detached_attached(fsm_t *s, event_t *e)
|
||||
{
|
||||
status_t rv;
|
||||
mme_ue_t *mme_ue = mme_ue_find(event_get_param1(e));
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
|
||||
switch (event_get(e))
|
||||
{
|
||||
case FSM_ENTRY_SIG:
|
||||
{
|
||||
break;
|
||||
return;
|
||||
}
|
||||
case FSM_EXIT_SIG:
|
||||
{
|
||||
break;
|
||||
return;
|
||||
}
|
||||
case MME_EVT_EMM_MESSAGE:
|
||||
{
|
||||
nas_message_t *message = (nas_message_t *)event_get_param4(e);
|
||||
d_assert(message, break, "Null param");
|
||||
d_assert(message, return, "Null param");
|
||||
|
||||
if (message->emm.h.security_header_type
|
||||
== NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE)
|
||||
|
@ -69,189 +84,47 @@ void emm_state_detached(fsm_t *s, event_t *e)
|
|||
mme_ue, &message->emm.service_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_service_request() failed "
|
||||
"in emm_state_detached");
|
||||
d_error("emm_handle_service_request() failed");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (MME_UE_HAVE_IMSI(mme_ue))
|
||||
if (!MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = s1ap_send_initial_context_setup_request(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"s1ap_send_initial_context_setup_request() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("NAS MAC Failure in emm_state_detached");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_service_reject() failed");
|
||||
FSM_TRAN(s, &emm_state_exception);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Unknown UE in emm_state_detached");
|
||||
d_warn("Unknown UE");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
d_assert(rv == CORE_OK, return,
|
||||
"nas_send_service_reject() failed");
|
||||
FSM_TRAN(s, &emm_state_exception);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(message->emm.h.message_type)
|
||||
{
|
||||
case NAS_ATTACH_REQUEST:
|
||||
{
|
||||
rv = emm_handle_attach_request(
|
||||
mme_ue, &message->emm.attach_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_attach_request() failed "
|
||||
"in emm_state_detached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_emm_to_esm(
|
||||
mme_ue, &mme_ue->pdn_connectivity_request);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_emm_to_esm() failed");
|
||||
FSM_TRAN(s, &emm_state_initial_context_setup);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
rv = mme_gtp_send_delete_all_sessions(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"mme_gtp_send_delete_all_sessions() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
}
|
||||
FSM_TRAN(s, &emm_state_authentication);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FSM_TRAN(s, &emm_state_identity);
|
||||
}
|
||||
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case NAS_TRACKING_AREA_UPDATE_REQUEST:
|
||||
if (!SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = emm_handle_tau_request(
|
||||
mme_ue, &message->emm.tracking_area_update_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_tau_request() failed"
|
||||
"in emm_state_detached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
}
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
if (MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_tau_accept(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_accept() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
FSM_TRAN(&mme_ue->sm,
|
||||
&emm_state_authentication);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("No PDN Connection "
|
||||
"in emm_state_detached");
|
||||
rv = nas_send_tau_reject(mme_ue,
|
||||
d_warn("No Security Context");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_reject() failed");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Unknown UE in emm_state_detached");
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_identity);
|
||||
}
|
||||
break;
|
||||
d_assert(rv == CORE_OK, return,
|
||||
"nas_send_service_reject() failed");
|
||||
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, return, "No ENB UE context");
|
||||
|
||||
rv = s1ap_send_ue_context_release_command(enb_ue,
|
||||
S1ap_Cause_PR_nas, S1ap_CauseNas_normal_release,
|
||||
S1AP_UE_CTX_REL_NO_ACTION, 0);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"s1ap_send_ue_context_release_command() failed");
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
d_warn("Unknown message type = %d",
|
||||
message->emm.h.message_type);
|
||||
break;
|
||||
}
|
||||
rv = s1ap_send_initial_context_setup_request(mme_ue);
|
||||
d_assert(rv == CORE_OK, return,
|
||||
"s1ap_send_initial_context_setup_request() failed");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Unknown event %s", mme_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emm_state_identity(fsm_t *s, event_t *e)
|
||||
{
|
||||
status_t rv;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
d_assert(s, return, "Null param");
|
||||
d_assert(e, return, "Null param");
|
||||
|
||||
mme_sm_trace(3, e);
|
||||
|
||||
mme_ue = mme_ue_find(event_get_param1(e));
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
|
||||
switch (event_get(e))
|
||||
{
|
||||
case FSM_ENTRY_SIG:
|
||||
{
|
||||
pkbuf_t *emmbuf = NULL;
|
||||
|
||||
rv = emm_build_identity_request(&emmbuf, mme_ue);
|
||||
d_assert(rv == CORE_OK && emmbuf, break, "emm build error");
|
||||
|
||||
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
|
||||
d_assert(rv == CORE_OK && emmbuf, break, "emm send error");
|
||||
|
||||
break;
|
||||
}
|
||||
case FSM_EXIT_SIG:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case MME_EVT_EMM_MESSAGE:
|
||||
{
|
||||
nas_message_t *message = (nas_message_t *)event_get_param4(e);
|
||||
d_assert(message, break, "Null param");
|
||||
|
||||
switch(message->emm.h.message_type)
|
||||
{
|
||||
|
@ -262,143 +135,168 @@ void emm_state_identity(fsm_t *s, event_t *e)
|
|||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_identity_response failed() "
|
||||
"in emm_state_identity");
|
||||
"in emm_state_attched");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
d_assert(MME_UE_HAVE_IMSI(mme_ue),
|
||||
break, "No IMSI in IDENTITY_RESPONSE");
|
||||
|
||||
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST)
|
||||
if (!MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_emm_to_esm(
|
||||
mme_ue, &mme_ue->pdn_connectivity_request);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_emm_to_esm() failed");
|
||||
FSM_TRAN(s, &emm_state_initial_context_setup);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
rv = mme_gtp_send_delete_all_sessions(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"mme_gtp_send_delete_all_sessions() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
}
|
||||
FSM_TRAN(s, &emm_state_authentication);
|
||||
}
|
||||
d_error("No IMSI");
|
||||
return;
|
||||
}
|
||||
else if (mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST)
|
||||
|
||||
break;
|
||||
}
|
||||
case NAS_ATTACH_REQUEST:
|
||||
{
|
||||
rv = emm_handle_attach_request(
|
||||
mme_ue, &message->emm.attach_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_tau_accept(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_accept() failed");
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_attached);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
FSM_TRAN(&mme_ue->sm,
|
||||
&emm_state_authentication);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("No PDN Connection "
|
||||
"in emm_state_identity");
|
||||
rv = nas_send_tau_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_reject() failed");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
}
|
||||
}
|
||||
d_error("emm_handle_attach_request() failed "
|
||||
"in emm_state_attached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
}
|
||||
else if (mme_ue->nas_eps.type ==
|
||||
MME_EPS_TYPE_SERVICE_REQUEST)
|
||||
|
||||
break;
|
||||
}
|
||||
case NAS_TRACKING_AREA_UPDATE_REQUEST:
|
||||
{
|
||||
rv = emm_handle_tau_request(
|
||||
mme_ue, &message->emm.tracking_area_update_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = s1ap_send_initial_context_setup_request(
|
||||
mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"s1ap_send_initial_context_setup_request() failed");
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_attached);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
d_warn("Have PDN Connection "
|
||||
"in emm_state_identity");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_service_reject() failed");
|
||||
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, break, "No ENB UE context");
|
||||
|
||||
rv = s1ap_send_ue_context_release_command(enb_ue,
|
||||
S1ap_Cause_PR_nas, S1ap_CauseNas_normal_release,
|
||||
S1AP_UE_CTX_REL_NO_ACTION, 0);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"s1ap_send_ue_context_release_command() failed");
|
||||
FSM_TRAN(s, &emm_state_attached);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("No PDN Connection "
|
||||
"in emm_state_identity");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_service_reject() failed");
|
||||
FSM_TRAN(s, &emm_state_exception);
|
||||
}
|
||||
}
|
||||
d_error("emm_handle_tau_request() failed "
|
||||
"in emm_state_attached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
}
|
||||
else
|
||||
d_assert(0,, "Invalid NAS_EPS type[%d]",
|
||||
mme_ue->nas_eps.type);
|
||||
|
||||
break;
|
||||
}
|
||||
case NAS_EMM_STATUS:
|
||||
{
|
||||
d_warn("[NAS] EMM STATUS [IMSI:%s,Cause:%d] "
|
||||
"in emm_state_identity",
|
||||
"in emm_state_attached",
|
||||
mme_ue->imsi_bcd,
|
||||
message->emm.emm_status.emm_cause);
|
||||
FSM_TRAN(s, &emm_state_exception);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
case NAS_DETACH_REQUEST:
|
||||
{
|
||||
emm_handle_detach_request(
|
||||
mme_ue, &message->emm.detach_request_from_ue);
|
||||
FSM_TRAN(s, &emm_state_detached);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_warn("Unknown message(type:%d)",
|
||||
message->emm.h.message_type);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MME_EVT_EMM_T3413:
|
||||
{
|
||||
if (mme_ue->max_paging_retry >= MAX_NUM_OF_PAGING)
|
||||
{
|
||||
/* Paging failed */
|
||||
d_warn("Paging to UE(%s) failed. Stop paging",
|
||||
mme_ue->imsi_bcd);
|
||||
if (mme_ue->last_paging_msg)
|
||||
{
|
||||
pkbuf_free(mme_ue->last_paging_msg);
|
||||
mme_ue->last_paging_msg = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mme_ue->max_paging_retry++;
|
||||
s1ap_handle_paging(mme_ue);
|
||||
/* Start T3413 */
|
||||
tm_start(mme_ue->t3413);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Unknown event %s", mme_event_get_name(e));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
rv = nas_send_identity_request(mme_ue);
|
||||
d_assert(rv == CORE_OK, return, "nas_send_identity_request() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(mme_ue->nas_eps.type)
|
||||
{
|
||||
case MME_EPS_TYPE_ATTACH_REQUEST:
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_emm_to_esm(mme_ue,
|
||||
&mme_ue->pdn_connectivity_request);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_emm_to_esm() failed");
|
||||
FSM_TRAN(s, &emm_state_initial_context_setup);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
rv = mme_gtp_send_delete_all_sessions(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"mme_gtp_send_delete_all_sessions() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
}
|
||||
FSM_TRAN(s, &emm_state_authentication);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MME_EPS_TYPE_TAU_REQUEST:
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_tau_accept(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_accept() failed");
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_attached);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
FSM_TRAN(&mme_ue->sm,
|
||||
&emm_state_authentication);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("No PDN Connection");
|
||||
rv = nas_send_tau_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_reject() failed");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Unknown event %s", mme_event_get_name(e));
|
||||
d_assert(0, return, "Invalid NAS_EPS Type[%d]",
|
||||
mme_ue->nas_eps.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -690,241 +588,6 @@ void emm_state_initial_context_setup(fsm_t *s, event_t *e)
|
|||
}
|
||||
}
|
||||
|
||||
void emm_state_attached(fsm_t *s, event_t *e)
|
||||
{
|
||||
status_t rv;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
d_assert(s, return, "Null param");
|
||||
d_assert(e, return, "Null param");
|
||||
|
||||
mme_sm_trace(3, e);
|
||||
|
||||
mme_ue = mme_ue_find(event_get_param1(e));
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
|
||||
switch (event_get(e))
|
||||
{
|
||||
case FSM_ENTRY_SIG:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case FSM_EXIT_SIG:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case MME_EVT_EMM_MESSAGE:
|
||||
{
|
||||
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)
|
||||
{
|
||||
rv = emm_handle_service_request(
|
||||
mme_ue, &message->emm.service_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_service_request() failed "
|
||||
"in emm_state_detached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = s1ap_send_initial_context_setup_request(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"s1ap_send_initial_context_setup_request() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
d_warn("Have PDN Connection in emm_state_attached");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_service_reject() failed");
|
||||
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, break, "No ENB UE context");
|
||||
|
||||
rv = s1ap_send_ue_context_release_command(enb_ue,
|
||||
S1ap_Cause_PR_nas, S1ap_CauseNas_normal_release,
|
||||
S1AP_UE_CTX_REL_NO_ACTION, 0);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"s1ap_send_ue_context_release_command() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("No PDN Connection in emm_state_attached");
|
||||
rv = nas_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_service_reject() failed");
|
||||
FSM_TRAN(s, &emm_state_exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Unknown UE in emm_state_attached");
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_identity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(message->emm.h.message_type)
|
||||
{
|
||||
case NAS_ATTACH_REQUEST:
|
||||
{
|
||||
rv = emm_handle_attach_request(
|
||||
mme_ue, &message->emm.attach_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_attach_request() failed "
|
||||
"in emm_state_attached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_emm_to_esm(
|
||||
mme_ue, &mme_ue->pdn_connectivity_request);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_emm_to_esm() failed");
|
||||
FSM_TRAN(s, &emm_state_initial_context_setup);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
rv = mme_gtp_send_delete_all_sessions(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"mme_gtp_send_delete_all_sessions() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
}
|
||||
FSM_TRAN(s, &emm_state_authentication);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FSM_TRAN(s, &emm_state_identity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NAS_EMM_STATUS:
|
||||
{
|
||||
d_warn("[NAS] EMM STATUS [IMSI:%s,Cause:%d] "
|
||||
"in emm_state_attached",
|
||||
mme_ue->imsi_bcd,
|
||||
message->emm.emm_status.emm_cause);
|
||||
FSM_TRAN(s, &emm_state_exception);
|
||||
break;
|
||||
}
|
||||
case NAS_DETACH_REQUEST:
|
||||
{
|
||||
emm_handle_detach_request(
|
||||
mme_ue, &message->emm.detach_request_from_ue);
|
||||
FSM_TRAN(s, &emm_state_detached);
|
||||
break;
|
||||
}
|
||||
case NAS_TRACKING_AREA_UPDATE_REQUEST:
|
||||
{
|
||||
rv = emm_handle_tau_request(
|
||||
mme_ue, &message->emm.tracking_area_update_request);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
d_error("emm_handle_tau_request() failed "
|
||||
"in emm_state_attached");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
rv = nas_send_tau_accept(mme_ue);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_accept() failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MME_HAVE_SGW_S11_PATH(mme_ue))
|
||||
{
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("No PDN Connection "
|
||||
"in emm_state_attached");
|
||||
rv = nas_send_tau_reject(
|
||||
mme_ue, EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
d_assert(rv == CORE_OK,,
|
||||
"nas_send_tau_reject() failed");
|
||||
FSM_TRAN(s, emm_state_exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Unknown UE in emm_state_attached");
|
||||
FSM_TRAN(&mme_ue->sm, &emm_state_identity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_warn("Unknown message(type:%d)",
|
||||
message->emm.h.message_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MME_EVT_EMM_T3413:
|
||||
{
|
||||
if (mme_ue->max_paging_retry >= MAX_NUM_OF_PAGING)
|
||||
{
|
||||
/* Paging failed */
|
||||
d_warn("Paging to UE(%s) failed. Stop paging",
|
||||
mme_ue->imsi_bcd);
|
||||
if (mme_ue->last_paging_msg)
|
||||
{
|
||||
pkbuf_free(mme_ue->last_paging_msg);
|
||||
mme_ue->last_paging_msg = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
mme_ue->max_paging_retry++;
|
||||
s1ap_handle_paging(mme_ue);
|
||||
/* Start T3413 */
|
||||
tm_start(mme_ue->t3413);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Unknown event %s", mme_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emm_state_exception(fsm_t *s, event_t *e)
|
||||
{
|
||||
mme_sm_trace(3, e);
|
||||
|
|
|
@ -127,6 +127,23 @@ status_t nas_send_attach_reject(mme_ue_t *mme_ue,
|
|||
return rv;
|
||||
}
|
||||
|
||||
status_t nas_send_identity_request(mme_ue_t *mme_ue)
|
||||
{
|
||||
status_t rv;
|
||||
pkbuf_t *emmbuf = NULL;
|
||||
|
||||
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
||||
|
||||
rv = emm_build_identity_request(&emmbuf, mme_ue);
|
||||
d_assert(rv == CORE_OK && emmbuf, return CORE_ERROR,
|
||||
"nas_build_detach_accept failed");
|
||||
|
||||
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
|
||||
d_assert(rv == CORE_OK,, "nas send failed");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
status_t nas_send_authentication_request(
|
||||
mme_ue_t *mme_ue, e_utran_vector_t *e_utran_vector)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,8 @@ CORE_DECLARE(status_t) nas_send_attach_accept(mme_ue_t *mme_ue);
|
|||
CORE_DECLARE(status_t) nas_send_attach_reject(mme_ue_t *mme_ue,
|
||||
nas_emm_cause_t emm_cause, nas_esm_cause_t esm_cause);
|
||||
|
||||
CORE_DECLARE(status_t) nas_send_identity_request(mme_ue_t *mme_ue);
|
||||
|
||||
CORE_DECLARE(status_t) nas_send_authentication_request(
|
||||
mme_ue_t *mme_ue, e_utran_vector_t *e_utran_vector);
|
||||
CORE_DECLARE(status_t) nas_send_authentication_reject(mme_ue_t *mme_ue);
|
||||
|
|
Loading…
Reference in New Issue