From 1c8a59d3b42019fad42c16dc7c4499fd2ba15b33 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Mon, 4 Sep 2017 20:06:54 +0900 Subject: [PATCH] Create Bearer Request (SGW->MME) --- lib/gtp/gtp_xact.c | 157 +++++++++++++++++++++++--------------- lib/gtp/gtp_xact.h | 6 +- src/mme/mme_event.c | 4 +- src/mme/mme_event.h | 2 +- src/mme/mme_init.c | 2 +- src/mme/mme_sm.c | 2 +- src/pgw/pgw_event.c | 4 +- src/pgw/pgw_event.h | 2 +- src/pgw/pgw_init.c | 2 +- src/pgw/pgw_sm.c | 2 +- src/sgw/sgw_event.c | 4 +- src/sgw/sgw_event.h | 2 +- src/sgw/sgw_init.c | 2 +- src/sgw/sgw_s11_handler.c | 12 +-- src/sgw/sgw_s11_handler.h | 14 ++-- src/sgw/sgw_s5c_handler.c | 84 +++++++++++++++++++- src/sgw/sgw_s5c_handler.h | 7 +- src/sgw/sgw_sm.c | 26 ++++--- 18 files changed, 229 insertions(+), 105 deletions(-) diff --git a/lib/gtp/gtp_xact.c b/lib/gtp/gtp_xact.c index 170bdaf2fd..1c5b6d8b1c 100644 --- a/lib/gtp/gtp_xact.c +++ b/lib/gtp/gtp_xact.c @@ -27,7 +27,7 @@ typedef enum { static int gtp_xact_initialized = 0; static tm_service_t *g_tm_service = NULL; static c_uintptr_t g_response_event = 0; -static c_uintptr_t g_duplicated_event = 0; +static c_uintptr_t g_holding_event = 0; static c_uint32_t g_xact_id = 0; index_declare(gtp_xact_pool, gtp_xact_t, SIZE_OF_GTP_XACT_POOL); @@ -36,7 +36,7 @@ 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(tm_service_t *tm_service, - c_uintptr_t response_event, c_uintptr_t duplicated_event) + c_uintptr_t response_event, c_uintptr_t holding_event) { d_assert(gtp_xact_initialized == 0, return CORE_ERROR, "GTP Transaction already has been initialized"); @@ -46,7 +46,7 @@ status_t gtp_xact_init(tm_service_t *tm_service, g_xact_id = 0; g_tm_service = tm_service; g_response_event = response_event; - g_duplicated_event = duplicated_event; + g_holding_event = holding_event; gtp_xact_initialized = 1; @@ -97,12 +97,12 @@ gtp_xact_t *gtp_xact_local_create( xact->response_rcount = GTP_T3_RESPONSE_RETRY_COUNT; } - if (g_duplicated_event) + if (g_holding_event) { - xact->tm_duplicated = event_timer(g_tm_service, - g_duplicated_event, GTP_T3_DUPLICATED_DURATION, xact->index); - d_assert(xact->tm_duplicated, return NULL, "Timer allocation failed"); - xact->duplicated_rcount = GTP_T3_DUPLICATED_RETRY_COUNT; + xact->tm_holding = event_timer(g_tm_service, + g_holding_event, GTP_T3_DUPLICATED_DURATION, xact->index); + d_assert(xact->tm_holding, return NULL, "Timer allocation failed"); + xact->holding_rcount = GTP_T3_DUPLICATED_RETRY_COUNT; } list_append(xact->org == GTP_LOCAL_ORIGINATOR ? @@ -141,12 +141,12 @@ gtp_xact_t *gtp_xact_remote_create(gtp_node_t *gnode, c_uint32_t sqn) xact->response_rcount = GTP_T3_RESPONSE_RETRY_COUNT; } - if (g_duplicated_event) + if (g_holding_event) { - xact->tm_duplicated = event_timer(g_tm_service, - g_duplicated_event, GTP_T3_DUPLICATED_DURATION, xact->index); - d_assert(xact->tm_duplicated, return NULL, "Timer allocation failed"); - xact->duplicated_rcount = GTP_T3_DUPLICATED_RETRY_COUNT; + xact->tm_holding = event_timer(g_tm_service, + g_holding_event, GTP_T3_DUPLICATED_DURATION, xact->index); + d_assert(xact->tm_holding, return NULL, "Timer allocation failed"); + xact->holding_rcount = GTP_T3_DUPLICATED_RETRY_COUNT; } list_append(xact->org == GTP_LOCAL_ORIGINATOR ? @@ -203,7 +203,7 @@ status_t gtp_xact_update_tx(gtp_xact_t *xact, { case GTP_XACT_INITIAL_STAGE: d_assert(xact->step == 0, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, hdesc->type, @@ -215,7 +215,7 @@ status_t gtp_xact_update_tx(gtp_xact_t *xact, case GTP_XACT_FINAL_STAGE: d_assert(xact->step == 2, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, hdesc->type, @@ -236,7 +236,7 @@ status_t gtp_xact_update_tx(gtp_xact_t *xact, case GTP_XACT_INTERMEDIATE_STAGE: case GTP_XACT_FINAL_STAGE: d_assert(xact->step == 1, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, hdesc->type, @@ -298,8 +298,9 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type) { pkbuf_t *pkbuf = NULL; - d_assert(xact->step == 3, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + d_assert(xact->step == 2 || xact->step == 3, + return CORE_ERROR, + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -308,43 +309,51 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type) pkbuf = xact->seq[2].pkbuf; if (pkbuf) { - if (xact->tm_duplicated) - tm_start(xact->tm_duplicated); + if (xact->tm_holding) + tm_start(xact->tm_holding); - d_warn("[%d]%s Request Duplicated. Retransmit!", - xact->gnode->port, + d_warn("[%d] %s Request Duplicated. Retransmit!" + " for type %d peer %s:%d", + xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? - "LOCAL " : "REMOTE"); + "LOCAL " : "REMOTE", + xact->step, type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); rv = gtp_send(xact->gnode, pkbuf); d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_send error"); } else { - d_warn("[%d]%s Request Duplicated. Discard!", - xact->gnode->port, + d_warn("[%d] %s Request Duplicated. Discard!" + " for type %d peer %s:%d", + xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? - "LOCAL " : "REMOTE"); + "LOCAL " : "REMOTE", + xact->step, type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); } return CORE_EAGAIN; } d_assert(xact->step == 1, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); - if (xact->tm_duplicated) - tm_start(xact->tm_duplicated); + if (xact->tm_holding) + tm_start(xact->tm_holding); break; case GTP_XACT_FINAL_STAGE: d_assert(xact->step == 1, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -365,8 +374,9 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type) { pkbuf_t *pkbuf = NULL; - d_assert(xact->step == 1, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + d_assert(xact->step == 1 || xact->step == 2, + return CORE_ERROR, + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -375,37 +385,45 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type) pkbuf = xact->seq[1].pkbuf; if (pkbuf) { - if (xact->tm_duplicated) - tm_start(xact->tm_duplicated); + if (xact->tm_holding) + tm_start(xact->tm_holding); - d_warn("[%d]%s Request Duplicated. Retransmit!", - xact->gnode->port, + d_warn("[%d] %s Request Duplicated. Retransmit!" + " for step %d type %d peer %s:%d", + xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? - "LOCAL " : "REMOTE"); + "LOCAL " : "REMOTE", + xact->step, type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); rv = gtp_send(xact->gnode, pkbuf); d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_send error"); } else { - d_warn("[%d]%s Request Duplicated. Discard!", - xact->gnode->port, + d_warn("[%d] %s Request Duplicated. Discard!" + " for step %d type %d peer %s:%d", + xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? - "LOCAL " : "REMOTE"); + "LOCAL " : "REMOTE", + xact->step, type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); } return CORE_EAGAIN; } d_assert(xact->step == 0, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); - if (xact->tm_duplicated) - tm_start(xact->tm_duplicated); + if (xact->tm_holding) + tm_start(xact->tm_holding); break; @@ -414,7 +432,7 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type) case GTP_XACT_FINAL_STAGE: d_assert(xact->step == 2, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -470,7 +488,7 @@ status_t gtp_xact_commit(gtp_xact_t *xact) case GTP_XACT_INITIAL_STAGE: { d_assert(xact->step == 1, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -487,7 +505,7 @@ status_t gtp_xact_commit(gtp_xact_t *xact) case GTP_XACT_FINAL_STAGE: d_assert(xact->step == 2 || xact->step == 3, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -514,7 +532,7 @@ status_t gtp_xact_commit(gtp_xact_t *xact) case GTP_XACT_INTERMEDIATE_STAGE: d_assert(xact->step == 2, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -528,7 +546,7 @@ status_t gtp_xact_commit(gtp_xact_t *xact) case GTP_XACT_FINAL_STAGE: d_assert(xact->step == 2 || xact->step == 3, return CORE_ERROR, - "[%d] %s invalid step %d for type %d peer %s:%d\n", + "[%d] %s invalid step %d for type %d peer %s:%d", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", xact->step, type, @@ -570,10 +588,13 @@ status_t gtp_xact_timeout(index_t index, c_uintptr_t event) if (event == g_response_event) { - d_trace(3, "[%d] %s Response Timeout peer %s:%d\n", + d_trace(3, "[%d] %s Response Timeout " + "for step %d type %d peer %s:%d\n", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", - INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); + xact->step, xact->seq[xact->step-1].type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); if (--xact->response_rcount > 0) { @@ -590,26 +611,40 @@ status_t gtp_xact_timeout(index_t index, c_uintptr_t event) } else { - d_warn("[%d]%s No Reponse. Give up", - xact->gnode->port, - xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE"); + d_warn("[%d] %s No Reponse. Give up! " + "for step %d type %d peer %s:%d", + xact->xid, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", + xact->step, xact->seq[xact->step-1].type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); gtp_xact_delete(xact); } } - else if (event == g_duplicated_event) + else if (event == g_holding_event) { - d_trace(3, "[%d] %s Duplicated Timeout peer %s:%d\n", + d_trace(3, "[%d] %s Holding Timeout " + "for step %d type %d peer %s:%d\n", xact->xid, xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", - INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port); + xact->step, xact->seq[xact->step-1].type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); - if (--xact->duplicated_rcount > 0) + if (--xact->holding_rcount > 0) { - if (xact->tm_duplicated) - tm_start(xact->tm_duplicated); + if (xact->tm_holding) + tm_start(xact->tm_holding); } else { + d_trace(3, "[%d] %s Delete Transaction " + "for step %d type %d peer %s:%d\n", + xact->xid, + xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE", + xact->step, xact->seq[xact->step-1].type, + INET_NTOP(&xact->gnode->addr, buf), + xact->gnode->port); gtp_xact_delete(xact); } } @@ -806,8 +841,8 @@ static status_t gtp_xact_delete(gtp_xact_t *xact) if (xact->tm_response) tm_delete(xact->tm_response); - if (xact->tm_duplicated) - tm_delete(xact->tm_duplicated); + if (xact->tm_holding) + tm_delete(xact->tm_holding); if (xact->assoc_xact) gtp_xact_deassociate(xact, xact->assoc_xact); diff --git a/lib/gtp/gtp_xact.h b/lib/gtp/gtp_xact.h index 8b87d46a2a..0b367086dc 100644 --- a/lib/gtp/gtp_xact.h +++ b/lib/gtp/gtp_xact.h @@ -40,8 +40,8 @@ typedef struct _gtp_xact_t { tm_block_id tm_response; /**< Timer waiting for next message */ c_uint8_t response_rcount; - tm_block_id tm_duplicated; /**< Timer waiting for duplicated message */ - c_uint8_t duplicated_rcount; + tm_block_id tm_holding; /**< Timer waiting for holding message */ + c_uint8_t holding_rcount; struct _gtp_xact_t *assoc_xact; /**< Associated transaction */ @@ -57,7 +57,7 @@ typedef struct _gtp_xact_t { } gtp_xact_t; CORE_DECLARE(status_t) gtp_xact_init(tm_service_t *tm_service, - c_uintptr_t response_event, c_uintptr_t duplicated_event); + c_uintptr_t response_event, c_uintptr_t holding_event); CORE_DECLARE(status_t) gtp_xact_final(void); CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create( diff --git a/src/mme/mme_event.c b/src/mme/mme_event.c index abc68ddbbf..d5d83c6a15 100644 --- a/src/mme/mme_event.c +++ b/src/mme/mme_event.c @@ -35,8 +35,8 @@ char* mme_event_get_name(event_t *e) return "MME_EVT_S11_MESSAGE"; case MME_EVT_S11_T3_RESPONSE: return "MME_EVT_S11_T3_RESPONSE"; - case MME_EVT_S11_T3_DUPLICATED: - return "MME_EVT_S11_T3_DUPLICATED"; + case MME_EVT_S11_T3_HOLDING: + return "MME_EVT_S11_T3_HOLDING"; case MME_EVT_S6A_MESSAGE: return "MME_EVT_S6A_MESSAGE"; diff --git a/src/mme/mme_event.h b/src/mme/mme_event.h index 88b452f7a0..59617e4d8f 100644 --- a/src/mme/mme_event.h +++ b/src/mme/mme_event.h @@ -24,7 +24,7 @@ typedef enum { MME_EVT_S11_MESSAGE, MME_EVT_S11_T3_RESPONSE, - MME_EVT_S11_T3_DUPLICATED, + MME_EVT_S11_T3_HOLDING, MME_EVT_S6A_MESSAGE, diff --git a/src/mme/mme_init.c b/src/mme/mme_init.c index cf7bb25fd6..2827177f8f 100644 --- a/src/mme/mme_init.c +++ b/src/mme/mme_init.c @@ -70,7 +70,7 @@ static void *THREAD_FUNC sm_main(thread_id id, void *data) "MME event queue creation failed"); tm_service_init(&mme_self()->tm_service); gtp_xact_init(&mme_self()->tm_service, - MME_EVT_S11_T3_RESPONSE, MME_EVT_S11_T3_DUPLICATED); + MME_EVT_S11_T3_RESPONSE, MME_EVT_S11_T3_HOLDING); fsm_create(&mme_sm, mme_state_initial, mme_state_final); fsm_init(&mme_sm, 0); diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index a2779dbb1e..0bd644cac5 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -415,7 +415,7 @@ void mme_state_operational(fsm_t *s, event_t *e) break; } case MME_EVT_S11_T3_RESPONSE: - case MME_EVT_S11_T3_DUPLICATED: + case MME_EVT_S11_T3_HOLDING: { gtp_xact_timeout(event_get_param1(e), event_get(e)); break; diff --git a/src/pgw/pgw_event.c b/src/pgw/pgw_event.c index 9119e0dfe3..42806ec754 100644 --- a/src/pgw/pgw_event.c +++ b/src/pgw/pgw_event.c @@ -19,8 +19,8 @@ char* pgw_event_get_name(event_t *e) return "PGW_EVT_S5C_MESSAGE"; case PGW_EVT_S5C_T3_RESPONSE: return "PGW_EVT_S5C_T3_RESPONSE"; - case PGW_EVT_S5C_T3_DUPLICATED: - return "PGW_EVT_S5C_T3_DUPLICATED"; + case PGW_EVT_S5C_T3_HOLDING: + return "PGW_EVT_S5C_T3_HOLDING"; case PGW_EVT_GX_MESSAGE: return "PGW_EVT_GX_SESSION_MSG"; diff --git a/src/pgw/pgw_event.h b/src/pgw/pgw_event.h index f355ccf3b7..d1403b9e35 100644 --- a/src/pgw/pgw_event.h +++ b/src/pgw/pgw_event.h @@ -13,7 +13,7 @@ typedef enum { PGW_EVT_S5C_MESSAGE, PGW_EVT_S5C_T3_RESPONSE, - PGW_EVT_S5C_T3_DUPLICATED, + PGW_EVT_S5C_T3_HOLDING, PGW_EVT_GX_MESSAGE, diff --git a/src/pgw/pgw_init.c b/src/pgw/pgw_init.c index e32dc46182..338b419251 100644 --- a/src/pgw/pgw_init.c +++ b/src/pgw/pgw_init.c @@ -74,7 +74,7 @@ static void *THREAD_FUNC sm_main(thread_id id, void *data) "PGW event queue creation failed"); tm_service_init(&pgw_self()->tm_service); gtp_xact_init(&pgw_self()->tm_service, - PGW_EVT_S5C_T3_RESPONSE, PGW_EVT_S5C_T3_DUPLICATED); + PGW_EVT_S5C_T3_RESPONSE, PGW_EVT_S5C_T3_HOLDING); fsm_create(&pgw_sm, pgw_state_initial, pgw_state_final); fsm_init(&pgw_sm, 0); diff --git a/src/pgw/pgw_sm.c b/src/pgw/pgw_sm.c index 7bc8806edf..26183cc6e9 100644 --- a/src/pgw/pgw_sm.c +++ b/src/pgw/pgw_sm.c @@ -114,7 +114,7 @@ void pgw_state_operational(fsm_t *s, event_t *e) break; } case PGW_EVT_S5C_T3_RESPONSE: - case PGW_EVT_S5C_T3_DUPLICATED: + case PGW_EVT_S5C_T3_HOLDING: { gtp_xact_timeout(event_get_param1(e), event_get(e)); break; diff --git a/src/sgw/sgw_event.c b/src/sgw/sgw_event.c index 005e27bfe9..e441d93e87 100644 --- a/src/sgw/sgw_event.c +++ b/src/sgw/sgw_event.c @@ -22,8 +22,8 @@ char* sgw_event_get_name(event_t *e) case SGW_EVT_T3_RESPONSE: return "SGW_EVT_T3_RESPONSE"; - case SGW_EVT_T3_DUPLICATED: - return "SGW_EVT_T3_DUPLICATED"; + case SGW_EVT_T3_HOLDING: + return "SGW_EVT_T3_HOLDING"; default: break; diff --git a/src/sgw/sgw_event.h b/src/sgw/sgw_event.h index f8cc8a1319..42a0fa7ca0 100644 --- a/src/sgw/sgw_event.h +++ b/src/sgw/sgw_event.h @@ -15,7 +15,7 @@ typedef enum { SGW_EVT_S5C_MESSAGE, SGW_EVT_T3_RESPONSE, - SGW_EVT_T3_DUPLICATED, + SGW_EVT_T3_HOLDING, SGW_EVT_LO_DLDATA_NOTI, diff --git a/src/sgw/sgw_init.c b/src/sgw/sgw_init.c index a2c0b5e09d..a2e955b15f 100644 --- a/src/sgw/sgw_init.c +++ b/src/sgw/sgw_init.c @@ -63,7 +63,7 @@ static void *THREAD_FUNC sm_main(thread_id id, void *data) "SGW event queue creation failed"); tm_service_init(&sgw_self()->tm_service); gtp_xact_init(&sgw_self()->tm_service, - SGW_EVT_T3_RESPONSE, SGW_EVT_T3_DUPLICATED); + SGW_EVT_T3_RESPONSE, SGW_EVT_T3_HOLDING); fsm_create(&sgw_sm, sgw_state_initial, sgw_state_final); fsm_init(&sgw_sm, 0); diff --git a/src/sgw/sgw_s11_handler.c b/src/sgw/sgw_s11_handler.c index 4f8cc6ac3f..bfca0804c1 100644 --- a/src/sgw/sgw_s11_handler.c +++ b/src/sgw/sgw_s11_handler.c @@ -10,7 +10,7 @@ #include "sgw_gtp_path.h" #include "sgw_s11_handler.h" -void sgw_handle_create_session_request(gtp_xact_t *s11_xact, +void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_message_t *gtp_message) { status_t rv; @@ -137,7 +137,7 @@ void sgw_handle_create_session_request(gtp_xact_t *s11_xact, "SGW[%d] --> PGW\n", sess->sgw_s5c_teid); } -CORE_DECLARE(void) sgw_handle_modify_bearer_request(gtp_xact_t *s11_xact, +CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_modify_bearer_request_t *req) { status_t rv; @@ -204,7 +204,7 @@ CORE_DECLARE(void) sgw_handle_modify_bearer_request(gtp_xact_t *s11_xact, "MME[%d] --> SGW[%d]\n", sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid); } -void sgw_handle_delete_session_request(gtp_xact_t *s11_xact, +void sgw_s11_handle_delete_session_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_message_t *gtp_message) { status_t rv; @@ -247,7 +247,7 @@ void sgw_handle_delete_session_request(gtp_xact_t *s11_xact, "SGW[%d] --> PGW[%d]\n", sess->sgw_s5c_teid, sess->pgw_s5c_teid); } -void sgw_handle_release_access_bearers_request(gtp_xact_t *s11_xact, +void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_release_access_bearers_request_t *req) { status_t rv; @@ -309,7 +309,7 @@ void sgw_handle_release_access_bearers_request(gtp_xact_t *s11_xact, "MME[%d] --> SGW[%d]\n", sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid); } -void sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer) +void sgw_s11_handle_lo_dldata_notification(sgw_bearer_t *bearer) { status_t rv; gtp_downlink_data_notification_t *noti = NULL; @@ -356,7 +356,7 @@ void sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer) "SGW[%d] --> MME[%d]\n", sgw_ue->sgw_s11_teid, sgw_ue->mme_s11_teid); } -void sgw_handle_downlink_data_notification_ack(sgw_ue_t *sgw_ue, +void sgw_s11_handle_downlink_data_notification_ack(sgw_ue_t *sgw_ue, gtp_downlink_data_notification_acknowledge_t *ack) { d_trace(3, "[GTP] Downlink Data Notification Ack: " diff --git a/src/sgw/sgw_s11_handler.h b/src/sgw/sgw_s11_handler.h index 3e94c4d8d2..6dfebbbdb2 100644 --- a/src/sgw/sgw_s11_handler.h +++ b/src/sgw/sgw_s11_handler.h @@ -9,23 +9,23 @@ extern "C" { #endif /* __cplusplus */ -CORE_DECLARE(void) sgw_handle_create_session_request(gtp_xact_t *s11_xact, +CORE_DECLARE(void) sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_message_t *gtp_message); -CORE_DECLARE(void) sgw_handle_modify_bearer_request(gtp_xact_t *s11_xact, +CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_modify_bearer_request_t *req); -CORE_DECLARE(void) sgw_handle_delete_session_request(gtp_xact_t *s11_xact, +CORE_DECLARE(void) sgw_s11_handle_delete_session_request(gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_message_t *gtp_message); -CORE_DECLARE(void) sgw_handle_release_access_bearers_request( +CORE_DECLARE(void) sgw_s11_handle_release_access_bearers_request( gtp_xact_t *s11_xact, sgw_ue_t *sgw_ue, gtp_release_access_bearers_request_t *req); -CORE_DECLARE(void) sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer); +CORE_DECLARE(void) sgw_s11_handle_lo_dldata_notification(sgw_bearer_t *bearer); -CORE_DECLARE(void) sgw_handle_downlink_data_notification_ack(sgw_ue_t *sgw_ue, - gtp_downlink_data_notification_acknowledge_t *ack); +CORE_DECLARE(void) sgw_s11_handle_downlink_data_notification_ack( + sgw_ue_t *sgw_ue, gtp_downlink_data_notification_acknowledge_t *ack); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/sgw/sgw_s5c_handler.c b/src/sgw/sgw_s5c_handler.c index e920ac4b0c..d0b018546d 100644 --- a/src/sgw/sgw_s5c_handler.c +++ b/src/sgw/sgw_s5c_handler.c @@ -10,7 +10,7 @@ #include "sgw_gtp_path.h" #include "sgw_s5c_handler.h" -void sgw_handle_create_session_response(gtp_xact_t *s5c_xact, +void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact, sgw_sess_t *sess, gtp_message_t *gtp_message) { status_t rv; @@ -114,7 +114,7 @@ void sgw_handle_create_session_response(gtp_xact_t *s5c_xact, "SGW[%d] <-- PGW[%d]\n", sess->sgw_s5c_teid, sess->pgw_s5c_teid); } -void sgw_handle_delete_session_response(gtp_xact_t *s5c_xact, +void sgw_s5c_handle_delete_session_response(gtp_xact_t *s5c_xact, sgw_sess_t *sess, gtp_message_t *gtp_message) { status_t rv; @@ -178,3 +178,83 @@ void sgw_handle_delete_session_response(gtp_xact_t *s5c_xact, rv = gtp_xact_commit(s11_xact); d_assert(rv == CORE_OK, return, "xact_commit error"); } + +void sgw_s5c_handle_create_bearer_request(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_bearer_request_t *req = NULL; + pkbuf_t *pkbuf = NULL; + sgw_ue_t *sgw_ue = NULL; + + gtp_f_teid_t *pgw_s5u_teid = NULL; + gtp_f_teid_t sgw_s1u_teid; + + d_assert(sess, return, "Null param"); + sgw_ue = sess->sgw_ue; + d_assert(sgw_ue, return, "Null param"); + d_assert(s5c_xact, return, "Null param"); + d_assert(gtp_message, return, "Null param"); + + req = >p_message->create_bearer_request; + + if (req->linked_eps_bearer_id.presence == 0) + { + d_error("No Linked EBI"); + return; + } + if (req->bearer_contexts.presence == 0) + { + d_error("No Bearer"); + return; + } + if (req->bearer_contexts.eps_bearer_id.presence == 0) + { + d_error("No EPS Bearer ID"); + return; + } + if (req->bearer_contexts.s5_s8_u_sgw_f_teid.presence == 0) + { + d_error("No GTP TEID"); + return; + } + + bearer = sgw_bearer_add(sess); + d_assert(bearer, return, "No Bearer Context"); + + /* Receive Data Plane(UL) : PGW-S5U */ + pgw_s5u_teid = req->bearer_contexts.s5_s8_u_sgw_f_teid.data; + bearer->pgw_s5u_teid = ntohl(pgw_s5u_teid->teid); + bearer->pgw_s5u_addr = pgw_s5u_teid->ipv4_addr; + req->bearer_contexts.s5_s8_u_sgw_f_teid.presence = 0; + + /* Send Data Plane(UL) : SGW-S1U */ + memset(&sgw_s1u_teid, 0, sizeof(gtp_f_teid_t)); + sgw_s1u_teid.ipv4 = 1; + sgw_s1u_teid.interface_type = GTP_F_TEID_S1_U_SGW_GTP_U; + sgw_s1u_teid.ipv4_addr = bearer->sgw_s1u_addr; + sgw_s1u_teid.teid = htonl(bearer->sgw_s1u_teid); + req->bearer_contexts.s1_u_enodeb_f_teid.presence = 1; + req->bearer_contexts.s1_u_enodeb_f_teid.data = &sgw_s1u_teid; + req->bearer_contexts.s1_u_enodeb_f_teid.len = GTP_F_TEID_IPV4_LEN; + + gtp_message->h.type = GTP_CREATE_BEARER_REQUEST_TYPE; + gtp_message->h.teid = sgw_ue->mme_s11_teid; + + rv = gtp_build_msg(&pkbuf, gtp_message); + d_assert(rv == CORE_OK, return, "gtp build failed"); + + s11_xact = gtp_xact_local_create(sess->mme, >p_message->h, pkbuf); + d_assert(s11_xact, return, "Null param"); + + gtp_xact_associate(s5c_xact, s11_xact); + + rv = gtp_xact_commit(s11_xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); + + d_trace(3, "[GTP] Create Bearer Request : SGW[%d] <-- PGW[%d]\n", + bearer->sgw_s1u_teid, bearer->pgw_s5u_teid); +} + diff --git a/src/sgw/sgw_s5c_handler.h b/src/sgw/sgw_s5c_handler.h index f082f87a8e..026faead28 100644 --- a/src/sgw/sgw_s5c_handler.h +++ b/src/sgw/sgw_s5c_handler.h @@ -9,10 +9,11 @@ extern "C" { #endif /* __cplusplus */ -CORE_DECLARE(void) sgw_handle_create_session_response(gtp_xact_t *s5c_xact, +CORE_DECLARE(void) sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact, sgw_sess_t *sess, gtp_message_t *gtp_message); - -CORE_DECLARE(void) sgw_handle_delete_session_response(gtp_xact_t *s5c_xact, +CORE_DECLARE(void) sgw_s5c_handle_delete_session_response(gtp_xact_t *s5c_xact, + sgw_sess_t *sess, gtp_message_t *gtp_message); +CORE_DECLARE(void) sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact, sgw_sess_t *sess, gtp_message_t *gtp_message); #ifdef __cplusplus diff --git a/src/sgw/sgw_sm.c b/src/sgw/sgw_sm.c index 3bd09f0295..a9851f99f6 100644 --- a/src/sgw/sgw_sm.c +++ b/src/sgw/sgw_sm.c @@ -78,21 +78,23 @@ void sgw_state_operational(fsm_t *s, event_t *e) switch(message.h.type) { case GTP_CREATE_SESSION_REQUEST_TYPE: - sgw_handle_create_session_request(xact, sgw_ue, &message); + sgw_s11_handle_create_session_request(xact, sgw_ue, + &message); break; case GTP_MODIFY_BEARER_REQUEST_TYPE: - sgw_handle_modify_bearer_request(xact, sgw_ue, + sgw_s11_handle_modify_bearer_request(xact, sgw_ue, &message.modify_bearer_request); break; case GTP_DELETE_SESSION_REQUEST_TYPE: - sgw_handle_delete_session_request(xact, sgw_ue, &message); + sgw_s11_handle_delete_session_request(xact, sgw_ue, + &message); break; case GTP_RELEASE_ACCESS_BEARERS_REQUEST_TYPE: - sgw_handle_release_access_bearers_request(xact, sgw_ue, + sgw_s11_handle_release_access_bearers_request(xact, sgw_ue, &message.release_access_bearers_request); break; case GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE: - sgw_handle_downlink_data_notification_ack(sgw_ue, + sgw_s11_handle_downlink_data_notification_ack(sgw_ue, &message.downlink_data_notification_acknowledge); break; default: @@ -124,10 +126,16 @@ void sgw_state_operational(fsm_t *s, event_t *e) switch(message.h.type) { case GTP_CREATE_SESSION_RESPONSE_TYPE: - sgw_handle_create_session_response(xact, sess, &message); + sgw_s5c_handle_create_session_response(xact, sess, + &message); break; case GTP_DELETE_SESSION_RESPONSE_TYPE: - sgw_handle_delete_session_response(xact, sess, &message); + sgw_s5c_handle_delete_session_response(xact, sess, + &message); + break; + case GTP_CREATE_BEARER_REQUEST_TYPE: + sgw_s5c_handle_create_bearer_request(xact, sess, + &message); break; default: d_warn("Not implmeneted(type:%d)", message.h.type); @@ -137,7 +145,7 @@ void sgw_state_operational(fsm_t *s, event_t *e) break; } case SGW_EVT_T3_RESPONSE: - case SGW_EVT_T3_DUPLICATED: + case SGW_EVT_T3_HOLDING: { gtp_xact_timeout(event_get_param1(e), event_get(e)); break; @@ -153,7 +161,7 @@ void sgw_state_operational(fsm_t *s, event_t *e) break; } - sgw_handle_lo_dldata_notification(bearer); + sgw_s11_handle_lo_dldata_notification(bearer); break; }