diff --git a/lib/gtp/gtp_xact.c b/lib/gtp/gtp_xact.c index d72191dd4..3fe2f973a 100644 --- a/lib/gtp/gtp_xact.c +++ b/lib/gtp/gtp_xact.c @@ -5,6 +5,7 @@ #include "types.h" #include "gtp_xact.h" +#include "gtp_message.h" #define SIZE_OF_GTP_XACT_POOL 32 #define GTP_MIN_XACT_ID 1 @@ -23,27 +24,39 @@ typedef enum { GTP_XACT_FINAL_STAGE, } gtp_xact_stage_t; +static int gtp_xact_initialized = 0; +static tm_service_t *g_tm_service = NULL; +static c_uint32_t g_xact_id = 0; + index_declare(gtp_xact_pool, gtp_xact_t, SIZE_OF_GTP_XACT_POOL); static gtp_xact_stage_t gtp_xact_get_stage(c_uint8_t type, c_uint32_t sqn); +static status_t gtp_xact_delete(gtp_xact_t *xact); status_t gtp_xact_init(gtp_xact_ctx_t *context, tm_service_t *tm_service, c_uintptr_t event) { + d_assert(gtp_xact_initialized == 0, return CORE_ERROR, + "GTP Transaction already has been initialized"); + index_init(>p_xact_pool, SIZE_OF_GTP_XACT_POOL); memset(context, 0, sizeof(gtp_xact_ctx_t)); - context->g_xact_id = 0; - - context->tm_service = tm_service; + g_xact_id = 0; + g_tm_service = tm_service; context->event = event;; + gtp_xact_initialized = 1; + return CORE_OK; } status_t gtp_xact_final(void) { + d_assert(gtp_xact_initialized == 1, return CORE_ERROR, + "GTP Transaction context already has been finalized"); + if (pool_size(>p_xact_pool) != pool_avail(>p_xact_pool)) d_error("%d not freed in gtp_xact_pool[%d] of GTP Transaction", pool_size(>p_xact_pool) - pool_avail(>p_xact_pool), @@ -54,41 +67,16 @@ status_t gtp_xact_final(void) pool_size(>p_xact_pool)); index_final(>p_xact_pool); - return CORE_OK; -} - -static status_t gtp_xact_delete(gtp_xact_t *xact) -{ - char buf[INET_ADDRSTRLEN]; - - d_assert(xact, , "Null param"); - d_assert(xact->gnode, , "Null param"); - d_assert(xact->tm_wait, , "Null param"); - - d_trace(3, "[%d] %s Delete peer %s:%d\n", - xact->xid, - xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", - INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); - - if (xact->pkbuf) - pkbuf_free(xact->pkbuf); - - tm_delete(xact->tm_wait); - - list_remove(xact->org == GTP_LOCAL_ORIGINATOR ? &xact->gnode->local_list : - &xact->gnode->remote_list, xact); - index_free(>p_xact_pool, xact); + gtp_xact_initialized = 0; return CORE_OK; } -gtp_xact_t *gtp_xact_local_create( - gtp_xact_ctx_t *context, net_sock_t *sock, gtp_node_t *gnode) +gtp_xact_t *gtp_xact_local_create(net_sock_t *sock, gtp_node_t *gnode) { char buf[INET_ADDRSTRLEN]; gtp_xact_t *xact = NULL; - d_assert(context, return NULL, "Null param"); d_assert(sock, return NULL, "Null param"); d_assert(gnode, return NULL, "Null param"); @@ -96,18 +84,10 @@ gtp_xact_t *gtp_xact_local_create( d_assert(xact, return NULL, "Transaction allocation failed"); xact->org = GTP_LOCAL_ORIGINATOR; - xact->xid = NEXT_ID(context->g_xact_id, GTP_MIN_XACT_ID, GTP_MAX_XACT_ID); + xact->xid = NEXT_ID(g_xact_id, GTP_MIN_XACT_ID, GTP_MAX_XACT_ID); xact->sock = sock; xact->gnode = gnode; - xact->tm_wait = event_timer(context->tm_service, context->event, - GTP_XACT_LOCAL_DURATION, xact->index); - d_assert(xact->tm_wait, - index_free(>p_xact_pool, xact); return NULL, - "Timer allocation failed"); - xact->retry_count = GTP_XACT_LOCAL_RETRY_COUNT; - tm_start(xact->tm_wait); - list_append(xact->org == GTP_LOCAL_ORIGINATOR ? &xact->gnode->local_list : &xact->gnode->remote_list, xact); @@ -119,13 +99,12 @@ gtp_xact_t *gtp_xact_local_create( return xact; } -gtp_xact_t *gtp_xact_remote_create(gtp_xact_ctx_t *context, +gtp_xact_t *gtp_xact_remote_create( net_sock_t *sock, gtp_node_t *gnode, c_uint32_t sqn) { char buf[INET_ADDRSTRLEN]; gtp_xact_t *xact = NULL; - d_assert(context, return NULL, "Null param"); d_assert(sock, return NULL, "Null param"); d_assert(gnode, return NULL, "Null param"); @@ -137,13 +116,18 @@ gtp_xact_t *gtp_xact_remote_create(gtp_xact_ctx_t *context, xact->sock = sock; xact->gnode = gnode; - xact->tm_wait = event_timer(context->tm_service, context->event, - GTP_XACT_REMOTE_DURATION, xact->index); - d_assert(xact->tm_wait, - index_free(>p_xact_pool, xact); return NULL, - "Timer allocation failed"); - xact->retry_count = GTP_XACT_REMOTE_RETRY_COUNT; - tm_start(xact->tm_wait); +#if 0 + if (event) + { + xact->tm_wait = event_timer(context->tm_service, event, + GTP_XACT_REMOTE_DURATION, xact->index); + d_assert(xact->tm_wait, + index_free(>p_xact_pool, xact); return NULL, + "Timer allocation failed"); + xact->retry_count = GTP_XACT_REMOTE_RETRY_COUNT; + tm_start(xact->tm_wait); + } +#endif list_append(xact->org == GTP_LOCAL_ORIGINATOR ? &xact->gnode->local_list : &xact->gnode->remote_list, xact); @@ -174,33 +158,26 @@ void gtp_xact_delete_all(gtp_node_t *gnode) } } -status_t gtp_xact_commit(gtp_xact_t *xact, - c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf) -{ - return gtp_xact_associated_commit(xact, NULL, type, teid, pkbuf); -} - -status_t gtp_xact_associated_commit(gtp_xact_t *xact, - gtp_xact_t *assoc_xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf) +status_t gtp_xact_update_tx(gtp_xact_t *xact, + c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf, + c_uintptr_t event) { char buf[INET_ADDRSTRLEN]; gtp_header_t *h = NULL; - d_assert(xact, goto out, "Null param"); - d_assert(xact->sock, goto out, "Null param"); - d_assert(xact->gnode, goto out, "Null param"); - d_assert(pkbuf, goto out, "Null param"); + d_assert(xact, return CORE_ERROR, "Null param"); + d_assert(xact->sock, return CORE_ERROR, "Null param"); + d_assert(xact->gnode, return CORE_ERROR, "Null param"); + d_assert(pkbuf, return CORE_ERROR, "Null param"); - d_trace(3, "[%d] %s Commit peer %s:%d\n", + d_trace(3, "[%d] %s UPD-TX peer %s:%d\n", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); - xact->pkbuf = pkbuf; - pkbuf_header(pkbuf, GTPV2C_HEADER_LEN); h = pkbuf->payload; - d_assert(h, goto out, "Null param"); + d_assert(h, return CORE_ERROR, "Null param"); memset(h, 0, sizeof(gtp_header_t)); h->version = 2; @@ -210,17 +187,87 @@ status_t gtp_xact_associated_commit(gtp_xact_t *xact, h->teid = htonl(teid); h->sqn = GTP_XID_TO_SQN(xact->xid); - d_assert(gtp_send(xact->sock, xact->gnode, xact->pkbuf) == CORE_OK, - goto out, "gtp_send error"); + xact->type = h->type; + xact->pkbuf = pkbuf; - if (assoc_xact) - gtp_xact_associate(xact, assoc_xact); + if (event) + { + xact->tm_wait = event_timer(g_tm_service, event, + GTP_XACT_LOCAL_DURATION, xact->index); + d_assert(xact->tm_wait, return CORE_ERROR, "Timer allocation failed"); + xact->retry_count = GTP_XACT_LOCAL_RETRY_COUNT; + } return CORE_OK; +} -out: - gtp_xact_delete(xact); - return CORE_ERROR; +status_t gtp_xact_update_rx(gtp_xact_t *xact, + c_uint8_t type, c_uintptr_t event) +{ + status_t rv; + char buf[INET_ADDRSTRLEN]; + + d_trace(3, "[%d] %s UPD-Rx peer %s:%d\n", + xact->xid, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", + INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); + + if (xact->org == GTP_REMOTE_ORIGINATOR) + { + if (xact->pkbuf) + { + d_warn("[%d]%s Request Duplicated. Retransmit!", + xact->gnode->port, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE"); + rv = gtp_send(xact->sock, xact->gnode, xact->pkbuf); + d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_send error"); + + return CORE_EAGAIN; + } + else if (xact->assoc_xact) + { + d_warn("[%d]%s Request Duplicated. Discard Associated transaction!", + xact->gnode->port, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE"); + + return CORE_EAGAIN; + } + } + + xact->type = type; + + return CORE_OK; +} + + +status_t gtp_xact_commit(gtp_xact_t *xact) +{ + char buf[INET_ADDRSTRLEN]; + + d_assert(xact, return CORE_ERROR, "Null param"); + d_assert(xact->sock, return CORE_ERROR, "Null param"); + d_assert(xact->gnode, return CORE_ERROR, "Null param"); + d_assert(xact->pkbuf, return CORE_ERROR, "Null param"); + + d_trace(3, "[%d] %s Commit peer %s:%d\n", + xact->xid, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", + INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); + + if (xact->org == GTP_LOCAL_ORIGINATOR) + { + gtp_xact_stage_t stage = gtp_xact_get_stage(xact->type, xact->xid); + if (stage == GTP_XACT_FINAL_STAGE) + { + gtp_xact_delete(xact); + return CORE_OK; + } + } + + d_assert(gtp_send(xact->sock, xact->gnode, xact->pkbuf) == CORE_OK, + return CORE_ERROR, "gtp_send error"); + + return CORE_OK; } status_t gtp_xact_timeout(index_t index) @@ -269,54 +316,7 @@ out: return CORE_ERROR; } -static gtp_xact_t *gtp_xact_find_by_sqn( - gtp_node_t *gnode, c_uint8_t type, c_uint32_t sqn) -{ - char buf[INET_ADDRSTRLEN]; - c_uint32_t xid; - gtp_xact_t *xact = NULL; - - d_assert(gnode, return NULL, "Null param"); - - switch(gtp_xact_get_stage(type, sqn)) - { - case GTP_XACT_INITIAL_STAGE: - xact = list_first(&gnode->remote_list); - break; - case GTP_XACT_INTERMEDIATE_STAGE: - xact = list_first(&gnode->local_list); - break; - case GTP_XACT_FINAL_STAGE: - if (sqn & GTP_MAX_XACT_ID) - xact = list_first(&gnode->remote_list); - else - xact = list_first(&gnode->local_list); - break; - - default: - d_assert(0, return NULL, "Unknown stage"); - } - - xid = GTP_SQN_TO_XID(sqn); - while(xact) - { - if (xact->xid == xid) - break; - xact = list_next(xact); - } - - if (xact) - { - d_trace(3, "[%d] %s Find peer %s:%d\n", - xact->xid, - xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", - INET_NTOP(&gnode->addr, buf), gnode->port); - } - - return xact; -} - -status_t gtp_xact_receive(gtp_xact_ctx_t *context, +status_t gtp_xact_receive( net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf, gtp_xact_t **xact, gtp_message_t *message) { @@ -325,7 +325,6 @@ status_t gtp_xact_receive(gtp_xact_ctx_t *context, gtp_xact_t *new = NULL; gtp_header_t *h = NULL; - d_assert(context, return CORE_ERROR, "Null param"); d_assert(sock, return CORE_ERROR, "Null param"); d_assert(gnode, return CORE_ERROR, "Null param"); d_assert(pkbuf, return CORE_ERROR, "Null param"); @@ -333,10 +332,10 @@ status_t gtp_xact_receive(gtp_xact_ctx_t *context, h = pkbuf->payload; d_assert(h, return CORE_ERROR, "Null param"); - new = gtp_xact_find_by_sqn(gnode, h->type, h->sqn); + new = gtp_xact_find_by_xid(gnode, h->type, GTP_SQN_TO_XID(h->sqn)); if (!new) { - new = gtp_xact_remote_create(context, sock, gnode, h->sqn); + new = gtp_xact_remote_create(sock, gnode, h->sqn); } d_assert(new, return CORE_ERROR, "Null param"); @@ -345,38 +344,11 @@ status_t gtp_xact_receive(gtp_xact_ctx_t *context, new->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", INET_NTOP(&gnode->addr, buf), gnode->port); - if (new->org == GTP_LOCAL_ORIGINATOR) + rv = gtp_xact_update_rx(new, h->type, 0); + if (rv != CORE_OK) { - gtp_xact_t *assoc_xact = new->assoc_xact; - - if (assoc_xact) - gtp_xact_deassociate(new, assoc_xact); - - gtp_xact_delete(new); - new = assoc_xact; - } - else - { - if (new->pkbuf) - { - d_warn("[%d]%s Request Duplicated. Retransmit!", - new->gnode->port, - new->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE"); - rv = gtp_send(new->sock, new->gnode, new->pkbuf); - d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_send error"); - - pkbuf_free(pkbuf); - return CORE_EAGAIN; - } - else if (new->assoc_xact) - { - d_warn("[%d]%s Request Duplicated. Discard Associated transaction!", - new->gnode->port, - new->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE"); - - pkbuf_free(pkbuf); - return CORE_EAGAIN; - } + pkbuf_free(pkbuf); + return rv; } rv = gtp_parse_msg(message, pkbuf); @@ -393,7 +365,7 @@ gtp_xact_t *gtp_xact_find(index_t index) return index_find(>p_xact_pool, index); } -static gtp_xact_stage_t gtp_xact_get_stage(c_uint8_t type, c_uint32_t sqn) +static gtp_xact_stage_t gtp_xact_get_stage(c_uint8_t type, c_uint32_t xid) { gtp_xact_stage_t stage = GTP_XACT_UNKNOWN_STAGE; @@ -414,7 +386,7 @@ static gtp_xact_stage_t gtp_xact_get_stage(c_uint8_t type, c_uint32_t sqn) case GTP_CREATE_BEARER_REQUEST_TYPE: case GTP_UPDATE_BEARER_REQUEST_TYPE: case GTP_DELETE_BEARER_REQUEST_TYPE: - if (sqn & GTP_MAX_XACT_ID) + if (xid & GTP_MAX_XACT_ID) stage = GTP_XACT_INTERMEDIATE_STAGE; else stage = GTP_XACT_INITIAL_STAGE; @@ -443,6 +415,51 @@ static gtp_xact_stage_t gtp_xact_get_stage(c_uint8_t type, c_uint32_t sqn) return stage; } +gtp_xact_t *gtp_xact_find_by_xid( + gtp_node_t *gnode, c_uint8_t type, c_uint32_t xid) +{ + char buf[INET_ADDRSTRLEN]; + gtp_xact_t *xact = NULL; + + d_assert(gnode, return NULL, "Null param"); + + switch(gtp_xact_get_stage(type, xid)) + { + case GTP_XACT_INITIAL_STAGE: + xact = list_first(&gnode->remote_list); + break; + case GTP_XACT_INTERMEDIATE_STAGE: + xact = list_first(&gnode->local_list); + break; + case GTP_XACT_FINAL_STAGE: + if (xid & GTP_MAX_XACT_ID) + xact = list_first(&gnode->remote_list); + else + xact = list_first(&gnode->local_list); + break; + + default: + d_assert(0, return NULL, "Unknown stage"); + } + + while(xact) + { + if (xact->xid == xid) + break; + xact = list_next(xact); + } + + if (xact) + { + d_trace(3, "[%d] %s Find peer %s:%d\n", + xact->xid, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", + INET_NTOP(&gnode->addr, buf), gnode->port); + } + + return xact; +} + void gtp_xact_associate(gtp_xact_t *xact1, gtp_xact_t *xact2) { d_assert(xact1, return, "Null param"); @@ -467,3 +484,32 @@ void gtp_xact_deassociate(gtp_xact_t *xact1, gtp_xact_t *xact2) xact2->assoc_xact = NULL; } +static status_t gtp_xact_delete(gtp_xact_t *xact) +{ + char buf[INET_ADDRSTRLEN]; + + d_assert(xact, , "Null param"); + d_assert(xact->gnode, , "Null param"); + d_assert(xact->tm_wait, , "Null param"); + + d_trace(3, "[%d] %s Delete peer %s:%d\n", + xact->xid, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", + INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); + + if (xact->pkbuf) + pkbuf_free(xact->pkbuf); + + if (xact->tm_wait) + tm_delete(xact->tm_wait); + + if (xact->assoc_xact) + gtp_xact_deassociate(xact, xact->assoc_xact); + + list_remove(xact->org == GTP_LOCAL_ORIGINATOR ? &xact->gnode->local_list : + &xact->gnode->remote_list, xact); + index_free(>p_xact_pool, xact); + + return CORE_OK; +} + diff --git a/lib/gtp/gtp_xact.h b/lib/gtp/gtp_xact.h index 99399e0dd..1563f6854 100644 --- a/lib/gtp/gtp_xact.h +++ b/lib/gtp/gtp_xact.h @@ -41,7 +41,8 @@ typedef struct _gtp_xact_t { net_sock_t *sock; /**< GTP Socket */ gtp_node_t *gnode; /**< Relevant GTP node context */ - pkbuf_t *pkbuf; /**< Relevant GTP node context */ + c_uint8_t type; /**< Save transmitted GTP message type */ + pkbuf_t *pkbuf; /**< Save transmiited packet */ tm_block_id tm_wait; /**< Timer waiting for next message */ c_uint8_t retry_count; /**< Retry count waiting for next message */ @@ -53,23 +54,27 @@ CORE_DECLARE(status_t) gtp_xact_init(gtp_xact_ctx_t *context, tm_service_t *tm_service, c_uintptr_t event); CORE_DECLARE(status_t) gtp_xact_final(void); -CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create(gtp_xact_ctx_t *context, +CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create( net_sock_t *sock, gtp_node_t *gnode); -CORE_DECLARE(gtp_xact_t *) gtp_xact_remote_create(gtp_xact_ctx_t *context, +CORE_DECLARE(gtp_xact_t *) gtp_xact_remote_create( net_sock_t *sock, gtp_node_t *gnode, c_uint32_t sqn); CORE_DECLARE(void) gtp_xact_delete_all(gtp_node_t *gnode); -CORE_DECLARE(status_t) gtp_xact_commit( - gtp_xact_t *xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf); -CORE_DECLARE(status_t) gtp_xact_associated_commit(gtp_xact_t *xact, - gtp_xact_t *assoc_xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf); +CORE_DECLARE(status_t) gtp_xact_update_tx(gtp_xact_t *xact, + c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf, c_uintptr_t event); +CORE_DECLARE(status_t) gtp_xact_update_rx(gtp_xact_t *xact, + c_uint8_t type, c_uintptr_t event); + +CORE_DECLARE(status_t) gtp_xact_commit(gtp_xact_t *xact); CORE_DECLARE(status_t) gtp_xact_timeout(index_t index); -CORE_DECLARE(status_t) gtp_xact_receive(gtp_xact_ctx_t *context, +CORE_DECLARE(status_t) gtp_xact_receive( net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf, gtp_xact_t **xact, gtp_message_t *gtp_message); CORE_DECLARE(gtp_xact_t *) gtp_xact_find(index_t index); +CORE_DECLARE(gtp_xact_t *)gtp_xact_find_by_xid( + gtp_node_t *gnode, c_uint8_t type, c_uint32_t xid); CORE_DECLARE(void) gtp_xact_associate(gtp_xact_t *xact1, gtp_xact_t *xact2); CORE_DECLARE(void) gtp_xact_deassociate(gtp_xact_t *xact1, gtp_xact_t *xact2); diff --git a/src/mme/mme_gtp_path.c b/src/mme/mme_gtp_path.c index 214a2b4b7..182e98922 100644 --- a/src/mme/mme_gtp_path.c +++ b/src/mme/mme_gtp_path.c @@ -83,6 +83,7 @@ status_t mme_gtp_close() status_t mme_s11_send_to_sgw(mme_sess_t *sess, c_uint8_t type, pkbuf_t *pkbuf) { + status_t rv; gtp_xact_t *xact = NULL; void *sgw = NULL; c_uint32_t teid; @@ -93,12 +94,14 @@ status_t mme_s11_send_to_sgw(mme_sess_t *sess, c_uint8_t type, pkbuf_t *pkbuf) d_assert(sgw, return CORE_ERROR, "Null param"); teid = sess->sgw_s11_teid; - xact = gtp_xact_local_create(&mme_self()->gtp_xact_ctx, - mme_self()->s11_sock, sgw); + xact = gtp_xact_local_create(mme_self()->s11_sock, sgw); d_assert(xact, return CORE_ERROR, "Null param"); - d_assert(gtp_xact_commit(xact, type, teid, pkbuf) == CORE_OK, - return CORE_ERROR, "xact commit error"); + rv = gtp_xact_update_tx(xact, type, teid, pkbuf, MME_EVT_S11_T3); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_update_tx error"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error"); return CORE_OK; } diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index 6b6622d4b..504df0ae1 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -33,8 +33,10 @@ void mme_s11_handle_create_session_request(mme_sess_t *sess) } void mme_s11_handle_create_session_response( - mme_sess_t *sess, gtp_create_session_response_t *rsp) + gtp_xact_t *xact, mme_sess_t *sess, + gtp_create_session_response_t *rsp) { + status_t rv; gtp_f_teid_t *sgw_s11_teid = NULL; gtp_f_teid_t *sgw_s1u_teid = NULL; @@ -96,6 +98,9 @@ void mme_s11_handle_create_session_response( d_trace(3, "[GTP] Create Session Response : " "MME[%d] <-- SGW[%d]\n", sess->mme_s11_teid, sess->sgw_s11_teid); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); } void mme_s11_handle_delete_all_sessions_request_in_ue(mme_ue_t *mme_ue) @@ -119,8 +124,11 @@ void mme_s11_handle_delete_all_sessions_request_in_ue(mme_ue_t *mme_ue) } void mme_s11_handle_delete_session_response( - mme_sess_t *sess, gtp_delete_session_response_t *rsp) + gtp_xact_t *xact, mme_sess_t *sess, + gtp_delete_session_response_t *rsp) { + status_t rv; + if (rsp->cause.presence == 0) { d_error("No Cause"); @@ -131,18 +139,29 @@ void mme_s11_handle_delete_session_response( "MME[%d] <-- SGW[%d]\n", sess->mme_s11_teid, sess->sgw_s11_teid); mme_sess_remove(sess); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); } void mme_s11_handle_modify_bearer_response( - mme_sess_t *sess, gtp_modify_bearer_response_t *rsp) + gtp_xact_t *xact, mme_sess_t *sess, + gtp_modify_bearer_response_t *rsp) { + status_t rv; + d_trace(3, "[GTP] Modify Bearer Response : " "MME[%d] <-- SGW[%d]\n", sess->mme_s11_teid, sess->sgw_s11_teid); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); } void mme_s11_handle_release_access_bearers_response( - mme_sess_t *sess, gtp_release_access_bearers_response_t *rsp) + gtp_xact_t *xact, mme_sess_t *sess, + gtp_release_access_bearers_response_t *rsp) { + status_t rv; d_assert(rsp, return, "Null param"); d_assert(sess, return, "Null param"); @@ -154,6 +173,9 @@ void mme_s11_handle_release_access_bearers_response( d_trace(3, "[GTP] Release Access Bearers Response : " "MME[%d] <-- SGW[%d]\n", sess->mme_s11_teid, sess->sgw_s11_teid); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); } void mme_s11_handle_downlink_data_notification( @@ -174,8 +196,11 @@ void mme_s11_handle_downlink_data_notification( rv = mme_s11_build_downlink_data_notification_ack(&s11buf, sess); d_assert(rv == CORE_OK, return, "S11 build error"); - d_assert(gtp_xact_commit(xact, - GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE, - sess->sgw_s11_teid, s11buf) == CORE_OK, - return , "xact commit error"); + rv = gtp_xact_update_tx(xact, + GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE, + sess->sgw_s11_teid, s11buf, 0); + d_assert(rv == CORE_OK, return, "xact_update_tx error"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); } diff --git a/src/mme/mme_s11_handler.h b/src/mme/mme_s11_handler.h index 0649cae02..c53f077d5 100644 --- a/src/mme/mme_s11_handler.h +++ b/src/mme/mme_s11_handler.h @@ -11,16 +11,20 @@ extern "C" { CORE_DECLARE(void) mme_s11_handle_create_session_request(mme_sess_t *sess); CORE_DECLARE(void) mme_s11_handle_create_session_response( - mme_sess_t *sess, gtp_create_session_response_t *rsp); + gtp_xact_t *xact, mme_sess_t *sess, + gtp_create_session_response_t *rsp); CORE_DECLARE(void) mme_s11_handle_delete_all_sessions_request_in_ue( mme_ue_t *mme_ue); CORE_DECLARE(void) mme_s11_handle_delete_session_response( - mme_sess_t *sess, gtp_delete_session_response_t *rsp); + gtp_xact_t *xact, mme_sess_t *sess, + gtp_delete_session_response_t *rsp); CORE_DECLARE(void) mme_s11_handle_modify_bearer_response( - mme_sess_t *sess, gtp_modify_bearer_response_t *rsp); + gtp_xact_t *xact, mme_sess_t *sess, + gtp_modify_bearer_response_t *rsp); CORE_DECLARE(void) mme_s11_handle_release_access_bearers_response( - mme_sess_t *sess, gtp_release_access_bearers_response_t *rsp); + gtp_xact_t *xact, mme_sess_t *sess, + gtp_release_access_bearers_response_t *rsp); CORE_DECLARE(void) mme_s11_handle_downlink_data_notification( gtp_xact_t *xact, mme_sess_t *sess, gtp_downlink_data_notification_t *noti); diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index ca42605e1..ce4e6a694 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -275,9 +275,7 @@ void mme_state_operational(fsm_t *s, event_t *e) d_assert(sock, pkbuf_free(pkbuf); break, "Null param"); d_assert(gnode, pkbuf_free(pkbuf); break, "Null param"); - rv = gtp_xact_receive( - &mme_self()->gtp_xact_ctx, sock, gnode, pkbuf, - &xact, &message); + rv = gtp_xact_receive(sock, gnode, pkbuf, &xact, &message); if (rv != CORE_OK) break; @@ -294,7 +292,7 @@ void mme_state_operational(fsm_t *s, event_t *e) case GTP_CREATE_SESSION_RESPONSE_TYPE: { mme_s11_handle_create_session_response( - sess, &message.create_session_response); + xact, sess, &message.create_session_response); if (MME_SESSION_IN_ATTACH_STATE(sess)) { emm_handle_attach_accept(mme_ue); @@ -307,12 +305,12 @@ void mme_state_operational(fsm_t *s, event_t *e) } case GTP_MODIFY_BEARER_RESPONSE_TYPE: mme_s11_handle_modify_bearer_response( - sess, &message.modify_bearer_response); + xact, sess, &message.modify_bearer_response); break; case GTP_DELETE_SESSION_RESPONSE_TYPE: { mme_s11_handle_delete_session_response( - sess, &message.delete_session_response); + xact, sess, &message.delete_session_response); if (MME_UE_DETACH_INITIATED(mme_ue)) { @@ -355,7 +353,7 @@ void mme_state_operational(fsm_t *s, event_t *e) case GTP_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE: { mme_s11_handle_release_access_bearers_response( - sess, &message.release_access_bearers_response); + xact, sess, &message.release_access_bearers_response); s1ap_handle_release_access_bearers_response(enb_ue); break; @@ -364,8 +362,7 @@ void mme_state_operational(fsm_t *s, event_t *e) case GTP_DOWNLINK_DATA_NOTIFICATION_TYPE: { mme_s11_handle_downlink_data_notification( - xact, - sess, &message.downlink_data_notification); + xact, sess, &message.downlink_data_notification); s1ap_handle_paging(mme_ue); /* Start T3413 */ diff --git a/src/pgw/pgw_gtp_path.c b/src/pgw/pgw_gtp_path.c index ba85d99c6..113c71e05 100644 --- a/src/pgw/pgw_gtp_path.c +++ b/src/pgw/pgw_gtp_path.c @@ -237,11 +237,16 @@ status_t pgw_gtp_close() status_t pgw_s5c_send_to_sgw( gtp_xact_t *xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf) { + status_t rv; + d_assert(pkbuf, return CORE_ERROR, "Null param"); d_assert(xact, return CORE_ERROR, "Null param"); - d_assert(gtp_xact_commit(xact, type, teid, pkbuf) == CORE_OK, - return CORE_ERROR, "xact commit error"); + rv = gtp_xact_update_tx(xact, type, teid, pkbuf, PGW_EVT_S5C_T3); + d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_xact_update_tx error"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error"); return CORE_OK; } diff --git a/src/pgw/pgw_sm.c b/src/pgw/pgw_sm.c index a6aa3cfc6..31dcd7482 100644 --- a/src/pgw/pgw_sm.c +++ b/src/pgw/pgw_sm.c @@ -82,9 +82,7 @@ void pgw_state_operational(fsm_t *s, event_t *e) message = copybuf->payload; d_assert(message, break, "Null param"); - rv = gtp_xact_receive( - &pgw_self()->gtp_xact_ctx, sock, gnode, recvbuf, - &xact, message); + rv = gtp_xact_receive(sock, gnode, recvbuf, &xact, message); if (rv != CORE_OK) break; diff --git a/src/sgw/sgw_gtp_path.c b/src/sgw/sgw_gtp_path.c index 90dcd01ee..7a45620d0 100644 --- a/src/sgw/sgw_gtp_path.c +++ b/src/sgw/sgw_gtp_path.c @@ -306,11 +306,15 @@ status_t sgw_gtp_close() status_t sgw_s11_send_to_mme( gtp_xact_t *xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf) { + status_t rv; d_assert(pkbuf, return CORE_ERROR, "Null param"); d_assert(xact, return CORE_ERROR, "Null param"); - d_assert(gtp_xact_commit(xact, type, teid, pkbuf) == CORE_OK, - return CORE_ERROR, "xact commit error"); + rv = gtp_xact_update_tx(xact, type, teid, pkbuf, SGW_EVT_GTP_T3); + d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_xact_update_tx error"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error"); return CORE_OK; } @@ -318,17 +322,21 @@ status_t sgw_s11_send_to_mme( status_t sgw_s5c_send_to_pgw( gtp_xact_t *assoc_xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf) { + status_t rv; gtp_xact_t *xact = NULL; d_assert(assoc_xact, return CORE_ERROR, "Null param"); d_assert(pkbuf, return CORE_ERROR, "Null param"); - xact = gtp_xact_local_create(&sgw_self()->gtp_xact_ctx, - sgw_self()->s5c_sock, &sgw_self()->s5c_node); + xact = gtp_xact_local_create(sgw_self()->s5c_sock, &sgw_self()->s5c_node); d_assert(xact, return CORE_ERROR, "Null param"); - d_assert(gtp_xact_associated_commit( - xact, assoc_xact, type, teid, pkbuf) == CORE_OK, - return CORE_ERROR, "gtp_send error"); + rv = gtp_xact_update_tx(xact, type, teid, pkbuf, SGW_EVT_GTP_T3); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_update_tx error"); + + gtp_xact_associate(xact, assoc_xact); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error"); return CORE_OK; } diff --git a/src/sgw/sgw_handler.c b/src/sgw/sgw_handler.c index a185b198d..3fc8dea02 100644 --- a/src/sgw/sgw_handler.c +++ b/src/sgw/sgw_handler.c @@ -83,10 +83,11 @@ void sgw_handle_create_session_request(gtp_xact_t *xact, "SGW[%d] --> PGW\n", sess->sgw_s5c_teid); } -void sgw_handle_create_session_response(gtp_xact_t *xact, +void sgw_handle_create_session_response(gtp_xact_t *s5c_xact, sgw_sess_t *sess, gtp_message_t *gtp_message) { status_t rv; + gtp_xact_t *s11_xact = NULL; sgw_bearer_t *bearer = NULL; gtp_create_session_response_t *rsp = NULL; pkbuf_t *pkbuf = NULL; @@ -97,7 +98,9 @@ void sgw_handle_create_session_response(gtp_xact_t *xact, gtp_f_teid_t sgw_s1u_teid; d_assert(sess, return, "Null param"); - d_assert(xact, return, "Null param"); + d_assert(s5c_xact, return, "Null param"); + s11_xact = s5c_xact->assoc_xact; + d_assert(s11_xact, return, "Null param"); d_assert(gtp_message, return, "Null param"); rsp = >p_message->create_session_response; @@ -166,7 +169,10 @@ void sgw_handle_create_session_response(gtp_xact_t *xact, rv = gtp_build_msg(&pkbuf, gtp_message); d_assert(rv == CORE_OK, return, "gtp build failed"); - d_assert(sgw_s11_send_to_mme(xact, GTP_CREATE_SESSION_RESPONSE_TYPE, + rv = gtp_xact_commit(s5c_xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); + + d_assert(sgw_s11_send_to_mme(s11_xact, gtp_message->h.type, sess->mme_s11_teid, pkbuf) == CORE_OK, return, "failed to send message"); d_trace(3, "[GTP] Create Session Response : " @@ -257,17 +263,20 @@ void sgw_handle_delete_session_request(gtp_xact_t *xact, "SGW[%d] --> PGW[%d]\n", sess->sgw_s5c_teid, sess->pgw_s5c_teid); } -void sgw_handle_delete_session_response(gtp_xact_t *xact, +void sgw_handle_delete_session_response(gtp_xact_t *s5c_xact, sgw_sess_t *sess, gtp_message_t *gtp_message) { status_t rv; + gtp_xact_t *s11_xact = NULL; gtp_delete_session_response_t *rsp = NULL; pkbuf_t *pkbuf = NULL; c_uint32_t mme_s11_teid; gtp_cause_t *cause = NULL; d_assert(sess, return, "Null param"); - d_assert(xact, return, "Null param"); + d_assert(s5c_xact, return, "Null param"); + s11_xact = s5c_xact->assoc_xact; + d_assert(s11_xact, return, "Null param"); d_assert(gtp_message, return, "Null param"); rsp = >p_message->delete_session_response; @@ -305,7 +314,10 @@ void sgw_handle_delete_session_response(gtp_xact_t *xact, rv = gtp_build_msg(&pkbuf, gtp_message); d_assert(rv == CORE_OK, return, "gtp build failed"); - d_assert(sgw_s11_send_to_mme(xact, GTP_DELETE_SESSION_RESPONSE_TYPE, + rv = gtp_xact_commit(s5c_xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); + + d_assert(sgw_s11_send_to_mme(s11_xact, gtp_message->h.type, mme_s11_teid, pkbuf) == CORE_OK, return, "failed to send message"); } @@ -394,9 +406,8 @@ void sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer) rv = gtp_build_msg(&pkbuf, >p_message); d_assert(rv == CORE_OK, return, "gtp build failed"); - xact = gtp_xact_local_create(&sgw_self()->gtp_xact_ctx, - sgw_self()->s11_sock, &sgw_self()->s11_node); - d_assert(xact, return , "Null param"); + xact = gtp_xact_local_create(sgw_self()->s11_sock, &sgw_self()->s11_node); + d_assert(xact, return, "Null param"); d_assert(sgw_s11_send_to_mme(xact, GTP_DOWNLINK_DATA_NOTIFICATION_TYPE, diff --git a/src/sgw/sgw_handler.h b/src/sgw/sgw_handler.h index c4f855f3d..3e15f4a57 100644 --- a/src/sgw/sgw_handler.h +++ b/src/sgw/sgw_handler.h @@ -13,7 +13,7 @@ CORE_DECLARE(void) sgw_handle_create_session_request(gtp_xact_t *xact, sgw_sess_t *sess, gtp_message_t *gtp_message); CORE_DECLARE(void) sgw_handle_create_session_response(gtp_xact_t *xact, - sgw_sess_t *sess, gtp_message_t *gtp_message); + sgw_sess_t *s5c_xact, gtp_message_t *gtp_message); CORE_DECLARE(void) sgw_handle_modify_bearer_request(gtp_xact_t *xact, sgw_sess_t *sess, gtp_modify_bearer_request_t *req); @@ -21,7 +21,7 @@ CORE_DECLARE(void) sgw_handle_modify_bearer_request(gtp_xact_t *xact, CORE_DECLARE(void) sgw_handle_delete_session_request(gtp_xact_t *xact, sgw_sess_t *sess, gtp_message_t *gtp_message); CORE_DECLARE(void) sgw_handle_delete_session_response(gtp_xact_t *xact, - sgw_sess_t *sess, gtp_message_t *gtp_message); + sgw_sess_t *s5c_xact, gtp_message_t *gtp_message); CORE_DECLARE(void) sgw_handle_release_access_bearers_request(gtp_xact_t *xact, sgw_sess_t *sess, gtp_release_access_bearers_request_t *req); diff --git a/src/sgw/sgw_sm.c b/src/sgw/sgw_sm.c index a980f09d7..edf69cf7c 100644 --- a/src/sgw/sgw_sm.c +++ b/src/sgw/sgw_sm.c @@ -67,9 +67,7 @@ void sgw_state_operational(fsm_t *s, event_t *e) d_assert(sock, pkbuf_free(pkbuf); break, "Null param"); d_assert(gnode, pkbuf_free(pkbuf); break, "Null param"); - rv = gtp_xact_receive( - &sgw_self()->gtp_xact_ctx, sock, gnode, pkbuf, - &xact, &message); + rv = gtp_xact_receive(sock, gnode, pkbuf, &xact, &message); if (rv != CORE_OK) break;