From 98e56968ee8aaab2b7e010244bd9bf10df6e979e Mon Sep 17 00:00:00 2001 From: James Park Date: Fri, 8 Sep 2017 11:46:28 -0700 Subject: [PATCH] 1. Move assert routine to accept "downlink notificaton" 2. Add state to sgw_ue 3. Only send "dl notification" when ue is s1u_inactive --- src/mme/mme_sm.c | 8 ++++-- src/sgw/sgw_context.h | 22 ++++++--------- src/sgw/sgw_gtp_path.c | 58 +++++++++++++++++++++++++++------------ src/sgw/sgw_s11_handler.c | 13 +++++++-- 4 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index adb4aa076c..7bc26342e6 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -353,8 +353,6 @@ void mme_state_operational(fsm_t *s, event_t *e) mme_ue = mme_ue_find_by_teid(message.h.teid); d_assert(mme_ue, pkbuf_free(pkbuf); break, "No UE Context(TEID:%d)", message.h.teid); - enb_ue = mme_ue->enb_ue; - d_assert(enb_ue, pkbuf_free(pkbuf);break, "Null param"); switch(message.h.type) { @@ -485,6 +483,9 @@ void mme_state_operational(fsm_t *s, event_t *e) if (FSM_CHECK(&bearer->sm, esm_state_disconnect)) { + enb_ue = mme_ue->enb_ue; + d_assert(enb_ue, break, "Null param"); + rv = nas_send_deactivate_bearer_context_request( enb_ue, bearer); d_assert(rv == CORE_OK, break, @@ -509,6 +510,9 @@ void mme_state_operational(fsm_t *s, event_t *e) { S1ap_Cause_t cause; + enb_ue = mme_ue->enb_ue; + d_assert(enb_ue, break, "Null param"); + mme_s11_handle_release_access_bearers_response( xact, mme_ue, &message.release_access_bearers_response); diff --git a/src/sgw/sgw_context.h b/src/sgw/sgw_context.h index 779d1147db..b1afc1ef08 100644 --- a/src/sgw/sgw_context.h +++ b/src/sgw/sgw_context.h @@ -63,6 +63,15 @@ typedef struct _sgw_ue_t { c_uint32_t mme_s11_teid; /* MME-S11-F-TEID */ c_uint32_t mme_s11_addr; /* MME-S11-F-TEID IPv4 Address */ +#define SGW_S1U_INACTIVE 0x0001 +#define SGW_DL_NOTI_SENT 0x0002 + +#define SGW_GET_UE_STATE(__uE) ((__uE)->state) +#define SGW_SET_UE_STATE(__uE,__sTATE) ((__uE)->state |= (__sTATE)) +#define SGW_RESET_UE_STATE(__uE, __sTATE) ((__uE)->state &= ~(__sTATE)) + + c_uint32_t state; + list_t sess_list; } sgw_ue_t; @@ -120,7 +129,6 @@ typedef struct _sgw_bearer_t { c_uint32_t pgw_s5u_teid; c_uint32_t pgw_s5u_addr; - c_uint32_t state; /* Pkts which will be buffered in case of UE-IDLE */ c_uint32_t num_buffered_pkt; @@ -130,18 +138,6 @@ typedef struct _sgw_bearer_t { sgw_sess_t *sess; } sgw_bearer_t; -#define SGW_DL_NOTI_SENT 0x0001 - -#define CHECK_DL_NOTI_SENT(__bEARER) ((__bEARER)->state & SGW_DL_NOTI_SENT) -#define SET_DL_NOTI_SENT(__bEARER) \ - do { \ - (__bEARER)->state |= SGW_DL_NOTI_SENT;\ - } while (0) -#define RESET_DL_NOTI_SENT(__bEARER) \ - do { \ - (__bEARER)->state &= ~SGW_DL_NOTI_SENT;\ - } while (0) - CORE_DECLARE(status_t) sgw_context_init(void); CORE_DECLARE(status_t) sgw_context_final(void); CORE_DECLARE(sgw_context_t*) sgw_self(void); diff --git a/src/sgw/sgw_gtp_path.c b/src/sgw/sgw_gtp_path.c index 094a48a2b3..8628924ae0 100644 --- a/src/sgw/sgw_gtp_path.c +++ b/src/sgw/sgw_gtp_path.c @@ -162,30 +162,52 @@ static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data) * Send downlink_data_notification to MME. * */ - if (!CHECK_DL_NOTI_SENT(bearer)) - { - event_t e; - status_t rv; + sgw_ue_t *sgw_ue = NULL; - event_set(&e, SGW_EVT_LO_DLDATA_NOTI); - event_set_param1(&e, (c_uintptr_t)bearer->index); - rv = sgw_event_send(&e); - if (rv != CORE_OK) + d_assert(bearer->sess, pkbuf_free(pkbuf); return 0, + "Session is NULL"); + d_assert(bearer->sess->sgw_ue, pkbuf_free(pkbuf); return 0, + "SGW_UE is NULL"); + + sgw_ue = bearer->sess->sgw_ue; + + if ((SGW_GET_UE_STATE(sgw_ue) & SGW_S1U_INACTIVE)) + { + if ( !(SGW_GET_UE_STATE(sgw_ue) & SGW_DL_NOTI_SENT)) { - d_error("sgw_event_send error"); - pkbuf_free(pkbuf); - return -1; + event_t e; + status_t rv; + + event_set(&e, SGW_EVT_LO_DLDATA_NOTI); + event_set_param1(&e, (c_uintptr_t)bearer->index); + rv = sgw_event_send(&e); + if (rv != CORE_OK) + { + d_error("sgw_event_send error"); + pkbuf_free(pkbuf); + return -1; + } + + SGW_SET_UE_STATE(sgw_ue, SGW_DL_NOTI_SENT); } - SET_DL_NOTI_SENT(bearer); + /* Buffer the packet */ + if (bearer->num_buffered_pkt < MAX_NUM_BUFFER_PKT) + { + bearer->buffered_pkts[bearer->num_buffered_pkt++] = + pkbuf; + return 0; + } + } + else + { + /* UE is S1U_ACTIVE state but there is no s1u teid */ + d_warn("UE is ACITVE but there is no matched " + "s1u_teid(tedid = 0x%x)",teid); + + /* Just drop it */ } - /* Buffer the packet */ - if (bearer->num_buffered_pkt < MAX_NUM_BUFFER_PKT) - { - bearer->buffered_pkts[bearer->num_buffered_pkt++] = pkbuf; - return 0; - } } } } diff --git a/src/sgw/sgw_s11_handler.c b/src/sgw/sgw_s11_handler.c index 8ace427061..44ab9e4c5e 100644 --- a/src/sgw/sgw_s11_handler.c +++ b/src/sgw/sgw_s11_handler.c @@ -180,6 +180,9 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact, bearer->enb_s1u_teid = ntohl(enb_s1u_teid->teid); bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr; + /* Reset UE state */ + SGW_RESET_UE_STATE(sgw_ue, SGW_S1U_INACTIVE); + rsp = >p_message.modify_bearer_response; memset(>p_message, 0, sizeof(gtp_message_t)); @@ -312,6 +315,9 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact, bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr; req->bearer_contexts.s1_u_enodeb_f_teid.presence = 0; + /* Reset UE state */ + SGW_RESET_UE_STATE(sgw_ue, SGW_S1U_INACTIVE); + /* Data Plane(DL) : SGW-S5U */ memset(&sgw_s5u_teid, 0, sizeof(gtp_f_teid_t)); sgw_s5u_teid.teid = htonl(bearer->sgw_s5u_teid); @@ -362,6 +368,11 @@ void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact, d_assert(s11_xact, return, "Null param"); d_assert(req, return, "Null param"); + /* Set UE state to S1UE_INACTIVE */ + SGW_SET_UE_STATE(sgw_ue, SGW_S1U_INACTIVE); + /* ReSet UE state to S1UE_INACTIVE */ + SGW_RESET_UE_STATE(sgw_ue, SGW_DL_NOTI_SENT); + /* Release S1U(DL) path */ sess = sgw_sess_first(sgw_ue); while (sess) @@ -374,8 +385,6 @@ void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact, bearer->enb_s1u_teid = 0; bearer->enb_s1u_addr = 0; - RESET_DL_NOTI_SENT(bearer); - bearer = next_bearer; }