SGW is added
This commit is contained in:
parent
84a369aa42
commit
54a8efdca6
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __GTP_PATH_H__
|
||||
#define __GTP_PATH_H__
|
||||
|
||||
#include "core.h"
|
||||
#include "core_pkbuf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" {
|
||||
|
|
14
src/mme/sm.h
14
src/mme/sm.h
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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__ */
|
Loading…
Reference in New Issue