forked from acouzens/open5gs
propose TAU process when Unknown GUTI or MAC Faield of Security Context
This commit is contained in:
parent
f4e4697430
commit
b40d19db2b
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)",
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
222
src/mme/mme_sm.c
222
src/mme/mme_sm.c
|
@ -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;
|
||||
|
|
|
@ -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 ? */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue