update it

This commit is contained in:
Sukchan Lee 2017-03-28 16:35:57 +09:00
parent bd895fc138
commit 3a2ae04d0f
16 changed files with 147 additions and 99 deletions

View File

@ -80,10 +80,41 @@ status_t gtp_send(net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf)
char buf[INET_ADDRSTRLEN];
ssize_t sent;
typedef struct _gtpv2c_header_t {
ED4(c_uint8_t version:3;,
c_uint8_t piggybacked:1;,
c_uint8_t teid_presence:1;,
c_uint8_t spare1:3;)
c_uint8_t type;
c_uint16_t length;
union {
struct {
c_uint32_t teid;
/* sqn : 31bit ~ 8bit, spare : 7bit ~ 0bit */
#define GTP_XID_TO_SQN(__xid) ((__xid) << 8)
#define GTP_SQN_TO_XID(__sqn) ((__sqn) >> 8)
c_uint32_t sqn;
};
/* sqn : 31bit ~ 8bit, spare : 7bit ~ 0bit */
c_uint32_t spare2;
};
} __attribute__ ((packed)) gtpv2c_header_t;
gtpv2c_header_t *h;
d_assert(sock, return CORE_ERROR, "Null param");
d_assert(gnode, return CORE_ERROR, "Null param");
d_assert(pkbuf, return CORE_ERROR, "Null param");
pkbuf_header(pkbuf, 12);
h = pkbuf->payload;
memset(h, 0, 12);
h->version = 2;
h->teid_presence = 1;
h->type = 32;
h->length = htons(pkbuf->len - 4);
h->sqn = 1;
sent = net_sendto(sock, pkbuf->payload, pkbuf->len,
gnode->addr, gnode->port);
d_trace(1,"Sent %d->%d bytes to [%s:%d]\n", pkbuf->len, sent,

View File

@ -37,20 +37,29 @@ ED4(c_uint8_t version:3;,
};
} __attribute__ ((packed)) gtpv2c_header_t;
static int g_gtp_xact_initialized = 0;
pool_declare(gtp_xact_pool, gtp_xact_ctx_t, SIZE_OF_GTP_XACT_POOL);
static int gtp_xact_pool_initialized = 0;
pool_declare(gtp_xact_pool, gtp_xact_info_t, SIZE_OF_GTP_XACT_POOL);
/**
* Initialize the transaction framework
*/
status_t gtp_xact_init()
status_t gtp_xact_init(gtp_xact_ctx_t *context, tm_service_t *tm_service,
c_uintptr_t event, c_uint32_t duration, int retry_count)
{
d_assert(g_gtp_xact_initialized == 0, return CORE_ERROR,
"XACTION already has been initialized");
if (gtp_xact_pool_initialized == 0)
{
pool_init(&gtp_xact_pool, SIZE_OF_GTP_XACT_POOL);
}
gtp_xact_pool_initialized = 1;
pool_init(&gtp_xact_pool, SIZE_OF_GTP_XACT_POOL);
memset(context, 0, sizeof(gtp_xact_ctx_t));
g_gtp_xact_initialized = 1;
context->g_xact_id = 1;
context->tm_service = tm_service;
context->event = event;;
context->duration = duration;;
context->retry_count = retry_count;;
return CORE_OK;
}
@ -60,76 +69,57 @@ status_t gtp_xact_init()
*/
status_t gtp_xact_final(void)
{
d_assert(g_gtp_xact_initialized == 1, return CORE_ERROR,
"XACTION ASNGW context already has been finalized");
pool_final(&gtp_xact_pool);
g_gtp_xact_initialized = 0;
if (gtp_xact_pool_initialized == 1)
{
pool_final(&gtp_xact_pool);
}
gtp_xact_pool_initialized = 0;
return CORE_OK;
}
/**
* Config Transaction
*/
void gtp_xact_config(gtp_xact_config_t *config, tm_service_t *tm_service,
c_uintptr_t event, c_uint32_t duration, int retry_count)
{
memset(config, 0, sizeof(gtp_xact_config_t));
config->g_xact_id = 1;
config->tm_service = tm_service;
config->event = event;;
config->duration = duration;;
config->retry_count = retry_count;;
}
/**
* Create a new transaction which was initiated by local ASN node.
*/
status_t gtp_xact_new_local(gtp_xact_config_t *config,
gtp_xact_ctx_t **xact, c_uint8_t type, net_sock_t *sock,
gtp_node_t *gnode, pkbuf_t *pkbuf)
gtp_xact_info_t *gtp_xact_new_local(gtp_xact_ctx_t *context,
c_uint8_t type, net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf)
{
gtp_xact_ctx_t *new = NULL;
gtp_xact_info_t *xact = NULL;
d_assert(xact, 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");
d_assert(context, return NULL, "Null param");
d_assert(sock, return NULL, "Null param");
d_assert(gnode, return NULL, "Null param");
d_assert(pkbuf, return NULL, "Null param");
pool_alloc_node(&gtp_xact_pool, &new);
d_assert(new, return CORE_ERROR, "Transaction allocation failed");
memset(new, 0, sizeof(gtp_xact_ctx_t));
pool_alloc_node(&gtp_xact_pool, &xact);
d_assert(xact, return NULL, "Transaction allocation failed");
memset(xact, 0, sizeof(gtp_xact_info_t));
new->xid = GTP_XACT_NEXT_ID(config->g_xact_id);
new->org = GTP_LOCAL_ORIGINATOR;
new->type = type;
new->sock = sock;
new->gnode = gnode;
new->pkbuf = pkbuf;
xact->xid = GTP_XACT_NEXT_ID(context->g_xact_id);
xact->org = GTP_LOCAL_ORIGINATOR;
xact->type = type;
xact->sock = sock;
xact->gnode = gnode;
xact->pkbuf = pkbuf;
new->tm_wait = event_timer(config->tm_service, config->event,
config->duration, (c_uintptr_t)new);
d_assert(new->tm_wait, return CORE_ERROR, "Timer allocation failed");
new->retry_count = config->retry_count;
xact->tm_wait = event_timer(context->tm_service, context->event,
context->duration, (c_uintptr_t)xact);
d_assert(xact->tm_wait, return NULL, "Timer allocation failed");
xact->retry_count = context->retry_count;
list_append(&gnode->local_xlist, new);
*xact = new;
list_append(&gnode->local_xlist, xact);
return CORE_OK;
return xact;
}
/**
* Create a new transaction which was initiated by remote node
*/
status_t gtp_xact_new_remote(gtp_xact_config_t *config,
gtp_xact_ctx_t **xact, net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf)
status_t gtp_xact_new_remote(gtp_xact_ctx_t *context,
gtp_xact_info_t **xact, net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf)
{
gtpv2c_header_t *h = NULL;
gtp_xact_ctx_t *new = NULL;
gtp_xact_info_t *new = NULL;
d_assert(xact, return CORE_ERROR, "Null param");
d_assert(sock, return CORE_ERROR, "Null param");
@ -139,7 +129,7 @@ status_t gtp_xact_new_remote(gtp_xact_config_t *config,
pool_alloc_node(&gtp_xact_pool, &new);
d_assert(new, return CORE_ERROR, "Transaction allocation failed");
memset(new, 0, sizeof(gtp_xact_ctx_t));
memset(new, 0, sizeof(gtp_xact_info_t));
h = pkbuf->payload;
@ -150,8 +140,8 @@ status_t gtp_xact_new_remote(gtp_xact_config_t *config,
new->gnode = gnode;
new->pkbuf = pkbuf;
new->tm_wait = event_timer(config->tm_service, config->event,
config->duration * config->retry_count, (c_uintptr_t)new);
new->tm_wait = event_timer(context->tm_service, context->event,
context->duration * context->retry_count, (c_uintptr_t)new);
d_assert(new->tm_wait, return CORE_ERROR, "Timer allocation failed");
new->retry_count = 1;
@ -163,7 +153,7 @@ status_t gtp_xact_new_remote(gtp_xact_config_t *config,
/**
* Delete a transaction
*/
status_t gtp_xact_delete(gtp_xact_ctx_t *xact)
status_t gtp_xact_delete(gtp_xact_info_t *xact)
{
d_assert(xact, return CORE_ERROR, "Null param");
d_assert(xact->tm_wait, return CORE_ERROR, "Null param");
@ -181,7 +171,7 @@ status_t gtp_xact_delete(gtp_xact_ctx_t *xact)
/**
* Update the transaction with the new packet to be sent for the next step
*/
status_t gtp_xact_update_tx(gtp_xact_ctx_t *xact, pkbuf_t *pkb)
status_t gtp_xact_update_tx(gtp_xact_info_t *xact, pkbuf_t *pkb)
{
return CORE_OK;
}
@ -189,7 +179,7 @@ status_t gtp_xact_update_tx(gtp_xact_ctx_t *xact, pkbuf_t *pkb)
/**
* Update the transaction with the new received packet for the next step
*/
status_t gtp_xact_update_rx(gtp_xact_ctx_t *xact)
status_t gtp_xact_update_rx(gtp_xact_info_t *xact)
{
return CORE_OK;
}
@ -197,7 +187,7 @@ status_t gtp_xact_update_rx(gtp_xact_ctx_t *xact)
/**
* Apply and commit the updated of the transcation
*/
status_t gtp_xact_commit(gtp_xact_ctx_t *xact)
status_t gtp_xact_commit(gtp_xact_info_t *xact)
{
return CORE_OK;
}
@ -205,11 +195,11 @@ status_t gtp_xact_commit(gtp_xact_ctx_t *xact)
/**
* Find the transaction with the given ASN header
*/
gtp_xact_ctx_t *gtp_xact_find(gtp_node_t *gnode, pkbuf_t *pkbuf)
gtp_xact_info_t *gtp_xact_find(gtp_node_t *gnode, pkbuf_t *pkbuf)
{
gtpv2c_header_t *h = NULL;
c_uint32_t xid;
gtp_xact_ctx_t *xact = NULL;
gtp_xact_info_t *xact = NULL;
d_assert(gnode, return NULL, "Null param");
d_assert(pkbuf, return NULL, "Null param");

View File

@ -15,19 +15,20 @@ extern "C" {
/**
* Transaction Configuration
*/
typedef struct _gtp_xact_config_t {
typedef struct _gtp_xact_ctx_t {
c_uint32_t g_xact_id;
void *pool;
tm_service_t *tm_service;
c_uintptr_t event;
c_uint32_t duration;
int retry_count;
} gtp_xact_config_t;
} gtp_xact_ctx_t;
/**
* Transaction context
*/
typedef struct _gtp_xact_ctx_t {
typedef struct _gtp_xact_info_t {
lnode_t node; /**< A node of list */
c_uint32_t xid; /**< Transaction ID */
@ -43,12 +44,14 @@ typedef struct _gtp_xact_ctx_t {
tm_block_id tm_wait; /**< Timer waiting for next message */
int retry_count; /**< Retry count waiting for next message */
} gtp_xact_ctx_t;
} gtp_xact_info_t;
/**
* Initialize the transaction framework
*/
CORE_DECLARE(status_t) gtp_xact_init(void);
CORE_DECLARE(status_t) gtp_xact_init(gtp_xact_ctx_t *context,
tm_service_t *tm_service, c_uintptr_t event, c_uint32_t duration,
int retry_count);
/**
* Finalize the transaction framework
@ -58,40 +61,40 @@ CORE_DECLARE(status_t) gtp_xact_final(void);
/**
* Create a new transaction which was initiated by local ASN node.
*/
CORE_DECLARE(status_t) gtp_xact_new_local(gtp_xact_config_t *config,
gtp_xact_ctx_t **xact, c_uint8_t type, net_sock_t *sock,
gtp_node_t *gnode, pkbuf_t *pkbuf);
CORE_DECLARE(gtp_xact_info_t *) gtp_xact_new_local(gtp_xact_ctx_t *context,
c_uint8_t type, net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf);
/**
* Create a new transaction which was initiated by remote node
*/
CORE_DECLARE(status_t) gtp_xact_new_remote(gtp_xact_config_t *config,
gtp_xact_ctx_t **xact, net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) gtp_xact_new_remote(gtp_xact_ctx_t *context,
gtp_xact_info_t **xact, net_sock_t *sock, gtp_node_t *gnode, pkbuf_t *pkbuf);
/**
* Delete a transaction
*/
CORE_DECLARE(status_t) gtp_xact_delete(gtp_xact_ctx_t *xact);
CORE_DECLARE(status_t) gtp_xact_delete(gtp_xact_info_t *xact);
/**
* Update the transaction with the new packet to be sent for the next step
*/
CORE_DECLARE(status_t) gtp_xact_update_tx(gtp_xact_ctx_t *xact, pkbuf_t *pkb);
CORE_DECLARE(status_t) gtp_xact_update_tx(gtp_xact_info_t *xact, pkbuf_t *pkb);
/**
* Update the transaction with the new received packet for the next step
*/
CORE_DECLARE(status_t) gtp_xact_update_rx(gtp_xact_ctx_t *xact);
CORE_DECLARE(status_t) gtp_xact_update_rx(gtp_xact_info_t *xact);
/**
* Apply and commit the updated of the transcation
*/
CORE_DECLARE(status_t) gtp_xact_commit(gtp_xact_ctx_t *xact);
CORE_DECLARE(status_t) gtp_xact_commit(gtp_xact_info_t *xact);
/**
* Find the transaction with the given ASN header
*/
CORE_DECLARE(gtp_xact_ctx_t *) gtp_xact_find(gtp_node_t *gnode, pkbuf_t *pkbuf);
CORE_DECLARE(gtp_xact_info_t *) gtp_xact_find(
gtp_node_t *gnode, pkbuf_t *pkbuf);
#ifdef __cplusplus
}

View File

@ -58,6 +58,9 @@ status_t mme_ctx_init()
sgw_ctx_t *sgw = mme_ctx_sgw_add();
d_assert(sgw, return CORE_ERROR, "Can't add SGW context");
self.s11_addr = inet_addr("127.0.0.1");
self.s11_port = GTPV2_C_UDP_PORT;
sgw->gnode.addr = inet_addr("127.0.0.1");
sgw->gnode.port = GTPV2_C_UDP_PORT+1;

View File

@ -9,7 +9,7 @@
#include "3gpp_defs.h"
#include "3gpp_types.h"
#include "nas_types.h"
#include "gtp_path.h"
#include "gtp_xact.h"
#include "sm.h"
@ -44,8 +44,9 @@ typedef struct _mme_ctx_t {
c_uint16_t s11_port; /* MME S11 local port */
net_sock_t *s11_sock; /* MME S11 local listen socket */
msgq_id queue_id;
tm_service_t tm_service;
msgq_id queue_id; /* Queue for processing MME control plane */
tm_service_t tm_service; /* Timer Service */
gtp_xact_ctx_t gtp_xact_ctx; /* GTP Transaction Context for MME */
c_uint32_t mme_ue_s1ap_id; /** mme_ue_s1ap_id generator */
plmn_id_t plmn_id;

View File

@ -6,11 +6,11 @@
#include "s1ap_path.h"
#include "nas_message.h"
static char EVT_NAME_LO_MME_ENGAGE_SGW[] = "LO_MME_ENGAGE_SGW";
static char EVT_NAME_LO_ENB_S1AP_ACCEPT[] = "LO_ENB_S1AP_ACCEPT";
static char EVT_NAME_LO_ENB_S1AP_CONNREFUSED[] = "LO_ENB_S1AP_CONNREFUSED";
static char EVT_NAME_TM_MME_S11_T3[] = "TM_MME_S11_T3";
static char EVT_NAME_MSG_ENB_S1AP[] = "MSG_ENB_S1AP";
static char EVT_NAME_MSG_UE_EMM[] = "MSG_UE_EMM";
static char EVT_NAME_MSG_UE_ESM[] = "MSG_UE_ESM";
@ -28,14 +28,14 @@ char* mme_event_get_name(event_t *e)
case FSM_EXIT_SIG:
return FSM_NAME_EXIT_SIG;
case EVT_LO_MME_ENGAGE_SGW:
return EVT_NAME_LO_MME_ENGAGE_SGW;
case EVT_LO_ENB_S1AP_ACCEPT:
return EVT_NAME_LO_ENB_S1AP_ACCEPT;
case EVT_LO_ENB_S1AP_CONNREFUSED:
return EVT_NAME_LO_ENB_S1AP_CONNREFUSED;
case EVT_TM_MME_S11_T3:
return EVT_NAME_TM_MME_S11_T3;
case EVT_MSG_ENB_S1AP:
return EVT_NAME_MSG_ENB_S1AP;
case EVT_MSG_UE_EMM:

View File

@ -6,20 +6,20 @@
#include "s1ap_message.h"
#include "context.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _ue_ctx_t ue_ctx_t;
typedef enum {
MME_EVT_BASE = FSM_USER_SIG,
EVT_LO_MME_ENGAGE_SGW,
EVT_LO_ENB_S1AP_ACCEPT,
EVT_LO_ENB_S1AP_CONNREFUSED,
EVT_TM_MME_S11_T3,
EVT_MSG_ENB_S1AP,
EVT_MSG_UE_EMM,
EVT_MSG_UE_ESM,

View File

@ -48,11 +48,12 @@ void *THREAD_FUNC mme_sm_main(thread_id id, void *data)
mme_self()->queue_id = event_create();
d_assert(mme_self()->queue_id, return NULL,
"MME event queue creation failed");
tm_service_init(&mme_self()->tm_service);
gtp_xact_init(&mme_self()->gtp_xact_ctx, &mme_self()->tm_service,
5, 3000, 3);
fsm_create(&mme_sm.fsm, mme_state_initial, mme_state_final);
d_assert(&mme_sm.fsm, return NULL, "MME state machine creation failed");
tm_service_init(&mme_self()->tm_service);
fsm_init((fsm_t*)&mme_sm, 0);
prev_tm = time_now();
@ -86,6 +87,7 @@ void *THREAD_FUNC mme_sm_main(thread_id id, void *data)
fsm_final((fsm_t*)&mme_sm, 0);
fsm_clear((fsm_t*)&mme_sm);
gtp_xact_final();
event_delete(mme_self()->queue_id);
return NULL;

View File

@ -4,6 +4,7 @@
#include "core_net.h"
#include "event.h"
#include "context.h"
#include "s11_path.h"
static int _gtpv2_c_recv_cb(net_sock_t *net_sock, void *data)

View File

@ -3,6 +3,7 @@
#include "core_debug.h"
#include "event.h"
#include "context.h"
void mme_s11_state_initial(s11_sm_t *s, event_t *e)
{

View File

@ -1,6 +1,7 @@
#ifndef __S1AP_HANDLER_H__
#define __S1AP_HANDLER_H__
#include "context.h"
#include "s1ap_message.h"
#ifdef __cplusplus

View File

@ -7,7 +7,7 @@
#include "sm.h"
#include "gtp_path.h"
#include "gtp_xact.h"
#ifdef __cplusplus
extern "C" {
@ -29,8 +29,9 @@ typedef struct _sgw_ctx_t {
net_sock_t* s5u_sock; /* SGW S5-U local listen socket */
gtp_node_t s5u_node; /* PGW S5-U remote GTPv1-U node */
msgq_id queue_id;
tm_service_t tm_service;
msgq_id queue_id; /* Queue for processing MME control plane */
tm_service_t tm_service; /* Timer Service */
gtp_xact_ctx_t gtp_xact_ctx; /* GTP Transaction Context for MME */
} sgw_ctx_t;

View File

@ -4,6 +4,8 @@
#include "event.h"
#include "context.h"
static char EVT_NAME_TM_MME_S11_T3[] = "TM_MME_S11_T3";
static char EVT_NAME_MSG_SGW_S11[] = "MSG_MME_S11";
char* sgw_event_get_name(event_t *e)
@ -18,6 +20,9 @@ char* sgw_event_get_name(event_t *e)
case FSM_EXIT_SIG:
return FSM_NAME_EXIT_SIG;
case EVT_TM_SGW_S11_T3:
return EVT_NAME_TM_MME_S11_T3;
case EVT_MSG_SGW_S11:
return EVT_NAME_MSG_SGW_S11;

View File

@ -10,6 +10,8 @@ extern "C" {
typedef enum {
SGW_EVT_BASE = FSM_USER_SIG,
EVT_TM_SGW_S11_T3,
EVT_MSG_SGW_S11,
EVT_MSG_SGW_S5C,

View File

@ -41,11 +41,12 @@ void *THREAD_FUNC sgw_sm_main(thread_id id, void *data)
sgw_self()->queue_id = event_create();
d_assert(sgw_self()->queue_id, return NULL,
"SGW event queue creation failed");
tm_service_init(&sgw_self()->tm_service);
gtp_xact_init(&sgw_self()->gtp_xact_ctx, &sgw_self()->tm_service,
5, 3000, 3);
fsm_create(&sgw_sm.fsm, sgw_state_initial, sgw_state_final);
d_assert(&sgw_sm.fsm, return NULL, "SGW state machine creation failed");
tm_service_init(&sgw_self()->tm_service);
fsm_init((fsm_t*)&sgw_sm, 0);
prev_tm = time_now();
@ -79,6 +80,7 @@ void *THREAD_FUNC sgw_sm_main(thread_id id, void *data)
fsm_final((fsm_t*)&sgw_sm, 0);
fsm_clear((fsm_t*)&sgw_sm);
gtp_xact_final();
event_delete(sgw_self()->queue_id);
return NULL;

View File

@ -63,6 +63,11 @@ void sgw_state_operational(sgw_sm_t *s, event_t *e)
pkbuf_free(pkbuf);
break;
}
case EVT_TM_SGW_S11_T3:
{
d_info("Timer expiration");
break;
}
case EVT_MSG_SGW_S5C:
{
gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);