forked from acouzens/open5gs
continue..
This commit is contained in:
parent
8db2513234
commit
8af8d063d7
|
@ -11,11 +11,11 @@
|
||||||
#define GTP_MIN_XACT_ID 1
|
#define GTP_MIN_XACT_ID 1
|
||||||
#define GTP_MAX_XACT_ID 0x800000
|
#define GTP_MAX_XACT_ID 0x800000
|
||||||
|
|
||||||
#define GTP_XACT_LOCAL_DURATION 3000 /* 3 seconds */
|
#define GTP_T3_RESPONSE_DURATION 3000 /* 3 seconds */
|
||||||
#define GTP_XACT_LOCAL_RETRY_COUNT 3
|
#define GTP_T3_RESPONSE_RETRY_COUNT 3
|
||||||
#define GTP_XACT_REMOTE_DURATION \
|
#define GTP_T3_DUPLICATED_DURATION \
|
||||||
(GTP_XACT_LOCAL_DURATION * GTP_XACT_LOCAL_RETRY_COUNT) /* 9 seconds */
|
(GTP_T3_RESPONSE_DURATION * GTP_T3_RESPONSE_RETRY_COUNT) /* 9 seconds */
|
||||||
#define GTP_XACT_REMOTE_RETRY_COUNT 1
|
#define GTP_T3_DUPLICATED_RETRY_COUNT 1
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GTP_XACT_UNKNOWN_STAGE,
|
GTP_XACT_UNKNOWN_STAGE,
|
||||||
|
@ -26,6 +26,8 @@ typedef enum {
|
||||||
|
|
||||||
static int gtp_xact_initialized = 0;
|
static int gtp_xact_initialized = 0;
|
||||||
static tm_service_t *g_tm_service = NULL;
|
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_uint32_t g_xact_id = 0;
|
static c_uint32_t g_xact_id = 0;
|
||||||
|
|
||||||
index_declare(gtp_xact_pool, gtp_xact_t, SIZE_OF_GTP_XACT_POOL);
|
index_declare(gtp_xact_pool, gtp_xact_t, SIZE_OF_GTP_XACT_POOL);
|
||||||
|
@ -33,19 +35,18 @@ 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 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);
|
static status_t gtp_xact_delete(gtp_xact_t *xact);
|
||||||
|
|
||||||
status_t gtp_xact_init(gtp_xact_ctx_t *context,
|
status_t gtp_xact_init(tm_service_t *tm_service,
|
||||||
tm_service_t *tm_service, c_uintptr_t event)
|
c_uintptr_t response_event, c_uintptr_t duplicated_event)
|
||||||
{
|
{
|
||||||
d_assert(gtp_xact_initialized == 0, return CORE_ERROR,
|
d_assert(gtp_xact_initialized == 0, return CORE_ERROR,
|
||||||
"GTP Transaction already has been initialized");
|
"GTP Transaction already has been initialized");
|
||||||
|
|
||||||
index_init(>p_xact_pool, SIZE_OF_GTP_XACT_POOL);
|
index_init(>p_xact_pool, SIZE_OF_GTP_XACT_POOL);
|
||||||
|
|
||||||
memset(context, 0, sizeof(gtp_xact_ctx_t));
|
|
||||||
|
|
||||||
g_xact_id = 0;
|
g_xact_id = 0;
|
||||||
g_tm_service = tm_service;
|
g_tm_service = tm_service;
|
||||||
context->event = event;;
|
g_response_event = response_event;
|
||||||
|
g_duplicated_event = duplicated_event;
|
||||||
|
|
||||||
gtp_xact_initialized = 1;
|
gtp_xact_initialized = 1;
|
||||||
|
|
||||||
|
@ -88,6 +89,22 @@ gtp_xact_t *gtp_xact_local_create(net_sock_t *sock, gtp_node_t *gnode)
|
||||||
xact->sock = sock;
|
xact->sock = sock;
|
||||||
xact->gnode = gnode;
|
xact->gnode = gnode;
|
||||||
|
|
||||||
|
if (g_response_event)
|
||||||
|
{
|
||||||
|
xact->tm_response = event_timer(g_tm_service,
|
||||||
|
g_response_event, GTP_T3_RESPONSE_DURATION, xact->index);
|
||||||
|
d_assert(xact->tm_response, return NULL, "Timer allocation failed");
|
||||||
|
xact->response_rcount = GTP_T3_RESPONSE_RETRY_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_duplicated_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;
|
||||||
|
}
|
||||||
|
|
||||||
list_append(xact->org == GTP_LOCAL_ORIGINATOR ?
|
list_append(xact->org == GTP_LOCAL_ORIGINATOR ?
|
||||||
&xact->gnode->local_list : &xact->gnode->remote_list, xact);
|
&xact->gnode->local_list : &xact->gnode->remote_list, xact);
|
||||||
|
|
||||||
|
@ -100,7 +117,7 @@ gtp_xact_t *gtp_xact_local_create(net_sock_t *sock, gtp_node_t *gnode)
|
||||||
}
|
}
|
||||||
|
|
||||||
gtp_xact_t *gtp_xact_remote_create(
|
gtp_xact_t *gtp_xact_remote_create(
|
||||||
net_sock_t *sock, gtp_node_t *gnode, c_uint32_t sqn)
|
net_sock_t *sock, gtp_node_t *gnode, c_uint32_t sqn)
|
||||||
{
|
{
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
gtp_xact_t *xact = NULL;
|
gtp_xact_t *xact = NULL;
|
||||||
|
@ -116,18 +133,21 @@ gtp_xact_t *gtp_xact_remote_create(
|
||||||
xact->sock = sock;
|
xact->sock = sock;
|
||||||
xact->gnode = gnode;
|
xact->gnode = gnode;
|
||||||
|
|
||||||
#if 0
|
if (g_response_event)
|
||||||
if (event)
|
|
||||||
{
|
{
|
||||||
xact->tm_wait = event_timer(context->tm_service, event,
|
xact->tm_response = event_timer(g_tm_service,
|
||||||
GTP_XACT_REMOTE_DURATION, xact->index);
|
g_response_event, GTP_T3_RESPONSE_DURATION, xact->index);
|
||||||
d_assert(xact->tm_wait,
|
d_assert(xact->tm_response, return NULL, "Timer allocation failed");
|
||||||
index_free(>p_xact_pool, xact); return NULL,
|
xact->response_rcount = GTP_T3_RESPONSE_RETRY_COUNT;
|
||||||
"Timer allocation failed");
|
}
|
||||||
xact->retry_count = GTP_XACT_REMOTE_RETRY_COUNT;
|
|
||||||
tm_start(xact->tm_wait);
|
if (g_duplicated_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;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
list_append(xact->org == GTP_LOCAL_ORIGINATOR ?
|
list_append(xact->org == GTP_LOCAL_ORIGINATOR ?
|
||||||
&xact->gnode->local_list : &xact->gnode->remote_list, xact);
|
&xact->gnode->local_list : &xact->gnode->remote_list, xact);
|
||||||
|
@ -159,10 +179,10 @@ void gtp_xact_delete_all(gtp_node_t *gnode)
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t gtp_xact_update_tx(gtp_xact_t *xact,
|
status_t gtp_xact_update_tx(gtp_xact_t *xact,
|
||||||
c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf,
|
c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf)
|
||||||
c_uintptr_t event)
|
|
||||||
{
|
{
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
|
gtp_xact_stage_t stage;
|
||||||
gtp_header_t *h = NULL;
|
gtp_header_t *h = NULL;
|
||||||
|
|
||||||
d_assert(xact, return CORE_ERROR, "Null param");
|
d_assert(xact, return CORE_ERROR, "Null param");
|
||||||
|
@ -175,6 +195,68 @@ status_t gtp_xact_update_tx(gtp_xact_t *xact,
|
||||||
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
stage = gtp_xact_get_stage(type, xact->xid);
|
||||||
|
if (xact->org == GTP_LOCAL_ORIGINATOR)
|
||||||
|
{
|
||||||
|
switch(stage)
|
||||||
|
{
|
||||||
|
case GTP_XACT_INITIAL_STAGE:
|
||||||
|
d_assert(xact->step == 0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
break;
|
||||||
|
case GTP_XACT_INTERMEDIATE_STAGE:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
case GTP_XACT_FINAL_STAGE:
|
||||||
|
d_assert(xact->step == 2, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (xact->org == GTP_REMOTE_ORIGINATOR)
|
||||||
|
{
|
||||||
|
switch(stage)
|
||||||
|
{
|
||||||
|
case GTP_XACT_INITIAL_STAGE:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
case GTP_XACT_INTERMEDIATE_STAGE:
|
||||||
|
case GTP_XACT_FINAL_STAGE:
|
||||||
|
d_assert(xact->step == 1, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d_assert(0, return CORE_ERROR, "invalid orginator(%d)", xact->org);
|
||||||
|
|
||||||
|
|
||||||
pkbuf_header(pkbuf, GTPV2C_HEADER_LEN);
|
pkbuf_header(pkbuf, GTPV2C_HEADER_LEN);
|
||||||
h = pkbuf->payload;
|
h = pkbuf->payload;
|
||||||
d_assert(h, return CORE_ERROR, "Null param");
|
d_assert(h, return CORE_ERROR, "Null param");
|
||||||
|
@ -187,54 +269,183 @@ status_t gtp_xact_update_tx(gtp_xact_t *xact,
|
||||||
h->teid = htonl(teid);
|
h->teid = htonl(teid);
|
||||||
h->sqn = GTP_XID_TO_SQN(xact->xid);
|
h->sqn = GTP_XID_TO_SQN(xact->xid);
|
||||||
|
|
||||||
xact->type = h->type;
|
/* Save Message type and packet of this step */
|
||||||
xact->pkbuf = pkbuf;
|
xact->seq[xact->step].type = h->type;
|
||||||
|
xact->seq[xact->step].pkbuf = pkbuf;
|
||||||
|
|
||||||
if (event)
|
/* Step */
|
||||||
{
|
xact->step++;
|
||||||
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;
|
return CORE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t gtp_xact_update_rx(gtp_xact_t *xact,
|
status_t gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type)
|
||||||
c_uint8_t type, c_uintptr_t event)
|
|
||||||
{
|
{
|
||||||
status_t rv;
|
status_t rv = CORE_OK;
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
|
gtp_xact_stage_t stage;
|
||||||
|
|
||||||
d_trace(3, "[%d] %s UPD-Rx peer %s:%d\n",
|
d_trace(3, "[%d] %s UPD-RX peer %s:%d\n",
|
||||||
xact->xid,
|
xact->xid,
|
||||||
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
if (xact->org == GTP_REMOTE_ORIGINATOR)
|
stage = gtp_xact_get_stage(type, xact->xid);
|
||||||
|
if (xact->org == GTP_LOCAL_ORIGINATOR)
|
||||||
{
|
{
|
||||||
if (xact->pkbuf)
|
switch(stage)
|
||||||
{
|
{
|
||||||
d_warn("[%d]%s Request Duplicated. Retransmit!",
|
case GTP_XACT_INITIAL_STAGE:
|
||||||
xact->gnode->port,
|
d_assert(0, return CORE_ERROR,
|
||||||
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE");
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
rv = gtp_send(xact->sock, xact->gnode, xact->pkbuf);
|
xact->xid,
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_send error");
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
return CORE_EAGAIN;
|
case GTP_XACT_INTERMEDIATE_STAGE:
|
||||||
}
|
if (xact->seq[1].type == type)
|
||||||
else if (xact->assoc_xact)
|
{
|
||||||
{
|
pkbuf_t *pkbuf = NULL;
|
||||||
d_warn("[%d]%s Request Duplicated. Discard Associated transaction!",
|
|
||||||
xact->gnode->port,
|
|
||||||
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE");
|
|
||||||
|
|
||||||
return CORE_EAGAIN;
|
d_assert(xact->step == 3, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
pkbuf = xact->seq[2].pkbuf;
|
||||||
|
if (pkbuf)
|
||||||
|
{
|
||||||
|
if (xact->tm_duplicated)
|
||||||
|
tm_start(xact->tm_duplicated);
|
||||||
|
|
||||||
|
d_warn("[%d]%s Request Duplicated. Retransmit!",
|
||||||
|
xact->gnode->port,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ?
|
||||||
|
"LOCAL " : "REMOTE");
|
||||||
|
rv = gtp_send(xact->sock, 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,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ?
|
||||||
|
"LOCAL " : "REMOTE");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CORE_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_assert(xact->step == 1, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
if (xact->tm_duplicated)
|
||||||
|
tm_start(xact->tm_duplicated);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTP_XACT_FINAL_STAGE:
|
||||||
|
d_assert(xact->step == 1, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
/* continue */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (xact->org == GTP_REMOTE_ORIGINATOR)
|
||||||
|
{
|
||||||
|
switch(stage)
|
||||||
|
{
|
||||||
|
case GTP_XACT_INITIAL_STAGE:
|
||||||
|
if (xact->seq[0].type == type)
|
||||||
|
{
|
||||||
|
pkbuf_t *pkbuf = NULL;
|
||||||
|
|
||||||
xact->type = type;
|
d_assert(xact->step == 2, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
pkbuf = xact->seq[1].pkbuf;
|
||||||
|
if (pkbuf)
|
||||||
|
{
|
||||||
|
if (xact->tm_duplicated)
|
||||||
|
tm_start(xact->tm_duplicated);
|
||||||
|
|
||||||
|
d_warn("[%d]%s Request Duplicated. Retransmit!",
|
||||||
|
xact->gnode->port,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ?
|
||||||
|
"LOCAL " : "REMOTE");
|
||||||
|
rv = gtp_send(xact->sock, 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,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ?
|
||||||
|
"LOCAL " : "REMOTE");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CORE_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_assert(xact->step == 0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
if (xact->tm_duplicated)
|
||||||
|
tm_start(xact->tm_duplicated);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTP_XACT_INTERMEDIATE_STAGE:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
case GTP_XACT_FINAL_STAGE:
|
||||||
|
d_assert(xact->step == 2, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n", xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
|
/* continue */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
d_assert(0, return CORE_ERROR,
|
||||||
|
"[%d] %s invalid stage peer %s:%d\n",
|
||||||
|
xact->xid,
|
||||||
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d_assert(0, return CORE_ERROR, "invalid orginator(%d)", xact->org);
|
||||||
|
|
||||||
|
/* Save Message type of this step */
|
||||||
|
xact->seq[xact->step].type = type;
|
||||||
|
|
||||||
|
/* Step */
|
||||||
|
xact->step++;
|
||||||
|
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
}
|
}
|
||||||
|
@ -243,11 +454,12 @@ status_t gtp_xact_update_rx(gtp_xact_t *xact,
|
||||||
status_t gtp_xact_commit(gtp_xact_t *xact)
|
status_t gtp_xact_commit(gtp_xact_t *xact)
|
||||||
{
|
{
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
|
pkbuf_t *pkbuf = NULL;
|
||||||
|
c_uint8_t type;
|
||||||
|
|
||||||
d_assert(xact, return CORE_ERROR, "Null param");
|
d_assert(xact, return CORE_ERROR, "Null param");
|
||||||
d_assert(xact->sock, 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->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",
|
d_trace(3, "[%d] %s Commit peer %s:%d\n",
|
||||||
xact->xid,
|
xact->xid,
|
||||||
|
@ -256,7 +468,8 @@ status_t gtp_xact_commit(gtp_xact_t *xact)
|
||||||
|
|
||||||
if (xact->org == GTP_LOCAL_ORIGINATOR)
|
if (xact->org == GTP_LOCAL_ORIGINATOR)
|
||||||
{
|
{
|
||||||
gtp_xact_stage_t stage = gtp_xact_get_stage(xact->type, xact->xid);
|
type = xact->seq[xact->step-1].type;
|
||||||
|
gtp_xact_stage_t stage = gtp_xact_get_stage(type, xact->xid);
|
||||||
if (stage == GTP_XACT_FINAL_STAGE)
|
if (stage == GTP_XACT_FINAL_STAGE)
|
||||||
{
|
{
|
||||||
gtp_xact_delete(xact);
|
gtp_xact_delete(xact);
|
||||||
|
@ -264,13 +477,16 @@ status_t gtp_xact_commit(gtp_xact_t *xact)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d_assert(gtp_send(xact->sock, xact->gnode, xact->pkbuf) == CORE_OK,
|
pkbuf = xact->seq[xact->step-1].pkbuf;
|
||||||
|
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
|
d_assert(gtp_send(xact->sock, xact->gnode, pkbuf) == CORE_OK,
|
||||||
return CORE_ERROR, "gtp_send error");
|
return CORE_ERROR, "gtp_send error");
|
||||||
|
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t gtp_xact_timeout(index_t index)
|
status_t gtp_xact_timeout(index_t index, c_uintptr_t event)
|
||||||
{
|
{
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
gtp_xact_t *xact = NULL;
|
gtp_xact_t *xact = NULL;
|
||||||
|
@ -286,14 +502,19 @@ status_t gtp_xact_timeout(index_t index)
|
||||||
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
if (xact->org == GTP_LOCAL_ORIGINATOR)
|
if (event == g_response_event)
|
||||||
{
|
{
|
||||||
if (--xact->retry_count > 0)
|
if (--xact->response_rcount > 0)
|
||||||
{
|
{
|
||||||
tm_start(xact->tm_wait);
|
pkbuf_t *pkbuf = NULL;
|
||||||
|
|
||||||
d_assert(xact->pkbuf, goto out, "Null param");
|
if (xact->tm_response)
|
||||||
d_assert(gtp_send(xact->sock, xact->gnode, xact->pkbuf) == CORE_OK,
|
tm_start(xact->tm_response);
|
||||||
|
|
||||||
|
pkbuf = xact->seq[xact->step-1].pkbuf;
|
||||||
|
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
|
d_assert(gtp_send(xact->sock, xact->gnode, pkbuf) == CORE_OK,
|
||||||
goto out, "gtp_send error");
|
goto out, "gtp_send error");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -304,9 +525,17 @@ status_t gtp_xact_timeout(index_t index)
|
||||||
gtp_xact_delete(xact);
|
gtp_xact_delete(xact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (event == g_duplicated_event)
|
||||||
{
|
{
|
||||||
gtp_xact_delete(xact);
|
if (--xact->duplicated_rcount > 0)
|
||||||
|
{
|
||||||
|
if (xact->tm_duplicated)
|
||||||
|
tm_start(xact->tm_duplicated);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtp_xact_delete(xact);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CORE_OK;
|
return CORE_OK;
|
||||||
|
@ -344,7 +573,7 @@ status_t gtp_xact_receive(
|
||||||
new->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
new->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
INET_NTOP(&gnode->addr, buf), gnode->port);
|
INET_NTOP(&gnode->addr, buf), gnode->port);
|
||||||
|
|
||||||
rv = gtp_xact_update_rx(new, h->type, 0);
|
rv = gtp_xact_update_rx(new, h->type);
|
||||||
if (rv != CORE_OK)
|
if (rv != CORE_OK)
|
||||||
{
|
{
|
||||||
pkbuf_free(pkbuf);
|
pkbuf_free(pkbuf);
|
||||||
|
@ -490,18 +719,23 @@ static status_t gtp_xact_delete(gtp_xact_t *xact)
|
||||||
|
|
||||||
d_assert(xact, , "Null param");
|
d_assert(xact, , "Null param");
|
||||||
d_assert(xact->gnode, , "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",
|
d_trace(3, "[%d] %s Delete peer %s:%d\n",
|
||||||
xact->xid,
|
xact->xid,
|
||||||
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
xact->org == GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
|
||||||
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
INET_NTOP(&xact->gnode->addr, buf), xact->gnode->port);
|
||||||
|
|
||||||
if (xact->pkbuf)
|
if (xact->seq[0].pkbuf)
|
||||||
pkbuf_free(xact->pkbuf);
|
pkbuf_free(xact->seq[0].pkbuf);
|
||||||
|
if (xact->seq[1].pkbuf)
|
||||||
|
pkbuf_free(xact->seq[1].pkbuf);
|
||||||
|
if (xact->seq[2].pkbuf)
|
||||||
|
pkbuf_free(xact->seq[2].pkbuf);
|
||||||
|
|
||||||
if (xact->tm_wait)
|
if (xact->tm_response)
|
||||||
tm_delete(xact->tm_wait);
|
tm_delete(xact->tm_response);
|
||||||
|
if (xact->tm_duplicated)
|
||||||
|
tm_delete(xact->tm_duplicated);
|
||||||
|
|
||||||
if (xact->assoc_xact)
|
if (xact->assoc_xact)
|
||||||
gtp_xact_deassociate(xact, xact->assoc_xact);
|
gtp_xact_deassociate(xact, xact->assoc_xact);
|
||||||
|
|
|
@ -14,16 +14,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/**
|
|
||||||
* Transaction Configuration
|
|
||||||
*/
|
|
||||||
typedef struct _gtp_xact_ctx_t {
|
|
||||||
c_uint32_t g_xact_id;
|
|
||||||
|
|
||||||
tm_service_t *tm_service;
|
|
||||||
c_uintptr_t event;
|
|
||||||
} gtp_xact_ctx_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction context
|
* Transaction context
|
||||||
*/
|
*/
|
||||||
|
@ -41,17 +31,25 @@ typedef struct _gtp_xact_t {
|
||||||
net_sock_t *sock; /**< GTP Socket */
|
net_sock_t *sock; /**< GTP Socket */
|
||||||
gtp_node_t *gnode; /**< Relevant GTP node context */
|
gtp_node_t *gnode; /**< Relevant GTP node context */
|
||||||
|
|
||||||
c_uint8_t type; /**< Save transmitted GTP message type */
|
int step; /**< Current step in the sequence.
|
||||||
pkbuf_t *pkbuf; /**< Save transmiited packet */
|
1 : Initial
|
||||||
|
2 : Triggered
|
||||||
|
3 : Triggered-Reply */
|
||||||
|
struct {
|
||||||
|
c_uint8_t type; /**< Message type history */
|
||||||
|
pkbuf_t *pkbuf; /**< Packet history */
|
||||||
|
} seq[3]; /**< history for the each step */
|
||||||
|
|
||||||
tm_block_id tm_wait; /**< Timer waiting for next message */
|
tm_block_id tm_response; /**< Timer waiting for next message */
|
||||||
c_uint8_t retry_count; /**< Retry count waiting for next message */
|
c_uint8_t response_rcount;
|
||||||
|
tm_block_id tm_duplicated; /**< Timer waiting for duplicated message */
|
||||||
|
c_uint8_t duplicated_rcount;
|
||||||
|
|
||||||
struct _gtp_xact_t *assoc_xact; /**< Associated transaction */
|
struct _gtp_xact_t *assoc_xact; /**< Associated transaction */
|
||||||
} gtp_xact_t;
|
} gtp_xact_t;
|
||||||
|
|
||||||
CORE_DECLARE(status_t) gtp_xact_init(gtp_xact_ctx_t *context,
|
CORE_DECLARE(status_t) gtp_xact_init(tm_service_t *tm_service,
|
||||||
tm_service_t *tm_service, c_uintptr_t event);
|
c_uintptr_t response_event, c_uintptr_t duplicated_event);
|
||||||
CORE_DECLARE(status_t) gtp_xact_final(void);
|
CORE_DECLARE(status_t) gtp_xact_final(void);
|
||||||
|
|
||||||
CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create(
|
CORE_DECLARE(gtp_xact_t *) gtp_xact_local_create(
|
||||||
|
@ -61,12 +59,11 @@ CORE_DECLARE(gtp_xact_t *) gtp_xact_remote_create(
|
||||||
CORE_DECLARE(void) gtp_xact_delete_all(gtp_node_t *gnode);
|
CORE_DECLARE(void) gtp_xact_delete_all(gtp_node_t *gnode);
|
||||||
|
|
||||||
CORE_DECLARE(status_t) gtp_xact_update_tx(gtp_xact_t *xact,
|
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);
|
c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf);
|
||||||
CORE_DECLARE(status_t) gtp_xact_update_rx(gtp_xact_t *xact,
|
CORE_DECLARE(status_t) gtp_xact_update_rx(gtp_xact_t *xact, c_uint8_t type);
|
||||||
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_commit(gtp_xact_t *xact);
|
||||||
CORE_DECLARE(status_t) gtp_xact_timeout(index_t index);
|
CORE_DECLARE(status_t) gtp_xact_timeout(index_t index, c_uintptr_t event);
|
||||||
|
|
||||||
CORE_DECLARE(status_t) gtp_xact_receive(
|
CORE_DECLARE(status_t) gtp_xact_receive(
|
||||||
net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf,
|
net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf,
|
||||||
|
|
|
@ -59,7 +59,6 @@ typedef struct _mme_context_t {
|
||||||
|
|
||||||
msgq_id queue_id; /* Queue for processing MME control plane */
|
msgq_id queue_id; /* Queue for processing MME control plane */
|
||||||
tm_service_t tm_service; /* Timer Service */
|
tm_service_t tm_service; /* Timer Service */
|
||||||
gtp_xact_ctx_t gtp_xact_ctx; /* GTP Transaction Context for MME */
|
|
||||||
|
|
||||||
/* Generator for unique identification */
|
/* Generator for unique identification */
|
||||||
c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */
|
c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */
|
||||||
|
|
|
@ -33,8 +33,10 @@ char* mme_event_get_name(event_t *e)
|
||||||
|
|
||||||
case MME_EVT_S11_MESSAGE:
|
case MME_EVT_S11_MESSAGE:
|
||||||
return "MME_EVT_S11_MESSAGE";
|
return "MME_EVT_S11_MESSAGE";
|
||||||
case MME_EVT_S11_T3:
|
case MME_EVT_S11_T3_RESPONSE:
|
||||||
return "MME_EVT_S11_T3";
|
return "MME_EVT_S11_T3_RESPONSE";
|
||||||
|
case MME_EVT_S11_T3_DUPLICATED:
|
||||||
|
return "MME_EVT_S11_T3_DUPLICATED";
|
||||||
|
|
||||||
case MME_EVT_S6A_MESSAGE:
|
case MME_EVT_S6A_MESSAGE:
|
||||||
return "MME_EVT_S6A_MESSAGE";
|
return "MME_EVT_S6A_MESSAGE";
|
||||||
|
|
|
@ -22,7 +22,8 @@ typedef enum {
|
||||||
MME_EVT_ESM_MESSAGE,
|
MME_EVT_ESM_MESSAGE,
|
||||||
|
|
||||||
MME_EVT_S11_MESSAGE,
|
MME_EVT_S11_MESSAGE,
|
||||||
MME_EVT_S11_T3,
|
MME_EVT_S11_T3_RESPONSE,
|
||||||
|
MME_EVT_S11_T3_DUPLICATED,
|
||||||
|
|
||||||
MME_EVT_S6A_MESSAGE,
|
MME_EVT_S6A_MESSAGE,
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ status_t mme_s11_send_to_sgw(mme_sess_t *sess, c_uint8_t type, pkbuf_t *pkbuf)
|
||||||
xact = gtp_xact_local_create(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(xact, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
rv = gtp_xact_update_tx(xact, type, teid, pkbuf, MME_EVT_S11_T3);
|
rv = gtp_xact_update_tx(xact, type, teid, pkbuf);
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_update_tx error");
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_update_tx error");
|
||||||
|
|
||||||
rv = gtp_xact_commit(xact);
|
rv = gtp_xact_commit(xact);
|
||||||
|
|
|
@ -69,8 +69,8 @@ static void *THREAD_FUNC sm_main(thread_id id, void *data)
|
||||||
d_assert(mme_self()->queue_id, return NULL,
|
d_assert(mme_self()->queue_id, return NULL,
|
||||||
"MME event queue creation failed");
|
"MME event queue creation failed");
|
||||||
tm_service_init(&mme_self()->tm_service);
|
tm_service_init(&mme_self()->tm_service);
|
||||||
gtp_xact_init(&mme_self()->gtp_xact_ctx,
|
gtp_xact_init(&mme_self()->tm_service,
|
||||||
&mme_self()->tm_service, MME_EVT_S11_T3);
|
MME_EVT_S11_T3_RESPONSE, MME_EVT_S11_T3_DUPLICATED);
|
||||||
|
|
||||||
fsm_create(&mme_sm, mme_state_initial, mme_state_final);
|
fsm_create(&mme_sm, mme_state_initial, mme_state_final);
|
||||||
fsm_init(&mme_sm, 0);
|
fsm_init(&mme_sm, 0);
|
||||||
|
|
|
@ -198,7 +198,7 @@ void mme_s11_handle_downlink_data_notification(
|
||||||
|
|
||||||
rv = gtp_xact_update_tx(xact,
|
rv = gtp_xact_update_tx(xact,
|
||||||
GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
|
GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
|
||||||
sess->sgw_s11_teid, s11buf, 0);
|
sess->sgw_s11_teid, s11buf);
|
||||||
d_assert(rv == CORE_OK, return, "xact_update_tx error");
|
d_assert(rv == CORE_OK, return, "xact_update_tx error");
|
||||||
|
|
||||||
rv = gtp_xact_commit(xact);
|
rv = gtp_xact_commit(xact);
|
||||||
|
|
|
@ -376,9 +376,10 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
||||||
pkbuf_free(pkbuf);
|
pkbuf_free(pkbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MME_EVT_S11_T3:
|
case MME_EVT_S11_T3_RESPONSE:
|
||||||
|
case MME_EVT_S11_T3_DUPLICATED:
|
||||||
{
|
{
|
||||||
gtp_xact_timeout(event_get_param1(e));
|
gtp_xact_timeout(event_get_param1(e), event_get(e));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MME_EVT_S6A_MESSAGE:
|
case MME_EVT_S6A_MESSAGE:
|
||||||
|
|
|
@ -33,7 +33,6 @@ typedef struct _pgw_context_t {
|
||||||
|
|
||||||
msgq_id queue_id; /* Qsesssess for processing PGW control plane */
|
msgq_id queue_id; /* Qsesssess for processing PGW control plane */
|
||||||
tm_service_t tm_service; /* Timer Service */
|
tm_service_t tm_service; /* Timer Service */
|
||||||
gtp_xact_ctx_t gtp_xact_ctx; /* GTP Transaction Context */
|
|
||||||
|
|
||||||
char *tun_dev_name; /* PGW Tunnel device name */
|
char *tun_dev_name; /* PGW Tunnel device name */
|
||||||
net_link_t* tun_link; /* PGW Tun Interace for U-plane */
|
net_link_t* tun_link; /* PGW Tun Interace for U-plane */
|
||||||
|
|
|
@ -17,8 +17,10 @@ char* pgw_event_get_name(event_t *e)
|
||||||
|
|
||||||
case PGW_EVT_S5C_MESSAGE:
|
case PGW_EVT_S5C_MESSAGE:
|
||||||
return "PGW_EVT_S5C_MESSAGE";
|
return "PGW_EVT_S5C_MESSAGE";
|
||||||
case PGW_EVT_S5C_T3:
|
case PGW_EVT_S5C_T3_RESPONSE:
|
||||||
return "PGW_EVT_S5C_T3";
|
return "PGW_EVT_S5C_T3_RESPONSE";
|
||||||
|
case PGW_EVT_S5C_T3_DUPLICATED:
|
||||||
|
return "PGW_EVT_S5C_T3_DUPLICATED";
|
||||||
|
|
||||||
case PGW_EVT_GX_MESSAGE:
|
case PGW_EVT_GX_MESSAGE:
|
||||||
return "PGW_EVT_GX_SESSION_MSG";
|
return "PGW_EVT_GX_SESSION_MSG";
|
||||||
|
|
|
@ -11,7 +11,8 @@ typedef enum {
|
||||||
PGW_EVT_BASE = FSM_USER_SIG,
|
PGW_EVT_BASE = FSM_USER_SIG,
|
||||||
|
|
||||||
PGW_EVT_S5C_MESSAGE,
|
PGW_EVT_S5C_MESSAGE,
|
||||||
PGW_EVT_S5C_T3,
|
PGW_EVT_S5C_T3_RESPONSE,
|
||||||
|
PGW_EVT_S5C_T3_DUPLICATED,
|
||||||
|
|
||||||
PGW_EVT_GX_MESSAGE,
|
PGW_EVT_GX_MESSAGE,
|
||||||
|
|
||||||
|
|
|
@ -242,7 +242,7 @@ status_t pgw_s5c_send_to_sgw(
|
||||||
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
||||||
d_assert(xact, return CORE_ERROR, "Null param");
|
d_assert(xact, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
rv = gtp_xact_update_tx(xact, type, teid, pkbuf, PGW_EVT_S5C_T3);
|
rv = gtp_xact_update_tx(xact, type, teid, pkbuf);
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_xact_update_tx error");
|
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_xact_update_tx error");
|
||||||
|
|
||||||
rv = gtp_xact_commit(xact);
|
rv = gtp_xact_commit(xact);
|
||||||
|
|
|
@ -73,8 +73,8 @@ static void *THREAD_FUNC sm_main(thread_id id, void *data)
|
||||||
d_assert(pgw_self()->queue_id, return NULL,
|
d_assert(pgw_self()->queue_id, return NULL,
|
||||||
"PGW event queue creation failed");
|
"PGW event queue creation failed");
|
||||||
tm_service_init(&pgw_self()->tm_service);
|
tm_service_init(&pgw_self()->tm_service);
|
||||||
gtp_xact_init(&pgw_self()->gtp_xact_ctx,
|
gtp_xact_init(&pgw_self()->tm_service,
|
||||||
&pgw_self()->tm_service, PGW_EVT_S5C_T3);
|
PGW_EVT_S5C_T3_RESPONSE, PGW_EVT_S5C_T3_DUPLICATED);
|
||||||
|
|
||||||
fsm_create(&pgw_sm, pgw_state_initial, pgw_state_final);
|
fsm_create(&pgw_sm, pgw_state_initial, pgw_state_final);
|
||||||
fsm_init(&pgw_sm, 0);
|
fsm_init(&pgw_sm, 0);
|
||||||
|
|
|
@ -115,9 +115,10 @@ void pgw_state_operational(fsm_t *s, event_t *e)
|
||||||
pkbuf_free(recvbuf);
|
pkbuf_free(recvbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGW_EVT_S5C_T3:
|
case PGW_EVT_S5C_T3_RESPONSE:
|
||||||
|
case PGW_EVT_S5C_T3_DUPLICATED:
|
||||||
{
|
{
|
||||||
gtp_xact_timeout(event_get_param1(e));
|
gtp_xact_timeout(event_get_param1(e), event_get(e));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGW_EVT_GX_MESSAGE:
|
case PGW_EVT_GX_MESSAGE:
|
||||||
|
|
|
@ -39,7 +39,6 @@ typedef struct _sgw_context_t {
|
||||||
|
|
||||||
msgq_id queue_id; /* Queue for processing SGW control plane */
|
msgq_id queue_id; /* Queue for processing SGW control plane */
|
||||||
tm_service_t tm_service; /* Timer Service */
|
tm_service_t tm_service; /* Timer Service */
|
||||||
gtp_xact_ctx_t gtp_xact_ctx; /* GTP Transaction Context */
|
|
||||||
|
|
||||||
hash_t *sess_hash; /* hash table (IMSI+APN) */
|
hash_t *sess_hash; /* hash table (IMSI+APN) */
|
||||||
} sgw_context_t;
|
} sgw_context_t;
|
||||||
|
|
|
@ -20,8 +20,10 @@ char* sgw_event_get_name(event_t *e)
|
||||||
case SGW_EVT_S5C_MESSAGE:
|
case SGW_EVT_S5C_MESSAGE:
|
||||||
return "SGW_EVT_S5C_MESSAGE";
|
return "SGW_EVT_S5C_MESSAGE";
|
||||||
|
|
||||||
case SGW_EVT_GTP_T3:
|
case SGW_EVT_T3_RESPONSE:
|
||||||
return "SGW_EVT_GTP_T3";
|
return "SGW_EVT_T3_RESPONSE";
|
||||||
|
case SGW_EVT_T3_DUPLICATED:
|
||||||
|
return "SGW_EVT_T3_DUPLICATED";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -13,7 +13,8 @@ typedef enum {
|
||||||
SGW_EVT_S11_MESSAGE,
|
SGW_EVT_S11_MESSAGE,
|
||||||
SGW_EVT_S5C_MESSAGE,
|
SGW_EVT_S5C_MESSAGE,
|
||||||
|
|
||||||
SGW_EVT_GTP_T3,
|
SGW_EVT_T3_RESPONSE,
|
||||||
|
SGW_EVT_T3_DUPLICATED,
|
||||||
|
|
||||||
SGW_EVT_LO_DLDATA_NOTI,
|
SGW_EVT_LO_DLDATA_NOTI,
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ status_t sgw_s11_send_to_mme(
|
||||||
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
||||||
d_assert(xact, return CORE_ERROR, "Null param");
|
d_assert(xact, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
rv = gtp_xact_update_tx(xact, type, teid, pkbuf, SGW_EVT_GTP_T3);
|
rv = gtp_xact_update_tx(xact, type, teid, pkbuf);
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_xact_update_tx error");
|
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp_xact_update_tx error");
|
||||||
|
|
||||||
rv = gtp_xact_commit(xact);
|
rv = gtp_xact_commit(xact);
|
||||||
|
@ -330,7 +330,7 @@ status_t sgw_s5c_send_to_pgw(
|
||||||
xact = gtp_xact_local_create(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(xact, return CORE_ERROR, "Null param");
|
||||||
|
|
||||||
rv = gtp_xact_update_tx(xact, type, teid, pkbuf, SGW_EVT_GTP_T3);
|
rv = gtp_xact_update_tx(xact, type, teid, pkbuf);
|
||||||
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_update_tx error");
|
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_update_tx error");
|
||||||
|
|
||||||
gtp_xact_associate(xact, assoc_xact);
|
gtp_xact_associate(xact, assoc_xact);
|
||||||
|
|
|
@ -62,8 +62,8 @@ static void *THREAD_FUNC sm_main(thread_id id, void *data)
|
||||||
d_assert(sgw_self()->queue_id, return NULL,
|
d_assert(sgw_self()->queue_id, return NULL,
|
||||||
"SGW event queue creation failed");
|
"SGW event queue creation failed");
|
||||||
tm_service_init(&sgw_self()->tm_service);
|
tm_service_init(&sgw_self()->tm_service);
|
||||||
gtp_xact_init(&sgw_self()->gtp_xact_ctx,
|
gtp_xact_init(&sgw_self()->tm_service,
|
||||||
&sgw_self()->tm_service, SGW_EVT_GTP_T3);
|
SGW_EVT_T3_RESPONSE, SGW_EVT_T3_DUPLICATED);
|
||||||
|
|
||||||
fsm_create(&sgw_sm, sgw_state_initial, sgw_state_final);
|
fsm_create(&sgw_sm, sgw_state_initial, sgw_state_final);
|
||||||
fsm_init(&sgw_sm, 0);
|
fsm_init(&sgw_sm, 0);
|
||||||
|
|
|
@ -116,9 +116,10 @@ void sgw_state_operational(fsm_t *s, event_t *e)
|
||||||
pkbuf_free(pkbuf);
|
pkbuf_free(pkbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SGW_EVT_GTP_T3:
|
case SGW_EVT_T3_RESPONSE:
|
||||||
|
case SGW_EVT_T3_DUPLICATED:
|
||||||
{
|
{
|
||||||
gtp_xact_timeout(event_get_param1(e));
|
gtp_xact_timeout(event_get_param1(e), event_get(e));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SGW_EVT_LO_DLDATA_NOTI:
|
case SGW_EVT_LO_DLDATA_NOTI:
|
||||||
|
|
Loading…
Reference in New Issue