diff --git a/src/mme/emm_handler.c b/src/mme/emm_handler.c index 76cec8d38..581840dd5 100644 --- a/src/mme/emm_handler.c +++ b/src/mme/emm_handler.c @@ -21,56 +21,6 @@ #include "emm_handler.h" -void event_emm_to_esm( - mme_ue_t *mme_ue, nas_esm_message_container_t *esm_message_container) -{ - pkbuf_t *esmbuf = NULL; - event_t e; - - nas_esm_header_t *h = NULL; - c_uint8_t pti = NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; - c_uint8_t ebi = NAS_EPS_BEARER_IDENTITY_UNASSIGNED; - mme_sess_t *sess = NULL; - mme_bearer_t *bearer = NULL; - - d_assert(mme_ue, return, "Null param"); - d_assert(esm_message_container, return, "Null param"); - d_assert(esm_message_container->length, return, "Null param"); - - /* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM. - * When calculating AES_CMAC, we need to use the headroom of the packet. */ - esmbuf = pkbuf_alloc(NAS_HEADROOM, esm_message_container->length); - d_assert(esmbuf, return, "Null param"); - memcpy(esmbuf->payload, - esm_message_container->buffer, esm_message_container->length); - - h = (nas_esm_header_t *)esm_message_container->buffer; - d_assert(h, return, "Null param"); - - pti = h->procedure_transaction_identity; - ebi = h->eps_bearer_identity; - - if (ebi != NAS_EPS_BEARER_IDENTITY_UNASSIGNED) - bearer = mme_bearer_find_by_ue_ebi(mme_ue, ebi); - else if (pti != NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) - bearer = mme_bearer_find_by_ue_pti(mme_ue, pti); - else - d_assert(0, return, "Invalid pti(%d) and ebi(%d)\n", pti, ebi); - - if (!bearer) - { - sess = mme_sess_add(mme_ue, pti); - d_assert(sess, return, "Null param"); - bearer = mme_default_bearer_in_sess(sess); - } - d_assert(bearer, return, "Null param"); - - event_set(&e, MME_EVT_ESM_MESSAGE); - event_set_param1(&e, (c_uintptr_t)bearer->index); - event_set_param2(&e, (c_uintptr_t)esmbuf); - mme_event_send(&e); -} - void emm_handle_attach_request( mme_ue_t *mme_ue, nas_attach_request_t *attach_request) { @@ -164,38 +114,6 @@ void emm_handle_attach_request( NAS_STORE_DATA(&mme_ue->pdn_connectivity_request, esm_message_container); } -void emm_handle_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, "Null param"); - sess = mme_sess_first(mme_ue); - 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(&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 = emm_build_attach_accept(&emmbuf, mme_ue, esmbuf); - d_assert(rv == CORE_OK && emmbuf, - pkbuf_free(esmbuf); return, "emm build error"); - - d_trace(3, "[NAS] Attach accept : UE[%s] <-- EMM\n", mme_ue->imsi_bcd); - - rv = s1ap_build_initial_context_setup_request(&s1apbuf, sess, emmbuf); - d_assert(rv == CORE_OK && s1apbuf, - pkbuf_free(emmbuf); return, "s1ap build error"); - - d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); -} - void emm_handle_attach_complete( mme_ue_t *mme_ue, nas_attach_complete_t *attach_complete) { @@ -214,7 +132,8 @@ void emm_handle_attach_complete( d_assert(mme_ue, return, "Null param"); - event_emm_to_esm(mme_ue, &attach_complete->esm_message_container); + rv = nas_send_emm_to_esm(mme_ue, &attach_complete->esm_message_container); + d_assert(rv == CORE_OK, return, "nas_send_emm_to_esm failed"); memset(&message, 0, sizeof(message)); message.h.security_header_type = @@ -255,53 +174,6 @@ void emm_handle_attach_complete( d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,); } -void emm_handle_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) -{ - status_t rv; - mme_enb_t *enb = NULL; - enb_ue_t *enb_ue = NULL; - mme_sess_t *sess = NULL; - mme_bearer_t *bearer = NULL; - pkbuf_t *s1apbuf = NULL, *esmbuf = NULL, *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"); - enb = enb_ue->enb; - d_assert(enb, return, "Null param"); - - sess = mme_sess_first(mme_ue); - if (sess) - { - bearer = mme_default_bearer_in_sess(sess); - if (bearer) - { - rv = esm_build_pdn_connectivity_reject( - &esmbuf, bearer->pti, esm_cause); - d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); - d_trace(3, "[NAS] PDN Connectivity reject : EMM <-- ESM\n", - bearer->pti); - } - } - - rv = emm_build_attach_reject(&emmbuf, emm_cause, esmbuf); - d_assert(rv == CORE_OK && emmbuf, - pkbuf_free(esmbuf); return, "emm build error"); - d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,); - d_trace(3, "[NAS] Attach reject : UE[%s] <-- EMM\n", mme_ue->imsi_bcd); - - cause.present = S1ap_Cause_PR_nas; - cause.choice.nas = s1ap_cause_nas;; - - rv = s1ap_build_ue_context_release_commmand(&s1apbuf, enb_ue, &cause); - d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error"); - d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error"); -} - void emm_handle_identity_response( mme_ue_t *mme_ue, nas_identity_response_t *identity_response) { diff --git a/src/mme/emm_handler.h b/src/mme/emm_handler.h index 7674743fa..03efe9651 100644 --- a/src/mme/emm_handler.h +++ b/src/mme/emm_handler.h @@ -9,18 +9,10 @@ extern "C" { #endif /* __cplusplus */ -CORE_DECLARE(void) event_emm_to_esm( - mme_ue_t *mme_ue, nas_esm_message_container_t *esm_message_container); - CORE_DECLARE(void) emm_handle_attach_request( mme_ue_t *mme_ue, nas_attach_request_t *attach_request); -CORE_DECLARE(void) emm_handle_attach_accept(mme_ue_t *mme_ue); CORE_DECLARE(void) emm_handle_attach_complete( mme_ue_t *mme_ue, nas_attach_complete_t *attach_complete); -CORE_DECLARE(void) emm_handle_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(void) emm_handle_identity_response( mme_ue_t *mme_ue, nas_identity_response_t *identity_response); diff --git a/src/mme/emm_sm.c b/src/mme/emm_sm.c index bf04ad49b..b5f33998b 100644 --- a/src/mme/emm_sm.c +++ b/src/mme/emm_sm.c @@ -128,8 +128,11 @@ void emm_state_identity(fsm_t *s, event_t *e) if (SECURITY_CONTEXT_IS_VALID(mme_ue)) { - event_emm_to_esm(mme_ue, + status_t rv; + rv = nas_send_emm_to_esm(mme_ue, &mme_ue->pdn_connectivity_request); + d_assert(rv == CORE_OK,, + "nas_send_emm_to_esm failed"); FSM_TRAN(s, &emm_state_default_esm); } else @@ -547,7 +550,9 @@ static void emm_state_attach_request(fsm_t *s, event_t *e, { if (SECURITY_CONTEXT_IS_VALID(mme_ue)) { - event_emm_to_esm(mme_ue, &mme_ue->pdn_connectivity_request); + status_t rv; + rv = nas_send_emm_to_esm(mme_ue, &mme_ue->pdn_connectivity_request); + d_assert(rv == CORE_OK,, "nas_send_emm_to_esm failed"); FSM_TRAN(s, &emm_state_default_esm); } else diff --git a/src/mme/esm_handler.c b/src/mme/esm_handler.c index 240141724..1b9b953ee 100644 --- a/src/mme/esm_handler.c +++ b/src/mme/esm_handler.c @@ -5,12 +5,10 @@ #include "nas_message.h" #include "mme_context.h" -#include "mme_event.h" -#include "esm_build.h" -#include "s1ap_build.h" -#include "s1ap_path.h" #include "nas_path.h" -#include "mme_s11_build.h" +#include "mme_gtp_path.h" + +#include "esm_build.h" void esm_handle_pdn_connectivity_request(mme_sess_t *sess, nas_pdn_connectivity_request_t *pdn_connectivity_request) @@ -70,56 +68,30 @@ void esm_handle_information_response(mme_sess_t *sess, void esm_handle_activate_default_bearer_accept(mme_bearer_t *bearer) { status_t rv; - gtp_header_t h; - gtp_xact_t *xact = NULL; mme_ue_t *mme_ue = NULL; - mme_sess_t *sess = NULL; - mme_bearer_t *dedicated_bearer = NULL; - pkbuf_t *pkbuf = NULL; + enb_ue_t *enb_ue = NULL; d_assert(bearer, return, "Null param"); - sess = bearer->sess; - d_assert(sess, return, "Null param"); - mme_ue = sess->mme_ue; + 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"); if (MME_HAVE_ENB_S1U_PATH(bearer)) { - memset(&h, 0, sizeof(gtp_header_t)); - h.type = GTP_MODIFY_BEARER_REQUEST_TYPE; - h.teid = mme_ue->sgw_s11_teid; + mme_bearer_t *dedicated_bearer = NULL; - rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer); - d_assert(rv == CORE_OK, return, "S11 build error"); - - xact = gtp_xact_local_create(sess->sgw, &h, pkbuf); - d_assert(xact, return, "Null param"); - - rv = gtp_xact_commit(xact); - d_assert(rv == CORE_OK, return, "xact_commit error"); + rv = mme_gtp_send_modify_bearer_request(bearer); + d_assert(rv == CORE_OK, return, + "mme_gtp_send_modify_bearer_request failed"); dedicated_bearer = mme_bearer_next(bearer); while(dedicated_bearer) { - enb_ue_t *enb_ue = NULL; - pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; - - enb_ue = mme_ue->enb_ue; - d_assert(enb_ue, return, "Null param"); - - rv = esm_build_activate_dedicated_bearer_context( - &esmbuf, dedicated_bearer); - d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); - - d_trace(3, "[NAS] Activate dedicated bearer context request : " - "EMM <-- ESM\n"); - - rv = s1ap_build_e_rab_setup_request( - &s1apbuf, dedicated_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,,); + rv = nas_send_activate_dedicated_bearer_context( + enb_ue, dedicated_bearer); + d_assert(rv == CORE_OK, return, + "nas_send_activate_dedicated_bearer_context failed"); dedicated_bearer = mme_bearer_next(dedicated_bearer); } @@ -129,33 +101,13 @@ void esm_handle_activate_default_bearer_accept(mme_bearer_t *bearer) void esm_handle_activate_dedicated_bearer_accept(mme_bearer_t *bearer) { status_t rv; - gtp_header_t h; - gtp_xact_t *xact = NULL; - mme_ue_t *mme_ue = NULL; - mme_sess_t *sess = NULL; - pkbuf_t *pkbuf = NULL; d_assert(bearer, return, "Null param"); - sess = bearer->sess; - d_assert(sess, return, "Null param"); - mme_ue = sess->mme_ue; - d_assert(mme_ue, return, "Null param"); - xact = bearer->xact; - d_assert(xact, return, "Null param"); if (MME_HAVE_ENB_S1U_PATH(bearer)) { - memset(&h, 0, sizeof(gtp_header_t)); - h.type = GTP_CREATE_BEARER_RESPONSE_TYPE; - h.teid = mme_ue->sgw_s11_teid; - - rv = mme_s11_build_create_bearer_response(&pkbuf, h.type, bearer); - d_assert(rv == CORE_OK, return, "S11 build error"); - - rv = gtp_xact_update_tx(xact, &h, pkbuf); - d_assert(xact, return, "Null param"); - - rv = gtp_xact_commit(xact); - d_assert(rv == CORE_OK, return, "xact_commit error"); + rv = mme_gtp_send_create_bearer_response(bearer); + d_assert(rv == CORE_OK, return, + "mme_gtp_send_create_bearer_response failed"); } } diff --git a/src/mme/esm_sm.c b/src/mme/esm_sm.c index 7921e4dbc..cc03ac619 100644 --- a/src/mme/esm_sm.c +++ b/src/mme/esm_sm.c @@ -315,7 +315,10 @@ static void esm_state_pdn_connectivity_request( { if (MME_HAVE_SGW_S11_PATH(mme_ue)) { - emm_handle_attach_accept(mme_ue); + status_t rv; + rv = nas_send_attach_accept(mme_ue); + d_assert(rv == CORE_OK, return, + "nas_send_attach_accept failed"); } else { diff --git a/src/mme/mme_gtp_path.c b/src/mme/mme_gtp_path.c index d7ff385d5..8d8d1db90 100644 --- a/src/mme/mme_gtp_path.c +++ b/src/mme/mme_gtp_path.c @@ -4,8 +4,8 @@ #include "core_net.h" #include "mme_event.h" -#include "mme_context.h" #include "mme_gtp_path.h" +#include "mme_s11_build.h" static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data) { @@ -90,3 +90,68 @@ status_t mme_gtp_close() return CORE_OK; } + +status_t mme_gtp_send_modify_bearer_request(mme_bearer_t *bearer) +{ + status_t rv; + + gtp_xact_t *xact = NULL; + mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; + + gtp_header_t h; + pkbuf_t *pkbuf = NULL; + + d_assert(bearer, return CORE_ERROR, "Null param"); + sess = bearer->sess; + d_assert(sess, return CORE_ERROR, "Null param"); + mme_ue = sess->mme_ue; + d_assert(mme_ue, return CORE_ERROR, "Null param"); + + memset(&h, 0, sizeof(gtp_header_t)); + h.type = GTP_MODIFY_BEARER_REQUEST_TYPE; + h.teid = mme_ue->sgw_s11_teid; + + rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer); + d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error"); + + xact = gtp_xact_local_create(sess->sgw, &h, pkbuf); + d_assert(xact, return CORE_ERROR, "Null param"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error"); + + return CORE_OK; +} + +status_t mme_gtp_send_create_bearer_response(mme_bearer_t *bearer) +{ + status_t rv; + + gtp_xact_t *xact = NULL; + mme_ue_t *mme_ue = NULL; + + gtp_header_t h; + pkbuf_t *pkbuf = NULL; + + d_assert(bearer, return CORE_ERROR, "Null param"); + mme_ue = bearer->mme_ue; + d_assert(mme_ue, return CORE_ERROR, "Null param"); + xact = bearer->xact; + d_assert(xact, return CORE_ERROR, "Null param"); + + memset(&h, 0, sizeof(gtp_header_t)); + h.type = GTP_CREATE_BEARER_RESPONSE_TYPE; + h.teid = mme_ue->sgw_s11_teid; + + rv = mme_s11_build_create_bearer_response(&pkbuf, h.type, bearer); + d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error"); + + rv = gtp_xact_update_tx(xact, &h, pkbuf); + d_assert(xact, return CORE_ERROR, "Null param"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error"); + + return CORE_OK; +} diff --git a/src/mme/mme_gtp_path.h b/src/mme/mme_gtp_path.h index b31293347..8ced7e954 100644 --- a/src/mme/mme_gtp_path.h +++ b/src/mme/mme_gtp_path.h @@ -3,6 +3,8 @@ #include "core_pkbuf.h" +#include "mme_context.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -10,6 +12,11 @@ extern "C" { CORE_DECLARE(status_t) mme_gtp_open(); CORE_DECLARE(status_t) mme_gtp_close(); +CORE_DECLARE(status_t) mme_gtp_send_modify_bearer_request( + mme_bearer_t *bearer); +CORE_DECLARE(status_t) mme_gtp_send_create_bearer_response( + mme_bearer_t *bearer); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index 5561455b6..28a0114d7 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -260,6 +260,7 @@ void mme_state_operational(fsm_t *s, event_t *e) } case MME_EVT_S6A_MESSAGE: { + status_t rv; mme_ue_t *mme_ue = mme_ue_find(event_get_param1(e)); pkbuf_t *s6abuf = (pkbuf_t *)event_get_param2(e); s6a_message_t *s6a_message = NULL; @@ -275,10 +276,12 @@ void mme_state_operational(fsm_t *s, event_t *e) { if (s6a_message->result_code != ER_DIAMETER_SUCCESS) { - emm_handle_attach_reject(mme_ue, + 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; @@ -291,10 +294,12 @@ void mme_state_operational(fsm_t *s, event_t *e) { if (s6a_message->result_code != ER_DIAMETER_SUCCESS) { - emm_handle_attach_reject(mme_ue, + 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; @@ -304,8 +309,10 @@ void mme_state_operational(fsm_t *s, event_t *e) if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm)) { - event_emm_to_esm(mme_ue, + rv = nas_send_emm_to_esm(mme_ue, &mme_ue->pdn_connectivity_request); + d_assert(rv == CORE_OK,, + "nas_send_emm_to_esm failed"); } else if (FSM_CHECK(&mme_ue->sm, emm_state_attached)) { @@ -377,7 +384,9 @@ void mme_state_operational(fsm_t *s, event_t *e) if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm)) { - emm_handle_attach_accept(mme_ue); + 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)) { diff --git a/src/mme/nas_path.c b/src/mme/nas_path.c index f7f6eae2c..48abdc680 100644 --- a/src/mme/nas_path.c +++ b/src/mme/nas_path.c @@ -6,6 +6,7 @@ #include "esm_build.h" #include "emm_build.h" #include "nas_path.h" +#include "mme_event.h" status_t nas_send_to_enb(enb_ue_t *enb_ue, pkbuf_t *pkbuf) { @@ -18,6 +19,28 @@ status_t nas_send_to_enb(enb_ue_t *enb_ue, pkbuf_t *pkbuf) return s1ap_send_to_enb(enb, pkbuf); } +status_t nas_send_emm_to_esm( + mme_ue_t *mme_ue, nas_esm_message_container_t *esm_message_container) +{ + pkbuf_t *esmbuf = NULL; + + d_assert(mme_ue, return CORE_ERROR, "Null param"); + d_assert(esm_message_container, return CORE_ERROR, "Null param"); + d_assert(esm_message_container->length, return CORE_ERROR, "Null param"); + + /* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM. + * When calculating AES_CMAC, we need to use the headroom of the packet. */ + esmbuf = pkbuf_alloc(NAS_HEADROOM, esm_message_container->length); + d_assert(esmbuf, return CORE_ERROR, "Null param"); + memcpy(esmbuf->payload, + esm_message_container->buffer, esm_message_container->length); + + d_assert(s1ap_send_to_esm(mme_ue, esmbuf) == CORE_OK, return CORE_ERROR, + "s1ap_send_to_esm failed"); + + return CORE_OK; +} + status_t nas_send_to_downlink_nas_transport( mme_ue_t *mme_ue, pkbuf_t *pkbuf) { @@ -34,3 +57,112 @@ status_t nas_send_to_downlink_nas_transport( return nas_send_to_enb(enb_ue, s1apbuf); } + +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(&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 = emm_build_attach_accept(&emmbuf, mme_ue, esmbuf); + d_assert(rv == CORE_OK && emmbuf, + pkbuf_free(esmbuf); return CORE_ERROR, "emm build error"); + + d_trace(3, "[NAS] Attach accept : UE[%s] <-- EMM\n", mme_ue->imsi_bcd); + + rv = s1ap_build_initial_context_setup_request(&s1apbuf, sess, emmbuf); + 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,,); + + return CORE_OK; +} + +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) +{ + status_t rv; + mme_enb_t *enb = NULL; + enb_ue_t *enb_ue = NULL; + mme_sess_t *sess = NULL; + mme_bearer_t *bearer = NULL; + pkbuf_t *s1apbuf = NULL, *esmbuf = 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"); + enb = enb_ue->enb; + d_assert(enb, return CORE_ERROR, "Null param"); + + sess = mme_sess_first(mme_ue); + if (sess) + { + bearer = mme_default_bearer_in_sess(sess); + if (bearer) + { + rv = esm_build_pdn_connectivity_reject( + &esmbuf, bearer->pti, esm_cause); + d_assert(rv == CORE_OK && esmbuf, return CORE_ERROR, + "esm build error"); + d_trace(3, "[NAS] PDN Connectivity reject : EMM <-- ESM\n", + bearer->pti); + } + } + + rv = emm_build_attach_reject(&emmbuf, emm_cause, esmbuf); + d_assert(rv == CORE_OK && emmbuf, + pkbuf_free(esmbuf); return CORE_ERROR, "emm build error"); + d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,); + d_trace(3, "[NAS] Attach reject : UE[%s] <-- EMM\n", mme_ue->imsi_bcd); + + cause.present = S1ap_Cause_PR_nas; + cause.choice.nas = s1ap_cause_nas;; + + rv = s1ap_build_ue_context_release_commmand(&s1apbuf, enb_ue, &cause); + d_assert(rv == CORE_OK && s1apbuf, + return CORE_ERROR, "s1ap build error"); + d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK, + return CORE_ERROR, "s1ap send error"); + + return CORE_OK; +} + +status_t nas_send_activate_dedicated_bearer_context( + enb_ue_t *enb_ue, mme_bearer_t *bearer) +{ + status_t rv; + pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; + + d_assert(enb_ue, return CORE_ERROR, "Null param"); + d_assert(bearer, return CORE_ERROR, "Null param"); + + rv = esm_build_activate_dedicated_bearer_context(&esmbuf, bearer); + d_assert(rv == CORE_OK && esmbuf, return CORE_ERROR, "esm build error"); + + d_trace(3, "[NAS] Activate dedicated 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"); + + d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); + + return CORE_OK; +} diff --git a/src/mme/nas_path.h b/src/mme/nas_path.h index 5aa3adbe7..0196a813d 100644 --- a/src/mme/nas_path.h +++ b/src/mme/nas_path.h @@ -10,8 +10,16 @@ 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_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_activate_dedicated_bearer_context( + enb_ue_t *enb_ue, mme_bearer_t *bearer); #ifdef __cplusplus } diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index de7ccd348..e6c3b9752 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -7,135 +7,12 @@ #include "s1ap_conv.h" #include "s1ap_build.h" #include "s1ap_path.h" -#include "nas_message.h" -#include "nas_security.h" #include "nas_path.h" -#include "esm_build.h" #include "mme_s11_build.h" #include "mme_gtp_path.h" #include "s1ap_handler.h" -static void event_s1ap_to_nas(enb_ue_t *enb_ue, S1ap_NAS_PDU_t *nasPdu) -{ - nas_security_header_t *sh = NULL; - nas_security_header_type_t security_header_type; - - nas_esm_header_t *h = NULL; - pkbuf_t *nasbuf = NULL; - event_t e; - - d_assert(enb_ue, return, "Null param"); - d_assert(nasPdu, return, "Null param"); - - /* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM. - * When calculating AES_CMAC, we need to use the headroom of the packet. */ - nasbuf = pkbuf_alloc(NAS_HEADROOM, nasPdu->size); - d_assert(nasbuf, return, "Null param"); - memcpy(nasbuf->payload, nasPdu->buf, nasPdu->size); - - sh = nasbuf->payload; - d_assert(sh, return, "Null param"); - - memset(&security_header_type, 0, sizeof(nas_security_header_type_t)); - switch(sh->security_header_type) - { - case NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE: - break; - case NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE: - security_header_type.service_request = 1; - break; - case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED: - security_header_type.integrity_protected = 1; - d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, - return, "pkbuf_header error"); - break; - case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED: - security_header_type.integrity_protected = 1; - security_header_type.ciphered = 1; - d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, - return, "pkbuf_header error"); - break; - case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT: - security_header_type.integrity_protected = 1; - security_header_type.new_security_context = 1; - d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, - return, "pkbuf_header error"); - break; - case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHTERD_WITH_NEW_INTEGRITY_CONTEXT: - security_header_type.integrity_protected = 1; - security_header_type.ciphered = 1; - security_header_type.new_security_context = 1; - d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, - return, "pkbuf_header error"); - break; - default: - d_error("Not implemented(securiry header type:0x%x)", - sh->security_header_type); - return; - } - - if (enb_ue->mme_ue) - { - d_assert(nas_security_decode( - enb_ue->mme_ue, security_header_type, nasbuf) == CORE_OK, - pkbuf_free(nasbuf);return, "nas_security_decode failed"); - } - - h = nasbuf->payload; - d_assert(h, pkbuf_free(nasbuf); return, "Null param"); - if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_EMM) - { - event_set(&e, MME_EVT_EMM_MESSAGE); - event_set_param1(&e, (c_uintptr_t)enb_ue->index); - event_set_param2(&e, (c_uintptr_t)security_header_type.type); - event_set_param3(&e, (c_uintptr_t)nasbuf); - mme_event_send(&e); - } - else if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_ESM) - { - mme_ue_t *mme_ue = enb_ue->mme_ue; - mme_sess_t *sess = NULL; - mme_bearer_t *bearer = NULL; - c_uint8_t pti = NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; - c_uint8_t ebi = NAS_EPS_BEARER_IDENTITY_UNASSIGNED; - - if (!mme_ue) - { - d_error("No mme_ue exists"); - pkbuf_free(nasbuf); - return; - } - - pti = h->procedure_transaction_identity; - ebi = h->eps_bearer_identity; - - if (ebi != NAS_EPS_BEARER_IDENTITY_UNASSIGNED) - bearer = mme_bearer_find_by_ue_ebi(mme_ue, ebi); - else if (pti != NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) - bearer = mme_bearer_find_by_ue_pti(mme_ue, pti); - else - d_assert(0, return, "Invalid pti(%d) and ebi(%d)\n", pti, ebi); - - if (!bearer) - { - sess = mme_sess_add(mme_ue, pti); - d_assert(sess, return, "Null param"); - bearer = mme_default_bearer_in_sess(sess); - } - d_assert(bearer, return, "Null param"); - - event_set(&e, MME_EVT_ESM_MESSAGE); - event_set_param1(&e, (c_uintptr_t)bearer->index); - event_set_param2(&e, (c_uintptr_t)nasbuf); - mme_event_send(&e); - } - else - d_assert(0, pkbuf_free(nasbuf); return, "Unknown protocol:%d", - h->protocol_discriminator); -} - - void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message) { char buf[INET_ADDRSTRLEN]; @@ -187,20 +64,6 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message) d_error("No supported TA exist in s1stup_req messages"); } - -#if 0 /* FIXME : does it needed? */ - if (mme_ctx_enb_find_by_enb_id(enb_id)) - { - S1ap_Cause_t cause; - d_error("eNB-id[0x%x] duplicated from [%s]", enb_id, - INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf)); - - cause.present = S1ap_Cause_PR_protocol; - cause.choice.protocol = - S1ap_CauseProtocol_message_not_compatible_with_receiver_state; - rv = s1ap_build_setup_failure(&s1apbuf, cause); - } -#endif d_assert(enb->s1ap_sock, return,); d_trace(3, "[S1AP] S1SetupRequest : eNB[%s:%d] --> MME\n", INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf), @@ -306,7 +169,8 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message) INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf), enb->enb_id); - event_s1ap_to_nas(enb_ue, &ies->nas_pdu); + d_assert(s1ap_send_to_nas(enb_ue, &ies->nas_pdu) == CORE_OK,, + "s1ap_send_to_nas failed"); } void s1ap_handle_uplink_nas_transport( @@ -329,7 +193,8 @@ void s1ap_handle_uplink_nas_transport( INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf), enb->enb_id); - event_s1ap_to_nas(enb_ue, &ies->nas_pdu); + d_assert(s1ap_send_to_nas(enb_ue, &ies->nas_pdu) == CORE_OK,, + "s1ap_send_to_nas failed"); } void s1ap_handle_ue_capability_info_indication( @@ -386,54 +251,27 @@ void s1ap_handle_ue_capability_info_indication( void s1ap_handle_activate_default_bearer_accept(mme_bearer_t *bearer) { status_t rv; - gtp_header_t h; - gtp_xact_t *xact = NULL; mme_ue_t *mme_ue = NULL; - mme_sess_t *sess = NULL; + enb_ue_t *enb_ue = NULL; mme_bearer_t *dedicated_bearer = NULL; - pkbuf_t *pkbuf = NULL; d_assert(bearer, return, "Null param"); - sess = bearer->sess; - d_assert(sess, return, "Null param"); - mme_ue = sess->mme_ue; + 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"); - memset(&h, 0, sizeof(gtp_header_t)); - h.type = GTP_MODIFY_BEARER_REQUEST_TYPE; - h.teid = mme_ue->sgw_s11_teid; - - rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer); - d_assert(rv == CORE_OK, return, "S11 build error"); - - xact = gtp_xact_local_create(sess->sgw, &h, pkbuf); - d_assert(xact, return, "Null param"); - - rv = gtp_xact_commit(xact); - d_assert(rv == CORE_OK, return, "xact_commit error"); + rv = mme_gtp_send_modify_bearer_request(bearer); + d_assert(rv == CORE_OK, return, + "mme_gtp_send_modify_bearer_request failed"); dedicated_bearer = mme_bearer_next(bearer); while(dedicated_bearer) { - enb_ue_t *enb_ue = NULL; - pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; - - enb_ue = mme_ue->enb_ue; - d_assert(enb_ue, return, "Null param"); - - rv = esm_build_activate_dedicated_bearer_context( - &esmbuf, dedicated_bearer); - d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); - - d_trace(3, "[NAS] Activate dedicated bearer context request : " - "EMM <-- ESM\n"); - - rv = s1ap_build_e_rab_setup_request( - &s1apbuf, dedicated_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,,); + rv = nas_send_activate_dedicated_bearer_context( + enb_ue, dedicated_bearer); + d_assert(rv == CORE_OK, return, + "nas_send_activate_dedicated_bearer_context failed"); dedicated_bearer = mme_bearer_next(dedicated_bearer); } @@ -486,7 +324,23 @@ void s1ap_handle_initial_context_setup_response( if (FSM_CHECK(&bearer->sm, esm_state_active)) { - s1ap_handle_activate_default_bearer_accept(bearer); + status_t rv; + mme_bearer_t *dedicated_bearer = NULL; + + rv = mme_gtp_send_modify_bearer_request(bearer); + d_assert(rv == CORE_OK, return, + "mme_gtp_send_modify_bearer_request failed"); + + dedicated_bearer = mme_bearer_next(bearer); + while(dedicated_bearer) + { + rv = nas_send_activate_dedicated_bearer_context( + enb_ue, dedicated_bearer); + d_assert(rv == CORE_OK, return, + "nas_send_activate_dedicated_bearer_context failed"); + + dedicated_bearer = mme_bearer_next(dedicated_bearer); + } } } } @@ -519,11 +373,8 @@ void s1ap_handle_e_rab_setup_response( s1ap_E_RABSetupItemBearerSURes.count; i++) { status_t rv; - gtp_header_t h; - gtp_xact_t *xact = NULL; - pkbuf_t *pkbuf = NULL; - mme_bearer_t *bearer = NULL, *linked_bearer = NULL; + mme_bearer_t *bearer = NULL; mme_ue_t *mme_ue = enb_ue->mme_ue; S1ap_E_RABSetupItemBearerSURes_t *e_rab = NULL; @@ -542,33 +393,33 @@ void s1ap_handle_e_rab_setup_response( if (FSM_CHECK(&bearer->sm, esm_state_active)) { - linked_bearer = mme_linked_bearer(bearer); + mme_bearer_t *linked_bearer = mme_linked_bearer(bearer); d_assert(linked_bearer, return, "Null param"); - if (linked_bearer->ebi == bearer->ebi) + if (linked_bearer->ebi == bearer->ebi) /* Default Bearer */ { - /* Default Bearer */ - s1ap_handle_activate_default_bearer_accept(bearer); + mme_bearer_t *dedicated_bearer = NULL; + + rv = mme_gtp_send_modify_bearer_request(bearer); + d_assert(rv == CORE_OK, return, + "mme_gtp_send_modify_bearer_request failed"); + + dedicated_bearer = mme_bearer_next(bearer); + while(dedicated_bearer) + { + rv = nas_send_activate_dedicated_bearer_context( + enb_ue, dedicated_bearer); + d_assert(rv == CORE_OK, return, + "nas_send_activate_dedicated_bearer_context failed"); + + dedicated_bearer = mme_bearer_next(dedicated_bearer); + } } - else + else /* Dedicated Bearer */ { - /* Dedicated Bearer */ - xact = bearer->xact; - d_assert(xact, return, "Null param"); - - memset(&h, 0, sizeof(gtp_header_t)); - h.type = GTP_CREATE_BEARER_RESPONSE_TYPE; - h.teid = mme_ue->sgw_s11_teid; - - rv = mme_s11_build_create_bearer_response( - &pkbuf, h.type, bearer); - d_assert(rv == CORE_OK, return, "S11 build error"); - - rv = gtp_xact_update_tx(xact, &h, pkbuf); - d_assert(xact, return, "Null param"); - - rv = gtp_xact_commit(xact); - d_assert(rv == CORE_OK, return, "xact_commit error"); + rv = mme_gtp_send_create_bearer_response(bearer); + d_assert(rv == CORE_OK, return, + "mme_gtp_send_create_bearer_response failed"); } } } diff --git a/src/mme/s1ap_path.c b/src/mme/s1ap_path.c index 10b794acb..da37b3a70 100644 --- a/src/mme/s1ap_path.c +++ b/src/mme/s1ap_path.c @@ -5,6 +5,7 @@ #include "mme_event.h" #include "s1ap_path.h" +#include "nas_security.h" static int _s1ap_accept_cb(net_sock_t *net_sock, void *data); @@ -199,3 +200,137 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf) return rv; } + +status_t s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf) +{ + event_t e; + nas_esm_header_t *h = NULL; + + mme_sess_t *sess = NULL; + mme_bearer_t *bearer = NULL; + c_uint8_t pti = NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; + c_uint8_t ebi = NAS_EPS_BEARER_IDENTITY_UNASSIGNED; + + d_assert(mme_ue, return CORE_ERROR, "Null param"); + d_assert(esmbuf, return CORE_ERROR, "Null param"); + h = esmbuf->payload; + d_assert(h, return CORE_ERROR, "Null param"); + + pti = h->procedure_transaction_identity; + ebi = h->eps_bearer_identity; + + if (ebi != NAS_EPS_BEARER_IDENTITY_UNASSIGNED) + bearer = mme_bearer_find_by_ue_ebi(mme_ue, ebi); + else if (pti != NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) + bearer = mme_bearer_find_by_ue_pti(mme_ue, pti); + else + d_assert(0, return CORE_ERROR, + "Invalid pti(%d) and ebi(%d)\n", pti, ebi); + + if (!bearer) + { + sess = mme_sess_add(mme_ue, pti); + d_assert(sess, return CORE_ERROR, "Null param"); + bearer = mme_default_bearer_in_sess(sess); + } + d_assert(bearer, return CORE_ERROR, "Null param"); + + event_set(&e, MME_EVT_ESM_MESSAGE); + event_set_param1(&e, (c_uintptr_t)bearer->index); + event_set_param2(&e, (c_uintptr_t)esmbuf); + mme_event_send(&e); + + return CORE_OK; +} + +status_t s1ap_send_to_nas(enb_ue_t *enb_ue, S1ap_NAS_PDU_t *nasPdu) +{ + nas_security_header_t *sh = NULL; + nas_security_header_type_t security_header_type; + + nas_emm_header_t *h = NULL; + pkbuf_t *nasbuf = NULL; + event_t e; + + d_assert(enb_ue, return CORE_ERROR, "Null param"); + d_assert(nasPdu, return CORE_ERROR, "Null param"); + + /* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM. + * When calculating AES_CMAC, we need to use the headroom of the packet. */ + nasbuf = pkbuf_alloc(NAS_HEADROOM, nasPdu->size); + d_assert(nasbuf, return CORE_ERROR, "Null param"); + memcpy(nasbuf->payload, nasPdu->buf, nasPdu->size); + + sh = nasbuf->payload; + d_assert(sh, return CORE_ERROR, "Null param"); + + memset(&security_header_type, 0, sizeof(nas_security_header_type_t)); + switch(sh->security_header_type) + { + case NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE: + break; + case NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE: + security_header_type.service_request = 1; + break; + case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED: + security_header_type.integrity_protected = 1; + d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, + return CORE_ERROR, "pkbuf_header error"); + break; + case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED: + security_header_type.integrity_protected = 1; + security_header_type.ciphered = 1; + d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, + return CORE_ERROR, "pkbuf_header error"); + break; + case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT: + security_header_type.integrity_protected = 1; + security_header_type.new_security_context = 1; + d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, + return CORE_ERROR, "pkbuf_header error"); + break; + case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHTERD_WITH_NEW_INTEGRITY_CONTEXT: + security_header_type.integrity_protected = 1; + security_header_type.ciphered = 1; + security_header_type.new_security_context = 1; + d_assert(pkbuf_header(nasbuf, -6) == CORE_OK, + return CORE_ERROR, "pkbuf_header error"); + break; + default: + d_error("Not implemented(securiry header type:0x%x)", + sh->security_header_type); + return CORE_ERROR; + } + + if (enb_ue->mme_ue) + { + d_assert(nas_security_decode( + enb_ue->mme_ue, security_header_type, nasbuf) == CORE_OK, + pkbuf_free(nasbuf);return CORE_ERROR, "nas_security_decode failed"); + } + + h = nasbuf->payload; + d_assert(h, pkbuf_free(nasbuf); return CORE_ERROR, "Null param"); + if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_EMM) + { + event_set(&e, MME_EVT_EMM_MESSAGE); + event_set_param1(&e, (c_uintptr_t)enb_ue->index); + event_set_param2(&e, (c_uintptr_t)security_header_type.type); + event_set_param3(&e, (c_uintptr_t)nasbuf); + mme_event_send(&e); + } + else if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_ESM) + { + mme_ue_t *mme_ue = enb_ue->mme_ue; + + d_assert(mme_ue, return CORE_ERROR, "Null param"); + s1ap_send_to_esm(mme_ue, nasbuf); + } + else + d_assert(0, pkbuf_free(nasbuf); return CORE_ERROR, + "Unknown protocol:%d", h->protocol_discriminator); + + return CORE_OK; +} + + diff --git a/src/mme/s1ap_path.h b/src/mme/s1ap_path.h index a8e1e6a60..41ce60124 100644 --- a/src/mme/s1ap_path.h +++ b/src/mme/s1ap_path.h @@ -5,6 +5,7 @@ #include "core_net.h" #include "mme_context.h" +#include "s1ap_message.h" #ifdef __cplusplus extern "C" { @@ -15,6 +16,9 @@ CORE_DECLARE(status_t) s1ap_close(); CORE_DECLARE(status_t) s1ap_send(net_sock_t *s, pkbuf_t *pkb); 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); int _s1ap_recv_cb(net_sock_t *net_sock, void *data);