if TAI list is not properly configured, MME sends Attach Reject or TAU

Rejct message.

Attach/TAU Reject contents
 - S1ap_CauseNas_unspecified
 - EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED
 - ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED if session is created.
This commit is contained in:
Sukchan Lee 2018-01-02 18:18:45 +09:00
parent f40159ea2a
commit 18859c1203
5 changed files with 155 additions and 54 deletions

View File

@ -18,10 +18,11 @@
#include "emm_handler.h"
void emm_handle_attach_request(
status_t emm_handle_attach_request(
mme_ue_t *mme_ue, nas_attach_request_t *attach_request)
{
status_t rv;
int served_tai_index = 0;
enb_ue_t *enb_ue = NULL;
nas_eps_attach_type_t *eps_attach_type =
@ -31,12 +32,12 @@ void emm_handle_attach_request(
nas_esm_message_container_t *esm_message_container =
&attach_request->esm_message_container;
d_assert(mme_ue, return, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
d_assert(enb_ue, return CORE_ERROR, "Null param");
d_assert(esm_message_container, return, "Null param");
d_assert(esm_message_container->length, return, "Null param");
d_assert(esm_message_container, return CORE_ERROR, "Null param");
d_assert(esm_message_container->length, return CORE_ERROR, "Null param");
/*
* ATTACH_REQUEST
@ -69,6 +70,18 @@ void emm_handle_attach_request(
memcpy(&mme_ue->tai, &enb_ue->nas.tai, sizeof(tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->nas.e_cgi, sizeof(e_cgi_t));
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);
if (served_tai_index < 0)
{
/* Send Attach Reject */
nas_send_attach_reject(mme_ue,
S1ap_CauseNas_unspecified,
EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
return CORE_ERROR;
}
/* Store UE specific information */
if (attach_request->presencemask &
NAS_ATTACH_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT)
@ -150,7 +163,7 @@ void emm_handle_attach_request(
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
rv = mme_gtp_send_delete_all_sessions(mme_ue);
d_assert(rv == CORE_OK, return, "gtp send failed");
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp send failed");
}
else
{
@ -158,9 +171,11 @@ void emm_handle_attach_request(
}
}
}
return CORE_OK;
}
void emm_handle_attach_complete(
status_t emm_handle_attach_complete(
mme_ue_t *mme_ue, nas_attach_complete_t *attach_complete)
{
status_t rv;
@ -176,10 +191,10 @@ void emm_handle_attach_complete(
time_exp_t time_exp;
time_exp_lt(&time_exp, time_now());
d_assert(mme_ue, return, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
rv = nas_send_emm_to_esm(mme_ue, &attach_complete->esm_message_container);
d_assert(rv == CORE_OK, return, "nas_send_emm_to_esm failed");
d_assert(rv == CORE_OK, return CORE_ERROR, "nas_send_emm_to_esm failed");
memset(&message, 0, sizeof(message));
message.h.security_header_type =
@ -216,11 +231,13 @@ void emm_handle_attach_complete(
mme_ue->imsi_bcd);
rv = nas_security_encode(&emmbuf, mme_ue, &message);
d_assert(rv == CORE_OK && emmbuf, return, "emm build error");
d_assert(rv == CORE_OK && emmbuf, return CORE_ERROR, "emm build error");
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
return CORE_OK;
}
void emm_handle_identity_response(
status_t emm_handle_identity_response(
mme_ue_t *mme_ue, nas_identity_response_t *identity_response)
{
status_t rv;
@ -228,11 +245,11 @@ void emm_handle_identity_response(
nas_mobile_identity_t *mobile_identity = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(identity_response, return, "Null param");
d_assert(identity_response, return CORE_ERROR, "Null param");
d_assert(mme_ue, return, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
d_assert(enb_ue, return CORE_ERROR, "Null param");
mobile_identity = &identity_response->mobile_identity;
@ -244,7 +261,7 @@ void emm_handle_identity_response(
&mobile_identity->imsi, mobile_identity->length, imsi_bcd);
mme_ue_set_imsi(mme_ue, imsi_bcd);
d_assert(mme_ue->imsi_len, return,
d_assert(mme_ue->imsi_len, return CORE_ERROR,
"Can't get IMSI(len:%d\n", mme_ue->imsi_len);
}
else
@ -252,21 +269,23 @@ void emm_handle_identity_response(
d_warn("Not supported Identity type(%d)", mobile_identity->imsi.type);
}
d_assert(MME_UE_HAVE_IMSI(mme_ue), return, "No IMSI in IDENTITY_RESPONSE");
d_assert(MME_UE_HAVE_IMSI(mme_ue),
return CORE_ERROR, "No IMSI in IDENTITY_RESPONSE");
if (mme_ue->nas_eps.type == 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, return, "nas_send_emm_to_esm failed");
d_assert(rv == CORE_OK,
return CORE_ERROR, "nas_send_emm_to_esm failed");
}
else
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
rv = mme_gtp_send_delete_all_sessions(mme_ue);
d_assert(rv == CORE_OK, return, "gtp send failed");
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp send failed");
}
else
{
@ -280,7 +299,8 @@ void emm_handle_identity_response(
{
/* Send TAU accept */
rv = nas_send_tau_accept(mme_ue);
d_assert(rv == CORE_OK, return, "nas_send_tau_accept failed");
d_assert(rv == CORE_OK,
return CORE_ERROR, "nas_send_tau_accept failed");
}
else
{
@ -293,6 +313,8 @@ void emm_handle_identity_response(
/* Send TAU reject */
nas_send_tau_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return CORE_ERROR;
}
}
}
@ -301,7 +323,7 @@ void emm_handle_identity_response(
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
rv = s1ap_send_initial_context_setup_request(mme_ue);
d_assert(rv == CORE_OK, return, "s1ap send error");
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
}
else
{
@ -313,21 +335,25 @@ void emm_handle_identity_response(
{
nas_send_service_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return CORE_ERROR;
}
}
}
return CORE_OK;
}
void emm_handle_detach_request(
status_t emm_handle_detach_request(
mme_ue_t *mme_ue, nas_detach_request_from_ue_t *detach_request)
{
status_t rv;
enb_ue_t *enb_ue = NULL;
d_assert(detach_request, return, "Null param");
d_assert(mme_ue, return, "Null param");
d_assert(detach_request, return CORE_ERROR, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
d_assert(enb_ue, return CORE_ERROR, "Null param");
d_trace(3, "[NAS] Detach request : UE_IMSI[%s] --> EMM\n",
mme_ue->imsi_bcd);
@ -357,23 +383,25 @@ void emm_handle_detach_request(
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
rv = mme_gtp_send_delete_all_sessions(mme_ue);
d_assert(rv == CORE_OK, return,
d_assert(rv == CORE_OK, return CORE_ERROR,
"mme_gtp_send_delete_all_sessions failed");
}
else
{
rv = nas_send_detach_accept(mme_ue);
d_assert(rv == CORE_OK, return,
d_assert(rv == CORE_OK, return CORE_ERROR,
"nas_send_detach_accept failed");
}
return CORE_OK;
}
void emm_handle_service_request(
status_t emm_handle_service_request(
mme_ue_t *mme_ue, nas_service_request_t *service_request)
{
status_t rv;
d_assert(mme_ue, return, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
/*
* ATTACH_REQUEST
@ -404,7 +432,7 @@ void emm_handle_service_request(
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
rv = s1ap_send_initial_context_setup_request(mme_ue);
d_assert(rv == CORE_OK, return, "s1ap send error");
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
}
else
{
@ -416,23 +444,30 @@ void emm_handle_service_request(
{
nas_send_service_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return CORE_ERROR;
}
}
}
return CORE_OK;
}
void emm_handle_emm_status(mme_ue_t *mme_ue, nas_emm_status_t *emm_status)
status_t emm_handle_emm_status(mme_ue_t *mme_ue, nas_emm_status_t *emm_status)
{
d_assert(mme_ue, return, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
d_warn("[NAS] EMM status(%d) : UE[%s] --> EMM",
emm_status->emm_cause, mme_ue->imsi_bcd);
return CORE_OK;
}
void emm_handle_tau_request(
status_t emm_handle_tau_request(
mme_ue_t *mme_ue, nas_tracking_area_update_request_t *tau_request)
{
status_t rv;
int served_tai_index = 0;
nas_eps_update_type_t *eps_update_type =
&tau_request->eps_update_type;
@ -440,9 +475,9 @@ void emm_handle_tau_request(
&tau_request->old_guti;
enb_ue_t *enb_ue = NULL;
d_assert(mme_ue, return, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
d_assert(enb_ue, return CORE_ERROR, "Null param");
/*
* ATTACH_REQUEST
@ -468,6 +503,15 @@ void emm_handle_tau_request(
memcpy(&mme_ue->tai, &enb_ue->nas.tai, sizeof(tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->nas.e_cgi, sizeof(e_cgi_t));
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);
if (served_tai_index < 0)
{
/* Send TAU reject */
nas_send_tau_reject(mme_ue, EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED);
return CORE_ERROR;
}
/* Store UE specific information */
if (tau_request->presencemask &
NAS_TRACKING_AREA_UPDATE_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT)
@ -530,7 +574,7 @@ void emm_handle_tau_request(
d_warn("Not implemented(type:%d)",
eps_mobile_identity->imsi.type);
return;
return CORE_OK;
}
}
@ -540,7 +584,8 @@ void emm_handle_tau_request(
{
/* Send TAU Accept */
rv = nas_send_tau_accept(mme_ue);
d_assert(rv == CORE_OK, return, "nas_send_tau_accept failed");
d_assert(rv == CORE_OK,
return CORE_ERROR, "nas_send_tau_accept failed");
}
else
{
@ -554,7 +599,11 @@ void emm_handle_tau_request(
/* Send TAU reject */
nas_send_tau_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return CORE_ERROR;
}
}
}
return CORE_OK;
}

View File

@ -9,23 +9,23 @@
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(void) emm_handle_attach_request(
CORE_DECLARE(status_t) emm_handle_attach_request(
mme_ue_t *mme_ue, nas_attach_request_t *attach_request);
CORE_DECLARE(void) emm_handle_attach_complete(
CORE_DECLARE(status_t) emm_handle_attach_complete(
mme_ue_t *mme_ue, nas_attach_complete_t *attach_complete);
CORE_DECLARE(void) emm_handle_identity_response(
CORE_DECLARE(status_t) emm_handle_identity_response(
mme_ue_t *mme_ue, nas_identity_response_t *identity_response);
CORE_DECLARE(void) emm_handle_detach_request(
CORE_DECLARE(status_t) emm_handle_detach_request(
mme_ue_t *mme_ue, nas_detach_request_from_ue_t *detach_request);
CORE_DECLARE(void) emm_handle_service_request(
CORE_DECLARE(status_t) emm_handle_service_request(
mme_ue_t *mme_ue, nas_service_request_t *service_request);
CORE_DECLARE(void) emm_handle_emm_status(
CORE_DECLARE(status_t) emm_handle_emm_status(
mme_ue_t *mme_ue, nas_emm_status_t *emm_status);
CORE_DECLARE(void) emm_handle_tau_request(
CORE_DECLARE(status_t) emm_handle_tau_request(
mme_ue_t *mme_ue, nas_tracking_area_update_request_t *tau_request);
#ifdef __cplusplus

View File

@ -36,6 +36,7 @@ void emm_state_final(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");
@ -64,8 +65,13 @@ void emm_state_detached(fsm_t *s, event_t *e)
if (message->emm.h.security_header_type
== NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE)
{
emm_handle_service_request(
rv = emm_handle_service_request(
mme_ue, &message->emm.service_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (MME_UE_HAVE_IMSI(mme_ue))
{
@ -96,8 +102,13 @@ void emm_state_detached(fsm_t *s, event_t *e)
{
case NAS_ATTACH_REQUEST:
{
emm_handle_attach_request(
rv = emm_handle_attach_request(
mme_ue, &message->emm.attach_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (MME_UE_HAVE_IMSI(mme_ue))
{
@ -119,8 +130,13 @@ void emm_state_detached(fsm_t *s, event_t *e)
case NAS_TRACKING_AREA_UPDATE_REQUEST:
{
emm_handle_tau_request(
rv = emm_handle_tau_request(
mme_ue, &message->emm.tracking_area_update_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (MME_UE_HAVE_IMSI(mme_ue))
{
@ -205,8 +221,13 @@ void emm_state_identity(fsm_t *s, event_t *e)
{
case NAS_IDENTITY_RESPONSE:
{
emm_handle_identity_response(mme_ue,
rv = emm_handle_identity_response(mme_ue,
&message->emm.identity_response);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST)
{
@ -440,6 +461,7 @@ void emm_state_security_mode(fsm_t *s, event_t *e)
void emm_state_default_esm(fsm_t *s, event_t *e)
{
status_t rv;
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
@ -471,8 +493,13 @@ void emm_state_default_esm(fsm_t *s, event_t *e)
{
d_trace(3, "[NAS] Attach complete : UE[%s] --> EMM\n",
mme_ue->imsi_bcd);
emm_handle_attach_complete(
rv = emm_handle_attach_complete(
mme_ue, &message->emm.attach_complete);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
FSM_TRAN(s, &emm_state_attached);
break;
}
@ -518,6 +545,7 @@ void emm_state_default_esm(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");
@ -546,8 +574,13 @@ void emm_state_attached(fsm_t *s, event_t *e)
if (message->emm.h.security_header_type
== NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE)
{
emm_handle_service_request(
rv = emm_handle_service_request(
mme_ue, &message->emm.service_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (MME_UE_HAVE_IMSI(mme_ue))
{
@ -578,8 +611,13 @@ void emm_state_attached(fsm_t *s, event_t *e)
{
case NAS_ATTACH_REQUEST:
{
emm_handle_attach_request(
rv = emm_handle_attach_request(
mme_ue, &message->emm.attach_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (MME_UE_HAVE_IMSI(mme_ue))
{
@ -613,8 +651,13 @@ void emm_state_attached(fsm_t *s, event_t *e)
}
case NAS_TRACKING_AREA_UPDATE_REQUEST:
{
emm_handle_tau_request(
rv = emm_handle_tau_request(
mme_ue, &message->emm.tracking_area_update_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, emm_state_exception);
break;
}
if (MME_UE_HAVE_IMSI(mme_ue))
{

View File

@ -71,7 +71,10 @@ void esm_state_inactive(fsm_t *s, event_t *e)
rv = esm_handle_pdn_connectivity_request(
bearer, &message->esm.pdn_connectivity_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, esm_state_session_exception);
break;
}
break;
}
case NAS_ESM_INFORMATION_RESPONSE:
@ -82,7 +85,10 @@ void esm_state_inactive(fsm_t *s, event_t *e)
rv = esm_handle_information_response(
sess, &message->esm.esm_information_response);
if (rv != CORE_OK)
{
FSM_TRAN(s, esm_state_session_exception);
break;
}
break;
}
case NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT:
@ -175,9 +181,12 @@ void esm_state_active(fsm_t *s, event_t *e)
rv = esm_handle_pdn_connectivity_request(
bearer, &message->esm.pdn_connectivity_request);
if (rv != CORE_OK)
{
FSM_TRAN(s, esm_state_session_exception);
else
FSM_TRAN(s, esm_state_inactive);
break;
}
FSM_TRAN(s, esm_state_inactive);
break;
}
case NAS_PDN_DISCONNECT_REQUEST:

View File

@ -163,7 +163,7 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i)
"00000905e060c040 0100210204d011d1 271a808021100100 0010810600000000"
"830600000000000d 00000a005255f501 10225c0a003103e5 c03e1355f501aaaa"
"11035758a6200b60 1404ef65233b8878 d290400804026004 00021f025d0107e0"
"004300060055f501 1022006440080055 f5010019d0100086 400130",
"004300060000f110 3039006440080055 f5010019d0100086 400130",
"000c406800000500 080002001f001a00 403f074172080910 10103254866202e0"