SGW is added

This commit is contained in:
Sukchan Lee 2017-03-24 18:47:05 +09:00
parent 84a369aa42
commit 54a8efdca6
26 changed files with 454 additions and 113 deletions

View File

@ -312,6 +312,7 @@ AC_CONFIG_FILES([lib/gtp/Makefile])
AC_CONFIG_FILES([lib/Makefile])
AC_CONFIG_FILES([src/mme/Makefile])
AC_CONFIG_FILES([src/hss/Makefile])
AC_CONFIG_FILES([src/sgw/Makefile])
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([test/Makefile])
AC_CONFIG_FILES([Makefile])

View File

@ -9,6 +9,26 @@
extern "C" {
#endif /* __cplusplus */
#define EVENT_SIZE sizeof(event_t)
#define EVENT_WAIT_TIMEOUT 10000 /* 10 msec */
#define event_set(__ptr_e, __evnt) ((__ptr_e)->event = (__evnt))
#define event_get(__ptr_e) ((__ptr_e)->event)
#define event_set_param1(__ptr_e, __param) \
((__ptr_e)->param1 = (c_uintptr_t)(__param))
#define event_set_param2(__ptr_e, __param) \
((__ptr_e)->param2 = (c_uintptr_t)(__param))
#define event_set_param3(__ptr_e, __param) \
((__ptr_e)->param3 = (c_uintptr_t)(__param))
#define event_set_param4(__ptr_e, __param) \
((__ptr_e)->param4 = (c_uintptr_t)(__param))
#define event_get_param1(__ptr_e) ((__ptr_e)->param1)
#define event_get_param2(__ptr_e) ((__ptr_e)->param2)
#define event_get_param3(__ptr_e) ((__ptr_e)->param3)
#define event_get_param4(__ptr_e) ((__ptr_e)->param4)
typedef struct {
fsm_event_t event;
c_uintptr_t param1;
@ -17,38 +37,11 @@ typedef struct {
c_uintptr_t param4;
} event_t;
#define EVENT_SIZE sizeof(event_t)
extern char *FSM_NAME_INIT_SIG;
extern char *FSM_NAME_ENTRY_SIG;
extern char *FSM_NAME_EXIT_SIG;
#define event_set(__ptr_e, __evnt) \
((__ptr_e)->event = (__evnt))
#define event_get(__ptr_e) \
((__ptr_e)->event)
#define event_set_param1(__ptr_e, __param) \
((__ptr_e)->param1 = (c_uintptr_t)(__param))
#define event_set_param2(__ptr_e, __param) \
((__ptr_e)->param2 = (c_uintptr_t)(__param))
#define event_set_param3(__ptr_e, __param) \
((__ptr_e)->param3 = (c_uintptr_t)(__param))
#define event_set_param4(__ptr_e, __param) \
((__ptr_e)->param4 = (c_uintptr_t)(__param))
#define event_get_param1(__ptr_e) \
((__ptr_e)->param1)
#define event_get_param2(__ptr_e) \
((__ptr_e)->param2)
#define event_get_param3(__ptr_e) \
((__ptr_e)->param3)
#define event_get_param4(__ptr_e) \
((__ptr_e)->param4)
extern char *EVT_NAME_UNKNOWN;
/**
* Create event message queue

View File

@ -10,6 +10,12 @@
#define EVT_Q_DEPTH 16
char *FSM_NAME_INIT_SIG = "INIT";
char *FSM_NAME_ENTRY_SIG = "ENTRY";
char *FSM_NAME_EXIT_SIG = "EXIT";
char *EVT_NAME_UNKNOWN = "UNKNOWN";
msgq_id event_create(void)
{
msgq_id queue_id = 0;

View File

@ -1,7 +1,7 @@
#ifndef __GTP_PATH_H__
#define __GTP_PATH_H__
#include "core.h"
#include "core_pkbuf.h"
#ifdef __cplusplus
extern "C" {

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in.
SUBDIRS = mme hss
SUBDIRS = mme hss sgw
noinst_LTLIBRARIES = libcellwire.la
@ -13,12 +13,14 @@ nodist_libcellwire_la_SOURCES = \
libcellwire_la_DEPENDENCIES = \
$(top_srcdir)/lib/logger/liblogger.la \
$(top_srcdir)/src/mme/libmme.la \
$(top_srcdir)/src/hss/libhss.la
$(top_srcdir)/src/hss/libhss.la \
$(top_srcdir)/src/sgw/libsgw.la
libcellwire_la_LIBADD = \
$(top_srcdir)/lib/logger/liblogger.la \
$(top_srcdir)/src/mme/libmme.la \
$(top_srcdir)/src/hss/libhss.la
$(top_srcdir)/src/hss/libhss.la \
$(top_srcdir)/src/sgw/libsgw.la
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include \

View File

@ -17,6 +17,9 @@ CORE_DECLARE_NONSTD(void) mme_terminate(void);
CORE_DECLARE(status_t) hss_initialize();
CORE_DECLARE_NONSTD(void) hss_terminate(void);
CORE_DECLARE(status_t) sgw_initialize();
CORE_DECLARE_NONSTD(void) sgw_terminate(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -60,6 +60,8 @@ status_t cellwire_initialize(char *config_path, char *log_path)
}
/* Parent */
rv = sgw_initialize();
if (rv != CORE_OK) return rv;
rv = mme_initialize();
if (rv != CORE_OK) return rv;
rv = thread_create(&net_thread, NULL, net_main, NULL);
@ -75,6 +77,7 @@ void cellwire_terminate(void)
{
thread_delete(net_thread);
mme_terminate();
sgw_terminate();
core_kill(hss_pid, SIGTERM);
core_kill(logger_pid, SIGTERM);

View File

@ -26,30 +26,30 @@ pool_declare(enb_pool, enb_ctx_t, SIZE_OF_ENB_POOL);
pool_declare(ue_pool, ue_ctx_t, SIZE_OF_UE_POOL);
pool_declare(rab_pool, rab_ctx_t, SIZE_OF_RAB_POOL);
static int g_mme_ctx_initialized = 0;
static int ctx_initialized = 0;
static list_t g_enb_list;
static list_t enb_list;
status_t mme_ctx_init()
{
d_assert(g_mme_ctx_initialized == 0, return CORE_ERROR,
"MME context already has been initialized");
d_assert(ctx_initialized == 0, return CORE_ERROR,
"MME context already has been ctx_initialized");
pool_init(&enb_pool, SIZE_OF_ENB_POOL);
pool_init(&ue_pool, SIZE_OF_UE_POOL);
pool_init(&rab_pool, SIZE_OF_RAB_POOL);
list_init(&g_enb_list);
list_init(&enb_list);
/* Initialize MME context */
memset(&self, 0, sizeof(mme_ctx_t));
self.mme_local_addr = inet_addr("127.0.0.1");
self.s1ap_port = S1AP_SCTP_PORT;
self.sgw_remote_addr = inet_addr("127.0.0.1");
self.s1ap_port = S1AP_SCTP_PORT;
self.s11_local_port = S11_UDP_PORT;
self.s11_remote_port = S11_UDP_PORT + 1; /* for loopback testing */
self.s11_remote_port = S11_UDP_PORT + 1;
self.plmn_id.mnc_len = 2;
self.plmn_id.mcc = 1; /* 001 */
@ -71,14 +71,14 @@ status_t mme_ctx_init()
self.selected_enc_algorithm = NAS_SECURITY_ALGORITHMS_EEA0;
self.selected_int_algorithm = NAS_SECURITY_ALGORITHMS_128_EIA1;
g_mme_ctx_initialized = 1;
ctx_initialized = 1;
return CORE_OK;
}
status_t mme_ctx_final()
{
d_assert(g_mme_ctx_initialized == 1, return CORE_ERROR,
d_assert(ctx_initialized == 1, return CORE_ERROR,
"HyperCell context already has been finalized");
mme_ctx_enb_remove_all();
@ -87,7 +87,7 @@ status_t mme_ctx_final()
pool_final(&ue_pool);
pool_final(&rab_pool);
g_mme_ctx_initialized = 0;
ctx_initialized = 0;
return CORE_OK;
}
@ -108,7 +108,7 @@ enb_ctx_t* mme_ctx_enb_add()
list_init(&enb->ue_list);
list_append(&g_enb_list, enb);
list_append(&enb_list, enb);
return enb;
}
@ -119,7 +119,7 @@ status_t mme_ctx_enb_remove(enb_ctx_t *enb)
mme_ctx_ue_remove_all(enb);
list_remove(&g_enb_list, enb);
list_remove(&enb_list, enb);
pool_free_node(&enb_pool, enb);
return CORE_OK;
@ -162,7 +162,7 @@ enb_ctx_t* mme_ctx_enb_find_by_enb_id(c_uint32_t enb_id)
{
enb_ctx_t *enb = NULL;
enb = list_first(&g_enb_list);
enb = list_first(&enb_list);
while (enb)
{
if (enb_id == enb->enb_id)
@ -176,7 +176,7 @@ enb_ctx_t* mme_ctx_enb_find_by_enb_id(c_uint32_t enb_id)
enb_ctx_t* mme_ctx_enb_first()
{
return list_first(&g_enb_list);
return list_first(&enb_list);
}
enb_ctx_t* mme_ctx_enb_next(enb_ctx_t *enb)

View File

@ -24,7 +24,7 @@ void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
FSM_TRAN(s, &enb_s1ap_state_operational);
}
@ -33,7 +33,7 @@ void enb_s1ap_state_final(enb_s1ap_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
}
void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e)
@ -44,7 +44,7 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e)
enb_ctx_t *enb = s->ctx;
d_assert(enb, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
switch (event_get(e))
{
@ -130,7 +130,7 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e)
default:
{
d_error("Unknown event %s", event_get_name(e));
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}
@ -141,7 +141,7 @@ void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e)
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
switch (event_get(e))
{
@ -155,7 +155,7 @@ void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e)
}
default:
{
d_error("Unknown event %s", event_get_name(e));
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}

View File

@ -2,10 +2,6 @@
#include "event.h"
static char FSM_NAME_INIT_SIG[] = "INIT";
static char FSM_NAME_ENTRY_SIG[] = "ENTRY";
static char FSM_NAME_EXIT_SIG[] = "EXIT";
static char EVT_NAME_LO_ENB_S1AP_ACCEPT[] = "LO_ENB_S1AP_ACCEPT";
static char EVT_NAME_LO_ENB_S1AP_CONNREFUSED[] = "LO_ENB_S1AP_CONNREFUSED";
@ -13,9 +9,7 @@ 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_MME_S11[] = "MSG_MME_S11";
static char EVT_NAME_UNKNOWN[] = "UNKNOWN";
char* event_get_name(event_t *e)
char* mme_event_get_name(event_t *e)
{
if (e == NULL)
return FSM_NAME_INIT_SIG;

View File

@ -8,7 +8,7 @@ extern "C" {
#endif /* __cplusplus */
typedef enum {
EVT_BASE = FSM_USER_SIG,
MME_EVT_BASE = FSM_USER_SIG,
EVT_LO_ENB_S1AP_ACCEPT,
EVT_LO_ENB_S1AP_CONNREFUSED,
@ -17,10 +17,12 @@ typedef enum {
EVT_MSG_UE_EMM,
EVT_MSG_MME_S11,
EVT_TOP,
MME_EVT_TOP,
} event_e;
CORE_DECLARE(char*) mme_event_get_name(event_t *e);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -8,8 +8,6 @@
#include "s6a_sm.h"
#define EVENT_WAIT_TIMEOUT 10000 /* 10 msec */
static thread_id mme_sm_thread;
void *THREAD_FUNC mme_sm_main(thread_id id, void *data);

View File

@ -9,7 +9,7 @@
void mme_state_initial(mme_sm_t *s, event_t *e)
{
sm_trace(1, e);
mme_sm_trace(1, e);
d_assert(s, return, "Null param");
@ -18,7 +18,7 @@ void mme_state_initial(mme_sm_t *s, event_t *e)
void mme_state_final(mme_sm_t *s, event_t *e)
{
sm_trace(1, e);
mme_sm_trace(1, e);
d_assert(s, return, "Null param");
}
@ -28,7 +28,7 @@ void mme_state_operational(mme_sm_t *s, event_t *e)
status_t rv;
char buf[INET_ADDRSTRLEN];
sm_trace(1, e);
mme_sm_trace(1, e);
d_assert(s, return, "Null param");
@ -171,34 +171,7 @@ void mme_state_operational(mme_sm_t *s, event_t *e)
}
default:
{
d_error("No handler for event %s", event_get_name(e));
break;
}
}
/* If event was packet type, its buffer allocated by data-plane should
* be freed here */
}
void mme_state_exception(mme_sm_t *s, event_t *e)
{
sm_trace(1, e);
d_assert(s, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
break;
}
case FSM_EXIT_SIG:
{
break;
}
default:
{
d_error("No handler for event %s", event_get_name(e));
d_error("No handler for event %s", mme_event_get_name(e));
break;
}
}

View File

@ -1,4 +1,4 @@
#define TRACE_MODULE _s11_path
#define TRACE_MODULE _mme_s11_path
#include "core_debug.h"
#include "core_pkbuf.h"
#include "core_net.h"

View File

@ -1,7 +1,7 @@
#ifndef __MME_S11_PATH_H__
#define __MME_S11_PATH_H__
#include "core.h"
#include "gtp_path.h"
#ifdef __cplusplus
extern "C" {

View File

@ -1,5 +1,5 @@
#ifndef __SM_H__
#define __SM_H__
#ifndef __MME_SM_H__
#define __MME_SM_H__
#include "core_param.h"
#include "core_fsm.h"
@ -40,14 +40,14 @@ void ue_emm_state_final(ue_emm_sm_t *s, event_t *e);
void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e);
void ue_emm_state_exception(ue_emm_sm_t *s, event_t *e);
#define sm_print(__pe) \
d_print("%s(): %s\n", __func__, event_get_name(__pe))
#define mme_sm_print(__pe) \
d_print("%s(): %s\n", __func__, mme_event_get_name(__pe))
#define sm_trace(__l, __pe) \
d_trace(__l, "%s(): %s\n", __func__, event_get_name(__pe))
#define mme_sm_trace(__l, __pe) \
d_trace(__l, "%s(): %s\n", __func__, mme_event_get_name(__pe))
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !__SM_H__ */
#endif /* !__MME_SM_H__ */

View File

@ -27,7 +27,7 @@ void ue_emm_state_initial(ue_emm_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
FSM_TRAN(s, &ue_emm_state_operational);
}
@ -36,7 +36,7 @@ void ue_emm_state_final(ue_emm_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
}
void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e)
@ -47,7 +47,7 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e)
ue_ctx_t *ue = s->ctx;
d_assert(ue, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
switch (event_get(e))
{
@ -117,7 +117,7 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e)
default:
{
d_error("Unknown event %s", event_get_name(e));
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}
@ -128,7 +128,7 @@ void ue_emm_state_exception(ue_emm_sm_t *s, event_t *e)
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
sm_trace(1, e);
mme_sm_trace(1, e);
switch (event_get(e))
{
@ -142,7 +142,7 @@ void ue_emm_state_exception(ue_emm_sm_t *s, event_t *e)
}
default:
{
d_error("Unknown event %s", event_get_name(e));
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}

34
src/sgw/Makefile.am Normal file
View File

@ -0,0 +1,34 @@
## Process this file with automake to produce Makefile.in.
noinst_LTLIBRARIES = libsgw.la
libsgw_la_SOURCES = \
event.h context.h \
s11_path.h \
sm.h
nodist_libsgw_la_SOURCES = \
init.c event.c context.c \
s11_path.c \
sgw_sm.c
libsgw_la_DEPENDENCIES = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/gtp/libgtp.la
libsgw_la_LIBADD = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/gtp/libgtp.la
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include \
-I$(top_srcdir)/lib/3gpp \
-I$(top_srcdir)/lib/gtp
AM_CFLAGS = \
-Wall -Werror
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = core *.stackdump
EXTRA_DIST = .libs $(noinst_LTLIBRARIES)

48
src/sgw/context.c Normal file
View File

@ -0,0 +1,48 @@
#define TRACE_MODULE _sgw_ctx
#include "core_debug.h"
#include "core_pool.h"
#include "core_index.h"
#include "context.h"
#include "gtp_path.h"
static sgw_ctx_t self;
static int ctx_initialized = 0;
status_t sgw_ctx_init()
{
d_assert(ctx_initialized == 0, return CORE_ERROR,
"MME context already has been initialized");
/* Initialize MME context */
memset(&self, 0, sizeof(sgw_ctx_t));
self.sgw_local_addr = inet_addr("127.0.0.1");
self.mme_remote_addr = inet_addr("127.0.0.1");
self.pgw_remote_addr = inet_addr("127.0.0.1");
self.s11_local_port = S11_UDP_PORT + 1;
self.s11_remote_port = S11_UDP_PORT;
ctx_initialized = 1;
return CORE_OK;
}
status_t sgw_ctx_final()
{
d_assert(ctx_initialized == 1, return CORE_ERROR,
"HyperCell context already has been finalized");
ctx_initialized = 0;
return CORE_OK;
}
sgw_ctx_t* sgw_self()
{
return &self;
}

38
src/sgw/context.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __SGW_CTX_H__
#define __SGW_CTX_H__
#include "core_list.h"
#include "core_errno.h"
#include "core_net.h"
#include "3gpp_message.h"
#include "sm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _sgw_ctx_t {
c_uint32_t sgw_local_addr;
c_uint32_t mme_remote_addr;
c_uint32_t pgw_remote_addr;
net_sock_t *s11_sock;
c_uint16_t s11_local_port;
c_uint16_t s11_remote_port;
msgq_id queue_id;
tm_service_t tm_service;
} sgw_ctx_t;
CORE_DECLARE(status_t) sgw_ctx_init(void);
CORE_DECLARE(status_t) sgw_ctx_final(void);
CORE_DECLARE(sgw_ctx_t*) sgw_self(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SGW_CTX_H__ */

27
src/sgw/event.c Normal file
View File

@ -0,0 +1,27 @@
#define TRACE_MODULE _mme_evt
#include "event.h"
static char EVT_NAME_MSG_SGW_S11[] = "MSG_MME_S11";
char* sgw_event_get_name(event_t *e)
{
if (e == NULL)
return FSM_NAME_INIT_SIG;
switch (event_get(e))
{
case FSM_ENTRY_SIG:
return FSM_NAME_ENTRY_SIG;
case FSM_EXIT_SIG:
return FSM_NAME_EXIT_SIG;
case EVT_MSG_SGW_S11:
return EVT_NAME_MSG_SGW_S11;
default:
break;
}
return EVT_NAME_UNKNOWN;
}

25
src/sgw/event.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef __SGW_EVENT_H__
#define __SGW_EVENT_H__
#include "core_event.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef enum {
SGW_EVT_BASE = FSM_USER_SIG,
EVT_MSG_SGW_S11,
SGW_EVT_TOP,
} event_e;
CORE_DECLARE(char*) sgw_event_get_name(event_t *e);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SGW_EVENT_H__ */

85
src/sgw/init.c Normal file
View File

@ -0,0 +1,85 @@
#define TRACE_MODULE _sgw_init
#include "core_debug.h"
#include "core_thread.h"
#include "context.h"
#include "event.h"
static thread_id sgw_sm_thread;
void *THREAD_FUNC sgw_sm_main(thread_id id, void *data);
status_t sgw_initialize()
{
status_t rv;
rv = sgw_ctx_init();
if (rv != CORE_OK) return rv;
rv = thread_create(&sgw_sm_thread, NULL, sgw_sm_main, NULL);
if (rv != CORE_OK) return rv;
return CORE_OK;
}
void sgw_terminate(void)
{
thread_delete(sgw_sm_thread);
sgw_ctx_final();
}
void *THREAD_FUNC sgw_sm_main(thread_id id, void *data)
{
event_t event;
sgw_sm_t sgw_sm;
c_time_t prev_tm, now_tm;
int r;
memset(&event, 0, sizeof(event_t));
sgw_self()->queue_id = event_create();
d_assert(sgw_self()->queue_id, return NULL,
"SGW event queue creation failed");
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();
while ((!thread_should_stop()))
{
r = event_timedrecv(sgw_self()->queue_id, &event, EVENT_WAIT_TIMEOUT);
d_assert(r != CORE_ERROR, continue,
"While receiving a event message, error occurs");
now_tm = time_now();
/* if the gap is over 10 ms, execute preriodic jobs */
if (now_tm - prev_tm > EVENT_WAIT_TIMEOUT)
{
tm_execute_tm_service(
&sgw_self()->tm_service, sgw_self()->queue_id);
prev_tm = now_tm;
}
if (r == CORE_TIMEUP)
{
continue;
}
fsm_dispatch((fsm_t*)&sgw_sm, (fsm_event_t*)&event);
}
fsm_final((fsm_t*)&sgw_sm, 0);
fsm_clear((fsm_t*)&sgw_sm);
event_delete(sgw_self()->queue_id);
return NULL;
}

57
src/sgw/s11_path.c Normal file
View File

@ -0,0 +1,57 @@
#define TRACE_MODULE _sgw_s11_path
#include "core_debug.h"
#include "core_pkbuf.h"
#include "core_net.h"
#include "3gpp_message.h"
#include "gtp_path.h"
#include "context.h"
#include "s11_path.h"
static int _sgw_s11_recv_cb(net_sock_t *net_sock, void *data)
{
event_t e;
int rc;
pkbuf_t *pkbuf = NULL;
d_assert(net_sock, return -1, "Null param");
pkbuf = gtp_read(net_sock);
if (pkbuf == NULL)
{
if (net_sock->sndrcv_errno == EAGAIN)
return 0;
return -1;
}
d_trace(1, "S11_PDU is received from SGW\n");
d_trace_hex(1, pkbuf->payload, pkbuf->len);
event_set(&e, EVT_MSG_SGW_S11);
event_set_param1(&e, (c_uintptr_t)net_sock);
event_set_param2(&e, (c_uintptr_t)pkbuf);
rc = event_send(sgw_self()->queue_id, &e);
if (rc <= 0)
return rc;
return 0;
}
status_t sgw_s11_open()
{
return gtp_open(&sgw_self()->s11_sock, _sgw_s11_recv_cb, NULL,
sgw_self()->sgw_local_addr, sgw_self()->s11_local_port);
}
status_t sgw_s11_close()
{
return gtp_close(sgw_self()->s11_sock);
}
status_t sgw_s11_send_to_mme(pkbuf_t *pkbuf)
{
return gtp_send(sgw_self()->s11_sock, pkbuf,
sgw_self()->mme_remote_addr, sgw_self()->s11_remote_port);
}

19
src/sgw/s11_path.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __SGW_S11_PATH_H__
#define __SGW_S11_PATH_H__
#include "gtp_path.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) sgw_s11_open();
CORE_DECLARE(status_t) sgw_s11_close();
CORE_DECLARE(status_t) sgw_s11_send_to_mme(pkbuf_t *pkbuf);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SGW_S11_PATH_H__ */

33
src/sgw/sm.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef __SGW_SM_H__
#define __SGW_SM_H__
#include "core_param.h"
#include "core_fsm.h"
#include "event.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _sgw_sm_t {
fsm_t fsm;
void *ctx;
} sgw_sm_t;
void sgw_state_initial(sgw_sm_t *s, event_t *e);
void sgw_state_final(sgw_sm_t *s, event_t *e);
void sgw_state_operational(sgw_sm_t *s, event_t *e);
void sgw_state_exception(sgw_sm_t *s, event_t *e);
#define sgw_sm_print(__pe) \
d_print("%s(): %s\n", __func__, sgw_event_get_name(__pe))
#define sgw_sm_trace(__l, __pe) \
d_trace(__l, "%s(): %s\n", __func__, sgw_event_get_name(__pe))
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !__SGW_SM_H__ */