forked from acouzens/open5gs
update it
This commit is contained in:
parent
ac51f9e0e6
commit
b787e31b4e
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue