propose TAU process when Unknown GUTI or MAC Faield of Security Context

This commit is contained in:
Sukchan Lee 2017-09-10 23:03:24 +09:00
parent f4e4697430
commit b40d19db2b
16 changed files with 528 additions and 527 deletions

View File

@ -8,104 +8,6 @@
#include "mme_kdf.h"
#include "emm_build.h"
status_t emm_build_identity_request(
pkbuf_t **emmbuf, mme_ue_t *mme_ue)
{
nas_message_t message;
nas_identity_request_t *identity_request =
&message.emm.identity_request;
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_IDENTITY_REQUEST;
/* Request IMSI */
identity_request->identity_type.type = NAS_IDENTITY_TYPE_2_IMSI;
d_assert(nas_plain_encode(emmbuf, &message) == CORE_OK && *emmbuf,,);
return CORE_OK;
}
status_t emm_build_security_mode_command(
pkbuf_t **emmbuf, mme_ue_t *mme_ue)
{
status_t rv;
int i;
nas_message_t message;
nas_security_mode_command_t *security_mode_command =
&message.emm.security_mode_command;
nas_security_algorithms_t *selected_nas_security_algorithms =
&security_mode_command->selected_nas_security_algorithms;
nas_key_set_identifier_t *nas_key_set_identifier =
&security_mode_command->nas_key_set_identifier;
nas_ue_security_capability_t *replayed_ue_security_capabilities =
&security_mode_command->replayed_ue_security_capabilities;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_SECURITY_MODE_COMMAND;
for (i = 0; i < mme_self()->num_of_integrity_order; i++)
{
if (mme_ue->ue_network_capability.eia &
(0x80 >> mme_self()->integrity_order[i]))
{
mme_ue->selected_int_algorithm = mme_self()->integrity_order[i];
break;
}
}
for (i = 0; i < mme_self()->num_of_ciphering_order; i++)
{
if (mme_ue->ue_network_capability.eea &
(0x80 >> mme_self()->ciphering_order[i]))
{
mme_ue->selected_enc_algorithm = mme_self()->ciphering_order[i];
break;
}
}
selected_nas_security_algorithms->type_of_integrity_protection_algorithm =
mme_ue->selected_int_algorithm;
selected_nas_security_algorithms->type_of_ciphering_algorithm =
mme_ue->selected_enc_algorithm;
nas_key_set_identifier->tsc = 0;
nas_key_set_identifier->nas_key_set_identifier = 0;
replayed_ue_security_capabilities->length =
sizeof(replayed_ue_security_capabilities->eea) +
sizeof(replayed_ue_security_capabilities->eia) +
sizeof(replayed_ue_security_capabilities->uea) +
sizeof(replayed_ue_security_capabilities->uia) +
sizeof(replayed_ue_security_capabilities->gea);
replayed_ue_security_capabilities->eea = mme_ue->ue_network_capability.eea;
replayed_ue_security_capabilities->eia = mme_ue->ue_network_capability.eia;
replayed_ue_security_capabilities->uea = mme_ue->ue_network_capability.uea;
replayed_ue_security_capabilities->uia = mme_ue->ue_network_capability.uia;
replayed_ue_security_capabilities->gea =
(mme_ue->ms_network_capability.gea1 << 6) |
mme_ue->ms_network_capability.extended_gea;
mme_kdf_nas(MME_KDF_NAS_INT_ALG, mme_ue->selected_int_algorithm,
mme_ue->kasme, mme_ue->knas_int);
mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_ue->selected_enc_algorithm,
mme_ue->kasme, mme_ue->knas_enc);
rv = nas_security_encode(emmbuf, mme_ue, &message);
d_assert(rv == CORE_OK && *emmbuf, return CORE_ERROR, "emm build error");
return CORE_OK;
}
status_t emm_build_attach_accept(
pkbuf_t **emmbuf, mme_ue_t *mme_ue, pkbuf_t *esmbuf)
{
@ -206,6 +108,126 @@ status_t emm_build_attach_reject(
return CORE_OK;
}
status_t emm_build_identity_request(
pkbuf_t **emmbuf, mme_ue_t *mme_ue)
{
nas_message_t message;
nas_identity_request_t *identity_request =
&message.emm.identity_request;
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_IDENTITY_REQUEST;
/* Request IMSI */
identity_request->identity_type.type = NAS_IDENTITY_TYPE_2_IMSI;
d_assert(nas_plain_encode(emmbuf, &message) == CORE_OK && *emmbuf,,);
return CORE_OK;
}
status_t emm_build_security_mode_command(
pkbuf_t **emmbuf, mme_ue_t *mme_ue)
{
status_t rv;
int i;
nas_message_t message;
nas_security_mode_command_t *security_mode_command =
&message.emm.security_mode_command;
nas_security_algorithms_t *selected_nas_security_algorithms =
&security_mode_command->selected_nas_security_algorithms;
nas_key_set_identifier_t *nas_key_set_identifier =
&security_mode_command->nas_key_set_identifier;
nas_ue_security_capability_t *replayed_ue_security_capabilities =
&security_mode_command->replayed_ue_security_capabilities;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_SECURITY_MODE_COMMAND;
for (i = 0; i < mme_self()->num_of_integrity_order; i++)
{
if (mme_ue->ue_network_capability.eia &
(0x80 >> mme_self()->integrity_order[i]))
{
mme_ue->selected_int_algorithm = mme_self()->integrity_order[i];
break;
}
}
for (i = 0; i < mme_self()->num_of_ciphering_order; i++)
{
if (mme_ue->ue_network_capability.eea &
(0x80 >> mme_self()->ciphering_order[i]))
{
mme_ue->selected_enc_algorithm = mme_self()->ciphering_order[i];
break;
}
}
selected_nas_security_algorithms->type_of_integrity_protection_algorithm =
mme_ue->selected_int_algorithm;
selected_nas_security_algorithms->type_of_ciphering_algorithm =
mme_ue->selected_enc_algorithm;
nas_key_set_identifier->tsc = 0;
nas_key_set_identifier->nas_key_set_identifier = 0;
replayed_ue_security_capabilities->length =
sizeof(replayed_ue_security_capabilities->eea) +
sizeof(replayed_ue_security_capabilities->eia) +
sizeof(replayed_ue_security_capabilities->uea) +
sizeof(replayed_ue_security_capabilities->uia) +
sizeof(replayed_ue_security_capabilities->gea);
replayed_ue_security_capabilities->eea = mme_ue->ue_network_capability.eea;
replayed_ue_security_capabilities->eia = mme_ue->ue_network_capability.eia;
replayed_ue_security_capabilities->uea = mme_ue->ue_network_capability.uea;
replayed_ue_security_capabilities->uia = mme_ue->ue_network_capability.uia;
replayed_ue_security_capabilities->gea =
(mme_ue->ms_network_capability.gea1 << 6) |
mme_ue->ms_network_capability.extended_gea;
mme_kdf_nas(MME_KDF_NAS_INT_ALG, mme_ue->selected_int_algorithm,
mme_ue->kasme, mme_ue->knas_int);
mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_ue->selected_enc_algorithm,
mme_ue->kasme, mme_ue->knas_enc);
rv = nas_security_encode(emmbuf, mme_ue, &message);
d_assert(rv == CORE_OK && *emmbuf, return CORE_ERROR, "emm build error");
return CORE_OK;
}
status_t emm_build_detach_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue)
{
status_t rv;
nas_message_t message;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_DETACH_ACCEPT;
rv = nas_security_encode(emmbuf, mme_ue, &message);
d_assert(rv == CORE_OK && emmbuf, return CORE_ERROR, "emm build error");
return CORE_OK;
}
status_t emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue)
{
nas_message_t message;

View File

@ -7,17 +7,23 @@
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) emm_build_identity_request(
pkbuf_t **emmbuf, mme_ue_t *mme_ue);
CORE_DECLARE(status_t) emm_build_security_mode_command(
pkbuf_t **emmbuf, mme_ue_t *mme_ue);
CORE_DECLARE(status_t) emm_build_attach_accept(
pkbuf_t **emmbuf, mme_ue_t *mme_ue, pkbuf_t *esmbuf);
CORE_DECLARE(status_t) emm_build_attach_reject(
pkbuf_t **emmbuf, nas_emm_cause_t emm_cause, pkbuf_t *esmbuf);
CORE_DECLARE(status_t) emm_build_identity_request(
pkbuf_t **emmbuf, mme_ue_t *mme_ue);
CORE_DECLARE(status_t) emm_build_security_mode_command(
pkbuf_t **emmbuf, mme_ue_t *mme_ue);
CORE_DECLARE(status_t) emm_build_detach_accept(
pkbuf_t **emmbuf, mme_ue_t *mme_ue);
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);

View File

@ -10,14 +10,10 @@
#include "mme_kdf.h"
#include "nas_security.h"
#include "nas_conv.h"
#include "esm_build.h"
#include "emm_build.h"
#include "s1ap_build.h"
#include "s1ap_path.h"
#include "nas_path.h"
#include "mme_fd_path.h"
#include "mme_s11_build.h"
#include "mme_gtp_path.h"
#include "emm_handler.h"
@ -255,25 +251,52 @@ void emm_handle_identity_response(
d_assert(MME_UE_HAVE_IMSI(mme_ue), return, "No IMSI in IDENTITY_RESPONSE");
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
if (mme_ue->nas_eps.type == MME_UE_EPS_ATTACH_TYPE) /* ATTACH_REQUEST */
{
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");
FSM_TRAN(&mme_ue->sm, &emm_state_default_esm);
}
else
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
rv = mme_gtp_send_delete_all_sessions(mme_ue);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_delete_all_sessions failed");
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");
FSM_TRAN(&mme_ue->sm, &emm_state_default_esm);
}
else
{
mme_s6a_send_air(mme_ue);
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);
}
}
else if (mme_ue->nas_eps.type == MME_UE_EPS_UPDATE_TYPE) /* TAU_REQUEST */
{
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
/* Send TAU accept */
rv = nas_send_tau_accept(mme_ue);
d_assert(rv == CORE_OK, return, "nas_send_tau_accept failed");
}
else
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
mme_s6a_send_air(mme_ue);
FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
}
else
{
/* Send TAU reject */
nas_send_tau_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
FSM_TRAN(&mme_ue->sm, &emm_state_detached);
}
}
FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
}
}
@ -341,72 +364,30 @@ void emm_handle_detach_request(
}
else
{
emm_handle_detach_accept(mme_ue);
rv = nas_send_detach_accept(mme_ue);
d_assert(rv == CORE_OK, return,
"nas_send_detach_accept failed");
}
}
void emm_handle_detach_accept(mme_ue_t *mme_ue)
{
status_t rv;
enb_ue_t *enb_ue = NULL;
nas_message_t message;
pkbuf_t *emmbuf = NULL;
S1ap_Cause_t cause;
d_assert(mme_ue, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
/* reply with detach accept */
if ((mme_ue->detach_type.switch_off & 0x1) == 0)
{
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_DETACH_ACCEPT;
d_trace(3, "[NAS] Detach accept : UE[%s] <-- EMM\n",
mme_ue->imsi_bcd);
rv = nas_security_encode(&emmbuf, mme_ue, &message);
d_assert(rv == CORE_OK && emmbuf, return, "emm build error");
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
}
/* 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);
d_assert(rv == CORE_OK, , "s1ap send error");
}
void emm_handle_service_request(
mme_ue_t *mme_ue, nas_service_request_t *service_request)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
enb_ue_t *enb_ue = NULL;
mme_sess_t *sess = NULL;
d_assert(mme_ue, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
if (!MME_UE_HAVE_IMSI(mme_ue))
{
/* Unknown UE. Send Service_reject to force UE to attach */
/* Unknown UE. Send Service_reject to force UE to attach
*
* FIXME : how about FSM_TRAN(&mme_ue->sm, emm_state_identity);
*/
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);
/* Update Kenb */
@ -414,10 +395,8 @@ void emm_handle_service_request(
{
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, mme_ue->kenb);
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");
rv = s1ap_send_initial_context_setup_request(mme_ue);
d_assert(rv == CORE_OK, return, "s1ap send error");
}
else
{
@ -529,31 +508,6 @@ void emm_handle_tau_request(
guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue)
? mme_ue->imsi_bcd : "Unknown");
#if 0
if (!MME_UE_HAVE_IMSI(mme_ue))
{
/* Unknown GUTI */
/* FIXME : Need to check if GUTI is allocated to old MME.
* if so , transmit context request to get the context of ue.
*/
/* Send TAU reject */
nas_send_tau_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
}
else if (!SECURITY_CONTEXT_IS_VALID(mme_ue))
{
/* Need Authencation */
d_warn("Need Authenticatoin");
}
else
{
/* Send TAU accept */
nas_send_tau_accept(mme_ue);
}
#endif
break;
}
default:
@ -567,16 +521,7 @@ 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
{
@ -590,15 +535,16 @@ void emm_handle_tau_request(
{
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");
mme_s6a_send_air(mme_ue);
FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
}
else
{
mme_s6a_send_air(mme_ue);
/* Send TAU reject */
nas_send_tau_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
FSM_TRAN(&mme_ue->sm, &emm_state_detached);
}
FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
}
}
}

View File

@ -21,7 +21,6 @@ CORE_DECLARE(void) emm_handle_authentication_response(
CORE_DECLARE(void) emm_handle_detach_request(
mme_ue_t *mme_ue, nas_detach_request_from_ue_t *detach_request);
CORE_DECLARE(void) emm_handle_detach_accept(mme_ue_t *mme_ue);
CORE_DECLARE(void) emm_handle_service_request(
mme_ue_t *mme_ue, nas_service_request_t *service_request);

View File

@ -60,6 +60,7 @@ 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 0 /* FIXME : Does it needed? */
if (message->emm.h.security_header_type
== NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE)
{
@ -67,6 +68,7 @@ void emm_state_detached(fsm_t *s, event_t *e)
mme_ue, &message->emm.service_request);
break;
}
#endif
switch(message->emm.h.message_type)
{
@ -76,12 +78,15 @@ void emm_state_detached(fsm_t *s, event_t *e)
mme_ue, &message->emm.attach_request);
break;
}
#if 0 /* FIXME : Does it needed? */
case NAS_TRACKING_AREA_UPDATE_REQUEST:
{
emm_handle_tau_request(
mme_ue, &message->emm.tracking_area_update_request);
break;
}
#endif
default:
{
d_warn("Unknown message type = %d",
@ -340,6 +345,22 @@ void emm_state_default_esm(fsm_t *s, event_t *e)
FSM_TRAN(s, &emm_state_attached);
break;
}
case NAS_TRACKING_AREA_UPDATE_COMPLETE:
{
status_t rv;
S1ap_Cause_t cause;
enb_ue_t *enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
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, "s1ap send error");
FSM_TRAN(s, &emm_state_attached);
break;
}
case NAS_EMM_STATUS:
{
emm_handle_emm_status(mme_ue, &message->emm.emm_status);
@ -425,21 +446,6 @@ void emm_state_attached(fsm_t *s, event_t *e)
mme_ue, &message->emm.tracking_area_update_request);
break;
}
case NAS_TRACKING_AREA_UPDATE_COMPLETE:
{
status_t rv;
S1ap_Cause_t cause;
enb_ue_t *enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
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, "s1ap send error");
break;
}
default:
{
d_warn("Unknown message(type:%d)",

View File

@ -70,21 +70,9 @@ void esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
if (mme_ue->nas_eps.type == MME_UE_EPS_ATTACH_TYPE)
{
rv = nas_send_attach_accept(mme_ue);
d_assert(rv == CORE_OK, return,
"nas_send_attach_accept failed");
}
else if (mme_ue->nas_eps.type == MME_UE_EPS_UPDATE_TYPE)
{
rv = nas_send_tau_accept(mme_ue);
d_assert(rv == CORE_OK, return,
"nas_send_tau_accept failed");
}
else
d_assert(0, return, "Invalid EPS type(%d)",
mme_ue->nas_eps.type);
rv = nas_send_attach_accept(mme_ue);
d_assert(rv == CORE_OK, return,
"nas_send_attach_accept failed");
}
else
{
@ -135,20 +123,14 @@ void esm_handle_information_response(mme_sess_t *sess,
void esm_handle_activate_default_bearer_accept(mme_bearer_t *bearer)
{
status_t rv;
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(bearer, return, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
mme_bearer_t *dedicated_bearer = mme_bearer_next(bearer);
while(dedicated_bearer)
{
rv = nas_send_activate_dedicated_bearer_context_request(
enb_ue, dedicated_bearer);
dedicated_bearer);
d_assert(rv == CORE_OK, return,
"nas_send_activate_dedicated_bearer_context failed");

View File

@ -7,27 +7,27 @@
#include "mme_event.h"
#include "mme_context.h"
#include "s1ap_build.h"
#include "s1ap_path.h"
#include "mme_gtp_path.h"
#include "nas_path.h"
#include "mme_fd_path.h"
#include "mme_s11_build.h"
#include "mme_s11_handler.h"
#include "mme_gtp_path.h"
#include "esm_build.h"
#include "nas_path.h"
void mme_s11_handle_create_session_response(gtp_xact_t *xact,
mme_bearer_t *bearer, gtp_create_session_response_t *rsp)
void mme_s11_handle_create_session_response(
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_create_session_response_t *rsp)
{
status_t rv;
gtp_f_teid_t *sgw_s11_teid = NULL;
gtp_f_teid_t *sgw_s1u_teid = NULL;
mme_ue_t *mme_ue = NULL;
mme_bearer_t *bearer = NULL;
mme_sess_t *sess = NULL;
pdn_t *pdn = NULL;
d_assert(xact, return, "Null param");
d_assert(bearer, return, "Null param");
d_assert(mme_ue, return, "Null param");
d_assert(rsp, return, "Null param");
if (rsp->sender_f_teid_for_control_plane.presence == 0)
@ -45,9 +45,22 @@ void mme_s11_handle_create_session_response(gtp_xact_t *xact,
d_error("No S1U TEID");
return;
}
if (rsp->bearer_contexts_created.presence == 0)
{
d_error("No Bearer");
return;
}
if (rsp->bearer_contexts_created. eps_bearer_id.presence == 0)
{
d_error("No EPS Bearer ID");
return;
}
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return, "Null param");
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
rsp->bearer_contexts_created.eps_bearer_id.u8);
d_assert(bearer, return, "Null param");
sess = bearer->sess;
d_assert(sess, return, "Null param");
pdn = sess->pdn;
@ -77,6 +90,19 @@ void mme_s11_handle_create_session_response(gtp_xact_t *xact,
rv = gtp_xact_commit(xact);
d_assert(rv == CORE_OK, return, "xact_commit error");
if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm))
{
rv = nas_send_attach_accept(mme_ue);
d_assert(rv == CORE_OK, return, "nas_send_attach_accept failed");
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
rv = nas_send_activate_default_bearer_context_request(bearer);
d_assert(rv == CORE_OK, return, "nas send failed");
}
else
d_assert(0,, "Invalid EMM state");
}
void mme_s11_handle_modify_bearer_response(
@ -95,6 +121,69 @@ void mme_s11_handle_modify_bearer_response(
d_assert(rv == CORE_OK, return, "xact_commit error");
}
void mme_s11_handle_delete_session_response(
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_delete_session_response_t *rsp)
{
status_t rv;
mme_sess_t *sess = NULL;
d_assert(rsp, return, "Null param");
sess = GTP_XACT_RETRIEVE_SESSION(xact);
d_assert(sess, return, "Null param");
if (rsp->cause.presence == 0)
{
d_error("No Cause");
return;
}
d_trace(3, "[GTP] Delete Session Response : MME[%d] <-- SGW[%d]\n",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
rv = gtp_xact_commit(xact);
d_assert(rv == CORE_OK, return, "xact_commit error");
if (FSM_CHECK(&mme_ue->sm, emm_state_authentication))
{
mme_sess_remove(sess);
if (mme_sess_first(mme_ue) == NULL)
{
CLEAR_SGW_S11_PATH(mme_ue);
mme_s6a_send_air(mme_ue);
}
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_detached))
{
mme_sess_remove(sess);
if (mme_sess_first(mme_ue) == NULL)
{
CLEAR_SGW_S11_PATH(mme_ue);
rv = nas_send_detach_accept(mme_ue);
d_assert(rv == CORE_OK, return, "nas_send_detach_accept failed");
}
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
mme_bearer_t *bearer = mme_default_bearer_in_sess(sess);
d_assert(bearer, return, "Null param");
if (FSM_CHECK(&bearer->sm, esm_state_disconnect))
{
rv = nas_send_deactivate_bearer_context_request(bearer);
d_assert(rv == CORE_OK, return,
"nas_send_deactivate_bearer_context_request failed");
}
else
{
d_assert(0,, "Invalid ESM state");
}
}
else
d_assert(0,, "Invalid EMM state");
}
void mme_s11_handle_create_bearer_request(
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_create_bearer_request_t *req)
{
@ -181,11 +270,16 @@ void mme_s11_handle_release_access_bearers_response(
gtp_release_access_bearers_response_t *rsp)
{
status_t rv;
enb_ue_t *enb_ue = NULL;
S1ap_Cause_t cause;
d_assert(xact, return, "Null param");
d_assert(mme_ue, return, "Null param");
d_assert(rsp, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
if (rsp->cause.presence == 0)
{
d_error("No Cause");
@ -197,6 +291,11 @@ void mme_s11_handle_release_access_bearers_response(
rv = gtp_xact_commit(xact);
d_assert(rv == CORE_OK, return, "xact_commit error");
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,, "s1ap send error");
}
void mme_s11_handle_downlink_data_notification(

View File

@ -10,8 +10,7 @@ extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(void) mme_s11_handle_create_session_response(
gtp_xact_t *xact, mme_bearer_t *bearer,
gtp_create_session_response_t *rsp);
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_create_session_response_t *rsp);
CORE_DECLARE(void) mme_s11_handle_modify_bearer_response(
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_modify_bearer_response_t *rsp);
CORE_DECLARE(void) mme_s11_handle_delete_session_response(

View File

@ -2,10 +2,11 @@
#include "core_debug.h"
#include "mme_s6a_handler.h"
#include "s6a_message.h"
#include "nas_path.h"
#include "mme_s6a_handler.h"
void mme_s6a_handle_aia(mme_ue_t *mme_ue, s6a_aia_message_t *aia_message)
{
pkbuf_t *emmbuf = NULL;
@ -44,6 +45,7 @@ void mme_s6a_handle_aia(mme_ue_t *mme_ue, s6a_aia_message_t *aia_message)
void mme_s6a_handle_ula(mme_ue_t *mme_ue, s6a_ula_message_t *ula_message)
{
status_t rv;
s6a_subscription_data_t *subscription_data = NULL;
d_assert(mme_ue, return, "Null param");
@ -53,4 +55,22 @@ void mme_s6a_handle_ula(mme_ue_t *mme_ue, s6a_ula_message_t *ula_message)
memcpy(&mme_ue->subscription_data,
subscription_data, sizeof(s6a_subscription_data_t));
if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm))
{
if (mme_ue->nas_eps.type == MME_UE_EPS_ATTACH_TYPE) /* ATTACH_REQUEST */
{
rv = nas_send_emm_to_esm(mme_ue, &mme_ue->pdn_connectivity_request);
d_assert(rv == CORE_OK,, "nas_send_emm_to_esm failed");
}
else if (mme_ue->nas_eps.type == MME_UE_EPS_UPDATE_TYPE) /* TAU_REQUEST */
{
rv = nas_send_tau_accept(mme_ue);
d_assert(rv == CORE_OK, return, "nas_send_tau_accept failed");
}
else
d_assert(0,, "Invalid Type(%d)", mme_ue->nas_eps.type);
}
else
d_assert(0,, "Invaild EMM state");
}

View File

@ -6,18 +6,16 @@
#include "mme_event.h"
#include "s1ap_build.h"
#include "s1ap_handler.h"
#include "s1ap_path.h"
#include "mme_fd_path.h"
#include "mme_gtp_path.h"
#include "mme_s11_handler.h"
#include "nas_security.h"
#include "nas_path.h"
#include "emm_handler.h"
#include "esm_build.h"
#include "esm_handler.h"
#include "mme_gtp_path.h"
#include "mme_s11_handler.h"
#include "fd_lib.h"
#include "mme_fd_path.h"
#include "mme_s6a_handler.h"
void mme_state_initial(fsm_t *s, event_t *e)
@ -255,7 +253,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
}
pkbuf_free(pkbuf);
break;
}
case MME_EVT_S6A_MESSAGE:
@ -270,56 +267,31 @@ void mme_state_operational(fsm_t *s, event_t *e)
s6a_message = s6abuf->payload;
d_assert(s6a_message, return, "Null param");
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
rv = nas_send_attach_reject(mme_ue,
S1ap_CauseNas_authentication_failure,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
d_assert(rv == CORE_OK,,
"nas_send_attach_reject failed");
mme_ue_remove(mme_ue);
pkbuf_free(s6abuf);
break;
}
switch(s6a_message->cmd_code)
{
case S6A_CMD_CODE_AUTHENTICATION_INFORMATION:
{
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
rv = nas_send_attach_reject(mme_ue,
S1ap_CauseNas_authentication_failure,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
d_assert(rv == CORE_OK,,
"nas_send_attach_reject failed");
mme_ue_remove(mme_ue);
break;
}
mme_s6a_handle_aia(mme_ue, &s6a_message->aia_message);
break;
}
case S6A_CMD_CODE_UPDATE_LOCATION:
{
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
rv = nas_send_attach_reject(mme_ue,
S1ap_CauseNas_unspecified,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
d_assert(rv == CORE_OK,,
"nas_send_attach_reject failed");
mme_ue_remove(mme_ue);
break;
}
mme_s6a_handle_ula(mme_ue, &s6a_message->ula_message);
if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm))
{
rv = nas_send_emm_to_esm(mme_ue,
&mme_ue->pdn_connectivity_request);
d_assert(rv == CORE_OK,,
"nas_send_emm_to_esm failed");
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
d_error("Not implemented for Tracking Area Update");
}
else
d_assert(0,, "Invaild EMM state");
break;
}
default:
@ -339,7 +311,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
gtp_xact_t *xact = NULL;
gtp_message_t message;
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(pkbuf, break, "Null param");
d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
@ -357,174 +328,26 @@ void mme_state_operational(fsm_t *s, event_t *e)
switch(message.h.type)
{
case GTP_CREATE_SESSION_RESPONSE_TYPE:
{
mme_bearer_t *bearer = NULL;
gtp_create_session_response_t *rsp
= &message.create_session_response;
d_assert(rsp, return, "Null param");
if (rsp->bearer_contexts_created.presence == 0)
{
d_error("No Bearer");
return;
}
if (rsp->bearer_contexts_created.
eps_bearer_id.presence == 0)
{
d_error("No EPS Bearer ID");
return;
}
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
rsp->bearer_contexts_created.eps_bearer_id.u8);
d_assert(bearer, return, "Null param");
mme_s11_handle_create_session_response(xact, bearer, rsp);
if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm))
{
if (mme_ue->nas_eps.type == MME_UE_EPS_ATTACH_TYPE)
{
rv = nas_send_attach_accept(mme_ue);
d_assert(rv == CORE_OK, return,
"nas_send_attach_accept failed");
}
else if (mme_ue->nas_eps.type == MME_UE_EPS_UPDATE_TYPE)
{
rv = nas_send_tau_accept(mme_ue);
d_assert(rv == CORE_OK, return,
"nas_send_tau_accept failed");
}
else
d_assert(0, return, "Invalid EPS type(%d)",
mme_ue->nas_eps.type);
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
mme_sess_t *sess = NULL;
enb_ue_t *enb_ue = NULL;
pkbuf_t *esmbuf = NULL, *s1apbuf = NULL;
sess = bearer->sess;
d_assert(sess, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
rv = esm_build_activate_default_bearer_context_request(
&esmbuf, sess);
d_assert(rv == CORE_OK && esmbuf, return,
"esm build error");
d_trace(3, "[NAS] Activate default bearer "
"context request : EMM <-- ESM\n");
rv = s1ap_build_e_rab_setup_request(
&s1apbuf, bearer, esmbuf);
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(esmbuf); return, "s1ap build error");
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,);
}
else
d_assert(0, break, "Invalid EMM state");
mme_s11_handle_create_session_response(
xact, mme_ue, &message.create_session_response);
break;
}
case GTP_MODIFY_BEARER_RESPONSE_TYPE:
mme_s11_handle_modify_bearer_response(
xact, mme_ue, &message.modify_bearer_response);
break;
case GTP_DELETE_SESSION_RESPONSE_TYPE:
{
mme_sess_t *sess = NULL;
gtp_delete_session_response_t *rsp =
&message.delete_session_response;
d_assert(rsp, return, "Null param");
sess = GTP_XACT_RETRIEVE_SESSION(xact);
d_assert(sess, return, "Null param");
if (rsp->cause.presence == 0)
{
d_error("No Cause");
return;
}
d_trace(3, "[GTP] Delete Session Response : "
"MME[%d] <-- SGW[%d]\n",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
rv = gtp_xact_commit(xact);
d_assert(rv == CORE_OK, return, "xact_commit error");
if (FSM_CHECK(&mme_ue->sm, emm_state_authentication))
{
mme_sess_remove(sess);
if (mme_sess_first(mme_ue) == NULL)
{
CLEAR_SGW_S11_PATH(mme_ue);
mme_s6a_send_air(mme_ue);
}
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_detached))
{
mme_sess_remove(sess);
if (mme_sess_first(mme_ue) == NULL)
{
CLEAR_SGW_S11_PATH(mme_ue);
emm_handle_detach_accept(mme_ue);
}
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
mme_bearer_t *bearer = mme_default_bearer_in_sess(sess);
d_assert(bearer, return, "Null param");
if (FSM_CHECK(&bearer->sm, esm_state_disconnect))
{
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, break, "Null param");
rv = nas_send_deactivate_bearer_context_request(
enb_ue, bearer);
d_assert(rv == CORE_OK, break,
"nas_send_deactivate_bearer"
"_context_request failed");
}
else
{
d_assert(0, break, "Invalid ESM state");
}
}
else
d_assert(0, break, "Invalid EMM state");
mme_s11_handle_delete_session_response(
xact, mme_ue, &message.delete_session_response);
break;
}
case GTP_CREATE_BEARER_REQUEST_TYPE:
mme_s11_handle_create_bearer_request(
xact, mme_ue, &message.create_bearer_request);
break;
case GTP_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
{
S1ap_Cause_t cause;
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, break, "Null param");
mme_s11_handle_release_access_bearers_response(
xact, mme_ue, &message.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);
d_assert(rv == CORE_OK,, "s1ap send error");
break;
}
case GTP_DOWNLINK_DATA_NOTIFICATION_TYPE:
{
mme_s11_handle_downlink_data_notification(
xact, mme_ue, &message.downlink_data_notification);
@ -532,7 +355,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
/* Start T3413 */
tm_start(mme_ue->t3413);
break;
}
default:
d_warn("Not implmeneted(type:%d)", message.h.type);
break;

View File

@ -8,10 +8,13 @@
#include "nas_path.h"
#include "mme_event.h"
status_t nas_send_to_enb(enb_ue_t *enb_ue, pkbuf_t *pkbuf)
status_t nas_send_to_enb(mme_ue_t *mme_ue, pkbuf_t *pkbuf)
{
mme_enb_t *enb = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param");
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR, "Null param");
@ -41,13 +44,13 @@ status_t nas_send_emm_to_esm(
return CORE_OK;
}
status_t nas_send_to_downlink_nas_transport(
mme_ue_t *mme_ue, pkbuf_t *pkbuf)
status_t nas_send_to_downlink_nas_transport(mme_ue_t *mme_ue, pkbuf_t *pkbuf)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param");
@ -55,21 +58,21 @@ status_t nas_send_to_downlink_nas_transport(
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(pkbuf); return CORE_ERROR, "s1ap build error");
return nas_send_to_enb(enb_ue, s1apbuf);
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas send error");
return CORE_OK;
}
status_t nas_send_attach_accept(mme_ue_t *mme_ue)
{
status_t rv;
mme_sess_t *sess = NULL;
enb_ue_t *enb_ue = NULL;
pkbuf_t *esmbuf = NULL, *emmbuf = NULL, *s1apbuf = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param");
sess = mme_sess_first(mme_ue);
d_assert(sess, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param");
rv = esm_build_activate_default_bearer_context_request(&esmbuf, sess);
d_assert(rv == CORE_OK && esmbuf, return CORE_ERROR, "esm build error");
@ -87,7 +90,8 @@ status_t nas_send_attach_accept(mme_ue_t *mme_ue)
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(emmbuf); return CORE_ERROR, "s1ap build error");
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,);
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas send error");
return CORE_OK;
}
@ -134,6 +138,38 @@ status_t nas_send_attach_reject(mme_ue_t *mme_ue,
return CORE_OK;
}
status_t nas_send_detach_accept(mme_ue_t *mme_ue)
{
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");
/* reply with detach accept */
if ((mme_ue->detach_type.switch_off & 0x1) == 0)
{
rv = emm_build_detach_accept(&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, return CORE_ERROR, "nas send failed");
}
/* 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);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
return CORE_OK;
}
status_t nas_send_pdn_connectivity_reject(
mme_sess_t *sess, nas_esm_cause_t esm_cause)
{
@ -155,14 +191,44 @@ status_t nas_send_pdn_connectivity_reject(
return CORE_OK;
}
status_t nas_send_activate_dedicated_bearer_context_request(
enb_ue_t *enb_ue, mme_bearer_t *bearer)
status_t nas_send_activate_default_bearer_context_request(mme_bearer_t *bearer)
{
status_t rv;
pkbuf_t *esmbuf = NULL, *s1apbuf = NULL;
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = NULL;
d_assert(enb_ue, return CORE_ERROR, "Null param");
d_assert(bearer, return CORE_ERROR, "Null param");
sess = bearer->sess;
d_assert(sess, return CORE_ERROR, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return CORE_ERROR, "Null param");
rv = esm_build_activate_default_bearer_context_request(&esmbuf, sess);
d_assert(rv == CORE_OK && esmbuf, return CORE_ERROR, "esm build error");
d_trace(3, "[NAS] Activate default bearer context request : EMM <-- ESM\n");
rv = s1ap_build_e_rab_setup_request(&s1apbuf, bearer, esmbuf);
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(esmbuf); return CORE_ERROR, "s1ap build error");
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas send error");
return CORE_OK;
}
status_t nas_send_activate_dedicated_bearer_context_request(
mme_bearer_t *bearer)
{
status_t rv;
pkbuf_t *esmbuf = NULL, *s1apbuf = NULL;
mme_ue_t *mme_ue = NULL;
d_assert(bearer, return CORE_ERROR, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return CORE_ERROR, "Null param");
rv = esm_build_activate_dedicated_bearer_context_request(&esmbuf, bearer);
d_assert(rv == CORE_OK && esmbuf, return CORE_ERROR, "esm build error");
@ -174,20 +240,22 @@ status_t nas_send_activate_dedicated_bearer_context_request(
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(esmbuf); return CORE_ERROR, "s1ap build error");
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,);
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas send error");
return CORE_OK;
}
status_t nas_send_deactivate_bearer_context_request(
enb_ue_t *enb_ue, mme_bearer_t *bearer)
status_t nas_send_deactivate_bearer_context_request(mme_bearer_t *bearer)
{
status_t rv;
pkbuf_t *esmbuf = NULL, *s1apbuf = NULL;
S1ap_Cause_t cause;
mme_ue_t *mme_ue = NULL;
d_assert(enb_ue, return CORE_ERROR, "Null param");
d_assert(bearer, return CORE_ERROR, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return CORE_ERROR, "Null param");
rv = esm_build_deactivate_bearer_context_request(
&esmbuf, bearer, ESM_CAUSE_REGULAR_DEACTIVATION);
@ -201,7 +269,8 @@ status_t nas_send_deactivate_bearer_context_request(
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(esmbuf); return CORE_ERROR, "s1ap build error");
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,);
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas send error");
return CORE_OK;
}
@ -211,14 +280,16 @@ status_t nas_send_tau_accept(mme_ue_t *mme_ue)
status_t rv;
enb_ue_t *enb_ue = NULL;
pkbuf_t *s1apbuf = NULL, *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");
if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
S1ap_Cause_t cause;
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param");
/* Build TAU accept */
rv = emm_build_tau_accept(&emmbuf, mme_ue);
d_assert(rv == CORE_OK, return CORE_ERROR, "emm build error");
@ -246,7 +317,8 @@ status_t nas_send_tau_accept(mme_ue_t *mme_ue)
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(emmbuf); return CORE_ERROR, "s1ap build error");
d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,);
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas send error");
}
return CORE_OK;
@ -272,7 +344,8 @@ status_t nas_send_tau_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
}
/* Send Dl NAS to UE */
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas dl send error");
/* FIXME : delay required before sending UE context release to make sure
@ -305,8 +378,8 @@ status_t nas_send_service_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
}
/* Send Dl NAS to UE */
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas dl send error");
/* FIXME : delay required before sending UE context release to make sure
* that UE receive DL NAS ? */

View File

@ -9,24 +9,31 @@
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) nas_send_to_enb(enb_ue_t *enb_ue, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) nas_send_to_enb(mme_ue_t *mme_ue, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) nas_send_emm_to_esm(
mme_ue_t *mme_ue, nas_esm_message_container_t *esm_message_container);
CORE_DECLARE(status_t) nas_send_to_downlink_nas_transport(
mme_ue_t *mme_ue, pkbuf_t *pkbuf);
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,
e_S1ap_CauseNas s1ap_cause_nas, nas_emm_cause_t emm_cause,
nas_esm_cause_t esm_cause);
CORE_DECLARE(status_t) nas_send_detach_accept(mme_ue_t *mme_ue);
CORE_DECLARE(status_t) nas_send_pdn_connectivity_reject(
mme_sess_t *sess, nas_esm_cause_t esm_cause);
CORE_DECLARE(status_t) nas_send_activate_default_bearer_context_request(
mme_bearer_t *bearer);
CORE_DECLARE(status_t) nas_send_activate_dedicated_bearer_context_request(
enb_ue_t *enb_ue, mme_bearer_t *bearer);
mme_bearer_t *bearer);
CORE_DECLARE(status_t) nas_send_deactivate_bearer_context_request(
enb_ue_t *enb_ue, mme_bearer_t *bearer);
mme_bearer_t *bearer);
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);

View File

@ -10,6 +10,8 @@
#include "s1ap_build.h"
#include "s1ap_conv.h"
static void s1ap_build_cause(S1ap_Cause_t *dst, S1ap_Cause_t *src);
status_t s1ap_build_setup_rsp(pkbuf_t **pkbuf)
{
int erval;
@ -402,35 +404,6 @@ status_t s1ap_build_e_rab_setup_request(
return CORE_OK;
}
static void s1ap_build_cause(S1ap_Cause_t *dst, S1ap_Cause_t *src)
{
d_assert(src, return, "Null param");
d_assert(dst, return, "Null param");
dst->present = src->present;
switch(dst->present)
{
case S1ap_Cause_PR_radioNetwork:
dst->choice.radioNetwork = src->choice.radioNetwork;
break;
case S1ap_Cause_PR_transport:
dst->choice.transport = src->choice.transport;
break;
case S1ap_Cause_PR_nas:
dst->choice.nas = src->choice.nas;
break;
case S1ap_Cause_PR_protocol:
dst->choice.protocol = src->choice.protocol;
break;
case S1ap_Cause_PR_misc:
dst->choice.misc = src->choice.misc;
break;
default:
d_error("Invalid src type : %d", dst->present);
break;
}
}
status_t s1ap_build_e_rab_release_command(pkbuf_t **s1apbuf,
mme_bearer_t *bearer, pkbuf_t *esmbuf, S1ap_Cause_t *cause)
{
@ -617,3 +590,33 @@ status_t s1ap_build_paging(pkbuf_t **s1apbuf, mme_ue_t *mme_ue)
return CORE_OK;
}
static void s1ap_build_cause(S1ap_Cause_t *dst, S1ap_Cause_t *src)
{
d_assert(src, return, "Null param");
d_assert(dst, return, "Null param");
dst->present = src->present;
switch(dst->present)
{
case S1ap_Cause_PR_radioNetwork:
dst->choice.radioNetwork = src->choice.radioNetwork;
break;
case S1ap_Cause_PR_transport:
dst->choice.transport = src->choice.transport;
break;
case S1ap_Cause_PR_nas:
dst->choice.nas = src->choice.nas;
break;
case S1ap_Cause_PR_protocol:
dst->choice.protocol = src->choice.protocol;
break;
case S1ap_Cause_PR_misc:
dst->choice.misc = src->choice.misc;
break;
default:
d_error("Invalid src type : %d", dst->present);
break;
}
}

View File

@ -5,11 +5,11 @@
#include "mme_event.h"
#include "s1ap_conv.h"
#include "s1ap_build.h"
#include "s1ap_path.h"
#include "nas_path.h"
#include "mme_gtp_path.h"
#include "s1ap_build.h"
#include "s1ap_handler.h"
void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message)
@ -250,15 +250,9 @@ void s1ap_handle_ue_capability_info_indication(
void s1ap_handle_activate_default_bearer_accept(mme_bearer_t *bearer)
{
status_t rv;
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
mme_bearer_t *dedicated_bearer = NULL;
d_assert(bearer, return, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return, "Null param");
rv = mme_gtp_send_modify_bearer_request(bearer);
d_assert(rv == CORE_OK, return,
@ -268,7 +262,7 @@ void s1ap_handle_activate_default_bearer_accept(mme_bearer_t *bearer)
while(dedicated_bearer)
{
rv = nas_send_activate_dedicated_bearer_context_request(
enb_ue, dedicated_bearer);
dedicated_bearer);
d_assert(rv == CORE_OK, return,
"nas_send_activate_dedicated_bearer_context failed");
@ -499,7 +493,6 @@ void s1ap_handle_ue_context_release_complete(
enb_ue_remove(enb_ue);
}
/* FIXME : Where is a good location S1AP handler or EMM handler?*/
void s1ap_handle_paging(mme_ue_t *mme_ue)
{
pkbuf_t *s1apbuf = NULL;

View File

@ -4,8 +4,10 @@
#include "mme_event.h"
#include "s1ap_build.h"
#include "nas_security.h"
#include "nas_path.h"
#include "s1ap_build.h"
#include "s1ap_path.h"
static int _s1ap_accept_cb(net_sock_t *net_sock, void *data);
@ -350,6 +352,25 @@ status_t s1ap_send_to_nas(enb_ue_t *enb_ue, S1ap_NAS_PDU_t *nasPdu)
return CORE_OK;
}
status_t s1ap_send_initial_context_setup_request(mme_ue_t *mme_ue)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
mme_sess_t *sess = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param");
sess = mme_sess_first(mme_ue);
d_assert(sess, return CORE_ERROR, "Null param");
rv = s1ap_build_initial_context_setup_request(&s1apbuf, sess, NULL);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = nas_send_to_enb(mme_ue, s1apbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "s1ap send error");
return CORE_OK;
}
status_t s1ap_send_ue_context_release_commmand(
enb_ue_t *enb_ue, S1ap_Cause_t *cause)

View File

@ -19,6 +19,9 @@ CORE_DECLARE(status_t) s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkb);
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);
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);