From bb5edf2a57e93ffb87b3b30292208d6d9420de35 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Tue, 5 Sep 2017 12:37:27 +0900 Subject: [PATCH] update it --- src/mme/emm_sm.c | 129 ++++++++++++++------------------- src/mme/esm_sm.c | 148 +++++++++++++++++++++++++++----------- src/mme/mme_context.h | 20 ++++-- src/mme/mme_s11_build.c | 2 +- src/mme/mme_s11_handler.c | 4 +- src/mme/mme_sm.c | 5 ++ src/mme/mme_sm.h | 4 +- src/mme/s1ap_handler.c | 2 +- src/pgw/pgw_context.h | 2 +- src/pgw/pgw_gx_handler.c | 2 +- src/sgw/sgw_context.h | 4 +- src/sgw/sgw_s11_handler.c | 4 +- 12 files changed, 189 insertions(+), 137 deletions(-) diff --git a/src/mme/emm_sm.c b/src/mme/emm_sm.c index 1c17133bc9..87e5c903ca 100644 --- a/src/mme/emm_sm.c +++ b/src/mme/emm_sm.c @@ -16,6 +16,9 @@ #include "mme_s11_handler.h" #include "nas_path.h" +void emm_state_attach_request(fsm_t *s, event_t *e, + mme_ue_t *mme_ue, nas_message_t *message); + void emm_state_initial(fsm_t *s, event_t *e) { d_assert(s, return, "Null param"); @@ -63,43 +66,7 @@ void emm_state_detached(fsm_t *s, event_t *e) { case NAS_ATTACH_REQUEST: { - /* Update Kenb */ - if (SECURITY_CONTEXT_IS_VALID(mme_ue)) - mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, - mme_ue->kenb); - - CLEAR_EPS_BEARER_ID(mme_ue); - mme_ue_paged(mme_ue); - - emm_handle_attach_request( - mme_ue, &message->emm.attach_request); - - if (!MME_UE_HAVE_IMSI(mme_ue)) - { - /* Unknown GUTI */ - FSM_TRAN(s, &emm_state_identity); - break; - } - - if (SECURITY_CONTEXT_IS_VALID(mme_ue)) - { - event_emm_to_esm( - mme_ue, &mme_ue->last_pdn_connectivity_request); - FSM_TRAN(s, &emm_state_default_esm); - } - else - { - if (MME_UE_HAVE_SESSION(mme_ue)) - { - mme_s11_handle_delete_all_sessions_in_ue(mme_ue); - } - else - { - mme_s6a_send_air(mme_ue); - } - FSM_TRAN(s, &emm_state_authentication); - } - + emm_state_attach_request(s, e, mme_ue, message); break; } } @@ -167,7 +134,7 @@ void emm_state_identity(fsm_t *s, event_t *e) } else { - if (MME_UE_HAVE_SESSION(mme_ue)) + if (MME_HAVE_SGW_S11_PATH(mme_ue)) { mme_s11_handle_delete_all_sessions_in_ue(mme_ue); } @@ -445,43 +412,7 @@ void emm_state_attached(fsm_t *s, event_t *e) { case NAS_ATTACH_REQUEST: { - /* Update Kenb */ - if (SECURITY_CONTEXT_IS_VALID(mme_ue)) - mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, - mme_ue->kenb); - - CLEAR_EPS_BEARER_ID(mme_ue); - mme_ue_paged(mme_ue); - - emm_handle_attach_request( - mme_ue, &message->emm.attach_request); - - if (!MME_UE_HAVE_IMSI(mme_ue)) - { - /* Unknown GUTI */ - FSM_TRAN(s, &emm_state_identity); - break; - } - - if (SECURITY_CONTEXT_IS_VALID(mme_ue)) - { - event_emm_to_esm( - mme_ue, &mme_ue->last_pdn_connectivity_request); - FSM_TRAN(s, &emm_state_default_esm); - } - else - { - if (MME_UE_HAVE_SESSION(mme_ue)) - { - mme_s11_handle_delete_all_sessions_in_ue(mme_ue); - } - else - { - mme_s6a_send_air(mme_ue); - } - FSM_TRAN(s, &emm_state_authentication); - } - + emm_state_attach_request(s, e, mme_ue, message); break; } case NAS_EMM_STATUS: @@ -495,7 +426,7 @@ void emm_state_attached(fsm_t *s, event_t *e) emm_handle_detach_request( mme_ue, &message->emm.detach_request_from_ue); - if (MME_UE_HAVE_SESSION(mme_ue)) + if (MME_HAVE_SGW_S11_PATH(mme_ue)) { mme_s11_handle_delete_all_sessions_in_ue(mme_ue); } @@ -552,3 +483,49 @@ void emm_state_attached(fsm_t *s, event_t *e) } } } + +void emm_state_attach_request(fsm_t *s, event_t *e, + mme_ue_t *mme_ue, nas_message_t *message) +{ + d_assert(s, return, "Null param"); + d_assert(e, return, "Null param"); + d_assert(mme_ue, return, "Null param"); + d_assert(message, return, "Null param"); + + /* Update Kenb */ + if (SECURITY_CONTEXT_IS_VALID(mme_ue)) + mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, + mme_ue->kenb); + + CLEAR_EPS_BEARER_ID(mme_ue); + mme_ue_paged(mme_ue); + + emm_handle_attach_request(mme_ue, &message->emm.attach_request); + + if (!MME_UE_HAVE_IMSI(mme_ue)) + { + /* Unknown GUTI */ + FSM_TRAN(s, &emm_state_identity); + } + else + { + if (SECURITY_CONTEXT_IS_VALID(mme_ue)) + { + event_emm_to_esm(mme_ue, &mme_ue->last_pdn_connectivity_request); + FSM_TRAN(s, &emm_state_default_esm); + } + else + { + if (MME_HAVE_SGW_S11_PATH(mme_ue)) + { + mme_s11_handle_delete_all_sessions_in_ue(mme_ue); + } + else + { + mme_s6a_send_air(mme_ue); + } + FSM_TRAN(s, &emm_state_authentication); + } + } +} + diff --git a/src/mme/esm_sm.c b/src/mme/esm_sm.c index 0404f0a18b..88c627d9a1 100644 --- a/src/mme/esm_sm.c +++ b/src/mme/esm_sm.c @@ -12,13 +12,17 @@ #include "mme_s11_handler.h" #include "nas_path.h" +static void esm_state_pdn_connectivity_request( + fsm_t *s, event_t *e, mme_ue_t *mme_ue, mme_sess_t *sess, + mme_bearer_t *bearer, nas_message_t *message); + void esm_state_initial(fsm_t *s, event_t *e) { d_assert(s, return, "Null param"); mme_sm_trace(3, e); - FSM_TRAN(s, &esm_state_operational); + FSM_TRAN(s, &esm_state_inactive); } void esm_state_final(fsm_t *s, event_t *e) @@ -28,7 +32,7 @@ void esm_state_final(fsm_t *s, event_t *e) mme_sm_trace(3, e); } -void esm_state_operational(fsm_t *s, event_t *e) +void esm_state_inactive(fsm_t *s, event_t *e) { mme_ue_t *mme_ue = NULL; mme_sess_t *sess = NULL; @@ -65,39 +69,8 @@ void esm_state_operational(fsm_t *s, event_t *e) { case NAS_PDN_CONNECTIVITY_REQUEST: { - esm_handle_pdn_connectivity_request( - sess, &message->esm.pdn_connectivity_request); - d_trace(3, "[NAS] PDN connectivity request : " - "UE[%s] --> ESM[%d]\n", - mme_ue->imsi_bcd, bearer->pti); - - d_assert(MME_UE_HAVE_IMSI(mme_ue), break, - "No IMSI in PDN_CPNNECTIVITY_REQUEST"); - d_assert(SECURITY_CONTEXT_IS_VALID(mme_ue), break, - "No Security Context in PDN_CPNNECTIVITY_REQUEST"); - - if (MME_UE_HAVE_APN(mme_ue)) - { - if (MME_UE_HAVE_SESSION(mme_ue)) - { - emm_handle_attach_accept(mme_ue); - } - else - { - mme_s11_handle_create_session_request(sess); - } - } - else - { - status_t rv; - pkbuf_t *esmbuf = NULL; - - rv = esm_build_information_request(&esmbuf, bearer); - d_assert(rv == CORE_OK && esmbuf, break, - "esm_build failed"); - d_assert(nas_send_to_downlink_nas_transport( - mme_ue, esmbuf) == CORE_OK,,); - } + esm_state_pdn_connectivity_request(s, e, + mme_ue, sess, bearer, message); break; } case NAS_ESM_INFORMATION_RESPONSE: @@ -115,19 +88,28 @@ void esm_state_operational(fsm_t *s, event_t *e) { mme_bearer_t *dedicated_bearer = NULL; - d_trace(3, "[NAS] Activate default eps bearer " + d_trace(3, "[NAS] Activate default EPS bearer " "context accept : UE[%s] --> ESM[%d]\n", mme_ue->imsi_bcd, bearer->pti); dedicated_bearer = mme_bearer_next(bearer); while(dedicated_bearer) { - if (MME_BEARER_IS_VALID(dedicated_bearer)) - continue; - - esm_handle_activate_dedicated_bearer_request( - dedicated_bearer); + if (!MME_HAVE_ENB_S1U_PATH(dedicated_bearer)) + { + esm_handle_activate_dedicated_bearer_request( + dedicated_bearer); + } dedicated_bearer = mme_bearer_next(dedicated_bearer); } + FSM_TRAN(s, esm_state_active); + break; + } + case NAS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT: + { + d_trace(3, "[NAS] Activate dedicated EPS bearer " + "context accept : UE[%s] --> ESM[%d]\n", + mme_ue->imsi_bcd, bearer->pti); + FSM_TRAN(s, esm_state_active); break; } default: @@ -148,13 +130,24 @@ void esm_state_operational(fsm_t *s, event_t *e) } } -void esm_state_exception(fsm_t *s, event_t *e) +void esm_state_active(fsm_t *s, event_t *e) { + mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; + mme_bearer_t *bearer = NULL; + d_assert(s, return, "Null param"); d_assert(e, return, "Null param"); mme_sm_trace(3, e); + bearer = mme_bearer_find(event_get_param1(e)); + 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"); + switch (event_get(e)) { case FSM_ENTRY_SIG: @@ -165,6 +158,30 @@ void esm_state_exception(fsm_t *s, event_t *e) { break; } + case MME_EVT_ESM_MESSAGE: + { + nas_message_t *message = (nas_message_t *)event_get_param3(e); + d_assert(message, break, "Null param"); + + switch(message->esm.h.message_type) + { + case NAS_PDN_CONNECTIVITY_REQUEST: + { + esm_state_pdn_connectivity_request(s, e, + mme_ue, sess, bearer, message); + FSM_TRAN(s, esm_state_inactive); + break; + } + default: + { + d_warn("Not implemented(type:%d)", + message->esm.h.message_type); + break; + } + } + break; + } + default: { d_error("Unknown event %s", mme_event_get_name(e)); @@ -172,3 +189,50 @@ void esm_state_exception(fsm_t *s, event_t *e) } } } + +static void esm_state_pdn_connectivity_request( + fsm_t *s, event_t *e, mme_ue_t *mme_ue, mme_sess_t *sess, + mme_bearer_t *bearer, nas_message_t *message) +{ + d_assert(s, return, "Null param"); + d_assert(e, return, "Null param"); + d_assert(mme_ue, return, "Null param"); + d_assert(sess, return, "Null param"); + d_assert(bearer, return, "Null param"); + d_assert(message, return, "Null param"); + + d_trace(3, "[NAS] PDN connectivity request : UE[%s] --> ESM[%d]\n", + mme_ue->imsi_bcd, bearer->pti); + + d_assert(MME_UE_HAVE_IMSI(mme_ue), return, + "No IMSI in PDN_CPNNECTIVITY_REQUEST"); + d_assert(SECURITY_CONTEXT_IS_VALID(mme_ue), return, + "No Security Context in PDN_CPNNECTIVITY_REQUEST"); + + esm_handle_pdn_connectivity_request( + sess, &message->esm.pdn_connectivity_request); + + if (MME_UE_HAVE_APN(mme_ue)) + { + if (MME_HAVE_SGW_S11_PATH(mme_ue)) + { + emm_handle_attach_accept(mme_ue); + } + else + { + mme_s11_handle_create_session_request(sess); + } + } + else + { + status_t rv; + pkbuf_t *esmbuf = NULL; + + rv = esm_build_information_request(&esmbuf, bearer); + d_assert(rv == CORE_OK && esmbuf, return, + "esm_build failed"); + d_assert(nas_send_to_downlink_nas_transport( + mme_ue, esmbuf) == CORE_OK,,); + } +} + diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index 2343dbc1be..d5b0c5f0a4 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -242,14 +242,20 @@ struct _mme_ue_t { nas_detach_type_t detach_type; }; -#define MME_SESSION_IS_VALID(__sESS) \ +#define MME_HAVE_SGW_S1U_PATH(__sESS) \ ((__sESS) && (mme_bearer_first(__sESS)) && \ ((mme_default_bearer_in_sess(__sESS)->sgw_s1u_teid) && \ (mme_default_bearer_in_sess(__sESS)->sgw_s1u_addr))) -#define MME_UE_HAVE_SESSION(__mME) \ - ((__mME) && (mme_sess_first(__mME)) && \ - MME_SESSION_IS_VALID(mme_sess_first(__mME))) +#define MME_HAVE_SGW_S11_PATH(__mME) \ + ((__mME) && ((__mME)->sgw_s11_teid) && ((__mME)->sgw_s11_addr)) + +#define CLEAR_SGW_S11_PATH(__mME) \ + do { \ + d_assert((__mME), break, "Null param"); \ + (__mME)->sgw_s11_teid = 0; \ + (__mME)->sgw_s11_addr = 0; \ + } while(0) typedef struct _mme_sess_t { lnode_t node; /* A node of list_t */ index_t index; /* An index of this node */ @@ -258,7 +264,7 @@ typedef struct _mme_sess_t { list_t bearer_list; /* Related Context */ -#define MME_S11_PATH_IN_SESSION(__sESS) \ +#define CONNECT_SGW_GTP_NODE(__sESS) \ do { \ d_assert((__sESS), return, "Null param"); \ (__sESS)->sgw = mme_sgw_next((__sESS)->sgw); \ @@ -271,7 +277,7 @@ typedef struct _mme_sess_t { #define MME_UE_HAVE_APN(__mME) \ ((__mME) && (mme_sess_first(__mME)) && \ ((mme_sess_first(__mME))->pdn)) -#define MME_SESSION_GET_PGW_IPV4_ADDR(__sESS) \ +#define MME_GET_PGW_IPV4_ADDR(__sESS) \ (((__sESS) && ((__sESS)->pdn) && (((__sESS)->pdn)->pgw.ipv4_addr)) ? \ (((__sESS)->pdn)->pgw.ipv4_addr) : (mme_self()->s5c_addr)) pdn_t *pdn; @@ -283,7 +289,7 @@ typedef struct _mme_sess_t { int pgw_pco_len; } mme_sess_t; -#define MME_BEARER_IS_VALID(__bEARER) \ +#define MME_HAVE_ENB_S1U_PATH(__bEARER) \ ((__bEARER) && ((__bEARER)->enb_s1u_teid) && ((__bEARER)->enb_s1u_addr)) typedef struct _mme_bearer_t { lnode_t node; /* A node of list_t */ diff --git a/src/mme/mme_s11_build.c b/src/mme/mme_s11_build.c index fbc00e1834..a584b3bd21 100644 --- a/src/mme/mme_s11_build.c +++ b/src/mme/mme_s11_build.c @@ -36,7 +36,7 @@ status_t mme_s11_build_create_session_request( d_assert(pdn, return CORE_ERROR, "Null param"); bearer = mme_default_bearer_in_sess(sess); d_assert(bearer, return CORE_ERROR, "Null param"); - pgw_ipv4_addr = MME_SESSION_GET_PGW_IPV4_ADDR(sess); + pgw_ipv4_addr = MME_GET_PGW_IPV4_ADDR(sess); d_assert(pgw_ipv4_addr, return CORE_ERROR, "Null param"); mme_ue = sess->mme_ue; d_assert(mme_ue, return CORE_ERROR, "Null param"); diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index 282a4264e1..ea30bef2e0 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -22,7 +22,7 @@ void mme_s11_handle_create_session_request(mme_sess_t *sess) mme_ue_t *mme_ue = NULL; /* Use round-robin for selecting SGW */ - MME_S11_PATH_IN_SESSION(sess); + CONNECT_SGW_GTP_NODE(sess); mme_ue = sess->mme_ue; d_assert(mme_ue, return, "Null param"); @@ -147,7 +147,7 @@ void mme_s11_handle_delete_all_sessions_in_ue(mme_ue_t *mme_ue) { next_sess = mme_sess_next(sess); - if (MME_SESSION_IS_VALID(sess)) + if (MME_HAVE_SGW_S1U_PATH(sess)) { gtp_header_t h; gtp_xact_t *xact = NULL; diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index 0b541af335..b70806f333 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -362,6 +362,11 @@ void mme_state_operational(fsm_t *s, event_t *e) mme_s11_handle_delete_session_response( xact, mme_ue, &message.delete_session_response); + if (mme_sess_first(mme_ue) == NULL) + { + CLEAR_SGW_S11_PATH(mme_ue); + } + if (FSM_CHECK(&mme_ue->sm, emm_state_authentication)) { if (mme_sess_first(mme_ue) == NULL) diff --git a/src/mme/mme_sm.h b/src/mme/mme_sm.h index f77a7091ad..82ff1729dd 100644 --- a/src/mme/mme_sm.h +++ b/src/mme/mme_sm.h @@ -31,8 +31,8 @@ void emm_state_exception(fsm_t *s, event_t *e); void esm_state_initial(fsm_t *s, event_t *e); void esm_state_final(fsm_t *s, event_t *e); -void esm_state_operational(fsm_t *s, event_t *e); -void esm_state_exception(fsm_t *s, event_t *e); +void esm_state_inactive(fsm_t *s, event_t *e); +void esm_state_active(fsm_t *s, event_t *e); #define mme_sm_print(__pe) \ d_print("%s(): %s\n", __func__, mme_event_get_name(__pe)) diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index 675c6503f6..1eeb89876b 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -540,7 +540,7 @@ void s1ap_handle_ue_context_release_request( mme_ue_t *mme_ue = enb_ue->mme_ue; status_t rv; - if (MME_UE_HAVE_SESSION(mme_ue)) + if (MME_HAVE_SGW_S11_PATH(mme_ue)) { mme_sess_t *sess = mme_sess_first(mme_ue); while (sess != NULL) diff --git a/src/pgw/pgw_context.h b/src/pgw/pgw_context.h index ec6a3f0430..85b5982adf 100644 --- a/src/pgw/pgw_context.h +++ b/src/pgw/pgw_context.h @@ -91,7 +91,7 @@ typedef struct _pgw_sess_t { list_t bearer_list; /* Related Context */ -#define PGW_S5C_PATH_IN_SESSION(__sESS, __xACT) \ +#define CONNECT_SGW_GTP_NODE(__sESS, __xACT) \ do { \ d_assert((__sESS), return, "Null param"); \ d_assert((__xACT), return, "Null param"); \ diff --git a/src/pgw/pgw_gx_handler.c b/src/pgw/pgw_gx_handler.c index 545eac6978..ef041e0aea 100644 --- a/src/pgw/pgw_gx_handler.c +++ b/src/pgw/pgw_gx_handler.c @@ -61,7 +61,7 @@ void pgw_gx_handle_cca_initial_request( d_assert(cca_message, return, "Null param"); d_assert(req, return, "Null param"); - PGW_S5C_PATH_IN_SESSION(sess, xact); + CONNECT_SGW_GTP_NODE(sess, xact); memset(&h, 0, sizeof(gtp_header_t)); h.type = GTP_CREATE_SESSION_RESPONSE_TYPE; diff --git a/src/sgw/sgw_context.h b/src/sgw/sgw_context.h index ff0d2acac4..779d1147db 100644 --- a/src/sgw/sgw_context.h +++ b/src/sgw/sgw_context.h @@ -83,14 +83,14 @@ typedef struct _sgw_sess_t { list_t bearer_list; /* Related Context */ -#define SGW_S11_PATH_IN_SESSION(__sESS, __xACT) \ +#define CONNECT_MME_GTP_NODE(__sESS, __xACT) \ do { \ d_assert((__sESS), return, "Null param"); \ d_assert((__xACT), return, "Null param"); \ (__sESS)->mme = (__xACT)->gnode; \ } while(0) sgw_mme_t *mme; -#define SGW_S5C_PATH_IN_SESSION(__sESS, __gNODE) \ +#define CONNECT_PGW_GTP_NODE(__sESS, __gNODE) \ do { \ d_assert((__sESS), return, "Null param"); \ d_assert((__gNODE), return, "Null param"); \ diff --git a/src/sgw/sgw_s11_handler.c b/src/sgw/sgw_s11_handler.c index 14ed7959a1..8ace427061 100644 --- a/src/sgw/sgw_s11_handler.c +++ b/src/sgw/sgw_s11_handler.c @@ -106,8 +106,8 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact, } /* Setup GTP Node */ - SGW_S5C_PATH_IN_SESSION(sess, pgw); - SGW_S11_PATH_IN_SESSION(sess, s11_xact); + CONNECT_MME_GTP_NODE(sess, s11_xact); + CONNECT_PGW_GTP_NODE(sess, pgw); req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 0;