update it

This commit is contained in:
Sukchan Lee 2017-09-05 12:37:27 +09:00
parent f4ec627532
commit bb5edf2a57
12 changed files with 189 additions and 137 deletions

View File

@ -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);
}
}
}

View File

@ -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,,);
}
}

View File

@ -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 */

View File

@ -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");

View File

@ -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;

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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"); \

View File

@ -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;

View File

@ -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"); \

View File

@ -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;