1. Move assert routine to accept "downlink notificaton"

2. Add state to sgw_ue
3. Only send "dl notification" when ue is s1u_inactive
This commit is contained in:
James Park 2017-09-08 11:46:28 -07:00
parent 97da327a61
commit 98e56968ee
4 changed files with 66 additions and 35 deletions

View File

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

View File

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

View File

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

View File

@ -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 = &gtp_message.modify_bearer_response;
memset(&gtp_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;
}