mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-04 14:03:21 +00:00 
			
		
		
		
	Compare commits
	
		
			111 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					d9ab53bbf0 | ||
| 
						 | 
					561c041010 | ||
| 
						 | 
					fbe3e3685f | ||
| 
						 | 
					2f43079fc6 | ||
| 
						 | 
					0bdbee24cf | ||
| 
						 | 
					081f8c8808 | ||
| 
						 | 
					a9dd6be8e8 | ||
| 
						 | 
					a25de7b287 | ||
| 
						 | 
					46b403c43d | ||
| 
						 | 
					b060ea1714 | ||
| 
						 | 
					f627565696 | ||
| 
						 | 
					badc1f2da3 | ||
| 
						 | 
					10cda2cfd7 | ||
| 
						 | 
					abdcbe7b7a | ||
| 
						 | 
					377f725f26 | ||
| 
						 | 
					ff31858a81 | ||
| 
						 | 
					9e27685cd0 | ||
| 
						 | 
					c09483b540 | ||
| 
						 | 
					44f0155f5a | ||
| 
						 | 
					a0eb08a2fa | ||
| 
						 | 
					8c289c6d6e | ||
| 
						 | 
					baf6af79d6 | ||
| 
						 | 
					2d1983cfb0 | ||
| 
						 | 
					5c4c4498d2 | ||
| 
						 | 
					f72aa7a468 | ||
| 
						 | 
					c8ec3702d0 | ||
| 
						 | 
					4e33365bf4 | ||
| 
						 | 
					fdae399c74 | ||
| 
						 | 
					e367b00d2c | ||
| 
						 | 
					b08c91190a | ||
| 
						 | 
					52080092b6 | ||
| 
						 | 
					88b5560a2a | ||
| 
						 | 
					6d99061b17 | ||
| 
						 | 
					f624adf540 | ||
| 
						 | 
					67827d5ea4 | ||
| 
						 | 
					20800c611b | ||
| 
						 | 
					6c8d4328fb | ||
| 
						 | 
					588a6ba012 | ||
| 
						 | 
					d4dd8bb72d | ||
| 
						 | 
					6d25211f3b | ||
| 
						 | 
					4ae9673935 | ||
| 
						 | 
					cd36e9a334 | ||
| 
						 | 
					0897c36947 | ||
| 
						 | 
					6989a8ae91 | ||
| 
						 | 
					df1f35e92b | ||
| 
						 | 
					6f5ec19388 | ||
| 
						 | 
					6eb05495aa | ||
| 
						 | 
					81a8b00d78 | ||
| 
						 | 
					382c909ffc | ||
| 
						 | 
					92ba86f1fd | ||
| 
						 | 
					adcc473d6e | ||
| 
						 | 
					5314bcb687 | ||
| 
						 | 
					30e7beb84c | ||
| 
						 | 
					e8071fa544 | ||
| 
						 | 
					32b7183483 | ||
| 
						 | 
					f6f1720fee | ||
| 
						 | 
					6b8cdafbbd | ||
| 
						 | 
					074b7b41e8 | ||
| 
						 | 
					2223dfef0e | ||
| 
						 | 
					7b046c75b2 | ||
| 
						 | 
					3bf6326763 | ||
| 
						 | 
					c2d962d4d1 | ||
| 
						 | 
					34270825a7 | ||
| 
						 | 
					d971a9c9ae | ||
| 
						 | 
					d40ba2a67c | ||
| 
						 | 
					7b1949da6c | ||
| 
						 | 
					2a3fe018e8 | ||
| 
						 | 
					36985520f9 | ||
| 
						 | 
					cca9f6d521 | ||
| 
						 | 
					da1a50e9d3 | ||
| 
						 | 
					c460386d39 | ||
| 
						 | 
					1c64000431 | ||
| 
						 | 
					1df4fc9a41 | ||
| 
						 | 
					ae6f1001f8 | ||
| 
						 | 
					4bce6df238 | ||
| 
						 | 
					bb806e492e | ||
| 
						 | 
					c3ffd52771 | ||
| 
						 | 
					ec91b9e8da | ||
| 
						 | 
					cd8f29aa59 | ||
| 
						 | 
					bb74b173ca | ||
| 
						 | 
					10b23bb64e | ||
| 
						 | 
					ea253016fc | ||
| 
						 | 
					a020b587c1 | ||
| 
						 | 
					0eb9ae4792 | ||
| 
						 | 
					f275617225 | ||
| 
						 | 
					92ecad5118 | ||
| 
						 | 
					d486e84816 | ||
| 
						 | 
					b287a3b022 | ||
| 
						 | 
					83a21c5840 | ||
| 
						 | 
					b9f4dcf4ea | ||
| 
						 | 
					a20c96bc21 | ||
| 
						 | 
					291a5ce514 | ||
| 
						 | 
					cdbc8d1ab0 | ||
| 
						 | 
					689c3b95e7 | ||
| 
						 | 
					b8a37b0ea1 | ||
| 
						 | 
					86908cdbe9 | ||
| 
						 | 
					0f08c2a624 | ||
| 
						 | 
					47bad3794e | ||
| 
						 | 
					fb566fd94c | ||
| 
						 | 
					3bbbd1b5b1 | ||
| 
						 | 
					172266b0c5 | ||
| 
						 | 
					1f14b132c2 | ||
| 
						 | 
					3613b27ca7 | ||
| 
						 | 
					4672ee559f | ||
| 
						 | 
					02773eff40 | ||
| 
						 | 
					5d6e63c20e | ||
| 
						 | 
					ee4dd7732e | ||
| 
						 | 
					8d343221d2 | ||
| 
						 | 
					7c20ac5c64 | ||
| 
						 | 
					dac66d0b80 | ||
| 
						 | 
					4245502ae2 | 
							
								
								
									
										59
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
# compiler output
 | 
			
		||||
*.o
 | 
			
		||||
*.lo
 | 
			
		||||
*.a
 | 
			
		||||
*.la
 | 
			
		||||
*.conf
 | 
			
		||||
.deps
 | 
			
		||||
.libs
 | 
			
		||||
 | 
			
		||||
# generated files
 | 
			
		||||
lib/freeDiameter-*/libfdcore/fdd.tab.[chy]
 | 
			
		||||
lib/freeDiameter-*/libfdcore/lex.fdd.[cl]
 | 
			
		||||
lib/freeDiameter-*/include/freeDiameter/version.h
 | 
			
		||||
lib/freeDiameter-*/include/freeDiameter/config.h.in
 | 
			
		||||
lib/freeDiameter-*/include/freeDiameter/freeDiameter-host.h
 | 
			
		||||
lib/core/include/core.h
 | 
			
		||||
support/systemd/nextepc-*.service
 | 
			
		||||
support/logrotate/nextepc
 | 
			
		||||
 | 
			
		||||
# autotools
 | 
			
		||||
stamp-h1
 | 
			
		||||
config.h
 | 
			
		||||
config.in
 | 
			
		||||
config.nice
 | 
			
		||||
config.log
 | 
			
		||||
configure
 | 
			
		||||
aclocal.m4
 | 
			
		||||
config.status
 | 
			
		||||
libtool
 | 
			
		||||
autom4te.cache
 | 
			
		||||
build-aux
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
m4
 | 
			
		||||
 | 
			
		||||
# executables
 | 
			
		||||
lib/core/test/testcore
 | 
			
		||||
test/testepc
 | 
			
		||||
nextepc-mmed
 | 
			
		||||
nextepc-pcrfd
 | 
			
		||||
nextepc-pgwd
 | 
			
		||||
nextepc-sgwd
 | 
			
		||||
nextepc-epcd
 | 
			
		||||
nextepc-hssd
 | 
			
		||||
 | 
			
		||||
# debian
 | 
			
		||||
debian/*.debhelper.log
 | 
			
		||||
debian/*.debhelper
 | 
			
		||||
debian/*.substvars
 | 
			
		||||
debian/tmp
 | 
			
		||||
debian/files
 | 
			
		||||
debian/autoreconf.before
 | 
			
		||||
debian/autoreconf.after
 | 
			
		||||
debian/nextepc-core
 | 
			
		||||
debian/nextepc-mme
 | 
			
		||||
debian/nextepc-sgw
 | 
			
		||||
debian/nextepc-pgw
 | 
			
		||||
debian/nextepc-pcrf
 | 
			
		||||
debian/nextepc-hss
 | 
			
		||||
							
								
								
									
										71
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -2,62 +2,48 @@
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
 | 
			
		||||
SUBDIRS = lib src test
 | 
			
		||||
SUBDIRS = lib src support test
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS = mmed hssd sgwd pgwd pcrfd epcd
 | 
			
		||||
bin_PROGRAMS = nextepc-mmed nextepc-hssd nextepc-sgwd nextepc-pgwd nextepc-pcrfd nextepc-epcd
 | 
			
		||||
 | 
			
		||||
dist_mmed_SOURCES = main.c 
 | 
			
		||||
mmed_LDADD = $(top_srcdir)/src/libmme.la
 | 
			
		||||
mmed_LDFLAGS = -export-dynamic
 | 
			
		||||
dist_nextepc_mmed_SOURCES = main.c
 | 
			
		||||
nextepc_mmed_LDADD = $(top_srcdir)/src/libmme.la
 | 
			
		||||
nextepc_mmed_LDFLAGS = -export-dynamic
 | 
			
		||||
 | 
			
		||||
dist_hssd_SOURCES = main.c 
 | 
			
		||||
hssd_LDADD = $(top_srcdir)/src/libhss.la
 | 
			
		||||
hssd_LDFLAGS = -export-dynamic
 | 
			
		||||
dist_nextepc_hssd_SOURCES = main.c
 | 
			
		||||
nextepc_hssd_LDADD = $(top_srcdir)/src/libhss.la
 | 
			
		||||
nextepc_hssd_LDFLAGS = -export-dynamic
 | 
			
		||||
 | 
			
		||||
dist_sgwd_SOURCES = main.c 
 | 
			
		||||
sgwd_LDADD = $(top_srcdir)/src/libsgw.la
 | 
			
		||||
sgwd_LDFLAGS = -export-dynamic
 | 
			
		||||
dist_nextepc_sgwd_SOURCES = main.c
 | 
			
		||||
nextepc_sgwd_LDADD = $(top_srcdir)/src/libsgw.la
 | 
			
		||||
nextepc_sgwd_LDFLAGS = -export-dynamic
 | 
			
		||||
 | 
			
		||||
dist_pgwd_SOURCES = main.c 
 | 
			
		||||
pgwd_LDADD = $(top_srcdir)/src/libpgw.la
 | 
			
		||||
pgwd_LDFLAGS = -export-dynamic
 | 
			
		||||
dist_nextepc_pgwd_SOURCES = main.c
 | 
			
		||||
nextepc_pgwd_LDADD = $(top_srcdir)/src/libpgw.la
 | 
			
		||||
nextepc_pgwd_LDFLAGS = -export-dynamic
 | 
			
		||||
 | 
			
		||||
dist_pcrfd_SOURCES = main.c 
 | 
			
		||||
pcrfd_LDADD = $(top_srcdir)/src/libpcrf.la
 | 
			
		||||
pcrfd_LDFLAGS = -export-dynamic
 | 
			
		||||
dist_nextepc_pcrfd_SOURCES = main.c
 | 
			
		||||
nextepc_pcrfd_LDADD = $(top_srcdir)/src/libpcrf.la
 | 
			
		||||
nextepc_pcrfd_LDFLAGS = -export-dynamic
 | 
			
		||||
 | 
			
		||||
dist_epcd_SOURCES = main.c 
 | 
			
		||||
epcd_LDADD = $(top_srcdir)/src/libepc.la
 | 
			
		||||
epcd_LDFLAGS = -export-dynamic
 | 
			
		||||
dist_nextepc_epcd_SOURCES = main.c
 | 
			
		||||
nextepc_epcd_LDADD = $(top_srcdir)/src/libepc.la
 | 
			
		||||
nextepc_epcd_LDFLAGS = -export-dynamic
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
    -I$(top_srcdir)/lib/core/include \
 | 
			
		||||
    -I$(top_srcdir)/src
 | 
			
		||||
 | 
			
		||||
sysconf_DATA = \
 | 
			
		||||
	support/nextepc.conf
 | 
			
		||||
 | 
			
		||||
freeDiameterdir = ${prefix}/etc/freeDiameter
 | 
			
		||||
freeDiameter_DATA = \
 | 
			
		||||
	support/freeDiameter/mme.conf \
 | 
			
		||||
	support/freeDiameter/hss.conf \
 | 
			
		||||
	support/freeDiameter/pgw.conf \
 | 
			
		||||
	support/freeDiameter/pcrf.conf
 | 
			
		||||
dist_freeDiameter_DATA = \
 | 
			
		||||
	support/freeDiameter/cacert.pem \
 | 
			
		||||
	support/freeDiameter/mme.key.pem \
 | 
			
		||||
	support/freeDiameter/mme.cert.pem \
 | 
			
		||||
	support/freeDiameter/hss.key.pem \
 | 
			
		||||
	support/freeDiameter/hss.cert.pem \
 | 
			
		||||
	support/freeDiameter/pgw.key.pem \
 | 
			
		||||
	support/freeDiameter/pgw.cert.pem \
 | 
			
		||||
	support/freeDiameter/pcrf.key.pem \
 | 
			
		||||
	support/freeDiameter/pcrf.cert.pem
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	$(MKDIR_P) $(prefix)/var/log
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/log/nextepc
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-mmed
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-sgwd
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-pgwd
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-pcrfd
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-hssd
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-epcd
 | 
			
		||||
 | 
			
		||||
CLEANFILES = symtbl.c
 | 
			
		||||
CLEANFILES = -R data debian/test
 | 
			
		||||
DISTCLEANFILES = $(DIST_ARCHIVES)
 | 
			
		||||
MAINTAINERCLEANFILES = \
 | 
			
		||||
    configure config.in \
 | 
			
		||||
@@ -66,6 +52,5 @@ MAINTAINERCLEANFILES = \
 | 
			
		||||
    build-aux/ar-lib build-aux/config.guess build-aux/depcomp \
 | 
			
		||||
	build-aux/ltmain.sh build-aux/test-driver build-aux/compile \
 | 
			
		||||
	build-aux/config.sub build-aux/missing build-aux/install-sh \
 | 
			
		||||
	.cscope.out .cscope.out.in .cscope.files .cscope.out.po \
 | 
			
		||||
    Makefile.in
 | 
			
		||||
MOSTLYCLEANFILES = core *.stackdump
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								acinclude.m4
									
									
									
									
									
								
							@@ -88,3 +88,21 @@ AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
 | 
			
		||||
  [m4_default([$3], :)])
 | 
			
		||||
AS_VAR_POPDEF([CACHEVAR])dnl
 | 
			
		||||
])dnl AX_CHECK_COMPILE_FLAGS
 | 
			
		||||
 | 
			
		||||
# adl_RECURSIVE_EVAL(VALUE, RESULT)
 | 
			
		||||
# =================================
 | 
			
		||||
# Interpolate the VALUE in loop until it doesn't change,
 | 
			
		||||
# and set the result to $RESULT.
 | 
			
		||||
# WARNING: It's easy to get an infinite loop with some unsane input.
 | 
			
		||||
# For example ${datadir} becomes ${datarootdir}, and then ${prefix}/share, and
 | 
			
		||||
# finally ${prefix} is replaced by the prefix.
 | 
			
		||||
AC_DEFUN([adl_RECURSIVE_EVAL],
 | 
			
		||||
[_lcl_receval="$1"
 | 
			
		||||
$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
 | 
			
		||||
     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
 | 
			
		||||
     _lcl_receval_old=''
 | 
			
		||||
     while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
 | 
			
		||||
       _lcl_receval_old="[$]_lcl_receval"
 | 
			
		||||
       eval _lcl_receval="\"[$]_lcl_receval\""
 | 
			
		||||
     done
 | 
			
		||||
     echo "[$]_lcl_receval")`])
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										200
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								configure.ac
									
									
									
									
									
								
							@@ -8,7 +8,7 @@ dnl This program is distributed in the hope that it will be useful, but
 | 
			
		||||
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
 | 
			
		||||
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 | 
			
		||||
AC_INIT([NEXTEPC], [0.1.0], [acetcom@gmail.com])
 | 
			
		||||
AC_INIT([NEXTEPC], [0.2.0], [acetcom@gmail.com])
 | 
			
		||||
 | 
			
		||||
CORE_CONFIG_NICE(config.nice)
 | 
			
		||||
 | 
			
		||||
@@ -16,9 +16,6 @@ dnl Must come before AM_INIT_AUTOMAKE.
 | 
			
		||||
AC_CONFIG_AUX_DIR([build-aux])
 | 
			
		||||
AM_INIT_AUTOMAKE([1.10 -Wall -Werror foreign])
 | 
			
		||||
 | 
			
		||||
# Minimum Autoconf version required.
 | 
			
		||||
AC_PREREQ(2.63)
 | 
			
		||||
 | 
			
		||||
# Where to generate output; srcdir location.
 | 
			
		||||
AC_CONFIG_HEADERS([config.h:config.in])dnl Keep filename to 8.3 for MS-DOS.
 | 
			
		||||
AC_CONFIG_SRCDIR([main.c])
 | 
			
		||||
@@ -32,7 +29,7 @@ case $host in
 | 
			
		||||
        ;;
 | 
			
		||||
    *-apple-darwin*)
 | 
			
		||||
        OSDIR="unix"
 | 
			
		||||
        OSPPCFLAGS="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK"
 | 
			
		||||
        OSCPPFLAGS="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK"
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        OSDIR="unix"
 | 
			
		||||
@@ -63,19 +60,23 @@ AH_VERBATIM([_REENTRANT],
 | 
			
		||||
#endif
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl Checks CC and freinds
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_CPP
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_AWK
 | 
			
		||||
AC_PROG_SED
 | 
			
		||||
#AC_PROG_YACC
 | 
			
		||||
#AC_PROG_LEX
 | 
			
		||||
AM_PROG_AR
 | 
			
		||||
dnl kernel style compile messages
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
dnl libtool
 | 
			
		||||
dnl Checks CC and freinds
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
AC_PROG_MKDIR_P
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AM_PROG_AR
 | 
			
		||||
LT_INIT
 | 
			
		||||
 | 
			
		||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
 | 
			
		||||
if test "x$PKG_CONFIG" = "xno"; then
 | 
			
		||||
	AC_MSG_ERROR([You need to install pkg-config])
 | 
			
		||||
fi
 | 
			
		||||
PKG_PROG_PKG_CONFIG([0.20])
 | 
			
		||||
 | 
			
		||||
dnl Checks for compile flag
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Wno-unused-result], [CFLAGS="$CFLAGS -Wno-unused-result"])
 | 
			
		||||
 | 
			
		||||
@@ -153,6 +154,32 @@ AC_SUBST(uint64_t_hex_fmt)
 | 
			
		||||
AC_SUBST(int64_literal)
 | 
			
		||||
AC_SUBST(uint64_literal)
 | 
			
		||||
 | 
			
		||||
AC_CHECK_SIZEOF(pid_t, 8)
 | 
			
		||||
 | 
			
		||||
if test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_short"; then
 | 
			
		||||
    pid_t_fmt='#define C_PID_T_FMT "hd"'
 | 
			
		||||
elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_int"; then
 | 
			
		||||
    pid_t_fmt='#define C_PID_T_FMT "d"'
 | 
			
		||||
elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long"; then
 | 
			
		||||
    pid_t_fmt='#define C_PID_T_FMT "ld"'
 | 
			
		||||
elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long_long"; then
 | 
			
		||||
    pid_t_fmt='#define C_PID_T_FMT APR_INT64_T_FMT'
 | 
			
		||||
else
 | 
			
		||||
    pid_t_fmt='#error Can not determine the proper size for pid_t'
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
case $host in
 | 
			
		||||
   *-solaris*)
 | 
			
		||||
       if test "$ac_cv_sizeof_long" = "8"; then
 | 
			
		||||
         pid_t_fmt='#define C_PID_T_FMT "d"'
 | 
			
		||||
       else
 | 
			
		||||
         pid_t_fmt='#define C_PID_T_FMT "ld"'
 | 
			
		||||
       fi
 | 
			
		||||
       ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
AC_SUBST(pid_t_fmt)
 | 
			
		||||
 | 
			
		||||
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_MAJOR],
 | 
			
		||||
        [`echo $PACKAGE_VERSION | $SED 's/^\([[^\.]]\+\)\.\([[^\.]]\+\)\.\([[^\.]]\+\).*/\1/'`],
 | 
			
		||||
        [Major version of this package])
 | 
			
		||||
@@ -163,6 +190,19 @@ AC_DEFINE_UNQUOTED([PACKAGE_VERSION_PATCHLEVEL],
 | 
			
		||||
        [`echo $PACKAGE_VERSION | $SED 's/^\([[^\.]]\+\)\.\([[^\.]]\+\)\.\([[^\.]]\+\).*/\3/'`],
 | 
			
		||||
        [Patch version of this package])
 | 
			
		||||
 | 
			
		||||
##################################
 | 
			
		||||
#### Checks for Directories. #####
 | 
			
		||||
##################################
 | 
			
		||||
 | 
			
		||||
adl_RECURSIVE_EVAL(["${bindir}"], [BIN_DIR])
 | 
			
		||||
adl_RECURSIVE_EVAL(["${libdir}"], [LIB_DIR])
 | 
			
		||||
adl_RECURSIVE_EVAL(["${sysconfdir}"], [SYSCONF_DIR])
 | 
			
		||||
adl_RECURSIVE_EVAL(["${localstatedir}"], [LOCALSTATE_DIR])
 | 
			
		||||
AC_SUBST(BIN_DIR)
 | 
			
		||||
AC_SUBST(LIB_DIR)
 | 
			
		||||
AC_SUBST(SYSCONF_DIR)
 | 
			
		||||
AC_SUBST(LOCALSTATE_DIR)
 | 
			
		||||
 | 
			
		||||
##################################
 | 
			
		||||
#### Checks for header files. ####
 | 
			
		||||
##################################
 | 
			
		||||
@@ -192,10 +232,11 @@ AC_CHECK_HEADERS( \
 | 
			
		||||
    net/if.h \
 | 
			
		||||
    netinet/ether.h \
 | 
			
		||||
    netinet/in.h \
 | 
			
		||||
    netinet/ip.h \
 | 
			
		||||
    netinet/in_systm.h \
 | 
			
		||||
    netinet/udp.h \
 | 
			
		||||
    netinet/tcp.h \
 | 
			
		||||
    netinet/sctp.h \
 | 
			
		||||
    usrsctp.h \
 | 
			
		||||
    sys/ioctl.h \
 | 
			
		||||
    sys/param.h \
 | 
			
		||||
    sys/socket.h \
 | 
			
		||||
@@ -207,6 +248,19 @@ AC_CHECK_HEADERS( \
 | 
			
		||||
    sys/uio.h \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS(netinet/ip.h net/route.h,,,[[
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#if HAVE_SYS_SOCKET_H
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#if HAVE_NETINET_IN_SYSTM_H
 | 
			
		||||
#include <netinet/in_systm.h>
 | 
			
		||||
#endif
 | 
			
		||||
]])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS(netinet/ip_icmp.h, [], [], [#include <netinet/ip.h>])
 | 
			
		||||
 | 
			
		||||
##########################################
 | 
			
		||||
#### Checks for typedefs, structures, ####
 | 
			
		||||
####  and compiler characteristics.   ####
 | 
			
		||||
@@ -218,6 +272,41 @@ AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,[
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <time.h>])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_MEMBER(struct sockaddr.sa_len,
 | 
			
		||||
                AC_DEFINE(HAVE_SA_LEN, 1, [Define this if your stack has sa_len in sockaddr struct.]),,
 | 
			
		||||
                [#ifdef HAVE_SYS_TYPES_H
 | 
			
		||||
                 #include <sys/types.h>
 | 
			
		||||
                 #endif
 | 
			
		||||
                 #include <sys/socket.h>])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_MEMBER(struct sockaddr_in.sin_len,
 | 
			
		||||
                AC_DEFINE(HAVE_SIN_LEN, 1, [Define this if your IPv4 has sin_len in sockaddr_in struct.]),,
 | 
			
		||||
                [#ifdef HAVE_SYS_TYPES_H
 | 
			
		||||
                 #include <sys/types.h>
 | 
			
		||||
                 #endif
 | 
			
		||||
                 #include <netinet/in.h>])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_MEMBER(struct sockaddr_in6.sin6_len,
 | 
			
		||||
                AC_DEFINE(HAVE_SIN6_LEN, 1, [Define this if your IPv6 has sin6_len in sockaddr_in6 struct.]),,
 | 
			
		||||
                [#ifdef HAVE_SYS_TYPES_H
 | 
			
		||||
                 #include <sys/types.h>
 | 
			
		||||
                 #endif
 | 
			
		||||
                 #include <netinet/in.h>])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_MEMBER(struct sockaddr_conn.sconn_len,
 | 
			
		||||
                AC_DEFINE(HAVE_SCONN_LEN, 1, [Define this if your userland stack has sconn_len in sockaddr_conn struct.]),,
 | 
			
		||||
                [#include "usrsctplib/usrsctp.h"])
 | 
			
		||||
 | 
			
		||||
AC_MSG_CHECKING(for socklen_t)
 | 
			
		||||
AC_TRY_COMPILE([#ifdef HAVE_SYS_TYPES_H
 | 
			
		||||
                #include <sys/types.h>
 | 
			
		||||
                #endif
 | 
			
		||||
                #include <sys/socket.h>],
 | 
			
		||||
               [socklen_t x; x = 1; return ((int)x);],
 | 
			
		||||
               [AC_MSG_RESULT(yes)],
 | 
			
		||||
               [AC_MSG_RESULT(int)
 | 
			
		||||
                AC_DEFINE(socklen_t, int, [Define a type for socklen_t.])])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FILE(/dev/random,
 | 
			
		||||
    AC_DEFINE([HAVE_DEV_RANDOM], [1],
 | 
			
		||||
        [Define to 1 if you have the /dev/random file.]))
 | 
			
		||||
@@ -292,19 +381,43 @@ AC_CHECK_FUNCS(\
 | 
			
		||||
    sched_yield \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(socket, , AC_CHECK_LIB(socket, socket))
 | 
			
		||||
AC_CHECK_FUNCS(inet_addr, , AC_CHECK_LIB(nsl, inet_addr))
 | 
			
		||||
 | 
			
		||||
AC_CHECK_LIB([pthread], [pthread_mutex_init], [LIBS="${LIBS} -lpthread"])
 | 
			
		||||
AC_CHECK_LIB([dl], [dlopen], [LIBS="${LIBS} -ldl"])
 | 
			
		||||
AC_CHECK_LIB([sctp], [sctp_sendmsg], [LIBS="${LIBS} -lsctp"])
 | 
			
		||||
AC_CHECK_LIB([gnutls], [gnutls_global_init], [LIBS="${LIBS} -lgnutls"])
 | 
			
		||||
AC_CHECK_LIB([gcrypt], [gcry_control], [LIBS="${LIBS} -lgcrypt"])
 | 
			
		||||
AC_CHECK_LIB([idn], [idna_strerror], [LIBS="${LIBS} -lidn"])
 | 
			
		||||
#AC_CHECK_LIB([fdcore], [fd_core_initialize], [LIBS="${LIBS} -lfdcore"])
 | 
			
		||||
#AC_CHECK_LIB([fdproto], [fd_libproto_init], [LIBS="${LIBS} -lfdproto"])
 | 
			
		||||
AC_CHECK_LIB([sctp], [sctp_sendmsg], [have_sctp_lib=yes], [have_sctp_lib=no])
 | 
			
		||||
if test "$have_sctp_lib" == "yes"; then
 | 
			
		||||
  LIBS="${LIBS} -lsctp"
 | 
			
		||||
else
 | 
			
		||||
  AC_CHECK_LIB([usrsctp], [usrsctp_init], [have_usrsctp_lib=yes], [have_usrsctp_lib=no])
 | 
			
		||||
  if test "$have_usrsctp_lib" == "yes"; then
 | 
			
		||||
    LIBS="${LIBS} -lusrsctp"
 | 
			
		||||
    AC_DEFINE([USE_USRSCTP], [1], [Define to 1 if you have the usrsctp library.])
 | 
			
		||||
  fi 
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL([USRSCTP], [test x$have_usrsctp_lib = xyes])
 | 
			
		||||
AC_CHECK_LIB([gnutls], [gnutls_global_init], [have_gnutls_lib=yes], [have_gnutls_lib=no])
 | 
			
		||||
if test "$have_gnutls_lib" == "yes"; then
 | 
			
		||||
  LIBS="${LIBS} -lgnutls"
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_ERROR([You must install the GnuTLS libraries and development headers to enable GnuTLS support.])
 | 
			
		||||
fi
 | 
			
		||||
AC_CHECK_LIB([gcrypt], [gcry_control], [have_gcrypt_lib=yes], [have_gcrypt_lib=no])
 | 
			
		||||
if test "$have_gcrypt_lib" == "yes"; then
 | 
			
		||||
  LIBS="${LIBS} -lgcrypt"
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_ERROR([You must install the Libgcrypt libraries and development headers to enable Libgcrypt support.])
 | 
			
		||||
fi
 | 
			
		||||
AC_CHECK_LIB([idn], [idna_strerror], [have_idn_lib=yes], [have_idn_lib=no])
 | 
			
		||||
if test "$have_idn_lib" == "yes"; then
 | 
			
		||||
  LIBS="${LIBS} -lidn"
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_ERROR([You must install the GNU Libidn libraries and development headers to enable GNU Libidn support.])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES([MONGOC], libmongoc-1.0 >= 1.3.1)
 | 
			
		||||
LIBS="$LIBS $MONGOC_LIBS"
 | 
			
		||||
#PKG_CHECK_MODULES([LIBXML2], libxml-2.0 >= 2.9.1)
 | 
			
		||||
#LIBS="$LIBS $LIBXML2_LIBS"
 | 
			
		||||
FREEDIAMETER_DIR=freeDiameter-1.2.1
 | 
			
		||||
AC_SUBST(FREEDIAMETER_DIR)
 | 
			
		||||
 | 
			
		||||
@@ -316,20 +429,14 @@ AC_CONFIG_SUBDIRS([lib/freeDiameter-1.2.1])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_FILES([lib/core/include/core.h])
 | 
			
		||||
AC_CONFIG_FILES([lib/core/src/Makefile])
 | 
			
		||||
case $host in
 | 
			
		||||
   *)
 | 
			
		||||
       AC_CONFIG_FILES([lib/core/src/unix/Makefile])
 | 
			
		||||
       ;;
 | 
			
		||||
esac
 | 
			
		||||
AC_CONFIG_FILES([lib/core/src/unix/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/core/test/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/core/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/logger/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/base/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/s1ap/asn1c/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/s1ap/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/nas/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/fd/extensions/dbg_msg_dumps/Makefile])
 | 
			
		||||
#AC_CONFIG_FILES([lib/fd/extensions/dict_legacy_xml/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/fd/extensions/dict_rfc5777/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/fd/extensions/dict_mip6i/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([lib/fd/extensions/dict_nasreq/Makefile])
 | 
			
		||||
@@ -350,13 +457,30 @@ AC_CONFIG_FILES([src/sgw/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([src/pgw/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([src/pcrf/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([src/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([test/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([support/nextepc.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/nextepc.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/mme.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/sgw.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/pgw.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/hss.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/pcrf.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/config/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([support/freeDiameter/mme.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/freeDiameter/hss.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/freeDiameter/pgw.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/freeDiameter/hss.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/freeDiameter/pcrf.conf])
 | 
			
		||||
#AC_CONFIG_FILES([support/freeDiameter/dict_legacy_xml.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/freeDiameter/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([support/systemd/nextepc-mmed.service])
 | 
			
		||||
AC_CONFIG_FILES([support/systemd/nextepc-sgwd.service])
 | 
			
		||||
AC_CONFIG_FILES([support/systemd/nextepc-pgwd.service])
 | 
			
		||||
AC_CONFIG_FILES([support/systemd/nextepc-hssd.service])
 | 
			
		||||
AC_CONFIG_FILES([support/systemd/nextepc-pcrfd.service])
 | 
			
		||||
AC_CONFIG_FILES([support/systemd/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([support/logrotate/nextepc])
 | 
			
		||||
AC_CONFIG_FILES([support/logrotate/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([support/newsyslog/nextepc.conf])
 | 
			
		||||
AC_CONFIG_FILES([support/newsyslog/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([support/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([test/Makefile])
 | 
			
		||||
AC_CONFIG_FILES([Makefile])
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
 | 
			
		||||
@@ -369,6 +493,8 @@ source code location    : ${srcdir}
 | 
			
		||||
compiler                : ${CC}
 | 
			
		||||
compiler flags          : ${CFLAGS}
 | 
			
		||||
linker flags            : ${LDFLAGS} ${LIBS}
 | 
			
		||||
config file directory   : `eval echo \`echo ${sysconfdir}\``
 | 
			
		||||
log file directory      : `eval echo \`echo ${prefix}/var/log\``
 | 
			
		||||
bin directory           : ${BIN_DIR}
 | 
			
		||||
lib directory           : ${LIB_DIR}/nextepc
 | 
			
		||||
config directory        : ${SYSCONF_DIR}/nextepc
 | 
			
		||||
log directory           : ${LOCALSTATE_DIR}/log/nextepc
 | 
			
		||||
"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										109
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
nextepc (0.2-5~artful) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Relase 0.2
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Thu, 02 Nov 2017 07:13:23 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-5~zesty) zesty; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Relase 0.2
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Thu, 02 Nov 2017 07:12:17 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-5~xenial) xenial; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Release 0.2
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Thu, 02 Nov 2017 07:11:16 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-4~xenial2) xenial; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix the bug nextepc-pgwd post install script
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 14:07:54 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-4~artful) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix the bug nextepc-pgwd post install script
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 14:06:31 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-4~zesty) zesty; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix the bug nextepc-pgwd post install script
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 14:04:23 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-4~xenial) xenial; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix the bug nextepc-pgwd post install script
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 14:01:58 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-3~artful) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * MongoDB re-connect using systemd
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 12:10:18 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-3~zesty) zesty; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * MongoDB re-connect using systemd
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 12:07:36 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-3~xenial) xenial; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * MongoDB re-connect using systemd
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 12:00:16 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-2~artful) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix PGW installation
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 05:02:03 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-2~xenial) xenial; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix PGW installation
 | 
			
		||||
 | 
			
		||||
 --  Sukchan Lee <acetcom@gmail.com>  Tue, 31 Oct 2017 03:16:02 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-1~artful2) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Fix the compile error [-Werror=pointer]
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Mon, 30 Oct 2017 13:14:42 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-1~artful1) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Remove mongodb build-dependancy for Ubuntu 17.10(i386)
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Mon, 30 Oct 2017 12:46:58 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-1~artful) artful; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Ubuntu 17.10(amd64)
 | 
			
		||||
  * Currently, `mongodb` is not available in Ubuntu 17.10(i386)
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Mon, 30 Oct 2017 06:50:47 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-1~zesty) zesty; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Ubuntu 17.04
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Mon, 30 Oct 2017 06:47:55 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.2-1~xenial) xenial; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Add matapackage
 | 
			
		||||
  * dh_overide_auto_test is re-enabled
 | 
			
		||||
 | 
			
		||||
 -- Sukchan Lee <acetcom@gmail.com>  Mon, 30 Oct 2017 03:48:39 +0000
 | 
			
		||||
 | 
			
		||||
nextepc (0.1.1) UNRELEASED; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Initial release.
 | 
			
		||||
 | 
			
		||||
 -- Harald Welte <laforge@gnumonks.org>  Tue, 17 Oct 2017 08:19:54 +0200
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
9
 | 
			
		||||
							
								
								
									
										132
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
Source: nextepc
 | 
			
		||||
Maintainer: Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
Section: net
 | 
			
		||||
Priority: optional
 | 
			
		||||
Build-Depends: debhelper (>= 9),
 | 
			
		||||
               autotools-dev,
 | 
			
		||||
               pkg-config,
 | 
			
		||||
               git,
 | 
			
		||||
               dh-autoreconf,
 | 
			
		||||
               dh-systemd,
 | 
			
		||||
               flex,
 | 
			
		||||
               bison,
 | 
			
		||||
               libsctp-dev,
 | 
			
		||||
               libgnutls28-dev,
 | 
			
		||||
               libgcrypt-dev,
 | 
			
		||||
               libssl-dev,
 | 
			
		||||
               libmongoc-dev,
 | 
			
		||||
               libbson-dev
 | 
			
		||||
Standards-Version: 3.9.6
 | 
			
		||||
Vcs-Browser: https://github.com/acetcom/nextepc
 | 
			
		||||
Vcs-Git: git://github.com/acetcom/nextepc
 | 
			
		||||
Homepage: http://nextepc.org/
 | 
			
		||||
 | 
			
		||||
Package: nextepc-core
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Description: Open Source based 3GPP EPC (Shared Files)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This package contains some core libraries/plugins required by the other
 | 
			
		||||
 binary packages such as nextepc-{mme,sgw,pgw,pcrf,hss}.
 | 
			
		||||
 | 
			
		||||
Package: nextepc-mme
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         nextepc-core (= ${binary:Version})
 | 
			
		||||
Description: Open Source based 3GPP EPC MME (Mobility Management Entity)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This package provides the MME (Mobility Management Engine), which
 | 
			
		||||
 terminates the S1 interfaces from the eNodeBs cells in the cellular
 | 
			
		||||
 network, and interfaces via S11 to the SGW as well as via S6a to the
 | 
			
		||||
 HSS.
 | 
			
		||||
 | 
			
		||||
Package: nextepc-sgw
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         nextepc-core (= ${binary:Version})
 | 
			
		||||
Description: Open Source based 3GPP EPC SGW (Serving Gateway)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This package provides the SGW (Serving Gateway) which is situated
 | 
			
		||||
 between the MME and PGW.  It implements the S11 interface to the MME,
 | 
			
		||||
 and the S5 interface to the PGW.
 | 
			
		||||
 | 
			
		||||
Package: nextepc-pgw
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         nextepc-core (= ${binary:Version}),
 | 
			
		||||
         ifupdown
 | 
			
		||||
Description: Open Source based 3GPP EPC PGW (Packet Data Network Gateway)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This package provides the PGW or PDN-GW (Packet Data Network Gateway)
 | 
			
		||||
 element f the EPC, i.e. the gateway between the EPC and the external
 | 
			
		||||
 packet data network, such as the public Internet.  It implements the S5
 | 
			
		||||
 interface towards the S-GW, the SGi interface towards the Internet,
 | 
			
		||||
 and the S7 interface towards the PCRF.
 | 
			
		||||
 | 
			
		||||
Package: nextepc-pcrf
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         mongodb,
 | 
			
		||||
         nextepc-core (= ${binary:Version})
 | 
			
		||||
Description: Open Source based 3GPP EPC PCRF (Policy and Charging Rules Function)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This package contains the PCRF (Policy and Charging Rules Function),
 | 
			
		||||
 which controls the service quality (QoS) of individual connections and
 | 
			
		||||
 how to account/charge related traffic.  It implements the Gx interface
 | 
			
		||||
 towards the PGW using the DIAMETER protocol.
 | 
			
		||||
 | 
			
		||||
Package: nextepc-hss
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         mongodb,
 | 
			
		||||
         nextepc-core (= ${binary:Version})
 | 
			
		||||
Description: Open Source based 3GPP EPC HSS (Home Subscriber Server)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This package provides the HSS (Home Subscriber Server) element of the
 | 
			
		||||
 EPC, i.e. the central database of mobile network subscribers, with
 | 
			
		||||
 their IMSI, MSISDN, cryptographic key materials, service subscription
 | 
			
		||||
 information, etc.  It implements the S6a interface towards the MME
 | 
			
		||||
 using the DIAMETER protocol.
 | 
			
		||||
 | 
			
		||||
Package: nextepc
 | 
			
		||||
Architecture: any
 | 
			
		||||
Multi-Arch: same
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         mongodb,
 | 
			
		||||
         nextepc-core (= ${binary:Version}),
 | 
			
		||||
         nextepc-mme (= ${binary:Version}),
 | 
			
		||||
         nextepc-sgw (= ${binary:Version}),
 | 
			
		||||
         nextepc-pgw (= ${binary:Version}),
 | 
			
		||||
         nextepc-hss (= ${binary:Version}),
 | 
			
		||||
         nextepc-pcrf (= ${binary:Version})
 | 
			
		||||
Description: Open Source based 3GPP EPC (metapackage)
 | 
			
		||||
 NextEPC is a C-language Open Source implementation of the 3GPP Evolved
 | 
			
		||||
 Packet Core, i.e. the core network of an LTE network.
 | 
			
		||||
 .
 | 
			
		||||
 This is a metapackage that depends on all the nextepc parts.
 | 
			
		||||
 (MME, SGW, PGW, HSS, PCRF)
 | 
			
		||||
							
								
								
									
										55
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
			
		||||
Upstream-Name: nextepc
 | 
			
		||||
Source: https://github.com/acetcom/nextepc
 | 
			
		||||
 | 
			
		||||
Files: *
 | 
			
		||||
Copyright: 2017 NextEPC Group
 | 
			
		||||
License: GPL-3
 | 
			
		||||
 | 
			
		||||
Files: lib/freeDiameter-1.2.1/*
 | 
			
		||||
Copyright: 2008-2011, WIDE Project and NICT
 | 
			
		||||
License: BSD-3-clause
 | 
			
		||||
 | 
			
		||||
Files: debian/*
 | 
			
		||||
Copyright: 2017  Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
License: GPL-3
 | 
			
		||||
 | 
			
		||||
License: GPL-3
 | 
			
		||||
 This package is free software: you can redistribute it and/or modify it
 | 
			
		||||
 under the terms of the GNU General Public License as published by
 | 
			
		||||
 the Free Software Foundation; version 3 of the License
 | 
			
		||||
 .
 | 
			
		||||
 This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 | 
			
		||||
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 | 
			
		||||
 for more details.
 | 
			
		||||
 .
 | 
			
		||||
 You should have received a copy of the GNU General Public License
 | 
			
		||||
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 .
 | 
			
		||||
 On Debian systems, the complete text of the GNU General Public
 | 
			
		||||
 License version 3 can be found in "/usr/share/common-licenses/GPL-3".
 | 
			
		||||
 | 
			
		||||
License: BSD-3-clause
 | 
			
		||||
 Software License Agreement (BSD License)
 | 
			
		||||
 .
 | 
			
		||||
 Copyright (c) 2008-2011, WIDE Project and NICT
 | 
			
		||||
 All rights reserved.
 | 
			
		||||
 .
 | 
			
		||||
 Redistribution and use of this software in source and binary forms, with or without modification, are·
 | 
			
		||||
 permitted provided that the following conditions are met:
 | 
			
		||||
 .
 | 
			
		||||
 * Redistributions of source code must retain the above·
 | 
			
		||||
   copyright notice, this list of conditions and the·
 | 
			
		||||
   following disclaimer.
 | 
			
		||||
 ···
 | 
			
		||||
 * Redistributions in binary form must reproduce the above·
 | 
			
		||||
   copyright notice, this list of conditions and the·
 | 
			
		||||
   following disclaimer in the documentation and/or other
 | 
			
		||||
   materials provided with the distribution.
 | 
			
		||||
 .
 | 
			
		||||
 * Neither the name of the WIDE Project or NICT nor the·
 | 
			
		||||
   names of its contributors may be used to endorse or·
 | 
			
		||||
   promote products derived from this software without·
 | 
			
		||||
   specific prior written permission of WIDE Project and·
 | 
			
		||||
   NICT.
 | 
			
		||||
							
								
								
									
										5
									
								
								debian/nextepc-core.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								debian/nextepc-core.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
usr/lib/*/nextepc/*
 | 
			
		||||
var/log/nextepc
 | 
			
		||||
etc/nextepc/nextepc.conf
 | 
			
		||||
etc/nextepc/freeDiameter/cacert.pem
 | 
			
		||||
support/logrotate/nextepc /etc/logrotate.d
 | 
			
		||||
							
								
								
									
										52
									
								
								debian/nextepc-core.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								debian/nextepc-core.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# postinst script for nextepc
 | 
			
		||||
#
 | 
			
		||||
# see: dh_installdeb(1)
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
# summary of how this script can be called:
 | 
			
		||||
#        * <postinst> `configure' <most-recently-configured-version>
 | 
			
		||||
#        * <old-postinst> `abort-upgrade' <new version>
 | 
			
		||||
#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
 | 
			
		||||
#          <new-version>
 | 
			
		||||
#        * <postinst> `abort-remove'
 | 
			
		||||
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
 | 
			
		||||
#          <failed-install-package> <version> `removing'
 | 
			
		||||
#          <conflicting-package> <version>
 | 
			
		||||
# for details, see http://www.debian.org/doc/debian-policy/ or
 | 
			
		||||
# the debian-policy package
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
    configure)
 | 
			
		||||
	# create a nextepc group and user
 | 
			
		||||
	if ! getent passwd nextepc >/dev/null; then
 | 
			
		||||
		adduser --system --disabled-password --disabled-login \
 | 
			
		||||
			--home /var/run/nextepc --no-create-home \
 | 
			
		||||
			--quiet --group nextepc
 | 
			
		||||
	fi
 | 
			
		||||
	for dir in /var/log/nextepc; do
 | 
			
		||||
		if ! dpkg-statoverride --list "$dir" >/dev/null 2>&1; then
 | 
			
		||||
			dpkg-statoverride --update --add nextepc nextepc 0755 "$dir"
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
    ;;
 | 
			
		||||
 | 
			
		||||
    abort-upgrade|abort-remove|abort-deconfigure)
 | 
			
		||||
    ;;
 | 
			
		||||
 | 
			
		||||
    *)
 | 
			
		||||
        echo "postinst called with unknown argument \`$1'" >&2
 | 
			
		||||
        exit 1
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# dh_installdeb will replace this with shell code automatically
 | 
			
		||||
# generated by other debhelper scripts.
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/nextepc-hss.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/nextepc-hss.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
usr/bin/nextepc-hssd
 | 
			
		||||
etc/nextepc/freeDiameter/hss.conf
 | 
			
		||||
etc/nextepc/freeDiameter/hss.cert.pem
 | 
			
		||||
etc/nextepc/freeDiameter/hss.key.pem
 | 
			
		||||
etc/nextepc/hss.conf
 | 
			
		||||
support/systemd/nextepc-hssd.service lib/systemd/system
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/nextepc-mme.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/nextepc-mme.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
usr/bin/nextepc-mmed
 | 
			
		||||
etc/nextepc/freeDiameter/mme.conf
 | 
			
		||||
etc/nextepc/freeDiameter/mme.cert.pem
 | 
			
		||||
etc/nextepc/freeDiameter/mme.key.pem
 | 
			
		||||
etc/nextepc/mme.conf
 | 
			
		||||
support/systemd/nextepc-mmed.service lib/systemd/system
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/nextepc-pcrf.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/nextepc-pcrf.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
usr/bin/nextepc-pcrfd
 | 
			
		||||
etc/nextepc/freeDiameter/pcrf.conf
 | 
			
		||||
etc/nextepc/freeDiameter/pcrf.cert.pem
 | 
			
		||||
etc/nextepc/freeDiameter/pcrf.key.pem
 | 
			
		||||
etc/nextepc/pcrf.conf
 | 
			
		||||
support/systemd/nextepc-pcrfd.service lib/systemd/system
 | 
			
		||||
							
								
								
									
										7
									
								
								debian/nextepc-pgw.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								debian/nextepc-pgw.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
usr/bin/nextepc-pgwd
 | 
			
		||||
etc/nextepc/freeDiameter/pgw.conf
 | 
			
		||||
etc/nextepc/freeDiameter/pgw.cert.pem
 | 
			
		||||
etc/nextepc/freeDiameter/pgw.key.pem
 | 
			
		||||
etc/nextepc/pgw.conf
 | 
			
		||||
support/network/nextepc etc/network/interfaces.d
 | 
			
		||||
support/systemd/nextepc-pgwd.service lib/systemd/system
 | 
			
		||||
							
								
								
									
										47
									
								
								debian/nextepc-pgw.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								debian/nextepc-pgw.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# postinst script for nextepc
 | 
			
		||||
#
 | 
			
		||||
# see: dh_installdeb(1)
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
# summary of how this script can be called:
 | 
			
		||||
#        * <postinst> `configure' <most-recently-configured-version>
 | 
			
		||||
#        * <old-postinst> `abort-upgrade' <new version>
 | 
			
		||||
#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
 | 
			
		||||
#          <new-version>
 | 
			
		||||
#        * <postinst> `abort-remove'
 | 
			
		||||
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
 | 
			
		||||
#          <failed-install-package> <version> `removing'
 | 
			
		||||
#          <conflicting-package> <version>
 | 
			
		||||
# for details, see http://www.debian.org/doc/debian-policy/ or
 | 
			
		||||
# the debian-policy package
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
    configure)
 | 
			
		||||
    if ! grep "source-directory" /etc/network/interfaces | grep "/etc/network/interfaces.d" > /dev/null; then
 | 
			
		||||
        echo "source-directory /etc/network/interfaces.d" >> /etc/network/interfaces
 | 
			
		||||
    fi 
 | 
			
		||||
    if ! grep "pgwtun" /proc/net/dev > /dev/null; then
 | 
			
		||||
        ifup pgwtun
 | 
			
		||||
    fi
 | 
			
		||||
    ;;
 | 
			
		||||
 | 
			
		||||
    abort-upgrade|abort-remove|abort-deconfigure)
 | 
			
		||||
    ;;
 | 
			
		||||
 | 
			
		||||
    *)
 | 
			
		||||
        echo "postinst called with unknown argument \`$1'" >&2
 | 
			
		||||
        exit 1
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# dh_installdeb will replace this with shell code automatically
 | 
			
		||||
# generated by other debhelper scripts.
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								debian/nextepc-sgw.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								debian/nextepc-sgw.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
usr/bin/nextepc-sgwd
 | 
			
		||||
etc/nextepc/sgw.conf
 | 
			
		||||
support/systemd/nextepc-sgwd.service lib/systemd/system
 | 
			
		||||
							
								
								
									
										43
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										43
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
 | 
			
		||||
# Uncomment this to turn on verbose mode.
 | 
			
		||||
export DH_VERBOSE=1
 | 
			
		||||
 | 
			
		||||
DEBIAN  := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
 | 
			
		||||
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
 | 
			
		||||
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
 | 
			
		||||
 | 
			
		||||
# This has to be exported to make some magic below work.
 | 
			
		||||
#export DH_OPTIONS
 | 
			
		||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 | 
			
		||||
 | 
			
		||||
%:
 | 
			
		||||
	dh $@ --with autoreconf --with systemd
 | 
			
		||||
 | 
			
		||||
override_dh_auto_test:
 | 
			
		||||
	mongodb_exclude_list=; \
 | 
			
		||||
	sctp_exclude_list=; \
 | 
			
		||||
	mongodb_forked=no; \
 | 
			
		||||
	remove_db_uri_conf=; \
 | 
			
		||||
	if which mongod > /dev/null; then \
 | 
			
		||||
		if ! ps -ef | grep mongod | grep -v grep > /dev/null; then \
 | 
			
		||||
			mongodb_forked=yes; \
 | 
			
		||||
			mongod --fork --logpath debian/test/var/log/mongodb.log --dbpath debian/test/db; \
 | 
			
		||||
		fi; \
 | 
			
		||||
	else \
 | 
			
		||||
	    remove_db_uri_conf="/DB_URI/d"; \
 | 
			
		||||
		mongodb_exclude_list="-x s1setup_test attach_test volte_test handover_test"; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	mkdir -p debian/test/db debian/test/etc/nextepc/freeDiameter debian/test/var/log/nextepc; \
 | 
			
		||||
	sed -e 's?@SYSCONF_DIR@?'`pwd`'/debian/test/etc?g;s?@LOCALSTATE_DIR@?'`pwd`'/debian/test/var?g;'$$remove_db_uri_conf'' support/config/nextepc.conf.in > debian/test/etc/nextepc/nextepc.conf; \
 | 
			
		||||
	for i in `find support/freeDiameter -name '*.conf.in' -printf "%f\n" | sed 's/.in$$//g'`; do \
 | 
			
		||||
		sed 's?@SYSCONF_DIR@/nextepc?'`pwd`'/support?g;s?@LIB_DIR@/nextepc/\([_a-z0-9]*\)\.so?'`pwd`'/lib/fd/extensions/\1/.libs/\1.so?g' support/freeDiameter/$$i.in > debian/test/etc/nextepc/freeDiameter/$$i; \
 | 
			
		||||
	done; \
 | 
			
		||||
	if ! cat /proc/net/protocols | grep SCTP > /dev/null; then \
 | 
			
		||||
		sctp_exclude_list="-x testsctp s1setup_test attach_test volte_test handover_test"; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	lib/core/test/testcore $$sctp_exclude_list || exit; \
 | 
			
		||||
	test/testepc -f debian/test/etc/nextepc/nextepc.conf -c $$sctp_exclude_list $$mongodb_exclude_list || exit; \
 | 
			
		||||
	if test "x$$mongodb_forked" = xyes; then \
 | 
			
		||||
		pkill mongod; \
 | 
			
		||||
	fi;
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
3.0 (native)
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
SUBDIRS = @FREEDIAMETER_DIR@ core logger base s1ap nas fd gtp ipfw
 | 
			
		||||
SUBDIRS = @FREEDIAMETER_DIR@ core base s1ap nas fd gtp ipfw
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ AM_CPPFLAGS = \
 | 
			
		||||
AM_CFLAGS = \
 | 
			
		||||
	-Wall -Werror
 | 
			
		||||
 | 
			
		||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 | 
			
		||||
DEFS = @DEFS@ -DSYSCONF_DIR=\"$(sysconfdir)/\"
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,11 @@
 | 
			
		||||
 | 
			
		||||
#include "core_file.h"
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_lib.h"
 | 
			
		||||
#include <mongoc.h>
 | 
			
		||||
 | 
			
		||||
#include "context.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_CONFIG_FILE_PATH SYSCONFDIR PACKAGE ".conf"
 | 
			
		||||
 | 
			
		||||
static context_t self;
 | 
			
		||||
 | 
			
		||||
static int context_initialized = 0;
 | 
			
		||||
@@ -29,6 +28,9 @@ status_t context_final()
 | 
			
		||||
    d_assert(context_initialized == 1, return CORE_ERROR,
 | 
			
		||||
            "Context already has been finalized");
 | 
			
		||||
 | 
			
		||||
    if (self.config.bson)
 | 
			
		||||
        bson_destroy(self.config.bson);
 | 
			
		||||
 | 
			
		||||
    context_initialized = 0;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -39,19 +41,19 @@ context_t* context_self()
 | 
			
		||||
    return &self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t context_read_file(char *file_path)
 | 
			
		||||
status_t context_read_file()
 | 
			
		||||
{
 | 
			
		||||
    char buf[MAX_ERROR_STRING_LEN];
 | 
			
		||||
    config_t *config = &self.config;
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    file_t *file;
 | 
			
		||||
 | 
			
		||||
    jsmn_parser parser;
 | 
			
		||||
    bson_error_t error;
 | 
			
		||||
    size_t json_len;
 | 
			
		||||
    jsmn_parser parser;
 | 
			
		||||
    int result;
 | 
			
		||||
 | 
			
		||||
    config->path = file_path;
 | 
			
		||||
    if (config->path == NULL) config->path = DEFAULT_CONFIG_FILE_PATH;
 | 
			
		||||
    d_assert(config->path, return CORE_ERROR,);
 | 
			
		||||
 | 
			
		||||
    rv = file_open(&file, config->path, FILE_READ, FILE_OS_DEFAULT);
 | 
			
		||||
    if (rv != CORE_OK) 
 | 
			
		||||
@@ -88,6 +90,13 @@ status_t context_read_file(char *file_path)
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    config->bson = bson_new_from_json((const uint8_t *)config->json, -1, &error);;
 | 
			
		||||
    if (config->bson == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        d_fatal("Failed to parse configuration file '%s'", config->path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d_print("  Config '%s'\n", config->path);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -96,132 +105,137 @@ status_t context_read_file(char *file_path)
 | 
			
		||||
status_t context_parse_config()
 | 
			
		||||
{
 | 
			
		||||
    config_t *config = &self.config;
 | 
			
		||||
    bson_iter_t iter, child1_iter, child2_iter;
 | 
			
		||||
    c_uint32_t length = 0;
 | 
			
		||||
 | 
			
		||||
    char *json = config->json;
 | 
			
		||||
    jsmntok_t *token = config->token;
 | 
			
		||||
    d_assert(config, return CORE_ERROR, );
 | 
			
		||||
 | 
			
		||||
    typedef enum { START, ROOT, SKIP, STOP } parse_state;
 | 
			
		||||
    parse_state state = START;
 | 
			
		||||
    self.log.console = -1;
 | 
			
		||||
 | 
			
		||||
    size_t root_tokens = 0;
 | 
			
		||||
    size_t skip_tokens = 0;
 | 
			
		||||
    size_t i, j, m, n;
 | 
			
		||||
 | 
			
		||||
    for (i = 0, j = 1; j > 0; i++, j--)
 | 
			
		||||
    if (!bson_iter_init(&iter, config->bson))
 | 
			
		||||
    {
 | 
			
		||||
        jsmntok_t *t = &token[i];
 | 
			
		||||
        d_error("bson_iter_init failed in this document");
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        j += t->size;
 | 
			
		||||
 | 
			
		||||
        switch (state)
 | 
			
		||||
    while(bson_iter_next(&iter))
 | 
			
		||||
    {
 | 
			
		||||
        const char *key = bson_iter_key(&iter);
 | 
			
		||||
        if (!strcmp(key, "DB_URI") && BSON_ITER_HOLDS_UTF8(&iter))
 | 
			
		||||
        {
 | 
			
		||||
            case START:
 | 
			
		||||
            self.db_uri = bson_iter_utf8(&iter, &length);
 | 
			
		||||
        }
 | 
			
		||||
        else if (!strcmp(key, "LOG") && BSON_ITER_HOLDS_DOCUMENT(&iter))
 | 
			
		||||
        {
 | 
			
		||||
            bson_iter_recurse(&iter, &child1_iter);
 | 
			
		||||
            while(bson_iter_next(&child1_iter))
 | 
			
		||||
            {
 | 
			
		||||
                state = ROOT;
 | 
			
		||||
                root_tokens = t->size;
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ROOT:
 | 
			
		||||
            {
 | 
			
		||||
                if (jsmntok_equal(json, t, "DB_URI") == 0)
 | 
			
		||||
                const char *child1_key = bson_iter_key(&child1_iter);
 | 
			
		||||
                if (!strcmp(child1_key, "CONSOLE") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.db_uri = jsmntok_to_string(json, t+1);
 | 
			
		||||
                    self.log.console = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (jsmntok_equal(json, t, "LOG_PATH") == 0)
 | 
			
		||||
                else if (!strcmp(child1_key, "SYSLOG") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_UTF8(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.log_path = jsmntok_to_string(json, t+1);
 | 
			
		||||
                    self.log.syslog = bson_iter_utf8(&child1_iter, &length);
 | 
			
		||||
                }
 | 
			
		||||
                else if (jsmntok_equal(json, t, "TRACE") == 0)
 | 
			
		||||
                else if (!strcmp(child1_key, "SOCKET") &&
 | 
			
		||||
                        BSON_ITER_HOLDS_DOCUMENT(&iter))
 | 
			
		||||
                {
 | 
			
		||||
                    for (m = 1, n = 1; n > 0; m++, n--)
 | 
			
		||||
                    bson_iter_recurse(&child1_iter, &child2_iter);
 | 
			
		||||
                    while(bson_iter_next(&child2_iter))
 | 
			
		||||
                    {
 | 
			
		||||
                        n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                        char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                        if (jsmntok_equal(json, t+m, "S1AP") == 0)
 | 
			
		||||
                        const char *child2_key = bson_iter_key(&child2_iter);
 | 
			
		||||
                        if (!strcmp(child2_key, "FILE") &&
 | 
			
		||||
                            BSON_ITER_HOLDS_UTF8(&child2_iter))
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.trace_level.s1ap = atoi(v);
 | 
			
		||||
                            self.log.socket.file =
 | 
			
		||||
                                bson_iter_utf8(&child2_iter, &length);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "NAS") == 0)
 | 
			
		||||
                        else if (!strcmp(child2_key, "UNIX_DOMAIN") &&
 | 
			
		||||
                            BSON_ITER_HOLDS_UTF8(&child2_iter))
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.trace_level.nas = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "FD") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.trace_level.fd = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "GTP") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.trace_level.gtp = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "OTHERS") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.trace_level.others = atoi(v);
 | 
			
		||||
                            self.log.socket.unix_domain =
 | 
			
		||||
                                bson_iter_utf8(&child2_iter, &length);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (jsmntok_equal(json, t, "HIDDEN") == 0)
 | 
			
		||||
                else if (!strcmp(child1_key, "FILE") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_UTF8(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    for (m = 1, n = 1; n > 0; m++, n--)
 | 
			
		||||
                    {
 | 
			
		||||
                        n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                        char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                        if (jsmntok_equal(json, t+m, "DISABLE_HSS") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.hidden.disable_hss = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "DISABLE_SGW") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.hidden.disable_sgw = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "DISABLE_PGW") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.hidden.disable_pgw = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (jsmntok_equal(json, t+m, "DISABLE_PCRF") == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (v) self.hidden.disable_pcrf = atoi(v);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    self.log.file = bson_iter_utf8(&child1_iter, &length);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                state = SKIP;
 | 
			
		||||
                skip_tokens = t->size;
 | 
			
		||||
 | 
			
		||||
                root_tokens--;
 | 
			
		||||
                if (root_tokens == 0) state = STOP;
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case SKIP:
 | 
			
		||||
        }
 | 
			
		||||
        else if (!strcmp(key, "TRACE") && BSON_ITER_HOLDS_DOCUMENT(&iter))
 | 
			
		||||
        {
 | 
			
		||||
            bson_iter_recurse(&iter, &child1_iter);
 | 
			
		||||
            while(bson_iter_next(&child1_iter))
 | 
			
		||||
            {
 | 
			
		||||
                skip_tokens += t->size;
 | 
			
		||||
 | 
			
		||||
                skip_tokens--;
 | 
			
		||||
                if (skip_tokens == 0) state = ROOT;
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
                const char *child1_key = bson_iter_key(&child1_iter);
 | 
			
		||||
                if (!strcmp(child1_key, "S1AP") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.trace_level.s1ap = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "NAS") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.trace_level.nas = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "FD") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.trace_level.fd = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "GTP") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.trace_level.gtp = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "OTHERS") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.trace_level.others = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            case STOP:
 | 
			
		||||
        }
 | 
			
		||||
        else if (!strcmp(key, "NODE") && BSON_ITER_HOLDS_DOCUMENT(&iter))
 | 
			
		||||
        {
 | 
			
		||||
            bson_iter_recurse(&iter, &child1_iter);
 | 
			
		||||
            while(bson_iter_next(&child1_iter))
 | 
			
		||||
            {
 | 
			
		||||
                break;
 | 
			
		||||
                const char *child1_key = bson_iter_key(&child1_iter);
 | 
			
		||||
                if (!strcmp(child1_key, "DISABLE_HSS") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.node.disable_hss = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "DISABLE_SGW") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.node.disable_sgw = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "DISABLE_PGW") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.node.disable_pgw = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!strcmp(child1_key, "DISABLE_PCRF") &&
 | 
			
		||||
                    BSON_ITER_HOLDS_INT32(&child1_iter))
 | 
			
		||||
                {
 | 
			
		||||
                    self.node.disable_pcrf = bson_iter_int32(&child1_iter);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
            {
 | 
			
		||||
                d_error("Failed to parse configuration in the state(%u)", 
 | 
			
		||||
                        state);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t context_db_init(char *db_uri)
 | 
			
		||||
status_t context_db_init(const char *db_uri)
 | 
			
		||||
{
 | 
			
		||||
    bson_t reply;
 | 
			
		||||
    bson_error_t error;
 | 
			
		||||
@@ -257,7 +271,7 @@ status_t context_db_init(char *db_uri)
 | 
			
		||||
    if (!mongoc_client_get_server_status(self.db_client, NULL, &reply, &error)) 
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Failed to conect to server [%s]", db_uri);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
        return CORE_EAGAIN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d_assert(bson_iter_init_find(&iter, &reply, "ok"), 
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,10 @@ extern "C" {
 | 
			
		||||
#define MAX_NUM_OF_CONFIG_TOKEN 256
 | 
			
		||||
 | 
			
		||||
typedef struct _config_t {
 | 
			
		||||
    char *path;
 | 
			
		||||
    const char *path;
 | 
			
		||||
    char json[MAX_CONFIG_FILE_SIZE+1];
 | 
			
		||||
    jsmntok_t token[MAX_NUM_OF_CONFIG_TOKEN];
 | 
			
		||||
    void *bson;
 | 
			
		||||
} config_t;
 | 
			
		||||
 | 
			
		||||
#define MAX_DB_URI_LEN          256
 | 
			
		||||
@@ -23,13 +24,22 @@ typedef struct _config_t {
 | 
			
		||||
typedef struct _context_t {
 | 
			
		||||
    config_t config;
 | 
			
		||||
 | 
			
		||||
    char *log_path;
 | 
			
		||||
 | 
			
		||||
    char *db_uri;
 | 
			
		||||
    const char *db_uri;
 | 
			
		||||
    void *db_client;
 | 
			
		||||
    char *db_name;
 | 
			
		||||
    void *database;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        const char *path;
 | 
			
		||||
        int console;
 | 
			
		||||
        const char *syslog;
 | 
			
		||||
        struct {
 | 
			
		||||
            const char *unix_domain;
 | 
			
		||||
            const char *file;
 | 
			
		||||
        } socket;
 | 
			
		||||
        const char *file;
 | 
			
		||||
    } log;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        int s1ap;
 | 
			
		||||
        int nas;
 | 
			
		||||
@@ -43,7 +53,7 @@ typedef struct _context_t {
 | 
			
		||||
        int disable_sgw;
 | 
			
		||||
        int disable_pgw;
 | 
			
		||||
        int disable_pcrf;
 | 
			
		||||
    } hidden;
 | 
			
		||||
    } node;
 | 
			
		||||
 | 
			
		||||
} context_t;
 | 
			
		||||
 | 
			
		||||
@@ -51,11 +61,11 @@ CORE_DECLARE(status_t)      context_init(void);
 | 
			
		||||
CORE_DECLARE(status_t)      context_final(void);
 | 
			
		||||
CORE_DECLARE(context_t*)    context_self(void);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t)      context_read_file(char *file_path);
 | 
			
		||||
CORE_DECLARE(status_t)      context_read_file(void);
 | 
			
		||||
CORE_DECLARE(status_t)      context_parse_config(void);
 | 
			
		||||
CORE_DECLARE(status_t)      context_setup_trace_module(void);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t)      context_db_init(char *db_uri);
 | 
			
		||||
CORE_DECLARE(status_t)      context_db_init(const char *db_uri);
 | 
			
		||||
CORE_DECLARE(status_t)      context_db_final(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -144,10 +144,6 @@
 | 
			
		||||
#include <netinet/tcp.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAVE_NETINET_SCTP_H
 | 
			
		||||
#include <netinet/sctp.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAVE_SYS_IOCTL_H
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#endif
 | 
			
		||||
@@ -215,6 +211,8 @@ typedef  c_int32_t             	c_intptr_t;
 | 
			
		||||
@uint64_t_fmt@
 | 
			
		||||
@uint64_t_hex_fmt@
 | 
			
		||||
 | 
			
		||||
@pid_t_fmt@
 | 
			
		||||
 | 
			
		||||
#ifdef INT16_MIN
 | 
			
		||||
#define C_INT16_MIN   INT16_MIN
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,11 @@ extern int g_trace_mask;
 | 
			
		||||
#define D_MSG_TO_CONSOLE    0x00000001
 | 
			
		||||
#define D_MSG_TO_STDOUT     0x00000002
 | 
			
		||||
#define D_MSG_TO_SYSLOG     0x00000004
 | 
			
		||||
#define D_MSG_TO_LOGD       0x00000008
 | 
			
		||||
#define D_MSG_TO_SOCKET     0x00000008
 | 
			
		||||
#define D_MSG_TO_FILE       0x00000010
 | 
			
		||||
#define D_MSG_TO_ALL        (D_MSG_TO_CONSOLE | D_MSG_TO_STDOUT | \
 | 
			
		||||
                             D_MSG_TO_SYSLOG | D_MSG_TO_LOGD)
 | 
			
		||||
                             D_MSG_TO_SYSLOG | D_MSG_TO_SOCKET | \
 | 
			
		||||
                             D_MSG_TO_FILE )
 | 
			
		||||
 | 
			
		||||
#define D_LOG_LEVEL_NONE    0
 | 
			
		||||
#define D_LOG_LEVEL_FATAL   1
 | 
			
		||||
@@ -138,13 +140,17 @@ CORE_DECLARE(int) d_msg(int tp, int lv, c_time_t t, char *fn, int ln,
 | 
			
		||||
        expr; \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
void d_msg_init();
 | 
			
		||||
 | 
			
		||||
void d_msg_final();
 | 
			
		||||
 | 
			
		||||
void d_msg_register_console(int console_fd);
 | 
			
		||||
 | 
			
		||||
void d_msg_deregister_console();
 | 
			
		||||
status_t d_msg_console_init(int console_fd);
 | 
			
		||||
void d_msg_console_final();
 | 
			
		||||
void d_msg_syslog_init(const char *name);
 | 
			
		||||
void d_msg_syslog_final();
 | 
			
		||||
status_t d_msg_socket_init(const char *name);
 | 
			
		||||
void d_msg_socket_final();
 | 
			
		||||
status_t d_msg_socket_start(const char *file);
 | 
			
		||||
void d_msg_socket_stop();
 | 
			
		||||
void d_msg_socket_final();
 | 
			
		||||
status_t d_msg_file_init(const char *file);
 | 
			
		||||
void d_msg_file_final();
 | 
			
		||||
 | 
			
		||||
void d_msg_to(int to, int on_off);
 | 
			
		||||
 | 
			
		||||
@@ -198,8 +204,6 @@ void d_trace_level(int *mod_name, int level);
 | 
			
		||||
 */
 | 
			
		||||
void d_trace_off(int *mod_name);
 | 
			
		||||
 | 
			
		||||
#define D_LOGD_IPC_PATH "/tmp/dlogmesg"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif /* __cplusplus */
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,6 @@ typedef struct {
 | 
			
		||||
    struct sockaddr_in remote;
 | 
			
		||||
    int opt;
 | 
			
		||||
 | 
			
		||||
    index_t app_index;
 | 
			
		||||
    int sndrcv_errno;
 | 
			
		||||
} net_sock_t;
 | 
			
		||||
 | 
			
		||||
@@ -114,7 +113,7 @@ CORE_DECLARE(int) net_write(net_sock_t *net_sock, char *buffer, size_t size,
 | 
			
		||||
CORE_DECLARE(int) net_send(net_sock_t *net_sock, char *buffer, size_t size);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(int) net_sendto(net_sock_t *net_sock, char *buffer, size_t size,
 | 
			
		||||
        c_uint32_t ip_addr, c_uint16_t port);
 | 
			
		||||
        c_uint32_t addr, c_uint16_t port);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Close the socket
 | 
			
		||||
@@ -263,10 +262,10 @@ CORE_DECLARE(int) net_unregister_link(net_link_t *net_link);
 | 
			
		||||
CORE_DECLARE(int) net_fds_read_run(long timeout);
 | 
			
		||||
 | 
			
		||||
/** TunTap interface */
 | 
			
		||||
CORE_DECLARE(int) net_tuntap_open(net_link_t **net_link, char *tuntap_dev_name, 
 | 
			
		||||
        int is_tap);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(int) net_tuntap_close(net_link_t *net_link);
 | 
			
		||||
CORE_DECLARE(int) net_tun_open(net_link_t **net_link, char *name, int is_tap);
 | 
			
		||||
CORE_DECLARE(int) net_tun_set_ipv4(
 | 
			
		||||
        net_link_t *net_link, c_uint32_t addr, c_uint8_t bits);
 | 
			
		||||
CORE_DECLARE(int) net_tun_close(net_link_t *net_link);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_param.h"
 | 
			
		||||
#include "core_file.h"
 | 
			
		||||
#include "core_thread.h"
 | 
			
		||||
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
@@ -9,61 +10,258 @@
 | 
			
		||||
 | 
			
		||||
int g_trace_mask = 1;
 | 
			
		||||
 | 
			
		||||
int g_msg_to = D_MSG_TO_LOGD | D_MSG_TO_STDOUT;
 | 
			
		||||
int g_msg_to = D_MSG_TO_STDOUT;
 | 
			
		||||
 | 
			
		||||
int g_console_connected = 0;
 | 
			
		||||
int g_syslog_connected = 0;
 | 
			
		||||
int g_logd_connected = 0;
 | 
			
		||||
int g_socket_connected = 0;
 | 
			
		||||
int g_file_connected = 0;
 | 
			
		||||
 | 
			
		||||
int g_log_level_console = D_LOG_LEVEL_FULL;
 | 
			
		||||
int g_log_level_stdout = D_LOG_LEVEL_FULL;
 | 
			
		||||
int g_log_level_syslog = D_LOG_LEVEL_FULL;
 | 
			
		||||
int g_log_level_logd = D_LOG_LEVEL_FULL;
 | 
			
		||||
int g_log_level_socket = D_LOG_LEVEL_FULL;
 | 
			
		||||
int g_log_level_file = D_LOG_LEVEL_FULL;
 | 
			
		||||
 | 
			
		||||
int g_console_fd = -1;
 | 
			
		||||
int g_logd_fd = -1;
 | 
			
		||||
struct sockaddr_un g_logd_addr;
 | 
			
		||||
static int g_console_fd = -1;
 | 
			
		||||
static int g_socket_fd = -1;
 | 
			
		||||
static struct sockaddr_un g_socket_addr;
 | 
			
		||||
 | 
			
		||||
void d_msg_init()
 | 
			
		||||
static thread_id socket_thread = 0;
 | 
			
		||||
static void *THREAD_FUNC socket_main(thread_id id, void *data);
 | 
			
		||||
static int socket_handler(const char *path);
 | 
			
		||||
 | 
			
		||||
static file_t *g_file = NULL;
 | 
			
		||||
 | 
			
		||||
status_t d_msg_console_init(int console_fd)
 | 
			
		||||
{
 | 
			
		||||
    openlog("libcore", 0, LOG_DAEMON);
 | 
			
		||||
 | 
			
		||||
    g_syslog_connected = 1;
 | 
			
		||||
 | 
			
		||||
    g_logd_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
 | 
			
		||||
    d_assert(g_logd_fd >= 0, return,
 | 
			
		||||
            "socket() failed. (%d:%s)\n", errno, strerror(errno));
 | 
			
		||||
 | 
			
		||||
    g_logd_addr.sun_family = AF_UNIX;
 | 
			
		||||
    strcpy(g_logd_addr.sun_path, D_LOGD_IPC_PATH);
 | 
			
		||||
 | 
			
		||||
    g_logd_connected = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_final()
 | 
			
		||||
{
 | 
			
		||||
    g_syslog_connected = 0;
 | 
			
		||||
    closelog();
 | 
			
		||||
 | 
			
		||||
    g_logd_connected = 0;
 | 
			
		||||
    close(g_logd_fd);
 | 
			
		||||
    g_logd_fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_register_console(int console_fd)
 | 
			
		||||
{
 | 
			
		||||
    d_assert(console_fd >= 0, return, "param 'console_fd' is invalid");
 | 
			
		||||
    d_assert(console_fd >= 0, return CORE_ERROR,
 | 
			
		||||
            "param 'console_fd' is invalid");
 | 
			
		||||
 | 
			
		||||
    g_console_fd = console_fd;
 | 
			
		||||
    g_console_connected = 1;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_deregister_console()
 | 
			
		||||
void d_msg_console_final()
 | 
			
		||||
{
 | 
			
		||||
    g_console_connected = 0;
 | 
			
		||||
    g_console_fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_syslog_init(const char *name)
 | 
			
		||||
{
 | 
			
		||||
    d_assert(name, return, );
 | 
			
		||||
 | 
			
		||||
    openlog(name, 0, LOG_DAEMON);
 | 
			
		||||
    g_syslog_connected = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_syslog_final()
 | 
			
		||||
{
 | 
			
		||||
    g_syslog_connected = 0;
 | 
			
		||||
    closelog();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t d_msg_socket_init(const char *name)
 | 
			
		||||
{
 | 
			
		||||
    d_assert(name, return CORE_ERROR, );
 | 
			
		||||
 | 
			
		||||
    g_socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
 | 
			
		||||
    d_assert(g_socket_fd >= 0, return CORE_ERROR,
 | 
			
		||||
            "socket() failed. (%d:%s)\n", errno, strerror(errno));
 | 
			
		||||
 | 
			
		||||
    g_socket_addr.sun_family = AF_UNIX;
 | 
			
		||||
    strcpy(g_socket_addr.sun_path, name);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t d_msg_socket_start(const char *file)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    d_assert(file, return CORE_ERROR, );
 | 
			
		||||
 | 
			
		||||
    rv = thread_create(&socket_thread, NULL, socket_main, (void*)file);
 | 
			
		||||
    d_assert(rv == CORE_OK, return CORE_ERROR,
 | 
			
		||||
            "socket thread creation failed");
 | 
			
		||||
 | 
			
		||||
    g_socket_connected = 1;
 | 
			
		||||
    d_msg_to(D_MSG_TO_SOCKET, 1);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_socket_stop()
 | 
			
		||||
{
 | 
			
		||||
    d_msg_to(D_MSG_TO_SOCKET, 0);
 | 
			
		||||
    g_socket_connected = 0;
 | 
			
		||||
 | 
			
		||||
    if (socket_thread)
 | 
			
		||||
        thread_delete(socket_thread);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_socket_final()
 | 
			
		||||
{
 | 
			
		||||
    close(g_socket_fd);
 | 
			
		||||
    g_socket_fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *THREAD_FUNC socket_main(thread_id id, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    char *path = data;
 | 
			
		||||
 | 
			
		||||
    ret = socket_handler(path);
 | 
			
		||||
    if (ret != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Failed to initialize logger.");
 | 
			
		||||
        d_error("Check file permission for `%s`", path); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int socket_handler(const char *path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int ret;
 | 
			
		||||
    size_t nbytes;
 | 
			
		||||
    ssize_t r;
 | 
			
		||||
    int us;
 | 
			
		||||
    fd_set readfd;
 | 
			
		||||
    struct timeval timer_val;
 | 
			
		||||
    struct sockaddr_un svaddr;
 | 
			
		||||
    file_t *file = NULL;
 | 
			
		||||
    char g_buffer[1024];
 | 
			
		||||
 | 
			
		||||
    us = socket(AF_UNIX, SOCK_DGRAM, 0);
 | 
			
		||||
    if (us < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("socket() failed. (%d:%s)", errno, strerror(errno));
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(&svaddr, &g_socket_addr, sizeof(struct sockaddr_un));
 | 
			
		||||
 | 
			
		||||
    ret = bind(us, (struct sockaddr *)&svaddr, sizeof(svaddr));
 | 
			
		||||
    if (ret != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (errno == EADDRINUSE)
 | 
			
		||||
        {
 | 
			
		||||
            ret = file_remove(svaddr.sun_path);
 | 
			
		||||
            if (ret != 0)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("unlink(`%s`) failed. (%d:%s)",
 | 
			
		||||
                        svaddr.sun_path, errno, strerror(errno));
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
            ret = bind(us, (struct sockaddr *)&svaddr, sizeof(svaddr));
 | 
			
		||||
            if (ret != 0)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("bind() failed 2. (%d:%s)", errno, strerror(errno));
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            d_error("bind() failed. (%d:%s)", errno, strerror(errno));
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = file_open(&file, path,
 | 
			
		||||
            FILE_CREATE | FILE_WRITE| FILE_APPEND,
 | 
			
		||||
            FILE_UREAD | FILE_UWRITE | FILE_GREAD);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Cannot open log file '%s'", path);
 | 
			
		||||
        close(us);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (!thread_should_stop())
 | 
			
		||||
    {
 | 
			
		||||
        timer_val.tv_sec = 0;
 | 
			
		||||
        timer_val.tv_usec = 50000;
 | 
			
		||||
        FD_ZERO(&readfd);
 | 
			
		||||
        FD_SET(us, &readfd);
 | 
			
		||||
 | 
			
		||||
        r = select (us+1, &readfd, NULL, NULL, &timer_val);
 | 
			
		||||
        if (r == -1)
 | 
			
		||||
        {
 | 
			
		||||
            if (errno == EINTR)
 | 
			
		||||
                break;
 | 
			
		||||
            d_error("select() error(%d: %s)", errno, strerror(errno));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (r == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if (FD_ISSET(us, &readfd))
 | 
			
		||||
        {
 | 
			
		||||
            r = read(us, g_buffer, sizeof(g_buffer));
 | 
			
		||||
 | 
			
		||||
            if (r < 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (errno == EINTR)
 | 
			
		||||
                    break;
 | 
			
		||||
                d_error("read() failed. (%d:%s)", errno, strerror(errno));
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (r == 0)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            nbytes = r;
 | 
			
		||||
            rv = file_write(file, g_buffer, &nbytes);
 | 
			
		||||
            if (rv != CORE_OK || r != nbytes)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("Cannot write %ld bytes to log file (%ld written)",
 | 
			
		||||
                        (long)r, (long)nbytes);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    file_close(file);
 | 
			
		||||
 | 
			
		||||
    close(us);
 | 
			
		||||
 | 
			
		||||
    file_remove(svaddr.sun_path);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t d_msg_file_init(const char *file)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    d_assert(file, return CORE_ERROR, );
 | 
			
		||||
 | 
			
		||||
    rv = file_open(&g_file, file,
 | 
			
		||||
            FILE_CREATE | FILE_WRITE| FILE_APPEND,
 | 
			
		||||
            FILE_UREAD | FILE_UWRITE | FILE_GREAD);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Cannot open log file '%s'", file);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_file_connected = 1;
 | 
			
		||||
    d_msg_to(D_MSG_TO_FILE, 1);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_file_final()
 | 
			
		||||
{
 | 
			
		||||
    d_msg_to(D_MSG_TO_FILE, 0);
 | 
			
		||||
    g_file_connected = 0;
 | 
			
		||||
 | 
			
		||||
    file_close(g_file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void d_msg_to(int to, int on_off)
 | 
			
		||||
{
 | 
			
		||||
    switch (to)
 | 
			
		||||
@@ -83,10 +281,15 @@ void d_msg_to(int to, int on_off)
 | 
			
		||||
                g_msg_to | D_MSG_TO_SYSLOG :
 | 
			
		||||
                g_msg_to & ~D_MSG_TO_SYSLOG;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_LOGD:
 | 
			
		||||
        case D_MSG_TO_SOCKET:
 | 
			
		||||
            g_msg_to = on_off ?
 | 
			
		||||
                g_msg_to | D_MSG_TO_LOGD :
 | 
			
		||||
                g_msg_to & ~D_MSG_TO_LOGD;
 | 
			
		||||
                g_msg_to | D_MSG_TO_SOCKET :
 | 
			
		||||
                g_msg_to & ~D_MSG_TO_SOCKET;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_FILE:
 | 
			
		||||
            g_msg_to = on_off ?
 | 
			
		||||
                g_msg_to | D_MSG_TO_FILE :
 | 
			
		||||
                g_msg_to & ~D_MSG_TO_FILE;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_ALL:
 | 
			
		||||
            g_msg_to = on_off ? D_MSG_TO_ALL : 0;
 | 
			
		||||
@@ -114,14 +317,17 @@ void d_log_set_level(int to, int level)
 | 
			
		||||
        case D_MSG_TO_SYSLOG:
 | 
			
		||||
            g_log_level_syslog = level;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_LOGD:
 | 
			
		||||
            g_log_level_logd = level;
 | 
			
		||||
        case D_MSG_TO_SOCKET:
 | 
			
		||||
            g_log_level_socket = level;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_FILE:
 | 
			
		||||
            g_log_level_socket = level;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_ALL:
 | 
			
		||||
            g_log_level_console = level;
 | 
			
		||||
            g_log_level_stdout = level;
 | 
			
		||||
            g_log_level_syslog = level;
 | 
			
		||||
            g_log_level_logd = level;
 | 
			
		||||
            g_log_level_socket = level;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
@@ -138,8 +344,10 @@ int d_log_get_level(int to)
 | 
			
		||||
            return g_log_level_stdout;
 | 
			
		||||
        case D_MSG_TO_SYSLOG:
 | 
			
		||||
            return g_log_level_syslog;
 | 
			
		||||
        case D_MSG_TO_LOGD:
 | 
			
		||||
            return g_log_level_logd;
 | 
			
		||||
        case D_MSG_TO_SOCKET:
 | 
			
		||||
            return g_log_level_socket;
 | 
			
		||||
        case D_MSG_TO_FILE:
 | 
			
		||||
            return g_log_level_socket;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
@@ -160,14 +368,17 @@ void d_log_full(int to)
 | 
			
		||||
        case D_MSG_TO_SYSLOG:
 | 
			
		||||
            g_log_level_syslog = D_LOG_LEVEL_FULL;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_LOGD:
 | 
			
		||||
            g_log_level_logd = D_LOG_LEVEL_FULL;
 | 
			
		||||
        case D_MSG_TO_SOCKET:
 | 
			
		||||
            g_log_level_socket = D_LOG_LEVEL_FULL;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_FILE:
 | 
			
		||||
            g_log_level_socket = D_LOG_LEVEL_FULL;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_ALL:
 | 
			
		||||
            g_log_level_console = D_LOG_LEVEL_FULL;
 | 
			
		||||
            g_log_level_stdout = D_LOG_LEVEL_FULL;
 | 
			
		||||
            g_log_level_syslog = D_LOG_LEVEL_FULL;
 | 
			
		||||
            g_log_level_logd = D_LOG_LEVEL_FULL;
 | 
			
		||||
            g_log_level_socket = D_LOG_LEVEL_FULL;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
@@ -187,14 +398,17 @@ void d_log_off(int to)
 | 
			
		||||
        case D_MSG_TO_SYSLOG:
 | 
			
		||||
            g_log_level_syslog = D_LOG_LEVEL_NONE;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_LOGD:
 | 
			
		||||
            g_log_level_logd = D_LOG_LEVEL_NONE;
 | 
			
		||||
        case D_MSG_TO_SOCKET:
 | 
			
		||||
            g_log_level_socket = D_LOG_LEVEL_NONE;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_FILE:
 | 
			
		||||
            g_log_level_socket = D_LOG_LEVEL_NONE;
 | 
			
		||||
            break;
 | 
			
		||||
        case D_MSG_TO_ALL:
 | 
			
		||||
            g_log_level_console = D_LOG_LEVEL_NONE;
 | 
			
		||||
            g_log_level_stdout = D_LOG_LEVEL_NONE;
 | 
			
		||||
            g_log_level_syslog = D_LOG_LEVEL_NONE;
 | 
			
		||||
            g_log_level_logd = D_LOG_LEVEL_NONE;
 | 
			
		||||
            g_log_level_socket = D_LOG_LEVEL_NONE;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
@@ -283,10 +497,15 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...)
 | 
			
		||||
            {
 | 
			
		||||
                syslog(LOG_DEBUG, "%s", fstr);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_logd_connected && (g_msg_to & D_MSG_TO_LOGD))
 | 
			
		||||
            if (g_socket_connected && (g_msg_to & D_MSG_TO_SOCKET))
 | 
			
		||||
            {
 | 
			
		||||
                sendto(g_logd_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_logd_addr, sizeof(g_logd_addr));
 | 
			
		||||
                sendto(g_socket_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr));
 | 
			
		||||
            }
 | 
			
		||||
            if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
 | 
			
		||||
            {
 | 
			
		||||
                size_t nbytes = n;
 | 
			
		||||
                file_write(g_file, fstr, &nbytes);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE))
 | 
			
		||||
            {
 | 
			
		||||
@@ -310,10 +529,15 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...)
 | 
			
		||||
            {
 | 
			
		||||
                syslog(LOG_DEBUG, "%s", fstr);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_logd_connected && (g_msg_to & D_MSG_TO_LOGD))
 | 
			
		||||
            if (g_socket_connected && (g_msg_to & D_MSG_TO_SOCKET))
 | 
			
		||||
            {
 | 
			
		||||
                sendto(g_logd_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_logd_addr, sizeof(g_logd_addr));
 | 
			
		||||
                sendto(g_socket_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr));
 | 
			
		||||
            }
 | 
			
		||||
            if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
 | 
			
		||||
            {
 | 
			
		||||
                size_t nbytes = n;
 | 
			
		||||
                file_write(g_file, fstr, &nbytes);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE))
 | 
			
		||||
            {
 | 
			
		||||
@@ -353,12 +577,20 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...)
 | 
			
		||||
            {
 | 
			
		||||
                syslog(LOG_INFO, "[%s\n", fstr + 13);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_logd_connected && (g_msg_to & D_MSG_TO_LOGD) &&
 | 
			
		||||
                    lv <= g_log_level_logd)
 | 
			
		||||
            if (g_socket_connected && (g_msg_to & D_MSG_TO_SOCKET) &&
 | 
			
		||||
                    lv <= g_log_level_socket)
 | 
			
		||||
            {
 | 
			
		||||
                fstr[n++] = '\n';
 | 
			
		||||
                sendto(g_logd_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_logd_addr, sizeof(g_logd_addr));
 | 
			
		||||
                sendto(g_socket_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr));
 | 
			
		||||
            }
 | 
			
		||||
            if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
 | 
			
		||||
            {
 | 
			
		||||
                size_t nbytes;
 | 
			
		||||
 | 
			
		||||
                fstr[n++] = '\n';
 | 
			
		||||
                nbytes = n;
 | 
			
		||||
                file_write(g_file, fstr, &nbytes);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE) &&
 | 
			
		||||
                    lv <= g_log_level_console)
 | 
			
		||||
@@ -384,11 +616,19 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...)
 | 
			
		||||
            {
 | 
			
		||||
                syslog(LOG_CRIT, "[%s\n", fstr + 13);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_logd_connected && (g_msg_to & D_MSG_TO_LOGD))
 | 
			
		||||
            if (g_socket_connected && (g_msg_to & D_MSG_TO_SOCKET))
 | 
			
		||||
            {
 | 
			
		||||
                fstr[n++] = '\n';
 | 
			
		||||
                sendto(g_logd_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_logd_addr, sizeof(g_logd_addr));
 | 
			
		||||
                sendto(g_socket_fd, fstr, n, 0,
 | 
			
		||||
                    (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr));
 | 
			
		||||
            }
 | 
			
		||||
            if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
 | 
			
		||||
            {
 | 
			
		||||
                size_t nbytes;
 | 
			
		||||
 | 
			
		||||
                fstr[n++] = '\n';
 | 
			
		||||
                nbytes = n;
 | 
			
		||||
                file_write(g_file, fstr, &nbytes);
 | 
			
		||||
            }
 | 
			
		||||
            if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE))
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ void fsm_init(void *s, void *_e)
 | 
			
		||||
    fsm_t *fsm = s;
 | 
			
		||||
    event_t *e = _e;
 | 
			
		||||
 | 
			
		||||
    if (fsm->initial != (fsm_state_t)0)
 | 
			
		||||
    if (fsm->initial != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        (*fsm->initial)(s, e);
 | 
			
		||||
        if (fsm->initial != fsm->state)
 | 
			
		||||
@@ -46,7 +46,7 @@ void fsm_dispatch(void *s, void *_e)
 | 
			
		||||
    fsm->state = (fsm_handler_t)0;
 | 
			
		||||
 | 
			
		||||
    (*tmp)(s, e);
 | 
			
		||||
    if (fsm->state != (fsm_state_t)0)
 | 
			
		||||
    if (fsm->state != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        if (e)
 | 
			
		||||
        {
 | 
			
		||||
@@ -91,7 +91,7 @@ void fsm_final(void *s, void *_e)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fsm->final != (fsm_state_t)0)
 | 
			
		||||
    if (fsm->final != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        (*fsm->final)(s, e);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,25 @@
 | 
			
		||||
#include "core_errno.h"
 | 
			
		||||
#include "core_time.h"
 | 
			
		||||
 | 
			
		||||
#if USE_USRSCTP == 1
 | 
			
		||||
#if HAVE_USRSCTP_H
 | 
			
		||||
#include <usrsctp.h>
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#if HAVE_NETINET_SCTP_H
 | 
			
		||||
#include <netinet/sctp.h>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
#include <netpacket/packet.h>
 | 
			
		||||
#include <linux/if_tun.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAVE_NET_ROUTE_H
 | 
			
		||||
#include <net/route.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NET_FD_TYPE_SOCK    0
 | 
			
		||||
#define NET_FD_TYPE_LINK    1
 | 
			
		||||
 | 
			
		||||
@@ -136,8 +150,13 @@ static net_sock_t *net_sock_create(int type, int protocol)
 | 
			
		||||
        event.sctp_send_failure_event = 1;
 | 
			
		||||
        event.sctp_shutdown_event = 1;
 | 
			
		||||
 | 
			
		||||
#if USE_USRSCTP == 1
 | 
			
		||||
        if (setsockopt(sock, IPPROTO_SCTP, SCTP_EVENT,
 | 
			
		||||
                                &event, sizeof( event)) != 0 ) 
 | 
			
		||||
#else
 | 
			
		||||
        if (setsockopt(sock, IPPROTO_SCTP, SCTP_EVENTS,
 | 
			
		||||
                                &event, sizeof( event)) != 0 ) 
 | 
			
		||||
#endif
 | 
			
		||||
        {
 | 
			
		||||
            d_error("Unable to subscribe to SCTP events: (%d:%s)",
 | 
			
		||||
                    errno, strerror( errno ));
 | 
			
		||||
@@ -327,7 +346,9 @@ int net_open_ext(net_sock_t **net_sock,
 | 
			
		||||
                (struct sockaddr *)&sock_addr, sizeof(sock_addr));
 | 
			
		||||
        if (rc < 0)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("connect error(proto:%d remote:%s dport:%d lport:%d)",
 | 
			
		||||
            d_error("connect error(%d:%s)(proto:%d remote:%s dport:%d lport:%d)",
 | 
			
		||||
                    errno,
 | 
			
		||||
                    strerror(errno),
 | 
			
		||||
                    proto,
 | 
			
		||||
                    remote_host,
 | 
			
		||||
                    rport,
 | 
			
		||||
@@ -428,14 +449,20 @@ int net_read(net_sock_t *net_sock, char *buffer, size_t size, int timeout)
 | 
			
		||||
        }
 | 
			
		||||
        else if (net_sock->proto == IPPROTO_SCTP)
 | 
			
		||||
        {
 | 
			
		||||
            struct sctp_sndrcvinfo sndrcvinfo;
 | 
			
		||||
            int flags = 0;
 | 
			
		||||
            struct sockaddr remote_addr;
 | 
			
		||||
            socklen_t addr_len = sizeof(struct sockaddr);
 | 
			
		||||
#if USE_USRSCTP == 1
 | 
			
		||||
            rc = usrsctp_recvv((struct socket *)net_sock, buffer, size,
 | 
			
		||||
                        (struct sockaddr *)&remote_addr, &addr_len, 
 | 
			
		||||
                        NULL, NULL, NULL, &flags);
 | 
			
		||||
#else
 | 
			
		||||
            struct sctp_sndrcvinfo sndrcvinfo;
 | 
			
		||||
 | 
			
		||||
            rc = sctp_recvmsg(net_sock->sock_id, buffer, size,
 | 
			
		||||
                        (struct sockaddr *)&remote_addr, &addr_len, 
 | 
			
		||||
                        &sndrcvinfo, &flags);
 | 
			
		||||
#endif
 | 
			
		||||
            if (rc < 0) net_sock->sndrcv_errno = errno;
 | 
			
		||||
 | 
			
		||||
            /* Save the remote address */
 | 
			
		||||
@@ -469,6 +496,7 @@ int net_read(net_sock_t *net_sock, char *buffer, size_t size, int timeout)
 | 
			
		||||
                                    SCTP_COMM_LOST)
 | 
			
		||||
                                net_sock->sndrcv_errno = ECONNREFUSED;
 | 
			
		||||
                            break;
 | 
			
		||||
#if USE_USRSCTP != 1
 | 
			
		||||
                        case SCTP_SEND_FAILED :
 | 
			
		||||
                            d_error("SCTP_SEND_FAILED"
 | 
			
		||||
                                    "(type:0x%x, flags:0x%x, error:0x%x)\n", 
 | 
			
		||||
@@ -476,6 +504,7 @@ int net_read(net_sock_t *net_sock, char *buffer, size_t size, int timeout)
 | 
			
		||||
                                    not->sn_send_failed.ssf_flags,
 | 
			
		||||
                                    not->sn_send_failed.ssf_error);
 | 
			
		||||
                            break;
 | 
			
		||||
#endif
 | 
			
		||||
                        case SCTP_SHUTDOWN_EVENT :
 | 
			
		||||
                            d_trace(3, "SCTP_SHUTDOWN_EVENT\n");
 | 
			
		||||
                            net_sock->sndrcv_errno = ECONNREFUSED;
 | 
			
		||||
@@ -541,6 +570,7 @@ int net_write(net_sock_t *net_sock, char *buffer, size_t size,
 | 
			
		||||
    }
 | 
			
		||||
    else if (net_sock->proto == IPPROTO_SCTP)
 | 
			
		||||
    {
 | 
			
		||||
#if USE_USRSCTP != 1
 | 
			
		||||
        rc = sctp_sendmsg(net_sock->sock_id, buffer, size,
 | 
			
		||||
                (struct sockaddr *)dest_addr, addrsize,
 | 
			
		||||
                htonl(net_sock->ppid), 
 | 
			
		||||
@@ -551,12 +581,10 @@ int net_write(net_sock_t *net_sock, char *buffer, size_t size,
 | 
			
		||||
        if (rc < 0) net_sock->sndrcv_errno = errno;
 | 
			
		||||
 | 
			
		||||
        return rc;
 | 
			
		||||
    }
 | 
			
		||||
    else 
 | 
			
		||||
    {
 | 
			
		||||
        return -1;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int net_send(net_sock_t *net_sock, char *buffer, size_t size)
 | 
			
		||||
@@ -568,7 +596,7 @@ int net_send(net_sock_t *net_sock, char *buffer, size_t size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int net_sendto(net_sock_t *net_sock, char *buffer, size_t size,
 | 
			
		||||
        c_uint32_t ip_addr, c_uint16_t port)
 | 
			
		||||
        c_uint32_t addr, c_uint16_t port)
 | 
			
		||||
{
 | 
			
		||||
    struct sockaddr_in sock_addr;
 | 
			
		||||
    d_assert(net_sock && buffer, return -1, "Invalid params\n");
 | 
			
		||||
@@ -576,10 +604,9 @@ int net_sendto(net_sock_t *net_sock, char *buffer, size_t size,
 | 
			
		||||
    memset(&sock_addr, 0, sizeof(sock_addr));
 | 
			
		||||
    sock_addr.sin_family = AF_INET;
 | 
			
		||||
    sock_addr.sin_port = htons(port);
 | 
			
		||||
    sock_addr.sin_addr.s_addr = ip_addr;
 | 
			
		||||
    sock_addr.sin_addr.s_addr = addr;
 | 
			
		||||
 | 
			
		||||
    return net_write(net_sock, buffer, size, 
 | 
			
		||||
                &sock_addr, sizeof(sock_addr));
 | 
			
		||||
    return net_write(net_sock, buffer, size, &sock_addr, sizeof(sock_addr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Close the socket */
 | 
			
		||||
@@ -638,6 +665,7 @@ int  net_accept(net_sock_t **new_accept_sock, net_sock_t *net_sock, int timeout)
 | 
			
		||||
 | 
			
		||||
            node->sock_id = new_sock;
 | 
			
		||||
            node->proto = net_sock->proto;
 | 
			
		||||
            node->ppid = net_sock->ppid;
 | 
			
		||||
            *new_accept_sock = node;
 | 
			
		||||
 | 
			
		||||
            /* Save local and remote address */
 | 
			
		||||
@@ -1167,6 +1195,7 @@ int net_raw_open(net_link_t **net_link, int proto)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Create tuntap socket */
 | 
			
		||||
#if 0 /* deprecated */
 | 
			
		||||
int net_tuntap_open(net_link_t **net_link, char *tuntap_dev_name, 
 | 
			
		||||
        int is_tap)
 | 
			
		||||
{
 | 
			
		||||
@@ -1220,7 +1249,179 @@ cleanup:
 | 
			
		||||
    return -1;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** Create tun socket */
 | 
			
		||||
int net_tun_open(net_link_t **net_link, char *ifname, int is_tap)
 | 
			
		||||
{
 | 
			
		||||
    int sock;
 | 
			
		||||
    net_link_t *new_link = NULL;
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
    char *dev = "/dev/net/tun";
 | 
			
		||||
    int rc;
 | 
			
		||||
    struct ifreq ifr;
 | 
			
		||||
    int flags = IFF_NO_PI;
 | 
			
		||||
 | 
			
		||||
    sock = open(dev, O_RDWR);
 | 
			
		||||
    if (sock < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can not open %s",dev);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    char name[C_PATH_MAX];
 | 
			
		||||
    int tun = 0;
 | 
			
		||||
 | 
			
		||||
#define TUNTAP_ID_MAX 255
 | 
			
		||||
    for (tun = 0; tun < TUNTAP_ID_MAX; tun++)
 | 
			
		||||
    {
 | 
			
		||||
        (void)snprintf(name, sizeof(name), "/dev/tun%i", tun);
 | 
			
		||||
        if ((sock = open(name, O_RDWR)) > 0)
 | 
			
		||||
        {
 | 
			
		||||
            (void)snprintf(name, sizeof(name), "tun%i", tun);
 | 
			
		||||
            ifname = name;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pool_alloc_node(&link_pool, &new_link);
 | 
			
		||||
    d_assert(new_link != NULL, return -1,"No link pool is availabe\n");
 | 
			
		||||
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
    memset(&ifr, 0, sizeof(ifr));
 | 
			
		||||
 | 
			
		||||
    ifr.ifr_flags = (is_tap ? (flags | IFF_TAP) : (flags | IFF_TUN));
 | 
			
		||||
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
 | 
			
		||||
 | 
			
		||||
    rc = ioctl(sock, TUNSETIFF, (void *)&ifr);
 | 
			
		||||
    if (rc < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("iotcl error(dev:%s flags = %d)", ifname, flags);
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Save socket descriptor */
 | 
			
		||||
    new_link->fd = sock;
 | 
			
		||||
    /* Save the interface name */
 | 
			
		||||
    strncpy(new_link->ifname, ifname, IFNAMSIZ);
 | 
			
		||||
 | 
			
		||||
    *net_link = new_link;
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
cleanup:
 | 
			
		||||
    pool_free_node(&link_pool, new_link);
 | 
			
		||||
    close(sock);
 | 
			
		||||
    return -1;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int net_tun_set_ipv4(net_link_t *link, c_uint32_t ip_addr, c_uint8_t bits)
 | 
			
		||||
{
 | 
			
		||||
#if LINUX != 1
 | 
			
		||||
    int sock;
 | 
			
		||||
    
 | 
			
		||||
	struct ifaliasreq ifa;
 | 
			
		||||
	struct ifreq ifr;
 | 
			
		||||
	struct sockaddr_in addr;
 | 
			
		||||
	struct sockaddr_in mask;
 | 
			
		||||
    c_uint32_t mask_addr = htonl(0xffffffff << (32 - bits));
 | 
			
		||||
 | 
			
		||||
    char buf[512];
 | 
			
		||||
    int len;
 | 
			
		||||
    struct rt_msghdr *rtm;
 | 
			
		||||
    struct sockaddr_in dst, gw;
 | 
			
		||||
	struct sockaddr_in *paddr;
 | 
			
		||||
 | 
			
		||||
    sock = socket(AF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
 | 
			
		||||
	(void)memset(&ifa, '\0', sizeof ifa);
 | 
			
		||||
	(void)strlcpy(ifa.ifra_name, link->ifname, sizeof ifa.ifra_name);
 | 
			
		||||
 | 
			
		||||
	(void)memset(&ifr, '\0', sizeof ifr);
 | 
			
		||||
	(void)strlcpy(ifr.ifr_name, link->ifname, sizeof ifr.ifr_name);
 | 
			
		||||
 | 
			
		||||
	/* Delete previously assigned address */
 | 
			
		||||
	(void)ioctl(sock, SIOCDIFADDR, &ifr);
 | 
			
		||||
 | 
			
		||||
	(void)memset(&addr, '\0', sizeof(addr));
 | 
			
		||||
	addr.sin_family = AF_INET;
 | 
			
		||||
	addr.sin_addr.s_addr = ip_addr;
 | 
			
		||||
	addr.sin_len = sizeof(addr);
 | 
			
		||||
	(void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
 | 
			
		||||
	(void)memcpy(&ifa.ifra_broadaddr, &addr, sizeof(addr));
 | 
			
		||||
 | 
			
		||||
	(void)memset(&mask, '\0', sizeof(mask));
 | 
			
		||||
	mask.sin_family = AF_INET;
 | 
			
		||||
	mask.sin_addr.s_addr = 0xffffffff;
 | 
			
		||||
	mask.sin_len = sizeof(mask);
 | 
			
		||||
	(void)memcpy(&ifa.ifra_mask, &mask, sizeof(ifa.ifra_mask));
 | 
			
		||||
 | 
			
		||||
	if (ioctl(sock, SIOCAIFADDR, &ifa) == -1) {
 | 
			
		||||
		d_error("Can't IP address(dev:%s err:%s)",
 | 
			
		||||
                link->ifname, strerror(errno));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    close(sock); /* AF_INET, SOCK_DGRAM */
 | 
			
		||||
 | 
			
		||||
    sock = socket(PF_ROUTE, SOCK_RAW, 0);
 | 
			
		||||
    if (sock < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't open PF_ROUTE(%s)", strerror(errno));
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    (void)memset(&buf, 0, sizeof(buf));
 | 
			
		||||
    rtm = (struct rt_msghdr *)buf;
 | 
			
		||||
    rtm->rtm_type = RTM_ADD;
 | 
			
		||||
    rtm->rtm_version = RTM_VERSION;
 | 
			
		||||
    rtm->rtm_pid = getpid();
 | 
			
		||||
    rtm->rtm_seq = 0;
 | 
			
		||||
    rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
 | 
			
		||||
    rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
 | 
			
		||||
    paddr = (struct sockaddr_in *)(rtm + 1);
 | 
			
		||||
 | 
			
		||||
	(void)memset(&dst, '\0', sizeof(dst));
 | 
			
		||||
	dst.sin_family = AF_INET;
 | 
			
		||||
	dst.sin_addr.s_addr = ip_addr & mask_addr;
 | 
			
		||||
	dst.sin_len = sizeof(dst);
 | 
			
		||||
	(void)memcpy(paddr, &dst, sizeof(dst));
 | 
			
		||||
    paddr = (struct sockaddr_in *)((char *)paddr +
 | 
			
		||||
            CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
 | 
			
		||||
 | 
			
		||||
	(void)memset(&gw, '\0', sizeof(gw));
 | 
			
		||||
	gw.sin_family = AF_INET;
 | 
			
		||||
	gw.sin_addr.s_addr = ip_addr;
 | 
			
		||||
	gw.sin_len = sizeof(gw);
 | 
			
		||||
	(void)memcpy(paddr, &gw, sizeof(gw));
 | 
			
		||||
    paddr = (struct sockaddr_in *)((char *)paddr +
 | 
			
		||||
            CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
 | 
			
		||||
 | 
			
		||||
	(void)memset(&mask, '\0', sizeof(mask));
 | 
			
		||||
	mask.sin_family = AF_INET;
 | 
			
		||||
	mask.sin_addr.s_addr = mask_addr;
 | 
			
		||||
	mask.sin_len = sizeof(mask);
 | 
			
		||||
	(void)memcpy(paddr, &mask, sizeof(mask));
 | 
			
		||||
    paddr = (struct sockaddr_in *)((char *)paddr +
 | 
			
		||||
            CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
 | 
			
		||||
 | 
			
		||||
    len = (char*)paddr - buf;
 | 
			
		||||
    rtm->rtm_msglen = len;
 | 
			
		||||
    if (write(sock, buf, len) < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't add routing(%s)", strerror(errno));
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    close(sock); /* PF_ROUTE, SOCK_RAW */
 | 
			
		||||
 | 
			
		||||
#endif  /* LINUX == 1 */
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
int net_link_open(net_link_t **net_link, char *device, int proto)
 | 
			
		||||
@@ -1367,7 +1568,7 @@ int net_raw_close(net_link_t *net_link)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int net_tuntap_close(net_link_t *net_link)
 | 
			
		||||
int net_tun_close(net_link_t *net_link)
 | 
			
		||||
{
 | 
			
		||||
    d_assert(net_link,return -1, "net_link is NULL\n");
 | 
			
		||||
    close(net_link->fd);
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,6 @@ status_t core_initialize(void)
 | 
			
		||||
    tlv_init();
 | 
			
		||||
    tm_init();
 | 
			
		||||
    msgq_init();
 | 
			
		||||
    d_msg_init();
 | 
			
		||||
    signal_init();
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -65,7 +64,6 @@ void core_terminate(void)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Reverse ordered finalization */
 | 
			
		||||
    d_msg_final();
 | 
			
		||||
    msgq_final();
 | 
			
		||||
    tm_final();
 | 
			
		||||
    tlv_final();
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,10 @@ testcore_SOURCES = \
 | 
			
		||||
	testpkbuf.c testmisc.c testhash.c \
 | 
			
		||||
    abts.h  abts_tests.h testutil.c testutil.h
 | 
			
		||||
 | 
			
		||||
if !USRSCTP
 | 
			
		||||
testcore_SOURCES += testsctp.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
testcore_LDADD = \
 | 
			
		||||
    $(top_srcdir)/lib/core/src/libcore.la
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,9 @@ const struct testlist {
 | 
			
		||||
    {testaes},
 | 
			
		||||
    {testsha2},
 | 
			
		||||
    {testnetlib},
 | 
			
		||||
#if USE_USRSCTP != 1
 | 
			
		||||
    {testsctp},
 | 
			
		||||
#endif
 | 
			
		||||
    {testtime},
 | 
			
		||||
    {testtimer},
 | 
			
		||||
    {testthread},
 | 
			
		||||
 
 | 
			
		||||
@@ -14,11 +14,9 @@
 | 
			
		||||
static char buffer[TEST_BUFFER_SIZE];
 | 
			
		||||
static int tcp_server_started = 0;
 | 
			
		||||
static int udp_server_started = 0;
 | 
			
		||||
static int sctp_stream_server_started = 0;
 | 
			
		||||
static int sctp_seq_server_started = 0;
 | 
			
		||||
 | 
			
		||||
pthread_t tserver_tid,userver_tid,streamserver_tid, seqserver_tid;
 | 
			
		||||
net_sock_t *tserver_sock,*userver_sock,*streamserver_sock,*seqserver_sock;
 | 
			
		||||
pthread_t tserver_tid,userver_tid;
 | 
			
		||||
net_sock_t *tserver_sock,*userver_sock;
 | 
			
		||||
 | 
			
		||||
static void *tcp_session_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
@@ -108,6 +106,7 @@ static void start_tcp_server()
 | 
			
		||||
    {
 | 
			
		||||
        sleep(1);
 | 
			
		||||
    }
 | 
			
		||||
    sleep(1);
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -183,171 +182,6 @@ static void stop_udp_server()
 | 
			
		||||
    pthread_join(userver_tid, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *sctp_stream_session_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    net_sock_t *net_sock = (net_sock_t *)param;
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_read(net_sock, buffer, TEST_BUFFER_SIZE, 1);
 | 
			
		||||
        if (rc > 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (!strncmp(buffer, "QUIT",4))
 | 
			
		||||
            {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* Send received data */
 | 
			
		||||
                rc = net_send(net_sock, buffer, rc);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (rc == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* Timeout */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (rc != -2 && net_sock->sndrcv_errno != EAGAIN)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    net_close(net_sock);
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_stream_sctp_session(net_sock_t *net_sock)
 | 
			
		||||
{
 | 
			
		||||
    pthread_t tid;
 | 
			
		||||
 | 
			
		||||
    pthread_create(&tid, NULL, sctp_stream_session_main, (void *)net_sock);
 | 
			
		||||
    pthread_detach(tid);
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *sctp_stream_server_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
    net_sock_t *new_sock;
 | 
			
		||||
 | 
			
		||||
    rc = net_listen(&streamserver_sock, 
 | 
			
		||||
            SOCK_STREAM, IPPROTO_SCTP, TEST_SERVER_PORT);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_sctp_listen Error(rc = %d)\n",rc);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sctp_stream_server_started = 1;
 | 
			
		||||
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_accept(&new_sock, streamserver_sock, 1);
 | 
			
		||||
        if (rc >0)
 | 
			
		||||
        {
 | 
			
		||||
            /* New connection arrived. Start session */
 | 
			
		||||
            start_stream_sctp_session(new_sock);
 | 
			
		||||
        }
 | 
			
		||||
        else if (rc == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* Timeout */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Error occured */
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_stream_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    pthread_create(&streamserver_tid, NULL, sctp_stream_server_main, NULL);
 | 
			
		||||
    while (sctp_stream_server_started == 0)
 | 
			
		||||
    {
 | 
			
		||||
        sleep(1);
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stop_stream_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    net_close(streamserver_sock);
 | 
			
		||||
    pthread_join(streamserver_tid, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *sctp_seq_server_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    rc = net_listen(&seqserver_sock, 
 | 
			
		||||
            SOCK_SEQPACKET, IPPROTO_SCTP, TEST_SERVER_PORT);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_sctp Error(rc = %d)\n",rc);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sctp_seq_server_started = 1;
 | 
			
		||||
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        d_trace(1,"Wait for data....\n");
 | 
			
		||||
        rc = net_read(seqserver_sock, buffer, TEST_BUFFER_SIZE, 2);
 | 
			
		||||
        if (rc >0)
 | 
			
		||||
        {
 | 
			
		||||
            d_trace(1,"RECV %d bytes\n", rc);
 | 
			
		||||
            if (!strncmp(buffer, "QUIT",4))
 | 
			
		||||
            {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* Send received data */
 | 
			
		||||
                rc = net_send(seqserver_sock, buffer, rc);
 | 
			
		||||
                d_trace(1,"SEND %d bytes\n", rc);
 | 
			
		||||
                if (rc == -1)
 | 
			
		||||
                {
 | 
			
		||||
                    printf("error = %d\n", seqserver_sock->sndrcv_errno);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (rc == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* Timeout */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Error occured */
 | 
			
		||||
            if (rc != -2 && seqserver_sock->sndrcv_errno != EAGAIN)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_seq_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    pthread_create(&seqserver_tid, NULL, sctp_seq_server_main, NULL);
 | 
			
		||||
    while (sctp_seq_server_started == 0)
 | 
			
		||||
    {
 | 
			
		||||
        sleep(1);
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stop_seq_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    net_close(seqserver_sock);
 | 
			
		||||
    pthread_join(seqserver_tid, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netlib1(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int rc = 0;
 | 
			
		||||
@@ -529,139 +363,6 @@ static void netlib3(abts_case *tc, void *data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netlib4(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int rc = 0;
 | 
			
		||||
    net_sock_t *net_sock[TEST_MAX_NUM];
 | 
			
		||||
    char inputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    char outputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* Start SCTP Server */
 | 
			
		||||
    start_stream_sctp_server();
 | 
			
		||||
 | 
			
		||||
    /* Connect to invalid port */
 | 
			
		||||
    d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_FATAL);
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0,TEST_SERVER_PORT + 1,
 | 
			
		||||
                SOCK_STREAM, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, -1, rc);
 | 
			
		||||
        ABTS_PTR_NULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
    d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_FULL);
 | 
			
		||||
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0, TEST_SERVER_PORT,
 | 
			
		||||
                SOCK_STREAM, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
        ABTS_PTR_NOTNULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i=0; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        sprintf(inputbuf[i],"asdf%d",i);
 | 
			
		||||
        memset(outputbuf[i], 0, sizeof(outputbuf[i]));
 | 
			
		||||
        rc = net_send(net_sock[i], inputbuf[i], strlen(inputbuf[i])+1);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, strlen(inputbuf[i])+1, rc);
 | 
			
		||||
        rc = 0;
 | 
			
		||||
        while (1)
 | 
			
		||||
        {
 | 
			
		||||
            int n;
 | 
			
		||||
            n = net_read(net_sock[i], outputbuf[i], sizeof(outputbuf[1]), 1);
 | 
			
		||||
            if (n < 0 && net_sock[i]->sndrcv_errno == EAGAIN)
 | 
			
		||||
                continue;
 | 
			
		||||
            rc += n;
 | 
			
		||||
            if (n == 0 || n == 6)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, rc);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, strlen(outputbuf[i])+1);
 | 
			
		||||
        ABTS_STR_EQUAL(tc, inputbuf[i], outputbuf[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0 ; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_close(net_sock[i]);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stop_stream_sctp_server();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netlib5(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int rc = 0;
 | 
			
		||||
    net_sock_t *net_sock[TEST_MAX_NUM];
 | 
			
		||||
    char inputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    char outputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* Connect to invalid port.
 | 
			
		||||
     * In SCTP cases, net_open should be success always
 | 
			
		||||
     */
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0, TEST_SERVER_PORT + 1,
 | 
			
		||||
                SOCK_SEQPACKET, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
        ABTS_PTR_NOTNULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0 ; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_close(net_sock[i]);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Start SCTP Server */
 | 
			
		||||
    start_seq_sctp_server();
 | 
			
		||||
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0, TEST_SERVER_PORT,
 | 
			
		||||
                SOCK_SEQPACKET, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
        ABTS_PTR_NOTNULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i=0; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        sprintf(inputbuf[i],"asdf%d",i);
 | 
			
		||||
        memset(outputbuf[i], 0, sizeof(outputbuf[i]));
 | 
			
		||||
        rc = net_sendto(net_sock[i], inputbuf[i], strlen(inputbuf[i])+1, 
 | 
			
		||||
                inet_addr("127.0.0.1"), TEST_SERVER_PORT);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, strlen(inputbuf[i])+1, rc);
 | 
			
		||||
        rc = 0;
 | 
			
		||||
        while (1)
 | 
			
		||||
        {
 | 
			
		||||
            int n;
 | 
			
		||||
            n = net_read(net_sock[i], outputbuf[i], sizeof(outputbuf[i]), 1);
 | 
			
		||||
            if (n < 0 && net_sock[i]->sndrcv_errno == EAGAIN)
 | 
			
		||||
                continue;
 | 
			
		||||
            rc += n;
 | 
			
		||||
            if (n == 0 || n == 6)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, rc);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, strlen(outputbuf[i])+1);
 | 
			
		||||
        ABTS_STR_EQUAL(tc, inputbuf[i], outputbuf[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0 ; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_close(net_sock[i]);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stop_seq_sctp_server();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netlib6(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
    net_ftp_t *ftp_session = NULL;
 | 
			
		||||
@@ -741,7 +442,7 @@ static void filter_updu(char *buf, int len)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netlib7(abts_case *tc, void *data)
 | 
			
		||||
static void netlib5(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    net_link_t *net_link = NULL;
 | 
			
		||||
    int promisc = 1;
 | 
			
		||||
@@ -788,7 +489,7 @@ static int make_test_updu(char *src_addr, char *dst_addr, char *buf, int len)
 | 
			
		||||
    return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netlib8(abts_case *tc, void *data)
 | 
			
		||||
static void netlib6(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    net_link_t *net_link = NULL;
 | 
			
		||||
    int promisc = 1;
 | 
			
		||||
@@ -827,14 +528,28 @@ abts_suite *testnetlib(abts_suite *suite)
 | 
			
		||||
    suite = ADD_SUITE(suite);
 | 
			
		||||
 | 
			
		||||
    abts_run_test(suite, netlib1, NULL);
 | 
			
		||||
    /*
 | 
			
		||||
     * OpenSUSE OBS
 | 
			
		||||
     * - Ubuntu 17.04 i586 failed
 | 
			
		||||
     * - Jinyoung Fixed
 | 
			
		||||
     *
 | 
			
		||||
[  542s] testnetlib          :  Line 262: expected <0>, but saw <-1>
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ASSERT: !(net_sock && buffer). Invalid params
 | 
			
		||||
[  542s]  (net_lib.c:590)
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ASSERT: !(net_sock). net_sock is NULL
 | 
			
		||||
[  542s]  (net_lib.c:408)
 | 
			
		||||
[  542s] [10/30 07:48:38.730] ASSERT: !(net_sock). net_sock is NULL
 | 
			
		||||
    */
 | 
			
		||||
    abts_run_test(suite, netlib2, NULL);
 | 
			
		||||
    abts_run_test(suite, netlib3, NULL);
 | 
			
		||||
    abts_run_test(suite, netlib4, NULL);
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
    abts_run_test(suite, netlib5, NULL);
 | 
			
		||||
    abts_run_test(suite, netlib6, NULL);
 | 
			
		||||
#if LINUX == 1
 | 
			
		||||
    abts_run_test(suite, netlib7, NULL);
 | 
			
		||||
    abts_run_test(suite, netlib8, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return suite;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										325
									
								
								lib/core/test/testsctp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								lib/core/test/testsctp.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,325 @@
 | 
			
		||||
#define TRACE_MODULE _testsctp
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_net.h"
 | 
			
		||||
#include "testutil.h"
 | 
			
		||||
 | 
			
		||||
#define TEST_SERVER_PORT    5121
 | 
			
		||||
#define TEST_BUFFER_SIZE    1024
 | 
			
		||||
 | 
			
		||||
#define TEST_MAX_NUM     4
 | 
			
		||||
 | 
			
		||||
static char buffer[TEST_BUFFER_SIZE];
 | 
			
		||||
static int sctp_stream_server_started = 0;
 | 
			
		||||
static int sctp_seq_server_started = 0;
 | 
			
		||||
 | 
			
		||||
pthread_t streamserver_tid, seqserver_tid;
 | 
			
		||||
net_sock_t *streamserver_sock,*seqserver_sock;
 | 
			
		||||
 | 
			
		||||
static void *sctp_stream_session_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    net_sock_t *net_sock = (net_sock_t *)param;
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_read(net_sock, buffer, TEST_BUFFER_SIZE, 1);
 | 
			
		||||
        if (rc > 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (!strncmp(buffer, "QUIT",4))
 | 
			
		||||
            {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* Send received data */
 | 
			
		||||
                rc = net_send(net_sock, buffer, rc);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (rc == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* Timeout */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (rc != -2 && net_sock->sndrcv_errno != EAGAIN)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    net_close(net_sock);
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_stream_sctp_session(net_sock_t *net_sock)
 | 
			
		||||
{
 | 
			
		||||
    pthread_t tid;
 | 
			
		||||
 | 
			
		||||
    pthread_create(&tid, NULL, sctp_stream_session_main, (void *)net_sock);
 | 
			
		||||
    pthread_detach(tid);
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *sctp_stream_server_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
    net_sock_t *new_sock;
 | 
			
		||||
 | 
			
		||||
    rc = net_listen(&streamserver_sock, 
 | 
			
		||||
            SOCK_STREAM, IPPROTO_SCTP, TEST_SERVER_PORT);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_sctp_listen Error(rc = %d)\n",rc);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sctp_stream_server_started = 1;
 | 
			
		||||
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_accept(&new_sock, streamserver_sock, 1);
 | 
			
		||||
        if (rc >0)
 | 
			
		||||
        {
 | 
			
		||||
            /* New connection arrived. Start session */
 | 
			
		||||
            start_stream_sctp_session(new_sock);
 | 
			
		||||
        }
 | 
			
		||||
        else if (rc == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* Timeout */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Error occured */
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_stream_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    pthread_create(&streamserver_tid, NULL, sctp_stream_server_main, NULL);
 | 
			
		||||
    while (sctp_stream_server_started == 0)
 | 
			
		||||
    {
 | 
			
		||||
        sleep(1);
 | 
			
		||||
    }
 | 
			
		||||
    sleep(1);
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stop_stream_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    net_close(streamserver_sock);
 | 
			
		||||
    pthread_join(streamserver_tid, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *sctp_seq_server_main(void *param)
 | 
			
		||||
{
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    rc = net_listen(&seqserver_sock, 
 | 
			
		||||
            SOCK_SEQPACKET, IPPROTO_SCTP, TEST_SERVER_PORT);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_sctp Error(rc = %d)\n",rc);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sctp_seq_server_started = 1;
 | 
			
		||||
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        d_trace(1,"Wait for data....\n");
 | 
			
		||||
        rc = net_read(seqserver_sock, buffer, TEST_BUFFER_SIZE, 2);
 | 
			
		||||
        if (rc >0)
 | 
			
		||||
        {
 | 
			
		||||
            d_trace(1,"RECV %d bytes\n", rc);
 | 
			
		||||
            if (!strncmp(buffer, "QUIT",4))
 | 
			
		||||
            {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* Send received data */
 | 
			
		||||
                rc = net_send(seqserver_sock, buffer, rc);
 | 
			
		||||
                d_trace(1,"SEND %d bytes\n", rc);
 | 
			
		||||
                if (rc == -1)
 | 
			
		||||
                {
 | 
			
		||||
                    printf("error = %d\n", seqserver_sock->sndrcv_errno);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (rc == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /* Timeout */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Error occured */
 | 
			
		||||
            if (rc != -2 && seqserver_sock->sndrcv_errno != EAGAIN)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_seq_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    pthread_create(&seqserver_tid, NULL, sctp_seq_server_main, NULL);
 | 
			
		||||
    while (sctp_seq_server_started == 0)
 | 
			
		||||
    {
 | 
			
		||||
        sleep(1);
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stop_seq_sctp_server()
 | 
			
		||||
{
 | 
			
		||||
    net_close(seqserver_sock);
 | 
			
		||||
    pthread_join(seqserver_tid, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_sctp1(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int rc = 0;
 | 
			
		||||
    net_sock_t *net_sock[TEST_MAX_NUM];
 | 
			
		||||
    char inputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    char outputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* Start SCTP Server */
 | 
			
		||||
    start_stream_sctp_server();
 | 
			
		||||
 | 
			
		||||
    /* Connect to invalid port */
 | 
			
		||||
    d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_FATAL);
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0,TEST_SERVER_PORT + 1,
 | 
			
		||||
                SOCK_STREAM, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, -1, rc);
 | 
			
		||||
        ABTS_PTR_NULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
    d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_FULL);
 | 
			
		||||
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0, TEST_SERVER_PORT,
 | 
			
		||||
                SOCK_STREAM, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
        ABTS_PTR_NOTNULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i=0; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        sprintf(inputbuf[i],"asdf%d",i);
 | 
			
		||||
        memset(outputbuf[i], 0, sizeof(outputbuf[i]));
 | 
			
		||||
        rc = net_send(net_sock[i], inputbuf[i], strlen(inputbuf[i])+1);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, strlen(inputbuf[i])+1, rc);
 | 
			
		||||
        rc = 0;
 | 
			
		||||
        while (1)
 | 
			
		||||
        {
 | 
			
		||||
            int n;
 | 
			
		||||
            n = net_read(net_sock[i], outputbuf[i], sizeof(outputbuf[1]), 1);
 | 
			
		||||
            if (n < 0 && net_sock[i]->sndrcv_errno == EAGAIN)
 | 
			
		||||
                continue;
 | 
			
		||||
            rc += n;
 | 
			
		||||
            if (n == 0 || n == 6)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, rc);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, strlen(outputbuf[i])+1);
 | 
			
		||||
        ABTS_STR_EQUAL(tc, inputbuf[i], outputbuf[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0 ; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_close(net_sock[i]);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stop_stream_sctp_server();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_sctp2(abts_case *tc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int rc = 0;
 | 
			
		||||
    net_sock_t *net_sock[TEST_MAX_NUM];
 | 
			
		||||
    char inputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    char outputbuf[TEST_MAX_NUM][25];
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* Connect to invalid port.
 | 
			
		||||
     * In SCTP cases, net_open should be success always
 | 
			
		||||
     */
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0, TEST_SERVER_PORT + 1,
 | 
			
		||||
                SOCK_SEQPACKET, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
        ABTS_PTR_NOTNULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0 ; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_close(net_sock[i]);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Start SCTP Server */
 | 
			
		||||
    start_seq_sctp_server();
 | 
			
		||||
 | 
			
		||||
    for (i =0 ; i<TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_sock[i] = NULL;
 | 
			
		||||
        rc = net_open(&net_sock[i], "127.0.0.1", 0, TEST_SERVER_PORT,
 | 
			
		||||
                SOCK_SEQPACKET, IPPROTO_SCTP);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
        ABTS_PTR_NOTNULL(tc, net_sock[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i=0; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        sprintf(inputbuf[i],"asdf%d",i);
 | 
			
		||||
        memset(outputbuf[i], 0, sizeof(outputbuf[i]));
 | 
			
		||||
        rc = net_sendto(net_sock[i], inputbuf[i], strlen(inputbuf[i])+1, 
 | 
			
		||||
                inet_addr("127.0.0.1"), TEST_SERVER_PORT);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, strlen(inputbuf[i])+1, rc);
 | 
			
		||||
        rc = 0;
 | 
			
		||||
        while (1)
 | 
			
		||||
        {
 | 
			
		||||
            int n;
 | 
			
		||||
            n = net_read(net_sock[i], outputbuf[i], sizeof(outputbuf[i]), 1);
 | 
			
		||||
            if (n < 0 && net_sock[i]->sndrcv_errno == EAGAIN)
 | 
			
		||||
                continue;
 | 
			
		||||
            rc += n;
 | 
			
		||||
            if (n == 0 || n == 6)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, rc);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 6, strlen(outputbuf[i])+1);
 | 
			
		||||
        ABTS_STR_EQUAL(tc, inputbuf[i], outputbuf[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0 ; i< TEST_MAX_NUM; i++)
 | 
			
		||||
    {
 | 
			
		||||
        rc = net_close(net_sock[i]);
 | 
			
		||||
        ABTS_INT_EQUAL(tc, 0, rc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stop_seq_sctp_server();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abts_suite *testsctp(abts_suite *suite)
 | 
			
		||||
{
 | 
			
		||||
    suite = ADD_SUITE(suite);
 | 
			
		||||
 | 
			
		||||
    abts_run_test(suite, test_sctp1, NULL);
 | 
			
		||||
    abts_run_test(suite, test_sctp2, NULL);
 | 
			
		||||
 | 
			
		||||
    return suite;
 | 
			
		||||
}
 | 
			
		||||
@@ -378,6 +378,15 @@ abts_suite *testtimer(abts_suite *suite)
 | 
			
		||||
{
 | 
			
		||||
    suite = ADD_SUITE(suite)
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
     * OpenSUSE OBS
 | 
			
		||||
     * - Ubuntu 16.10 i586 failed
 | 
			
		||||
     * - It is probably VM issue
 | 
			
		||||
     * [  661s] testtimer           :  Line 176: expected <1449351760>, but saw <0>
 | 
			
		||||
     * [  661s] Line 305: expected <1019>, but saw <1024>
 | 
			
		||||
     * [  661s] Line 372: expected <1019>, but saw <1024>
 | 
			
		||||
     * [  661s] FAILED 3 of 4
 | 
			
		||||
     */
 | 
			
		||||
    abts_run_test(suite, test_now, NULL);
 | 
			
		||||
    abts_run_test(suite, timer_test_1, NULL);
 | 
			
		||||
    abts_run_test(suite, timer_test_2, NULL);
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,7 @@ abts_suite *testtlv(abts_suite *suite);
 | 
			
		||||
abts_suite *testaes(abts_suite *suite);
 | 
			
		||||
abts_suite *testsha2(abts_suite *suite);
 | 
			
		||||
abts_suite *testnetlib(abts_suite *suite);
 | 
			
		||||
abts_suite *testsctp(abts_suite *suite);
 | 
			
		||||
abts_suite *testtime(abts_suite *suite);
 | 
			
		||||
abts_suite *testtimer(abts_suite *suite);
 | 
			
		||||
abts_suite *testthread(abts_suite *suite);
 | 
			
		||||
 
 | 
			
		||||
@@ -14,22 +14,22 @@ dnl Must come before AM_INIT_AUTOMAKE.
 | 
			
		||||
AC_CONFIG_AUX_DIR([build-aux])
 | 
			
		||||
AM_INIT_AUTOMAKE([1.10 -Wall -Werror foreign])
 | 
			
		||||
 | 
			
		||||
# Minimum Autoconf version required.
 | 
			
		||||
AC_PREREQ(2.63)
 | 
			
		||||
 | 
			
		||||
# Where to generate output; srcdir location.
 | 
			
		||||
AC_CONFIG_HEADERS([include/freeDiameter/config.h])
 | 
			
		||||
AC_CANONICAL_HOST
 | 
			
		||||
case $host in
 | 
			
		||||
    *linux*)
 | 
			
		||||
        sctp=true;
 | 
			
		||||
        ;;
 | 
			
		||||
    *-apple-darwin*)
 | 
			
		||||
        AC_DEFINE_UNQUOTED([DISABLE_SCTP],
 | 
			
		||||
                [1], [Disable SCTP])
 | 
			
		||||
        sctp=false;
 | 
			
		||||
        ;;
 | 
			
		||||
    *-freebsd*)
 | 
			
		||||
        AC_DEFINE_UNQUOTED([SCTP_USE_MAPPED_ADDRESSES],
 | 
			
		||||
                [1], [Disable SCTP])
 | 
			
		||||
        sctp=true;
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        sctp=true;
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
AM_CONDITIONAL([SCTP], [test x$sctp = xtrue])
 | 
			
		||||
@@ -63,17 +63,16 @@ AH_BOTTOM([
 | 
			
		||||
#endif /* FD_IS_CONFIG */
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl kernel style compile messages
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
dnl Checks CC and freinds
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_CPP
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_AWK
 | 
			
		||||
AC_PROG_SED
 | 
			
		||||
AC_PROG_YACC
 | 
			
		||||
AC_PROG_LEX
 | 
			
		||||
AM_PROG_AR
 | 
			
		||||
 | 
			
		||||
dnl libtool
 | 
			
		||||
LT_INIT([dlopen])
 | 
			
		||||
 | 
			
		||||
dnl Check Endian
 | 
			
		||||
@@ -105,14 +104,29 @@ AC_DEFINE_UNQUOTED([FD_PROJECT_VERSION_API],
 | 
			
		||||
        [6],
 | 
			
		||||
        [API version of this package])
 | 
			
		||||
 | 
			
		||||
PREFIX=$ac_default_prefix
 | 
			
		||||
if test "x$prefix" != "xNONE"; then
 | 
			
		||||
    PREFIX=$prefix
 | 
			
		||||
fi
 | 
			
		||||
# adl_RECURSIVE_EVAL(VALUE, RESULT)
 | 
			
		||||
# =================================
 | 
			
		||||
# Interpolate the VALUE in loop until it doesn't change,
 | 
			
		||||
# and set the result to $RESULT.
 | 
			
		||||
# WARNING: It's easy to get an infinite loop with some unsane input.
 | 
			
		||||
# For example ${datadir} becomes ${datarootdir}, and then ${prefix}/share, and
 | 
			
		||||
# finally ${prefix} is replaced by the prefix.
 | 
			
		||||
AC_DEFUN([adl_RECURSIVE_EVAL],
 | 
			
		||||
[_lcl_receval="$1"
 | 
			
		||||
$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
 | 
			
		||||
     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
 | 
			
		||||
     _lcl_receval_old=''
 | 
			
		||||
     while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
 | 
			
		||||
       _lcl_receval_old="[$]_lcl_receval"
 | 
			
		||||
       eval _lcl_receval="\"[$]_lcl_receval\""
 | 
			
		||||
     done
 | 
			
		||||
     echo "[$]_lcl_receval")`])
 | 
			
		||||
adl_RECURSIVE_EVAL(["${libdir}"], [LIB_DIR])
 | 
			
		||||
adl_RECURSIVE_EVAL(["${sysconfdir}"], [SYSCONF_DIR])
 | 
			
		||||
AC_DEFINE_UNQUOTED([DEFAULT_CONF_PATH],
 | 
			
		||||
        ["${PREFIX}/etc/freeDiameter"], [Default Configuration Path])
 | 
			
		||||
        ["${SYSCONF_DIR}/nextepc/freeDiameter"], [Default Configuration Path])
 | 
			
		||||
AC_DEFINE_UNQUOTED([DEFAULT_EXTENSIONS_PATH],
 | 
			
		||||
        ["${PREFIX}/lib/freeDiameter"], [Default Configuration Path])
 | 
			
		||||
        ["${LIB_DIR}/nextepc"], [Default Extensions Path])
 | 
			
		||||
AC_SUBST(PREFIX)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -173,6 +187,6 @@ source code location    : ${srcdir}
 | 
			
		||||
compiler                : ${CC}
 | 
			
		||||
compiler flags          : ${CFLAGS}
 | 
			
		||||
linker flags            : ${LDFLAGS} ${LIBS}
 | 
			
		||||
default conf path       : `eval echo \`echo ${prefix}/etc/freeDiameter\``
 | 
			
		||||
default extention path  : `eval echo \`echo ${prefix}/lib/freeDiameter\``
 | 
			
		||||
config directory        : ${SYSCONF_DIR}/nextepc/freeDiameter
 | 
			
		||||
extensions directory    : ${LIB_DIR}/nextepc
 | 
			
		||||
"
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@ endif
 | 
			
		||||
AM_YFLAGS = -p fdd -d
 | 
			
		||||
AM_LFLAGS = -p -Cem -Pfdd
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = fdd.tab.h
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
    -I$(top_srcdir)/include
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,6 @@ int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t fla
 | 
			
		||||
		case AF_INET:
 | 
			
		||||
			if (! (flags & EP_ACCEPTALL)) {
 | 
			
		||||
				if (IN_IS_ADDR_UNSPECIFIED(&ptr.sin->sin_addr) 
 | 
			
		||||
				 || IN_IS_ADDR_LOOPBACK(&ptr.sin->sin_addr)
 | 
			
		||||
				    /* the next one filters both EXPERIMENTAL, BADCLASS and MULTICAST. */
 | 
			
		||||
				 || ((ntohl(ptr.sin->sin_addr.s_addr) & 0xe0000000) == 0xe0000000)
 | 
			
		||||
				 || (ptr.sin->sin_addr.s_addr == INADDR_BROADCAST)) {
 | 
			
		||||
@@ -78,10 +77,7 @@ int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t fla
 | 
			
		||||
		case AF_INET6:
 | 
			
		||||
			if (! (flags & EP_ACCEPTALL)) {
 | 
			
		||||
				if (IN6_IS_ADDR_UNSPECIFIED(&ptr.sin6->sin6_addr) 
 | 
			
		||||
				 || IN6_IS_ADDR_LOOPBACK(&ptr.sin6->sin6_addr)
 | 
			
		||||
				 || IN6_IS_ADDR_MULTICAST(&ptr.sin6->sin6_addr)
 | 
			
		||||
				 || IN6_IS_ADDR_LINKLOCAL(&ptr.sin6->sin6_addr)
 | 
			
		||||
				 || IN6_IS_ADDR_SITELOCAL(&ptr.sin6->sin6_addr)) {
 | 
			
		||||
				 || IN6_IS_ADDR_MULTICAST(&ptr.sin6->sin6_addr)) {
 | 
			
		||||
					LOG_A("  DEBUG:fd_ep_add_merge  Address was ignored, not added.");
 | 
			
		||||
					return 0;
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -347,10 +347,11 @@ struct sysctlhead {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* EMULATE_SYSCTL */
 | 
			
		||||
 | 
			
		||||
#ifndef __FreeBSD__
 | 
			
		||||
int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
 | 
			
		||||
         size_t newlen);
 | 
			
		||||
 | 
			
		||||
#ifndef __FreeBSD__
 | 
			
		||||
#define test_bit(ix, pData)     ((*pData) & (1<<(ix)))
 | 
			
		||||
#define __set_bit(ix, pData)    (*pData) |= (1<<(ix))
 | 
			
		||||
#define __clear_bit(ix, pData)  (*pData) &= ~(1<<(ix))
 | 
			
		||||
 
 | 
			
		||||
@@ -122,8 +122,8 @@ int logger_start(const char *path)
 | 
			
		||||
            ret = unlink(D_LOGD_IPC_PATH);
 | 
			
		||||
            if (ret != 0)
 | 
			
		||||
            {
 | 
			
		||||
                fprintf(stderr, "unlink() failed. (%d:%s)\n",
 | 
			
		||||
                        errno, strerror(errno));
 | 
			
		||||
                fprintf(stderr, "unlink(`%s`) failed. (%d:%s)\n",
 | 
			
		||||
                        D_LOGD_IPC_PATH, errno, strerror(errno));
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
            ret = bind(us, (struct sockaddr *)&svaddr, sizeof(svaddr));
 | 
			
		||||
@@ -212,5 +212,7 @@ int logger_start(const char *path)
 | 
			
		||||
 | 
			
		||||
    close(us);
 | 
			
		||||
 | 
			
		||||
    unlink(D_LOGD_IPC_PATH);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								main.c
									
									
									
									
									
								
							@@ -30,7 +30,8 @@ static void show_help(const char *name)
 | 
			
		||||
           "   -h                   Show help\n"
 | 
			
		||||
           "   -d                   Start as daemon\n"
 | 
			
		||||
           "   -f                   Set configuration file name\n"
 | 
			
		||||
           "   -l log_path          Fork log daemon with file path to be logged to\n"
 | 
			
		||||
           "   -l log_file          Log file path to be logged to\n"
 | 
			
		||||
           "   -p pid_file          PID file path\n"
 | 
			
		||||
           "\n", name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -46,6 +47,12 @@ static int check_signal(int signum)
 | 
			
		||||
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        case SIGHUP:
 | 
			
		||||
        {
 | 
			
		||||
            d_info("SIGHUP received");
 | 
			
		||||
            app_logger_restart();
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case SIGUSR1:
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
@@ -73,12 +80,14 @@ int main(int argc, char *argv[])
 | 
			
		||||
     *
 | 
			
		||||
     * Keep the order of starting-up
 | 
			
		||||
     */
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    char *config_path = NULL;
 | 
			
		||||
    char *log_path = NULL;
 | 
			
		||||
    char *pid_path = NULL;
 | 
			
		||||
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        int opt = getopt (argc, argv, "vhdf:l:");
 | 
			
		||||
        int opt = getopt (argc, argv, "vhdf:l:p:");
 | 
			
		||||
        if (opt == -1)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
@@ -114,6 +123,9 @@ int main(int argc, char *argv[])
 | 
			
		||||
            case 'l':
 | 
			
		||||
                log_path = optarg;
 | 
			
		||||
                break;
 | 
			
		||||
            case 'p':
 | 
			
		||||
                pid_path = optarg;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                show_help(argv[0]);
 | 
			
		||||
                return EXIT_FAILURE;
 | 
			
		||||
@@ -126,8 +138,13 @@ int main(int argc, char *argv[])
 | 
			
		||||
    atexit(terminate);
 | 
			
		||||
 | 
			
		||||
    core_initialize();
 | 
			
		||||
    if (app_initialize(config_path, log_path) != CORE_OK)
 | 
			
		||||
    app_log_pid(pid_path);
 | 
			
		||||
    rv = app_initialize(config_path, log_path);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        if (rv == CORE_EAGAIN)
 | 
			
		||||
            return EXIT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
        d_fatal("NextEPC initialization failed. Aborted");
 | 
			
		||||
        return EXIT_FAILURE;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,57 +10,46 @@ COMMON_INCLUDES = app.h
 | 
			
		||||
libmme_la_SOURCES = $(COMMON_INCLUDES) mme.c $(COMMON_SOURCES)
 | 
			
		||||
libmme_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/mme/libmme.la
 | 
			
		||||
libmme_la_LIBADD = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/mme/libmme.la
 | 
			
		||||
 | 
			
		||||
libhss_la_SOURCES = $(COMMON_INCLUDES) hss.c $(COMMON_SOURCES)
 | 
			
		||||
libhss_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/hss/libhss.la
 | 
			
		||||
libhss_la_LIBADD = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/hss/libhss.la
 | 
			
		||||
 | 
			
		||||
libsgw_la_SOURCES = $(COMMON_INCLUDES) sgw.c $(COMMON_SOURCES)
 | 
			
		||||
libsgw_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/sgw/libsgw.la
 | 
			
		||||
libsgw_la_LIBADD = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/sgw/libsgw.la
 | 
			
		||||
 | 
			
		||||
libpgw_la_SOURCES = $(COMMON_INCLUDES) pgw.c $(COMMON_SOURCES)
 | 
			
		||||
libpgw_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/pgw/libpgw.la
 | 
			
		||||
libpgw_la_LIBADD = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/pgw/libpgw.la
 | 
			
		||||
 | 
			
		||||
libpcrf_la_SOURCES = $(COMMON_INCLUDES) pcrf.c $(COMMON_SOURCES)
 | 
			
		||||
libpcrf_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/pcrf/libpcrf.la
 | 
			
		||||
libpcrf_la_LIBADD = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/pcrf/libpcrf.la
 | 
			
		||||
 | 
			
		||||
libepc_la_SOURCES = $(COMMON_INCLUDES) epc.c $(COMMON_SOURCES)
 | 
			
		||||
libepc_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/mme/libmme.la \
 | 
			
		||||
    $(top_srcdir)/src/hss/libhss.la \
 | 
			
		||||
    $(top_srcdir)/src/sgw/libsgw.la \
 | 
			
		||||
@@ -68,7 +57,6 @@ libepc_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/src/pcrf/libpcrf.la
 | 
			
		||||
libepc_la_LIBADD = \
 | 
			
		||||
    $(top_srcdir)/lib/base/libbase.la \
 | 
			
		||||
    $(top_srcdir)/lib/logger/liblogger.la \
 | 
			
		||||
    $(top_srcdir)/src/mme/libmme.la \
 | 
			
		||||
    $(top_srcdir)/src/hss/libhss.la \
 | 
			
		||||
    $(top_srcdir)/src/sgw/libsgw.la \
 | 
			
		||||
@@ -77,13 +65,14 @@ libepc_la_LIBADD = \
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
	-I$(top_srcdir)/lib/core/include \
 | 
			
		||||
	-I$(top_srcdir)/lib/logger \
 | 
			
		||||
	-I$(top_srcdir)/lib/base
 | 
			
		||||
 | 
			
		||||
AM_CFLAGS = \
 | 
			
		||||
	-Wall -Werror
 | 
			
		||||
 | 
			
		||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 | 
			
		||||
DEFS = @DEFS@ \
 | 
			
		||||
	   -DSYSCONF_DIR=\"$(sysconfdir)/\" \
 | 
			
		||||
	   -DLOCALSTATE_DIR=\"$(localstatedir)/\"
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in
 | 
			
		||||
MOSTLYCLEANFILES = core *.stackdump
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								src/app.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/app.h
									
									
									
									
									
								
							@@ -8,17 +8,24 @@
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif /* __cplusplus */
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) app_initialize(char *config_path, char *log_path);
 | 
			
		||||
extern const char *app_name;
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) app_initialize(
 | 
			
		||||
        const char *config_path, const char *log_path);
 | 
			
		||||
CORE_DECLARE(void) app_terminate(void);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) app_will_initialize(char *config_path, char *log_path);
 | 
			
		||||
CORE_DECLARE(status_t) app_did_initialize(char *config_path, char *log_path);
 | 
			
		||||
CORE_DECLARE(status_t) app_will_initialize(
 | 
			
		||||
        const char *config_path, const char *log_path);
 | 
			
		||||
CORE_DECLARE(status_t) app_did_initialize(void);
 | 
			
		||||
CORE_DECLARE(void) app_will_terminate(void);
 | 
			
		||||
CORE_DECLARE(void) app_did_terminate(void);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) config_initialize(char *config_path);
 | 
			
		||||
CORE_DECLARE(status_t) config_initialize(const char *config_path);
 | 
			
		||||
CORE_DECLARE(void) config_terminate(void);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) app_logger_restart(void);
 | 
			
		||||
CORE_DECLARE(status_t) app_log_pid(const char *pid_path);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) mme_initialize();
 | 
			
		||||
CORE_DECLARE(void) mme_terminate(void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								src/epc.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/epc.c
									
									
									
									
									
								
							@@ -19,7 +19,9 @@ static semaphore_id sgw_sem2 = 0;
 | 
			
		||||
static semaphore_id hss_sem1 = 0;
 | 
			
		||||
static semaphore_id hss_sem2 = 0;
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
const char *app_name = "epc";
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    pid_t pid;
 | 
			
		||||
    status_t rv;
 | 
			
		||||
@@ -39,7 +41,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    semaphore_create(&pcrf_sem1, 0); /* copied to PCRF/PGW/SGW/HSS process */
 | 
			
		||||
    semaphore_create(&pcrf_sem2, 0); /* copied to PCRF/PGW/SGW/HSS process */
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_pcrf == 0)
 | 
			
		||||
    if (context_self()->node.disable_pcrf == 0)
 | 
			
		||||
    {
 | 
			
		||||
        pid = fork();
 | 
			
		||||
        d_assert(pid >= 0, _exit(EXIT_FAILURE), "fork() failed");
 | 
			
		||||
@@ -83,7 +85,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    semaphore_create(&pgw_sem1, 0); /* copied to PGW/SGW/HSS process */
 | 
			
		||||
    semaphore_create(&pgw_sem2, 0); /* copied to PGW/SGW/HSS process */
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_pgw == 0)
 | 
			
		||||
    if (context_self()->node.disable_pgw == 0)
 | 
			
		||||
    {
 | 
			
		||||
        pid = fork();
 | 
			
		||||
        d_assert(pid >= 0, _exit(EXIT_FAILURE), "fork() failed");
 | 
			
		||||
@@ -131,7 +133,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    semaphore_create(&sgw_sem1, 0); /* copied to SGW/HSS process */
 | 
			
		||||
    semaphore_create(&sgw_sem2, 0); /* copied to SGW/HSS process */
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_sgw == 0)
 | 
			
		||||
    if (context_self()->node.disable_sgw == 0)
 | 
			
		||||
    {
 | 
			
		||||
        pid = fork();
 | 
			
		||||
        d_assert(pid >= 0, _exit(EXIT_FAILURE), "fork() failed");
 | 
			
		||||
@@ -181,7 +183,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    semaphore_create(&hss_sem1, 0); /* copied to HSS process */
 | 
			
		||||
    semaphore_create(&hss_sem2, 0); /* copied to HSS process */
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_hss == 0)
 | 
			
		||||
    if (context_self()->node.disable_hss == 0)
 | 
			
		||||
    {
 | 
			
		||||
        pid = fork();
 | 
			
		||||
        d_assert(pid >= 0, _exit(EXIT_FAILURE), "fork() failed");
 | 
			
		||||
@@ -226,7 +228,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
        if (hss_sem1) semaphore_wait(hss_sem1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = app_did_initialize(config_path, log_path);
 | 
			
		||||
    rv = app_did_initialize();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    d_trace(1, "MME try to initialize\n");
 | 
			
		||||
@@ -245,7 +247,7 @@ void app_terminate(void)
 | 
			
		||||
    mme_terminate();
 | 
			
		||||
    d_trace(1, "MME terminate...done\n");
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_hss == 0)
 | 
			
		||||
    if (context_self()->node.disable_hss == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (hss_sem2) semaphore_post(hss_sem2);
 | 
			
		||||
        if (hss_sem1) semaphore_wait(hss_sem1);
 | 
			
		||||
@@ -253,7 +255,7 @@ void app_terminate(void)
 | 
			
		||||
    if (hss_sem1) semaphore_delete(hss_sem1);
 | 
			
		||||
    if (hss_sem2) semaphore_delete(hss_sem2);
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_sgw == 0)
 | 
			
		||||
    if (context_self()->node.disable_sgw == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (sgw_sem2) semaphore_post(sgw_sem2);
 | 
			
		||||
        if (sgw_sem1) semaphore_wait(sgw_sem1);
 | 
			
		||||
@@ -261,7 +263,7 @@ void app_terminate(void)
 | 
			
		||||
    if (sgw_sem1) semaphore_delete(sgw_sem1);
 | 
			
		||||
    if (sgw_sem2) semaphore_delete(sgw_sem2);
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_pgw == 0)
 | 
			
		||||
    if (context_self()->node.disable_pgw == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (pgw_sem2) semaphore_post(pgw_sem2);
 | 
			
		||||
        if (pgw_sem1) semaphore_wait(pgw_sem1);
 | 
			
		||||
@@ -269,7 +271,7 @@ void app_terminate(void)
 | 
			
		||||
    if (pgw_sem1) semaphore_delete(pgw_sem1);
 | 
			
		||||
    if (pgw_sem2) semaphore_delete(pgw_sem2);
 | 
			
		||||
 | 
			
		||||
    if (context_self()->hidden.disable_pcrf == 0)
 | 
			
		||||
    if (context_self()->node.disable_pcrf == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (pcrf_sem2) semaphore_post(pcrf_sem2);
 | 
			
		||||
        if (pcrf_sem1) semaphore_wait(pcrf_sem1);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,9 @@
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "app.h"
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
const char *app_name = "hss";
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int others = 0;
 | 
			
		||||
@@ -26,7 +28,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    d_assert(rv == CORE_OK, return rv, "Failed to intialize HSS");
 | 
			
		||||
    d_trace(1, "HSS initialize...done\n");
 | 
			
		||||
 | 
			
		||||
    rv = app_did_initialize(config_path, log_path);
 | 
			
		||||
    rv = app_did_initialize();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
 
 | 
			
		||||
@@ -297,6 +297,12 @@ status_t hss_db_auth_info(
 | 
			
		||||
            utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
 | 
			
		||||
            memcpy(auth_info->k, CORE_HEX(utf8, length, buf), HSS_KEY_LEN);
 | 
			
		||||
        }
 | 
			
		||||
        else if (!strcmp(key, "opc") && BSON_ITER_HOLDS_UTF8(&inner_iter)) 
 | 
			
		||||
        {
 | 
			
		||||
            utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
 | 
			
		||||
            auth_info->use_opc = 1;
 | 
			
		||||
            memcpy(auth_info->opc, CORE_HEX(utf8, length, buf), HSS_KEY_LEN);
 | 
			
		||||
        }
 | 
			
		||||
        else if (!strcmp(key, "op") && BSON_ITER_HOLDS_UTF8(&inner_iter)) 
 | 
			
		||||
        {
 | 
			
		||||
            utf8 = (char *)bson_iter_utf8(&inner_iter, &length);
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,8 @@ extern "C" {
 | 
			
		||||
 | 
			
		||||
typedef struct _hss_db_auth_info_t {
 | 
			
		||||
    c_uint8_t       k[HSS_KEY_LEN];
 | 
			
		||||
    c_uint8_t       use_opc;
 | 
			
		||||
    c_uint8_t       opc[HSS_KEY_LEN];
 | 
			
		||||
    c_uint8_t       op[HSS_KEY_LEN];
 | 
			
		||||
    c_uint8_t       amf[HSS_AMF_LEN];
 | 
			
		||||
    c_uint8_t       rand[RAND_LEN];
 | 
			
		||||
 
 | 
			
		||||
@@ -105,7 +105,10 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
 | 
			
		||||
    memcpy(visited_plmn_id, hdr->avp_value->os.data, hdr->avp_value->os.len);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    milenage_opc(auth_info.k, auth_info.op, opc);
 | 
			
		||||
    if (auth_info.use_opc)
 | 
			
		||||
        memcpy(opc, auth_info.opc, sizeof(opc));
 | 
			
		||||
    else
 | 
			
		||||
        milenage_opc(auth_info.k, auth_info.op, opc);
 | 
			
		||||
    milenage_generate(opc, auth_info.amf, auth_info.k,
 | 
			
		||||
        core_uint64_to_buffer(auth_info.sqn, HSS_SQN_LEN, sqn), auth_info.rand,
 | 
			
		||||
        autn, ik, ck, ak, xres, &xres_len);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										217
									
								
								src/init.c
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								src/init.c
									
									
									
									
									
								
							@@ -2,23 +2,32 @@
 | 
			
		||||
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_thread.h"
 | 
			
		||||
#include "core_file.h"
 | 
			
		||||
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "logger.h"
 | 
			
		||||
 | 
			
		||||
#include "app.h"
 | 
			
		||||
 | 
			
		||||
static thread_id logger_thread = 0;
 | 
			
		||||
static void *THREAD_FUNC logger_main(thread_id id, void *data);
 | 
			
		||||
#define DEFAULT_CONFIG_FILE_PATH SYSCONF_DIR PACKAGE "/nextepc.conf"
 | 
			
		||||
#define DEFAULT_RUNTIME_DIR_PATH LOCALSTATE_DIR "run/"
 | 
			
		||||
 | 
			
		||||
status_t app_will_initialize(char *config_path, char *log_path)
 | 
			
		||||
static status_t app_logger_init();
 | 
			
		||||
static status_t app_logger_final();
 | 
			
		||||
static status_t app_logger_start();
 | 
			
		||||
static status_t app_logger_stop();
 | 
			
		||||
 | 
			
		||||
status_t app_will_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int others = 0;
 | 
			
		||||
 | 
			
		||||
    context_init();
 | 
			
		||||
 | 
			
		||||
    rv = context_read_file(config_path);
 | 
			
		||||
    context_self()->config.path = config_path;
 | 
			
		||||
    if (context_self()->config.path == NULL)
 | 
			
		||||
        context_self()->config.path = DEFAULT_CONFIG_FILE_PATH;
 | 
			
		||||
 | 
			
		||||
    rv = context_read_file();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    rv = context_parse_config();
 | 
			
		||||
@@ -30,40 +39,30 @@ status_t app_will_initialize(char *config_path, char *log_path)
 | 
			
		||||
        d_trace_level(&_app_init, others);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    context_self()->log.path = log_path;
 | 
			
		||||
    rv = app_logger_init();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    if (context_self()->db_uri)
 | 
			
		||||
    {
 | 
			
		||||
        rv = context_db_init(context_self()->db_uri);
 | 
			
		||||
        if (rv != CORE_OK) return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t app_did_initialize(char *config_path, char *log_path)
 | 
			
		||||
status_t app_did_initialize(void)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    status_t rv = app_logger_start();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    if (log_path) 
 | 
			
		||||
        context_self()->log_path = log_path;
 | 
			
		||||
 | 
			
		||||
    if (context_self()->log_path)
 | 
			
		||||
    {
 | 
			
		||||
        d_print("  Logging '%s'\n", context_self()->log_path);
 | 
			
		||||
        rv = thread_create(&logger_thread, NULL, 
 | 
			
		||||
                logger_main, context_self()->log_path);
 | 
			
		||||
        if (rv != CORE_OK) return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_will_terminate(void)
 | 
			
		||||
{
 | 
			
		||||
    if (logger_thread)
 | 
			
		||||
    {
 | 
			
		||||
        thread_delete(logger_thread);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    app_logger_stop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_did_terminate(void)
 | 
			
		||||
@@ -73,16 +72,172 @@ void app_did_terminate(void)
 | 
			
		||||
        context_db_final();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    app_logger_final();
 | 
			
		||||
 | 
			
		||||
    context_final();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *THREAD_FUNC logger_main(thread_id id, void *data)
 | 
			
		||||
status_t app_log_pid(const char *pid_path)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    char *path = data;
 | 
			
		||||
    file_t *pid_file = NULL;
 | 
			
		||||
    file_info_t finfo;
 | 
			
		||||
    static pid_t saved_pid = -1;
 | 
			
		||||
    pid_t mypid;
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    char default_pid_path[MAX_FILEPATH_LEN];
 | 
			
		||||
    char buf[128];
 | 
			
		||||
 | 
			
		||||
    ret = logger_start(path);
 | 
			
		||||
    d_assert(ret == 0, return NULL, "Failed to intialize Logger");
 | 
			
		||||
    if (pid_path == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        snprintf(default_pid_path, sizeof(default_pid_path),
 | 
			
		||||
                "%snextepc-%sd/pid", DEFAULT_RUNTIME_DIR_PATH, app_name);
 | 
			
		||||
        pid_path = default_pid_path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
    mypid = getpid();
 | 
			
		||||
    if (mypid != saved_pid
 | 
			
		||||
        && file_stat(&finfo, pid_path, FILE_INFO_MTIME) == CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_warn("pid file %s overwritten -- Unclean "
 | 
			
		||||
                "shutdown of previous NextEPC run?", pid_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((rv = file_open(&pid_file, pid_path,
 | 
			
		||||
            FILE_WRITE | FILE_CREATE | FILE_TRUNCATE,
 | 
			
		||||
            FILE_UREAD | FILE_UWRITE | FILE_GREAD | FILE_WREAD)) != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("could not create %s", pid_path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    snprintf(buf, sizeof(buf), "%" C_PID_T_FMT "\r\n", mypid);
 | 
			
		||||
    file_puts(buf, pid_file);
 | 
			
		||||
    file_close(pid_file);
 | 
			
		||||
    saved_pid = mypid;
 | 
			
		||||
 | 
			
		||||
    d_print("  PID[%" C_PID_T_FMT "] : '%s'\n", saved_pid, pid_path);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t app_logger_restart()
 | 
			
		||||
{
 | 
			
		||||
    app_logger_stop();
 | 
			
		||||
    app_logger_final();
 | 
			
		||||
 | 
			
		||||
    app_logger_init();
 | 
			
		||||
    app_logger_start();
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static status_t app_logger_init()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    if (context_self()->log.console >= 0)
 | 
			
		||||
    {
 | 
			
		||||
        rv = d_msg_console_init(context_self()->log.console);
 | 
			
		||||
        if (rv != CORE_OK) 
 | 
			
		||||
        {
 | 
			
		||||
            d_error("console logger init failed : (file:%d)",
 | 
			
		||||
                context_self()->log.console);
 | 
			
		||||
            return rv;
 | 
			
		||||
        }
 | 
			
		||||
        d_print("  Console Logging '%d'\n", context_self()->log.console);
 | 
			
		||||
    }
 | 
			
		||||
    if (context_self()->log.syslog)
 | 
			
		||||
    {
 | 
			
		||||
        d_msg_syslog_init(context_self()->log.syslog);
 | 
			
		||||
        d_print("  Syslog Logging '%s'\n", context_self()->log.syslog);
 | 
			
		||||
    }
 | 
			
		||||
    if (context_self()->log.socket.file &&
 | 
			
		||||
        context_self()->log.socket.unix_domain)
 | 
			
		||||
    {
 | 
			
		||||
        if (context_self()->log.path)
 | 
			
		||||
            context_self()->log.socket.file = context_self()->log.path;
 | 
			
		||||
 | 
			
		||||
        rv = d_msg_socket_init(context_self()->log.socket.unix_domain);
 | 
			
		||||
        if (rv != CORE_OK) 
 | 
			
		||||
        {
 | 
			
		||||
            d_error("socket logger init failed : (unix_domain:%s, file:%s)",
 | 
			
		||||
                context_self()->log.socket.unix_domain,
 | 
			
		||||
                context_self()->log.socket.file);
 | 
			
		||||
            return rv;
 | 
			
		||||
        }
 | 
			
		||||
        d_print("  Socket Logging '%s' on %s\n",
 | 
			
		||||
                context_self()->log.socket.file,
 | 
			
		||||
                context_self()->log.socket.unix_domain);
 | 
			
		||||
    }
 | 
			
		||||
    if (context_self()->log.file)
 | 
			
		||||
    {
 | 
			
		||||
        if (context_self()->log.path)
 | 
			
		||||
            context_self()->log.file = context_self()->log.path;
 | 
			
		||||
 | 
			
		||||
        rv = d_msg_file_init(context_self()->log.file);
 | 
			
		||||
        if (rv != CORE_OK) 
 | 
			
		||||
        {
 | 
			
		||||
            d_error("file logger init failed : (file:%s)",
 | 
			
		||||
                context_self()->log.file);
 | 
			
		||||
            return rv;
 | 
			
		||||
        }
 | 
			
		||||
        d_print("  File Logging '%s'\n", context_self()->log.file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static status_t app_logger_start()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    if (context_self()->log.socket.file &&
 | 
			
		||||
        context_self()->log.socket.unix_domain)
 | 
			
		||||
    {
 | 
			
		||||
        rv = d_msg_socket_start(context_self()->log.socket.file);
 | 
			
		||||
        if (rv != CORE_OK) 
 | 
			
		||||
        {
 | 
			
		||||
            d_error("socket logger start failed : (unix_domain:%s, file:%s)",
 | 
			
		||||
                context_self()->log.socket.unix_domain,
 | 
			
		||||
                context_self()->log.socket.file);
 | 
			
		||||
            return rv;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static status_t app_logger_stop()
 | 
			
		||||
{
 | 
			
		||||
    if (context_self()->log.socket.file &&
 | 
			
		||||
        context_self()->log.socket.unix_domain)
 | 
			
		||||
    {
 | 
			
		||||
        d_msg_socket_stop();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static status_t app_logger_final()
 | 
			
		||||
{
 | 
			
		||||
    if (context_self()->log.console >= 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_msg_console_final();
 | 
			
		||||
    }
 | 
			
		||||
    if (context_self()->log.syslog)
 | 
			
		||||
    {
 | 
			
		||||
        d_msg_syslog_final();
 | 
			
		||||
    }
 | 
			
		||||
    if (context_self()->log.socket.file &&
 | 
			
		||||
        context_self()->log.socket.unix_domain)
 | 
			
		||||
    {
 | 
			
		||||
        d_msg_socket_final();
 | 
			
		||||
    }
 | 
			
		||||
    if (context_self()->log.file)
 | 
			
		||||
    {
 | 
			
		||||
        d_msg_file_final();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,9 @@
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "app.h"
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
const char *app_name = "mme";
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int others = 0;
 | 
			
		||||
@@ -26,7 +28,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    d_assert(rv == CORE_OK, return rv, "Failed to intialize MME");
 | 
			
		||||
    d_trace(1, "MME initialize...done\n");
 | 
			
		||||
 | 
			
		||||
    rv = app_did_initialize(config_path, log_path);
 | 
			
		||||
    rv = app_did_initialize();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -42,3 +44,4 @@ void app_terminate(void)
 | 
			
		||||
 | 
			
		||||
    app_did_terminate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,12 @@ libmme_la_SOURCES = \
 | 
			
		||||
	mme_gtp_path.c mme_s11_build.c mme_s11_handler.c \
 | 
			
		||||
	mme_sm.c 
 | 
			
		||||
 | 
			
		||||
if USRSCTP
 | 
			
		||||
libmme_la_SOURCES += s1ap_usrsctp.c
 | 
			
		||||
else
 | 
			
		||||
libmme_la_SOURCES += s1ap_sctp.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libmme_la_DEPENDENCIES = \
 | 
			
		||||
    $(top_srcdir)/lib/core/src/libcore.la \
 | 
			
		||||
    $(top_srcdir)/lib/s1ap/libs1ap.la \
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
#include "nas_conv.h"
 | 
			
		||||
#include "mme_context.h"
 | 
			
		||||
#include "mme_event.h"
 | 
			
		||||
#include "s1ap_path.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_CELL_PER_ENB            8
 | 
			
		||||
 | 
			
		||||
@@ -41,13 +42,13 @@ status_t mme_context_init()
 | 
			
		||||
    list_init(&self.sgw_list);
 | 
			
		||||
 | 
			
		||||
    index_init(&mme_enb_pool, MAX_NUM_OF_ENB);
 | 
			
		||||
    list_init(&self.enb_list);
 | 
			
		||||
 | 
			
		||||
    index_init(&mme_ue_pool, MAX_POOL_OF_UE);
 | 
			
		||||
    index_init(&enb_ue_pool, MAX_POOL_OF_UE);
 | 
			
		||||
    index_init(&mme_sess_pool, MAX_POOL_OF_SESS);
 | 
			
		||||
    index_init(&mme_bearer_pool, MAX_POOL_OF_BEARER);
 | 
			
		||||
 | 
			
		||||
    self.s1ap_sock_hash = hash_make();
 | 
			
		||||
    self.enb_id_hash = hash_make();
 | 
			
		||||
    self.mme_ue_s1ap_id_hash = hash_make();
 | 
			
		||||
    self.imsi_ue_hash = hash_make();
 | 
			
		||||
    self.guti_ue_hash = hash_make();
 | 
			
		||||
@@ -69,12 +70,15 @@ status_t mme_context_final()
 | 
			
		||||
    mme_enb_remove_all();
 | 
			
		||||
    mme_ue_remove_all();
 | 
			
		||||
 | 
			
		||||
    d_assert(self.s1ap_sock_hash, , "Null param");
 | 
			
		||||
    hash_destroy(self.s1ap_sock_hash);
 | 
			
		||||
    d_assert(self.enb_id_hash, , "Null param");
 | 
			
		||||
    hash_destroy(self.enb_id_hash);
 | 
			
		||||
 | 
			
		||||
    d_assert(self.mme_ue_s1ap_id_hash, , "Null param");
 | 
			
		||||
    hash_destroy(self.mme_ue_s1ap_id_hash);
 | 
			
		||||
 | 
			
		||||
    d_assert(self.imsi_ue_hash, , "Null param");
 | 
			
		||||
    hash_destroy(self.imsi_ue_hash);
 | 
			
		||||
 | 
			
		||||
    d_assert(self.guti_ue_hash, , "Null param");
 | 
			
		||||
    hash_destroy(self.guti_ue_hash);
 | 
			
		||||
 | 
			
		||||
@@ -101,7 +105,7 @@ static status_t mme_context_prepare()
 | 
			
		||||
    self.relative_capacity = 0xff;
 | 
			
		||||
 | 
			
		||||
    self.s1ap_port = S1AP_SCTP_PORT;
 | 
			
		||||
    self.s11_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.gtpc_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.s5c_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -121,9 +125,9 @@ static status_t mme_context_validation()
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.s11_addr == 0)
 | 
			
		||||
    if (self.gtpc_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No MME.NEWORK.S11_IPV4 in '%s'",
 | 
			
		||||
        d_error("No MME.NEWORK.GTPC_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
@@ -139,7 +143,7 @@ static status_t mme_context_validation()
 | 
			
		||||
    {
 | 
			
		||||
        if (sgw->addr == 0)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("No SGW.NEWORK.S11_IPV4 in '%s'",
 | 
			
		||||
            d_error("No SGW.NEWORK.GTPC_IPV4 in '%s'",
 | 
			
		||||
                    context_self()->config.path);
 | 
			
		||||
            return CORE_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
@@ -312,15 +316,15 @@ status_t mme_context_parse_config()
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s1ap_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S11_IPV4") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPC_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s11_addr = inet_addr(v);
 | 
			
		||||
                                if (v) self.gtpc_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S11_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPC_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s11_port = atoi(v);
 | 
			
		||||
                                if (v) self.gtpc_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@@ -645,12 +649,12 @@ status_t mme_context_parse_config()
 | 
			
		||||
                        {
 | 
			
		||||
                            n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "S11_IPV4") == 0)
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "GTPC_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) sgw->addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S11_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPC_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) sgw->port = atoi(v);
 | 
			
		||||
@@ -693,12 +697,12 @@ status_t mme_context_parse_config()
 | 
			
		||||
                        {
 | 
			
		||||
                            n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "S5C_IPV4") == 0)
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "GTPC_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5c_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5C_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPC_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5c_port = atoi(v);
 | 
			
		||||
@@ -759,6 +763,13 @@ status_t mme_context_setup_trace_module()
 | 
			
		||||
        d_trace_level(&_s1ap_build, s1ap);
 | 
			
		||||
        extern int _s1ap_handler;
 | 
			
		||||
        d_trace_level(&_s1ap_handler, s1ap);
 | 
			
		||||
#if USE_USRSCTP == 1
 | 
			
		||||
        extern int _s1ap_usrsctp;
 | 
			
		||||
        d_trace_level(&_s1ap_usrsctp, s1ap);
 | 
			
		||||
#else
 | 
			
		||||
        extern int _s1ap_sctp;
 | 
			
		||||
        d_trace_level(&_s1ap_sctp, s1ap);
 | 
			
		||||
#endif
 | 
			
		||||
        extern int _s1ap_path;
 | 
			
		||||
        d_trace_level(&_s1ap_path, s1ap);
 | 
			
		||||
        extern int _s1ap_recv;
 | 
			
		||||
@@ -908,7 +919,7 @@ mme_sgw_t* mme_sgw_next(mme_sgw_t *sgw)
 | 
			
		||||
    return list_next(sgw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mme_enb_t* mme_enb_add(net_sock_t *s1ap_sock)
 | 
			
		||||
mme_enb_t* mme_enb_add(net_sock_t *sock)
 | 
			
		||||
{
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    event_t e;
 | 
			
		||||
@@ -916,15 +927,13 @@ mme_enb_t* mme_enb_add(net_sock_t *s1ap_sock)
 | 
			
		||||
    index_alloc(&mme_enb_pool, &enb);
 | 
			
		||||
    d_assert(enb, return NULL, "Null param");
 | 
			
		||||
 | 
			
		||||
    /* IMPORTANT! 
 | 
			
		||||
     * eNB Index is saved in net_sock_t structure */
 | 
			
		||||
    s1ap_sock->app_index = enb->index;
 | 
			
		||||
 | 
			
		||||
    enb->s1ap_sock = s1ap_sock;
 | 
			
		||||
    enb->s1ap_sock = sock;
 | 
			
		||||
    list_init(&enb->enb_ue_list);
 | 
			
		||||
    list_append(&self.enb_list, enb);
 | 
			
		||||
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)enb->index);
 | 
			
		||||
    hash_set(self.s1ap_sock_hash,
 | 
			
		||||
            &enb->s1ap_sock, sizeof(enb->s1ap_sock), enb);
 | 
			
		||||
    
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)enb->s1ap_sock);
 | 
			
		||||
    fsm_create(&enb->sm, s1ap_state_initial, s1ap_state_final);
 | 
			
		||||
    fsm_init(&enb->sm, &e);
 | 
			
		||||
 | 
			
		||||
@@ -936,17 +945,21 @@ status_t mme_enb_remove(mme_enb_t *enb)
 | 
			
		||||
    event_t e;
 | 
			
		||||
 | 
			
		||||
    d_assert(enb, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(enb->s1ap_sock, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)enb->index);
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)enb->s1ap_sock);
 | 
			
		||||
    fsm_final(&enb->sm, &e);
 | 
			
		||||
    fsm_clear(&enb->sm);
 | 
			
		||||
 | 
			
		||||
    hash_set(self.s1ap_sock_hash,
 | 
			
		||||
            &enb->s1ap_sock, sizeof(enb->s1ap_sock), NULL);
 | 
			
		||||
    if (enb->enb_id)
 | 
			
		||||
        hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL);
 | 
			
		||||
 | 
			
		||||
    enb_ue_remove_in_enb(enb);
 | 
			
		||||
 | 
			
		||||
    net_unregister_sock(enb->s1ap_sock);
 | 
			
		||||
    net_close(enb->s1ap_sock);
 | 
			
		||||
    s1ap_sctp_close(enb->s1ap_sock);
 | 
			
		||||
 | 
			
		||||
    list_remove(&self.enb_list, enb);
 | 
			
		||||
    index_free(&mme_enb_pool, enb);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -954,16 +967,13 @@ status_t mme_enb_remove(mme_enb_t *enb)
 | 
			
		||||
 | 
			
		||||
status_t mme_enb_remove_all()
 | 
			
		||||
{
 | 
			
		||||
    mme_enb_t *enb = NULL, *next_enb = NULL;
 | 
			
		||||
    hash_index_t *hi = NULL;
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
 | 
			
		||||
    enb = mme_enb_first();
 | 
			
		||||
    while (enb)
 | 
			
		||||
    for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi))
 | 
			
		||||
    {
 | 
			
		||||
        next_enb = mme_enb_next(enb);
 | 
			
		||||
 | 
			
		||||
        enb = mme_enb_this(hi);
 | 
			
		||||
        mme_enb_remove(enb);
 | 
			
		||||
 | 
			
		||||
        enb = next_enb;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -977,44 +987,44 @@ mme_enb_t* mme_enb_find(index_t index)
 | 
			
		||||
 | 
			
		||||
mme_enb_t* mme_enb_find_by_sock(net_sock_t *sock)
 | 
			
		||||
{
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    d_assert(sock, return NULL,"Invalid param");
 | 
			
		||||
    return (mme_enb_t *)hash_get(self.s1ap_sock_hash, &sock, sizeof(sock));
 | 
			
		||||
 | 
			
		||||
    enb = mme_enb_first();
 | 
			
		||||
    while (enb)
 | 
			
		||||
    {
 | 
			
		||||
        if (sock == enb->s1ap_sock)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        enb = mme_enb_next(enb);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return enb;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mme_enb_t* mme_enb_find_by_enb_id(c_uint32_t enb_id)
 | 
			
		||||
{
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    
 | 
			
		||||
    enb = list_first(&self.enb_list);
 | 
			
		||||
    while (enb)
 | 
			
		||||
    {
 | 
			
		||||
        if (enb_id == enb->enb_id)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        enb = list_next(enb);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return enb;
 | 
			
		||||
    d_assert(enb_id, return NULL,"Invalid param");
 | 
			
		||||
    return (mme_enb_t *)hash_get(self.enb_id_hash, &enb_id, sizeof(enb_id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mme_enb_t* mme_enb_first()
 | 
			
		||||
status_t mme_enb_set_enb_id(mme_enb_t *enb, c_uint32_t enb_id)
 | 
			
		||||
{
 | 
			
		||||
    return list_first(&self.enb_list);
 | 
			
		||||
    d_assert(enb, return CORE_ERROR, "Invalid param");
 | 
			
		||||
    d_assert(enb_id, return CORE_ERROR, "Invalid param");
 | 
			
		||||
 | 
			
		||||
    enb->enb_id = enb_id;
 | 
			
		||||
    hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), enb);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mme_enb_t* mme_enb_next(mme_enb_t *enb)
 | 
			
		||||
hash_index_t* mme_enb_first()
 | 
			
		||||
{
 | 
			
		||||
    return list_next(enb);
 | 
			
		||||
    d_assert(self.s1ap_sock_hash, return NULL, "Null param");
 | 
			
		||||
    return hash_first(self.s1ap_sock_hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hash_index_t* mme_enb_next(hash_index_t *hi)
 | 
			
		||||
{
 | 
			
		||||
    return hash_next(hi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mme_enb_t *mme_enb_this(hash_index_t *hi)
 | 
			
		||||
{
 | 
			
		||||
    d_assert(hi, return NULL, "Null param");
 | 
			
		||||
    return hash_this_val(hi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** enb_ue_context handling function */
 | 
			
		||||
@@ -1152,7 +1162,7 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
 | 
			
		||||
    list_init(&mme_ue->sess_list);
 | 
			
		||||
 | 
			
		||||
    mme_ue->mme_s11_teid = mme_ue->index;
 | 
			
		||||
    mme_ue->mme_s11_addr = mme_self()->s11_addr;
 | 
			
		||||
    mme_ue->mme_s11_addr = mme_self()->gtpc_addr;
 | 
			
		||||
 | 
			
		||||
    /* Create t3413 timer */
 | 
			
		||||
    mme_ue->t3413 = timer_create(&self.tm_service, MME_EVT_EMM_T3413,
 | 
			
		||||
 
 | 
			
		||||
@@ -55,9 +55,9 @@ typedef struct _mme_context_t {
 | 
			
		||||
    c_uint16_t      s1ap_port;      /* MME S1AP local port */
 | 
			
		||||
    net_sock_t      *s1ap_sock;     /* MME S1AP local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s11_addr;       /* MME S11 local address */
 | 
			
		||||
    c_uint16_t      s11_port;       /* MME S11 local port */
 | 
			
		||||
    net_sock_t      *s11_sock;      /* MME S11 local listen socket */
 | 
			
		||||
    c_uint32_t      gtpc_addr;      /* MME GTPC local address */
 | 
			
		||||
    c_uint16_t      gtpc_port;      /* MME GTPC local port */
 | 
			
		||||
    net_sock_t      *gtpc_sock;     /* MME GTPC local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s5c_addr;       /* PGW S5C remote address */
 | 
			
		||||
    c_uint16_t      s5c_port;       /* PGW S5C remote port */
 | 
			
		||||
@@ -99,8 +99,9 @@ typedef struct _mme_context_t {
 | 
			
		||||
    c_uint32_t      t3413_value; /* Paging retry timer */
 | 
			
		||||
 | 
			
		||||
    list_t          sgw_list;  /* SGW GTP Node List */
 | 
			
		||||
    list_t          enb_list;  /* eNB S1AP Node List */
 | 
			
		||||
 | 
			
		||||
    hash_t          *s1ap_sock_hash;        /* hash table for S1AP IP address */
 | 
			
		||||
    hash_t          *enb_id_hash;           /* hash table for ENB-ID */
 | 
			
		||||
    hash_t          *mme_ue_s1ap_id_hash;   /* hash table for MME-UE-S1AP-ID */
 | 
			
		||||
    hash_t          *imsi_ue_hash;          /* hash table (IMSI : MME_UE) */
 | 
			
		||||
    hash_t          *guti_ue_hash;          /* hash table (GUTI : MME_UE) */
 | 
			
		||||
@@ -111,8 +112,10 @@ typedef struct _mme_enb_t {
 | 
			
		||||
    index_t         index;  /* An index of this node */
 | 
			
		||||
    fsm_t           sm;     /* A state machine */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      enb_id; /* eNB_ID received from eNB */
 | 
			
		||||
    net_sock_t      *s1ap_sock;
 | 
			
		||||
    c_uint32_t      enb_id;     /* eNB_ID received from eNB */
 | 
			
		||||
    c_uint32_t      s1ap_addr;  /* eNB S1AP IP address */
 | 
			
		||||
    c_uint16_t      s1ap_port;  /* eNB S1AP Port */
 | 
			
		||||
    net_sock_t      *s1ap_sock; /* eNB S1AP Socket */
 | 
			
		||||
 | 
			
		||||
    c_uint8_t       num_of_tai;
 | 
			
		||||
    tai_t           tai[MAX_NUM_OF_TAC * MAX_NUM_OF_BPLMN];
 | 
			
		||||
@@ -441,14 +444,17 @@ CORE_DECLARE(mme_sgw_t*)    mme_sgw_find(c_uint32_t addr, c_uint16_t port);
 | 
			
		||||
CORE_DECLARE(mme_sgw_t*)    mme_sgw_first(void);
 | 
			
		||||
CORE_DECLARE(mme_sgw_t*)    mme_sgw_next(mme_sgw_t *sgw);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_add(net_sock_t *s1ap_sock);
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_add(net_sock_t *sock);
 | 
			
		||||
CORE_DECLARE(status_t)      mme_enb_remove(mme_enb_t *enb);
 | 
			
		||||
CORE_DECLARE(status_t)      mme_enb_remove_all(void);
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_find(index_t index);
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_find_by_sock(net_sock_t *sock);
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_find_by_enb_id(c_uint32_t enb_id);
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_first(void);
 | 
			
		||||
CORE_DECLARE(mme_enb_t*)    mme_enb_next(mme_enb_t *enb);
 | 
			
		||||
CORE_DECLARE(status_t)      mme_enb_set_enb_id(
 | 
			
		||||
        mme_enb_t *enb, c_uint32_t enb_id);
 | 
			
		||||
CORE_DECLARE(hash_index_t *) mme_enb_first();
 | 
			
		||||
CORE_DECLARE(hash_index_t *) mme_enb_next(hash_index_t *hi);
 | 
			
		||||
CORE_DECLARE(mme_enb_t *)    mme_enb_this(hash_index_t *hi);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(mme_ue_t*)     mme_ue_add(enb_ue_t *enb_ue);
 | 
			
		||||
CORE_DECLARE(status_t)      mme_ue_remove(mme_ue_t *mme_ue);
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    c_uint32_t addr;
 | 
			
		||||
    c_uint16_t port;
 | 
			
		||||
    mme_sgw_t *sgw = NULL;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
@@ -31,19 +30,14 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
    addr = sock->remote.sin_addr.s_addr;
 | 
			
		||||
    port = ntohs(sock->remote.sin_port);
 | 
			
		||||
 | 
			
		||||
    sgw = mme_sgw_find(addr, port);
 | 
			
		||||
    d_assert(sgw, return -1, "Can't find SGW from [%s:%d]",
 | 
			
		||||
            INET_NTOP(&addr, buf), port);
 | 
			
		||||
 | 
			
		||||
    sgw->sock = sock; /* Is it needed? */
 | 
			
		||||
 | 
			
		||||
    d_trace(10, "S11_PDU is received from SGW[%s:%d]\n",
 | 
			
		||||
            INET_NTOP(&addr, buf), port);
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
 | 
			
		||||
    event_set(&e, MME_EVT_S11_MESSAGE);
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)sgw);
 | 
			
		||||
    event_set_param2(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)addr);
 | 
			
		||||
    event_set_param2(&e, (c_uintptr_t)port);
 | 
			
		||||
    event_set_param3(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    rv = mme_event_send(&e);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
@@ -59,18 +53,18 @@ status_t mme_gtp_open()
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    mme_sgw_t *sgw = mme_sgw_first();
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&mme_self()->s11_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            mme_self()->s11_addr, mme_self()->s11_port, NULL);
 | 
			
		||||
    rv = gtp_listen(&mme_self()->gtpc_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            mme_self()->gtpc_addr, mme_self()->gtpc_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S11 Path for SGW");
 | 
			
		||||
        d_error("Can't establish GTP-C Path for SGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* socket descriptor needs in gnode when packet is sending initilly */
 | 
			
		||||
    while(sgw)
 | 
			
		||||
    {
 | 
			
		||||
        sgw->sock = mme_self()->s11_sock;
 | 
			
		||||
        sgw->sock = mme_self()->gtpc_sock;
 | 
			
		||||
        sgw = mme_sgw_next(sgw);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -81,10 +75,10 @@ status_t mme_gtp_close()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    rv = gtp_close(mme_self()->s11_sock);
 | 
			
		||||
    rv = gtp_close(mme_self()->gtpc_sock);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't close S11 Path for SGW");
 | 
			
		||||
        d_error("Can't close GTP-C Path for SGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
#include "mme_event.h"
 | 
			
		||||
 | 
			
		||||
#include "mme_fd_path.h"
 | 
			
		||||
#include "s1ap_path.h"
 | 
			
		||||
 | 
			
		||||
static thread_id sm_thread;
 | 
			
		||||
static void *THREAD_FUNC sm_main(thread_id id, void *data);
 | 
			
		||||
@@ -53,6 +54,8 @@ void mme_terminate(void)
 | 
			
		||||
 | 
			
		||||
    mme_context_final();
 | 
			
		||||
 | 
			
		||||
    s1ap_final();
 | 
			
		||||
 | 
			
		||||
    gtp_xact_final();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,16 +50,16 @@ void mme_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
            rv = mme_gtp_open();
 | 
			
		||||
            if (rv != CORE_OK)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("Can't establish S11 path");
 | 
			
		||||
                d_error("Can't establish S11-GTP path");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            rv = s1ap_open();
 | 
			
		||||
            if (rv != CORE_OK)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("Can't establish S1AP path");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
    
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case FSM_EXIT_SIG:
 | 
			
		||||
@@ -67,43 +67,47 @@ void mme_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
            rv = mme_gtp_close();
 | 
			
		||||
            if (rv != CORE_OK)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("Can't close S11 path");
 | 
			
		||||
                break;
 | 
			
		||||
                d_error("Can't close S11-GTP path");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            rv = s1ap_close();
 | 
			
		||||
            rv = s1ap_close(mme_self()->s1ap_sock);
 | 
			
		||||
            if (rv != CORE_OK)
 | 
			
		||||
            {
 | 
			
		||||
                d_error("Can't close S1AP path");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            mme_self()->s1ap_sock = NULL;
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case MME_EVT_S1AP_LO_ACCEPT:
 | 
			
		||||
        {
 | 
			
		||||
            int rc;
 | 
			
		||||
 | 
			
		||||
            net_sock_t *sock = (net_sock_t *)event_get_param1(e);
 | 
			
		||||
            d_assert(sock, break, "Null param");
 | 
			
		||||
            c_uint32_t addr = (c_uint32_t)event_get_param2(e);
 | 
			
		||||
            c_uint16_t port = (c_uint16_t)event_get_param3(e);
 | 
			
		||||
 | 
			
		||||
            d_trace(1, "eNB-S1 accepted[%s] in master_sm module\n", 
 | 
			
		||||
                INET_NTOP(&sock->remote.sin_addr.s_addr, buf));
 | 
			
		||||
                INET_NTOP(&addr, buf));
 | 
			
		||||
                    
 | 
			
		||||
            mme_enb_t *enb = mme_enb_find_by_sock(sock);
 | 
			
		||||
            if (!enb)
 | 
			
		||||
            {
 | 
			
		||||
                rc = net_register_sock(sock, _s1ap_recv_cb, NULL);
 | 
			
		||||
#if USE_USRSCTP != 1
 | 
			
		||||
                int rc = net_register_sock(sock, s1ap_recv_cb, NULL);
 | 
			
		||||
                d_assert(rc == 0, break, "register _s1ap_recv_cb failed");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
                mme_enb_t *enb = mme_enb_add(sock);
 | 
			
		||||
                d_assert(enb, break, "Null param");
 | 
			
		||||
                enb->s1ap_addr = addr;
 | 
			
		||||
                enb->s1ap_port = port;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                d_warn("eNB context duplicated with IP-address [%s]!!!", 
 | 
			
		||||
                        INET_NTOP(&sock->remote.sin_addr.s_addr, buf));
 | 
			
		||||
                        INET_NTOP(&addr, buf));
 | 
			
		||||
#if USE_USRSCTP != 1
 | 
			
		||||
                net_close(sock);
 | 
			
		||||
#endif
 | 
			
		||||
                d_warn("S1 Socket Closed");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
@@ -111,7 +115,13 @@ void mme_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
        }
 | 
			
		||||
        case MME_EVT_S1AP_LO_CONNREFUSED:
 | 
			
		||||
        {
 | 
			
		||||
            mme_enb_t *enb = mme_enb_find(event_get_param1(e));
 | 
			
		||||
            mme_enb_t *enb = NULL;
 | 
			
		||||
            net_sock_t *sock = NULL;
 | 
			
		||||
 | 
			
		||||
            sock = (net_sock_t *)event_get_param1(e);
 | 
			
		||||
            d_assert(sock, break, "Null param");
 | 
			
		||||
            
 | 
			
		||||
            enb = mme_enb_find_by_sock(sock);
 | 
			
		||||
            if (enb)
 | 
			
		||||
            {
 | 
			
		||||
                d_trace(1, "eNB-S1[%x] connection refused!!!\n", 
 | 
			
		||||
@@ -129,14 +139,19 @@ void mme_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
        {
 | 
			
		||||
            s1ap_message_t message;
 | 
			
		||||
            mme_enb_t *enb = NULL;
 | 
			
		||||
            net_sock_t *sock = NULL;
 | 
			
		||||
            pkbuf_t *pkbuf = NULL;
 | 
			
		||||
 | 
			
		||||
            enb = mme_enb_find(event_get_param1(e));
 | 
			
		||||
            d_assert(enb, break, "No eNB context");
 | 
			
		||||
            d_assert(FSM_STATE(&enb->sm), break, "No S1AP State Machine");
 | 
			
		||||
            sock = (net_sock_t *)event_get_param1(e);
 | 
			
		||||
            d_assert(sock, break, "Null param");
 | 
			
		||||
            
 | 
			
		||||
            pkbuf = (pkbuf_t *)event_get_param2(e);
 | 
			
		||||
            d_assert(pkbuf, break, "Null param");
 | 
			
		||||
 | 
			
		||||
            enb = mme_enb_find_by_sock(sock);
 | 
			
		||||
            d_assert(enb, break, "No eNB context");
 | 
			
		||||
            d_assert(FSM_STATE(&enb->sm), break, "No S1AP State Machine");
 | 
			
		||||
 | 
			
		||||
            d_assert(s1ap_decode_pdu(&message, pkbuf) == CORE_OK,
 | 
			
		||||
                    pkbuf_free(pkbuf); break, "Can't decode S1AP_PDU");
 | 
			
		||||
            event_set_param3(e, (c_uintptr_t)&message);
 | 
			
		||||
@@ -329,13 +344,16 @@ void mme_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
        case MME_EVT_S11_MESSAGE:
 | 
			
		||||
        {
 | 
			
		||||
            status_t rv;
 | 
			
		||||
            gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
 | 
			
		||||
            pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
 | 
			
		||||
            gtp_node_t *gnode = NULL;
 | 
			
		||||
            c_uint32_t addr = (c_uint32_t)event_get_param1(e);
 | 
			
		||||
            c_uint16_t port = (c_uint16_t)event_get_param2(e);
 | 
			
		||||
            pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
 | 
			
		||||
            gtp_xact_t *xact = NULL;
 | 
			
		||||
            gtp_message_t message;
 | 
			
		||||
            mme_ue_t *mme_ue = NULL;
 | 
			
		||||
 | 
			
		||||
            d_assert(pkbuf, break, "Null param");
 | 
			
		||||
            gnode = mme_sgw_find(addr, port);
 | 
			
		||||
            d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
 | 
			
		||||
 | 
			
		||||
            rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
 | 
			
		||||
 
 | 
			
		||||
@@ -143,8 +143,7 @@ status_t s1ap_build_downlink_nas_transport(
 | 
			
		||||
    d_trace(3, "[S1AP] downlinkNASTransport : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_addr, buf), enb_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -303,8 +302,7 @@ status_t s1ap_build_initial_context_setup_request(
 | 
			
		||||
    d_trace(3, "[S1AP] Initial Context Setup Request : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_addr, buf), enb_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    if (emmbuf && emmbuf->len)
 | 
			
		||||
    {
 | 
			
		||||
@@ -404,8 +402,7 @@ status_t s1ap_build_e_rab_setup_request(
 | 
			
		||||
    d_trace(3, "[S1AP] E-RAB Setup Request : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_addr, buf), enb_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    pkbuf_free(esmbuf);
 | 
			
		||||
 | 
			
		||||
@@ -473,8 +470,7 @@ status_t s1ap_build_e_rab_release_command(pkbuf_t **s1apbuf,
 | 
			
		||||
    d_trace(3, "[S1AP] E-RAB Release Command : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_addr, buf), enb_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    pkbuf_free(esmbuf);
 | 
			
		||||
 | 
			
		||||
@@ -530,8 +526,7 @@ status_t s1ap_build_ue_context_release_commmand(
 | 
			
		||||
    d_trace(3, "[S1AP] UE Context Release Command : "
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_addr, buf), enb_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -638,8 +633,7 @@ status_t s1ap_build_path_switch_ack(pkbuf_t **s1apbuf, mme_ue_t *mme_ue)
 | 
			
		||||
    d_trace(3, "[S1AP] Path Switch Ack : "
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb_ue->enb->s1ap_addr, buf), enb_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -778,8 +772,7 @@ status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue)
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Command : ",
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            source_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&source_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            source_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&source_ue->enb->s1ap_addr, buf), source_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -811,8 +804,7 @@ status_t s1ap_build_handover_preparation_failure(
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Preparation Failure : ",
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            source_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&source_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            source_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&source_ue->enb->s1ap_addr, buf), source_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -954,8 +946,7 @@ status_t s1ap_build_handover_request(
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Request : ",
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            target_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&target_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            target_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&target_ue->enb->s1ap_addr, buf), target_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -987,8 +978,7 @@ status_t s1ap_build_handover_cancel_ack(pkbuf_t **s1apbuf, enb_ue_t *source_ue)
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Cancel Ack : ",
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            source_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&source_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            source_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&source_ue->enb->s1ap_addr, buf), source_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -1040,8 +1030,7 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
 | 
			
		||||
    d_trace(3, "[S1AP] MME Status Transfer : ",
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n",
 | 
			
		||||
            target_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&target_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            target_ue->enb->enb_id);
 | 
			
		||||
            INET_NTOP(&target_ue->enb->s1ap_addr, buf), target_ue->enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -66,10 +66,10 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
 | 
			
		||||
    d_assert(enb->s1ap_sock, return,);
 | 
			
		||||
    d_trace(3, "[S1AP] S1SetupRequest : eNB[%s:%d] --> MME\n",
 | 
			
		||||
        INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
        enb_id);
 | 
			
		||||
        INET_NTOP(&enb->s1ap_addr, buf), enb_id);
 | 
			
		||||
 | 
			
		||||
    enb->enb_id = enb_id;
 | 
			
		||||
    d_assert(mme_enb_set_enb_id(enb, enb_id) == CORE_OK,
 | 
			
		||||
            return, "hash add error");
 | 
			
		||||
 | 
			
		||||
    d_assert(s1ap_build_setup_rsp(&s1apbuf) == CORE_OK, 
 | 
			
		||||
            return, "build error");
 | 
			
		||||
@@ -77,8 +77,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
 | 
			
		||||
    d_assert(enb->s1ap_sock, return,);
 | 
			
		||||
    d_trace(3, "[S1AP] S1SetupResponse: eNB[%s:%d] <-- MME\n",
 | 
			
		||||
        INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
        enb_id);
 | 
			
		||||
        INET_NTOP(&enb->s1ap_addr, buf), enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
@@ -167,8 +166,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_trace(3, "[S1AP] InitialUEMessage : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    d_assert(s1ap_send_to_nas(enb_ue, &ies->nas_pdu) == CORE_OK,,
 | 
			
		||||
            "s1ap_send_to_nas failed");
 | 
			
		||||
@@ -191,8 +189,7 @@ void s1ap_handle_uplink_nas_transport(
 | 
			
		||||
    d_trace(3, "[S1AP] uplinkNASTransport : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    d_assert(s1ap_send_to_nas(enb_ue, &ies->nas_pdu) == CORE_OK,,
 | 
			
		||||
            "s1ap_send_to_nas failed");
 | 
			
		||||
@@ -245,8 +242,7 @@ void s1ap_handle_ue_capability_info_indication(
 | 
			
		||||
    d_trace(3, "[S1AP] UE Capability Info Indication : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_initial_context_setup_response(
 | 
			
		||||
@@ -271,8 +267,7 @@ void s1ap_handle_initial_context_setup_response(
 | 
			
		||||
    d_trace(3, "[S1AP] Initial Context Setup Response : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < ies->e_RABSetupListCtxtSURes.
 | 
			
		||||
            s1ap_E_RABSetupItemCtxtSURes.count; i++)
 | 
			
		||||
@@ -332,8 +327,7 @@ void s1ap_handle_e_rab_setup_response(
 | 
			
		||||
    d_trace(3, "[S1AP] E-RAB Setup Response : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < ies->e_RABSetupListBearerSURes.
 | 
			
		||||
            s1ap_E_RABSetupItemBearerSURes.count; i++)
 | 
			
		||||
@@ -394,8 +388,7 @@ void s1ap_handle_ue_context_release_request(
 | 
			
		||||
    d_trace(3, "[S1AP] UE Context Release Request : "
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->mme_ue_s1ap_id,
 | 
			
		||||
        INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
        enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    switch(ies->cause.present)
 | 
			
		||||
    {
 | 
			
		||||
@@ -473,8 +466,7 @@ void s1ap_handle_ue_context_release_complete(
 | 
			
		||||
    d_trace(3, "[S1AP] UE Context Release Complete : "
 | 
			
		||||
            "UE[mME-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    enb_ue_remove(enb_ue);
 | 
			
		||||
 | 
			
		||||
@@ -514,14 +506,15 @@ void s1ap_handle_ue_context_release_complete(
 | 
			
		||||
void s1ap_handle_paging(mme_ue_t *mme_ue)
 | 
			
		||||
{
 | 
			
		||||
    pkbuf_t *s1apbuf = NULL;
 | 
			
		||||
    hash_index_t *hi = NULL;
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    int i;
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    /* Find enB with matched TAI */
 | 
			
		||||
    enb =  mme_enb_first();
 | 
			
		||||
    while (enb)
 | 
			
		||||
    for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi))
 | 
			
		||||
    {
 | 
			
		||||
        enb = mme_enb_this(hi);
 | 
			
		||||
        for (i = 0; i < enb->num_of_tai; i++)
 | 
			
		||||
        {
 | 
			
		||||
            if (!memcmp(&enb->tai[i], &mme_ue->tai, sizeof(tai_t)))
 | 
			
		||||
@@ -544,7 +537,6 @@ void s1ap_handle_paging(mme_ue_t *mme_ue)
 | 
			
		||||
                        "s1ap send error");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        enb = mme_enb_next(enb);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -601,8 +593,7 @@ void s1ap_handle_path_switch_request(
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Cannot find UE from sourceMME-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
                ies->sourceMME_UE_S1AP_ID,
 | 
			
		||||
                INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
                enb->enb_id);
 | 
			
		||||
                INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
        cause.present = S1ap_Cause_PR_radioNetwork;
 | 
			
		||||
        cause.choice.radioNetwork = 
 | 
			
		||||
@@ -684,8 +675,7 @@ void s1ap_handle_path_switch_request(
 | 
			
		||||
    d_trace(3, "[S1AP] PathSwitchRequest : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            enb_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
@@ -707,8 +697,7 @@ void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_assert(source_ue, return,
 | 
			
		||||
            "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
            ies->eNB_UE_S1AP_ID,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
    d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return,
 | 
			
		||||
            "Conflict MME-UE-S1AP-ID : %d != %d\n",
 | 
			
		||||
            source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
 | 
			
		||||
@@ -737,8 +726,7 @@ void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Required : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            source_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
@@ -762,8 +750,7 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_assert(target_ue, return,
 | 
			
		||||
            "Cannot find UE for MME-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
            ies->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    target_ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID;
 | 
			
		||||
 | 
			
		||||
@@ -832,8 +819,7 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Request Ack : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            target_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
@@ -855,8 +841,7 @@ void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_assert(target_ue, return,
 | 
			
		||||
            "Cannot find UE for MME-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
            ies->mme_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
 | 
			
		||||
    source_ue = target_ue->source_ue;
 | 
			
		||||
    d_assert(source_ue, return,);
 | 
			
		||||
@@ -872,8 +857,7 @@ void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Failure : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            target_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
@@ -896,8 +880,7 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_assert(source_ue, return,
 | 
			
		||||
            "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
            ies->eNB_UE_S1AP_ID,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
    d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return,
 | 
			
		||||
            "Conflict MME-UE-S1AP-ID : %d != %d\n",
 | 
			
		||||
            source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
 | 
			
		||||
@@ -917,8 +900,7 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_trace(3, "[S1AP] Handover Cancel : "
 | 
			
		||||
            "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n",
 | 
			
		||||
            source_ue->enb_ue_s1ap_id,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
@@ -939,8 +921,7 @@ void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_assert(source_ue, return,
 | 
			
		||||
            "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
            ies->eNB_UE_S1AP_ID,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
    d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return,
 | 
			
		||||
            "Conflict MME-UE-S1AP-ID : %d != %d\n",
 | 
			
		||||
            source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
 | 
			
		||||
@@ -993,8 +974,7 @@ void s1ap_handle_handover_notification(mme_enb_t *enb, s1ap_message_t *message)
 | 
			
		||||
    d_assert(target_ue, return,
 | 
			
		||||
            "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]",
 | 
			
		||||
            ies->eNB_UE_S1AP_ID,
 | 
			
		||||
            INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
 | 
			
		||||
            enb->enb_id);
 | 
			
		||||
            INET_NTOP(&enb->s1ap_addr, buf), enb->enb_id);
 | 
			
		||||
    d_assert(target_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return,
 | 
			
		||||
            "Conflict MME-UE-S1AP-ID : %d != %d\n",
 | 
			
		||||
            target_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
#define TRACE_MODULE _s1ap_path
 | 
			
		||||
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_thread.h"
 | 
			
		||||
 | 
			
		||||
#include "mme_event.h"
 | 
			
		||||
 | 
			
		||||
@@ -11,193 +12,6 @@
 | 
			
		||||
#include "s1ap_build.h"
 | 
			
		||||
#include "s1ap_path.h"
 | 
			
		||||
 | 
			
		||||
static int _s1ap_accept_cb(net_sock_t *net_sock, void *data);
 | 
			
		||||
 | 
			
		||||
status_t s1ap_open(void)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    rc = net_listen_ext(&mme_self()->s1ap_sock, 
 | 
			
		||||
            SOCK_STREAM, IPPROTO_SCTP, SCTP_S1AP_PPID,
 | 
			
		||||
            mme_self()->s1ap_addr, mme_self()->s1ap_port);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S1-ENB(port:%d) path(%d:%s)",
 | 
			
		||||
            mme_self()->s1ap_port, errno, strerror(errno));
 | 
			
		||||
        mme_self()->s1ap_sock = NULL;
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rc = net_register_sock(
 | 
			
		||||
            mme_self()->s1ap_sock, _s1ap_accept_cb, NULL);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S1-ENB path(%d:%s)",
 | 
			
		||||
            errno, strerror(errno));
 | 
			
		||||
        net_close(mme_self()->s1ap_sock);
 | 
			
		||||
        mme_self()->s1ap_sock = NULL;
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d_trace(1, "s1_enb_listen() %s:%d\n", 
 | 
			
		||||
        INET_NTOP(&mme_self()->s1ap_addr, buf), mme_self()->s1ap_port);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_close()
 | 
			
		||||
{
 | 
			
		||||
    d_assert(mme_self(), return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(mme_self()->s1ap_sock != NULL, return CORE_ERROR,
 | 
			
		||||
            "S1-ENB path already opened");
 | 
			
		||||
    net_unregister_sock(mme_self()->s1ap_sock);
 | 
			
		||||
    net_close(mme_self()->s1ap_sock);
 | 
			
		||||
    mme_self()->s1ap_sock = NULL;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _s1ap_accept_cb(net_sock_t *net_sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
    ssize_t r;
 | 
			
		||||
    net_sock_t *remote_sock;
 | 
			
		||||
 | 
			
		||||
    d_assert(net_sock, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    r = net_accept(&remote_sock, net_sock, 0);
 | 
			
		||||
    if (r > 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_trace(1, "eNB-S1 accepted[%s] in s1_path module\n", 
 | 
			
		||||
            INET_NTOP(&remote_sock->remote.sin_addr.s_addr, buf));
 | 
			
		||||
 | 
			
		||||
        event_t e;
 | 
			
		||||
        event_set(&e, MME_EVT_S1AP_LO_ACCEPT);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)remote_sock);
 | 
			
		||||
        /* FIXME : how to close remote_sock */
 | 
			
		||||
        mme_event_send(&e);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_accept failed(r = %d, errno = %d)", r, errno);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static status_t s1ap_recv(net_sock_t *sock, pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    event_t e;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    d_trace(10, "S1AP_PDU is received from eNB-Inf\n");
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
 | 
			
		||||
    event_set(&e, MME_EVT_S1AP_MESSAGE);
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)sock->app_index);
 | 
			
		||||
    event_set_param2(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    return mme_event_send(&e);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _s1ap_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    pkbuf_t *pkbuf;
 | 
			
		||||
    ssize_t r;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
 | 
			
		||||
    if (pkbuf == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        char tmp_buf[MAX_SDU_LEN];
 | 
			
		||||
 | 
			
		||||
        d_fatal("Can't allocate pkbuf");
 | 
			
		||||
 | 
			
		||||
        /* Read data from socket to exit from select */
 | 
			
		||||
        net_read(sock, tmp_buf, MAX_SDU_LEN, 0);
 | 
			
		||||
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    r = net_read(sock, pkbuf->payload, pkbuf->len, 0);
 | 
			
		||||
    if (r == -2)
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf_free(pkbuf);
 | 
			
		||||
    }
 | 
			
		||||
    else if (r <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf_free(pkbuf);
 | 
			
		||||
 | 
			
		||||
        if (sock->sndrcv_errno == EAGAIN)
 | 
			
		||||
        {
 | 
			
		||||
            d_warn("net_read failed(%d:%s)",
 | 
			
		||||
                    sock->sndrcv_errno, strerror(sock->sndrcv_errno));
 | 
			
		||||
            return 0;
 | 
			
		||||
        } 
 | 
			
		||||
        else if (sock->sndrcv_errno == ECONNREFUSED)
 | 
			
		||||
        {
 | 
			
		||||
            d_warn("net_read failed(%d:%s)",
 | 
			
		||||
                    sock->sndrcv_errno, strerror(sock->sndrcv_errno));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            d_error("net_read failed(%d:%s)",
 | 
			
		||||
                    sock->sndrcv_errno, strerror(sock->sndrcv_errno));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        event_t e;
 | 
			
		||||
 | 
			
		||||
        event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)sock->app_index);
 | 
			
		||||
        mme_event_send(&e);
 | 
			
		||||
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf->len = r;
 | 
			
		||||
 | 
			
		||||
        rv = s1ap_recv(sock, pkbuf);
 | 
			
		||||
        if (rv != CORE_OK)
 | 
			
		||||
        {
 | 
			
		||||
            pkbuf_free(pkbuf);
 | 
			
		||||
            d_error("s1_recv() failed");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_send(net_sock_t *s, pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
 | 
			
		||||
    ssize_t sent;
 | 
			
		||||
 | 
			
		||||
    d_assert(s, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    sent = net_send(s, pkbuf->payload, pkbuf->len);
 | 
			
		||||
    d_trace(10,"Sent %d->%d bytes to [%s:%d]\n", 
 | 
			
		||||
            pkbuf->len, sent, INET_NTOP(&s->remote.sin_addr.s_addr, buf), 
 | 
			
		||||
            ntohs(s->remote.sin_port));
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
    if (sent < 0 || sent != pkbuf->len)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_send error (%d:%s)", 
 | 
			
		||||
                s->sndrcv_errno, strerror(s->sndrcv_errno));
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    pkbuf_free(pkbuf);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv = CORE_ERROR;
 | 
			
		||||
@@ -205,7 +19,7 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
 | 
			
		||||
    d_assert(pkbuf,,);
 | 
			
		||||
    d_assert(enb->s1ap_sock,,);
 | 
			
		||||
 | 
			
		||||
    rv = s1ap_send(enb->s1ap_sock, pkbuf);
 | 
			
		||||
    rv = s1ap_sendto(enb->s1ap_sock, pkbuf, enb->s1ap_addr, enb->s1ap_port);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("s1_send error");
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,15 @@ extern "C" {
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_open();
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_close();
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_sctp_close(net_sock_t *sock);
 | 
			
		||||
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_final();
 | 
			
		||||
 | 
			
		||||
#if 0 /* depreciated */
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_send(net_sock_t *s, pkbuf_t *pkb);
 | 
			
		||||
#endif
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_sendto(net_sock_t *s, pkbuf_t *pkb,
 | 
			
		||||
        c_uint32_t addr, c_uint16_t port);
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkb);
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_delayed_send_to_enb(mme_enb_t *enb,
 | 
			
		||||
        pkbuf_t *pkbuf, c_uint32_t duration);
 | 
			
		||||
@@ -43,7 +51,7 @@ CORE_DECLARE(status_t) s1ap_send_handover_cancel_ack(enb_ue_t *source_ue);
 | 
			
		||||
CORE_DECLARE(status_t) s1ap_send_mme_status_transfer(
 | 
			
		||||
        enb_ue_t *target_ue, S1ap_ENBStatusTransferIEs_t *ies);
 | 
			
		||||
 | 
			
		||||
int _s1ap_recv_cb(net_sock_t *net_sock, void *data);
 | 
			
		||||
int s1ap_recv_cb(net_sock_t *net_sock, void *data);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										234
									
								
								src/mme/s1ap_sctp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								src/mme/s1ap_sctp.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
#define TRACE_MODULE _s1ap_sctp
 | 
			
		||||
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_thread.h"
 | 
			
		||||
 | 
			
		||||
#include "mme_event.h"
 | 
			
		||||
 | 
			
		||||
#include "s1ap_path.h"
 | 
			
		||||
 | 
			
		||||
static int s1ap_accept_cb(net_sock_t *net_sock, void *data);
 | 
			
		||||
 | 
			
		||||
status_t s1ap_open(void)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    rc = net_listen_ext(&mme_self()->s1ap_sock, 
 | 
			
		||||
            SOCK_STREAM, IPPROTO_SCTP, SCTP_S1AP_PPID,
 | 
			
		||||
            mme_self()->s1ap_addr, mme_self()->s1ap_port);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S1-ENB(port:%d) path(%d:%s)",
 | 
			
		||||
            mme_self()->s1ap_port, errno, strerror(errno));
 | 
			
		||||
        mme_self()->s1ap_sock = NULL;
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rc = net_register_sock(
 | 
			
		||||
            mme_self()->s1ap_sock, s1ap_accept_cb, NULL);
 | 
			
		||||
    if (rc != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S1-ENB path(%d:%s)",
 | 
			
		||||
            errno, strerror(errno));
 | 
			
		||||
        net_close(mme_self()->s1ap_sock);
 | 
			
		||||
        mme_self()->s1ap_sock = NULL;
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d_trace(1, "s1_enb_listen() %s:%d\n", 
 | 
			
		||||
        INET_NTOP(&mme_self()->s1ap_addr, buf), mme_self()->s1ap_port);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_close()
 | 
			
		||||
{
 | 
			
		||||
    s1ap_sctp_close(mme_self()->s1ap_sock);
 | 
			
		||||
    mme_self()->s1ap_sock = NULL;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_sctp_close(net_sock_t *sock)
 | 
			
		||||
{
 | 
			
		||||
    net_unregister_sock(sock);
 | 
			
		||||
    net_close(sock);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_final()
 | 
			
		||||
{
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int s1ap_accept_cb(net_sock_t *net_sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
    ssize_t r;
 | 
			
		||||
    net_sock_t *remote_sock;
 | 
			
		||||
 | 
			
		||||
    d_assert(net_sock, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    r = net_accept(&remote_sock, net_sock, 0);
 | 
			
		||||
    if (r > 0)
 | 
			
		||||
    {
 | 
			
		||||
        event_t e;
 | 
			
		||||
        c_uint32_t addr = remote_sock->remote.sin_addr.s_addr;
 | 
			
		||||
        c_uint16_t port = ntohs(remote_sock->remote.sin_port);
 | 
			
		||||
        d_trace(1, "eNB-S1 accepted[%s] in s1_path module\n", 
 | 
			
		||||
            INET_NTOP(&addr, buf));
 | 
			
		||||
 | 
			
		||||
        event_set(&e, MME_EVT_S1AP_LO_ACCEPT);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)remote_sock);
 | 
			
		||||
        event_set_param2(&e, (c_uintptr_t)addr);
 | 
			
		||||
        event_set_param3(&e, (c_uintptr_t)port);
 | 
			
		||||
        /* FIXME : how to close remote_sock */
 | 
			
		||||
        mme_event_send(&e);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_accept failed(r = %d, errno = %d)", r, errno);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static status_t s1ap_recv(net_sock_t *sock, pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    event_t e;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    d_trace(10, "S1AP_PDU is received from eNB-Inf\n");
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
 | 
			
		||||
    event_set(&e, MME_EVT_S1AP_MESSAGE);
 | 
			
		||||
    event_set_param1(&e, (c_uintptr_t)sock);
 | 
			
		||||
    event_set_param2(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    return mme_event_send(&e);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int s1ap_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    pkbuf_t *pkbuf;
 | 
			
		||||
    ssize_t r;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
 | 
			
		||||
    if (pkbuf == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        char tmp_buf[MAX_SDU_LEN];
 | 
			
		||||
 | 
			
		||||
        d_fatal("Can't allocate pkbuf");
 | 
			
		||||
 | 
			
		||||
        /* Read data from socket to exit from select */
 | 
			
		||||
        net_read(sock, tmp_buf, MAX_SDU_LEN, 0);
 | 
			
		||||
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    r = net_read(sock, pkbuf->payload, pkbuf->len, 0);
 | 
			
		||||
    if (r == -2)
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf_free(pkbuf);
 | 
			
		||||
    }
 | 
			
		||||
    else if (r <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf_free(pkbuf);
 | 
			
		||||
 | 
			
		||||
        if (sock->sndrcv_errno == EAGAIN)
 | 
			
		||||
        {
 | 
			
		||||
            d_warn("net_read failed(%d:%s)",
 | 
			
		||||
                    sock->sndrcv_errno, strerror(sock->sndrcv_errno));
 | 
			
		||||
            return 0;
 | 
			
		||||
        } 
 | 
			
		||||
        else if (sock->sndrcv_errno == ECONNREFUSED)
 | 
			
		||||
        {
 | 
			
		||||
            d_warn("net_read failed(%d:%s)",
 | 
			
		||||
                    sock->sndrcv_errno, strerror(sock->sndrcv_errno));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            d_error("net_read failed(%d:%s)",
 | 
			
		||||
                    sock->sndrcv_errno, strerror(sock->sndrcv_errno));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        event_t e;
 | 
			
		||||
 | 
			
		||||
        event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)sock);
 | 
			
		||||
        mme_event_send(&e);
 | 
			
		||||
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf->len = r;
 | 
			
		||||
 | 
			
		||||
        rv = s1ap_recv(sock, pkbuf);
 | 
			
		||||
        if (rv != CORE_OK)
 | 
			
		||||
        {
 | 
			
		||||
            pkbuf_free(pkbuf);
 | 
			
		||||
            d_error("s1_recv() failed");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0 /* deprecated */
 | 
			
		||||
status_t s1ap_send(net_sock_t *s, pkbuf_t *pkbuf)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
 | 
			
		||||
    ssize_t sent;
 | 
			
		||||
 | 
			
		||||
    d_assert(s, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    sent = net_send(s, pkbuf->payload, pkbuf->len);
 | 
			
		||||
    d_trace(10,"Sent %d->%d bytes to [%s:%d]\n", 
 | 
			
		||||
            pkbuf->len, sent, INET_NTOP(&s->remote.sin_addr.s_addr, buf), 
 | 
			
		||||
            ntohs(s->remote.sin_port));
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
    if (sent < 0 || sent != pkbuf->len)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_send error (%d:%s)", 
 | 
			
		||||
                s->sndrcv_errno, strerror(s->sndrcv_errno));
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    pkbuf_free(pkbuf);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
status_t s1ap_sendto(net_sock_t *s, pkbuf_t *pkbuf,
 | 
			
		||||
        c_uint32_t addr, c_uint16_t port)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
    ssize_t sent;
 | 
			
		||||
 | 
			
		||||
    d_assert(s, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    sent = net_sendto(s, pkbuf->payload, pkbuf->len, addr, port);
 | 
			
		||||
    d_trace(10,"Sent %d->%d bytes to [%s:%d]\n", 
 | 
			
		||||
            pkbuf->len, sent, INET_NTOP(&addr, buf), port);
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
    if (sent < 0 || sent != pkbuf->len)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("net_send error (%d:%s)", 
 | 
			
		||||
                s->sndrcv_errno, strerror(s->sndrcv_errno));
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    pkbuf_free(pkbuf);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -29,13 +29,16 @@ void s1ap_state_final(fsm_t *s, event_t *e)
 | 
			
		||||
void s1ap_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
{
 | 
			
		||||
    mme_enb_t *enb = NULL;
 | 
			
		||||
    net_sock_t *sock = NULL;
 | 
			
		||||
 | 
			
		||||
    d_assert(s, return, "Null param");
 | 
			
		||||
    d_assert(e, return, "Null param");
 | 
			
		||||
 | 
			
		||||
    mme_sm_trace(3, e);
 | 
			
		||||
 | 
			
		||||
    enb = mme_enb_find(event_get_param1(e));
 | 
			
		||||
    sock = (net_sock_t *)event_get_param1(e);
 | 
			
		||||
    d_assert(sock, return, "Null param");
 | 
			
		||||
    enb = mme_enb_find_by_sock(sock);
 | 
			
		||||
    d_assert(enb, return, "Null param");
 | 
			
		||||
 | 
			
		||||
    switch (event_get(e))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										460
									
								
								src/mme/s1ap_usrsctp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										460
									
								
								src/mme/s1ap_usrsctp.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,460 @@
 | 
			
		||||
#define TRACE_MODULE _s1ap_usrsctp
 | 
			
		||||
 | 
			
		||||
#include "core_debug.h"
 | 
			
		||||
#include "core_thread.h"
 | 
			
		||||
 | 
			
		||||
#include "mme_event.h"
 | 
			
		||||
 | 
			
		||||
#include "s1ap_path.h"
 | 
			
		||||
 | 
			
		||||
#if HAVE_USRSCTP_H
 | 
			
		||||
#ifndef INET
 | 
			
		||||
#define INET            1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef INET6
 | 
			
		||||
#define INET6           1
 | 
			
		||||
#endif
 | 
			
		||||
#include <usrsctp.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LOCAL_UDP_PORT  9899
 | 
			
		||||
 | 
			
		||||
static void handle_notification(union sctp_notification *notif, size_t n);
 | 
			
		||||
static int s1ap_usrsctp_recv_cb(struct socket *sock,
 | 
			
		||||
        union sctp_sockstore addr, void *data, size_t datalen,
 | 
			
		||||
        struct sctp_rcvinfo rcv, int flags, void *ulp_info);
 | 
			
		||||
 | 
			
		||||
static void debug_printf(const char *format, ...);
 | 
			
		||||
 | 
			
		||||
int accept_thread_should_stop = 0;
 | 
			
		||||
static thread_id accept_thread;
 | 
			
		||||
static void *THREAD_FUNC accept_main(thread_id id, void *data);
 | 
			
		||||
 | 
			
		||||
status_t s1ap_open(void)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
 | 
			
		||||
    struct socket *psock = NULL;
 | 
			
		||||
    struct sockaddr_in local_addr;
 | 
			
		||||
    const int on = 1;
 | 
			
		||||
    struct sctp_event event;
 | 
			
		||||
    c_uint16_t event_types[] = {
 | 
			
		||||
        SCTP_ASSOC_CHANGE,
 | 
			
		||||
        SCTP_PEER_ADDR_CHANGE,
 | 
			
		||||
        SCTP_REMOTE_ERROR,
 | 
			
		||||
        SCTP_SHUTDOWN_EVENT,
 | 
			
		||||
        SCTP_ADAPTATION_INDICATION,
 | 
			
		||||
        SCTP_PARTIAL_DELIVERY_EVENT
 | 
			
		||||
    };
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    usrsctp_init(LOCAL_UDP_PORT, NULL, debug_printf);
 | 
			
		||||
#ifdef SCTP_DEBUG
 | 
			
		||||
    usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL);
 | 
			
		||||
#endif
 | 
			
		||||
    usrsctp_sysctl_set_sctp_blackhole(2);
 | 
			
		||||
    usrsctp_sysctl_set_sctp_enable_sack_immediately(1);
 | 
			
		||||
 | 
			
		||||
    if (!(psock = usrsctp_socket(
 | 
			
		||||
            AF_INET, SOCK_STREAM, IPPROTO_SCTP, s1ap_usrsctp_recv_cb,
 | 
			
		||||
            NULL, 0, NULL)))
 | 
			
		||||
    {
 | 
			
		||||
        d_error("usrsctp_socket failed");
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mme_self()->s1ap_sock = (net_sock_t *)psock;
 | 
			
		||||
 | 
			
		||||
    if (usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_RECVRCVINFO,
 | 
			
		||||
                &on, sizeof(int)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("usrsctp_setsockopt SCTP_RECVRCVINFO failed");
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(&event, 0, sizeof(event));
 | 
			
		||||
    event.se_assoc_id = SCTP_FUTURE_ASSOC;
 | 
			
		||||
    event.se_on = 1;
 | 
			
		||||
    for (i = 0; i < (int)(sizeof(event_types)/sizeof(c_uint16_t)); i++)
 | 
			
		||||
    {
 | 
			
		||||
        event.se_type = event_types[i];
 | 
			
		||||
        if (usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_EVENT,
 | 
			
		||||
                    &event, sizeof(struct sctp_event)) < 0)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("usrsctp_setsockopt SCTP_EVENT failed");
 | 
			
		||||
            return CORE_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset((void *)&local_addr, 0, sizeof(struct sockaddr_in));
 | 
			
		||||
    local_addr.sin_family = AF_INET;
 | 
			
		||||
    local_addr.sin_len = sizeof(struct sockaddr_in);
 | 
			
		||||
    local_addr.sin_port = htons(mme_self()->s1ap_port);
 | 
			
		||||
    local_addr.sin_addr.s_addr = mme_self()->s1ap_addr;
 | 
			
		||||
 | 
			
		||||
    if (usrsctp_bind(psock, (struct sockaddr *)&local_addr,
 | 
			
		||||
                sizeof(struct sockaddr_in)) == -1)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("usrsctp_bind failed(%s:%d)",
 | 
			
		||||
            INET_NTOP(&mme_self()->s1ap_addr, buf), mme_self()->s1ap_port);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (usrsctp_listen(psock, 1) < 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("usrsctp_listen failed");
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = thread_create(&accept_thread, NULL, accept_main, NULL);
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    d_trace(1, "s1_enb_listen() %s:%d\n", 
 | 
			
		||||
        INET_NTOP(&mme_self()->s1ap_addr, buf), mme_self()->s1ap_port);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_final()
 | 
			
		||||
{
 | 
			
		||||
    while(usrsctp_finish() != 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("try to finsih SCTP\n");
 | 
			
		||||
        core_sleep(time_from_msec(1000));
 | 
			
		||||
    }
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_close()
 | 
			
		||||
{
 | 
			
		||||
    struct socket *psock = NULL;
 | 
			
		||||
 | 
			
		||||
    d_assert(mme_self(), return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(mme_self()->s1ap_sock != NULL, return CORE_ERROR,
 | 
			
		||||
            "S1-ENB path already opened");
 | 
			
		||||
 | 
			
		||||
    accept_thread_should_stop = 1;
 | 
			
		||||
 | 
			
		||||
    psock = (struct socket *)mme_self()->s1ap_sock;
 | 
			
		||||
    usrsctp_close(psock);
 | 
			
		||||
#if 0
 | 
			
		||||
    thread_delete(accept_thread);
 | 
			
		||||
#else
 | 
			
		||||
    d_error("[FIXME] should delete accept_thread : "
 | 
			
		||||
            "how to release usrsctp_accept() blocking?");
 | 
			
		||||
#endif
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_sctp_close(net_sock_t *sock)
 | 
			
		||||
{
 | 
			
		||||
    usrsctp_close((struct socket *)sock);
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
status_t s1ap_sendto(net_sock_t *s, pkbuf_t *pkbuf,
 | 
			
		||||
        c_uint32_t addr, c_uint16_t port)
 | 
			
		||||
{
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
    ssize_t sent;
 | 
			
		||||
    struct socket *psock = (struct socket *)s;
 | 
			
		||||
    struct sctp_sndinfo sndinfo;
 | 
			
		||||
 | 
			
		||||
    d_assert(s, return CORE_ERROR, "Null param");
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR, "Null param");
 | 
			
		||||
 | 
			
		||||
    memset((void *)&sndinfo, 0, sizeof(struct sctp_sndinfo));
 | 
			
		||||
    sndinfo.snd_ppid = htonl(SCTP_S1AP_PPID);
 | 
			
		||||
    sent = usrsctp_sendv(psock, pkbuf->payload, pkbuf->len, 
 | 
			
		||||
            NULL, 0,  /* Only SOCK_STREAM is supported at this time */
 | 
			
		||||
            (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
 | 
			
		||||
            SCTP_SENDV_SNDINFO, 0);
 | 
			
		||||
 | 
			
		||||
    d_trace(10,"Sent %d->%d bytes to [%s:%d]\n", 
 | 
			
		||||
            pkbuf->len, sent, INET_NTOP(&addr, buf), port);
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
    if (sent < 0 || sent != pkbuf->len)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("sent : %d, pkbuf->len : %d\n", sent, pkbuf->len);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    pkbuf_free(pkbuf);
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *THREAD_FUNC accept_main(thread_id id, void *data)
 | 
			
		||||
{
 | 
			
		||||
    event_t e;
 | 
			
		||||
 | 
			
		||||
    struct socket *sock = NULL;
 | 
			
		||||
    struct sockaddr_in remote_addr;
 | 
			
		||||
    socklen_t addr_len;
 | 
			
		||||
 | 
			
		||||
    while (!accept_thread_should_stop)
 | 
			
		||||
    {
 | 
			
		||||
        if ((sock = usrsctp_accept((struct socket *)mme_self()->s1ap_sock,
 | 
			
		||||
                    (struct sockaddr *)&remote_addr, &addr_len)) == NULL)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("usrsctp_accept failed");
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        event_set(&e, MME_EVT_S1AP_LO_ACCEPT);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)sock);
 | 
			
		||||
        mme_event_send(&e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int s1ap_usrsctp_recv_cb(struct socket *sock,
 | 
			
		||||
    union sctp_sockstore addr, void *data, size_t datalen,
 | 
			
		||||
    struct sctp_rcvinfo rcv, int flags, void *ulp_info)
 | 
			
		||||
{
 | 
			
		||||
    if (data)
 | 
			
		||||
    {
 | 
			
		||||
        if (flags & MSG_NOTIFICATION)
 | 
			
		||||
        {
 | 
			
		||||
            handle_notification((union sctp_notification *)data, datalen);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            c_uint32_t ppid = ntohl(rcv.rcv_ppid);
 | 
			
		||||
            if ((flags & MSG_EOR) && ppid == SCTP_S1AP_PPID)
 | 
			
		||||
            {
 | 
			
		||||
                event_t e;
 | 
			
		||||
                pkbuf_t *pkbuf;
 | 
			
		||||
 | 
			
		||||
                pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
 | 
			
		||||
                d_assert(pkbuf, return 1, );
 | 
			
		||||
 | 
			
		||||
                pkbuf->len = datalen;
 | 
			
		||||
                memcpy(pkbuf->payload, data, pkbuf->len);
 | 
			
		||||
 | 
			
		||||
                event_set(&e, MME_EVT_S1AP_MESSAGE);
 | 
			
		||||
                event_set_param1(&e, (c_uintptr_t)sock);
 | 
			
		||||
                event_set_param2(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
                mme_event_send(&e);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                d_warn("Unknwon PPID(%d) for data length(%ld)\n",
 | 
			
		||||
                        ppid, datalen);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        free(data);
 | 
			
		||||
    }
 | 
			
		||||
    return (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_association_change_event(struct sctp_assoc_change *sac)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int i, n;
 | 
			
		||||
 | 
			
		||||
    printf("Association change ");
 | 
			
		||||
    switch (sac->sac_state) {
 | 
			
		||||
    case SCTP_COMM_UP:
 | 
			
		||||
        printf("SCTP_COMM_UP");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_COMM_LOST:
 | 
			
		||||
        printf("SCTP_COMM_LOST");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_RESTART:
 | 
			
		||||
        printf("SCTP_RESTART");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_SHUTDOWN_COMP:
 | 
			
		||||
        printf("SCTP_SHUTDOWN_COMP");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_CANT_STR_ASSOC:
 | 
			
		||||
        printf("SCTP_CANT_STR_ASSOC");
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        printf("UNKNOWN");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    printf(", streams (in/out) = (%u/%u)",
 | 
			
		||||
           sac->sac_inbound_streams, sac->sac_outbound_streams);
 | 
			
		||||
    n = sac->sac_length - sizeof(struct sctp_assoc_change);
 | 
			
		||||
    if (((sac->sac_state == SCTP_COMM_UP) ||
 | 
			
		||||
         (sac->sac_state == SCTP_RESTART)) && (n > 0)) {
 | 
			
		||||
        printf(", supports");
 | 
			
		||||
        for (i = 0; i < n; i++) {
 | 
			
		||||
            switch (sac->sac_info[i]) {
 | 
			
		||||
            case SCTP_ASSOC_SUPPORTS_PR:
 | 
			
		||||
                printf(" PR");
 | 
			
		||||
                break;
 | 
			
		||||
            case SCTP_ASSOC_SUPPORTS_AUTH:
 | 
			
		||||
                printf(" AUTH");
 | 
			
		||||
                break;
 | 
			
		||||
            case SCTP_ASSOC_SUPPORTS_ASCONF:
 | 
			
		||||
                printf(" ASCONF");
 | 
			
		||||
                break;
 | 
			
		||||
            case SCTP_ASSOC_SUPPORTS_MULTIBUF:
 | 
			
		||||
                printf(" MULTIBUF");
 | 
			
		||||
                break;
 | 
			
		||||
            case SCTP_ASSOC_SUPPORTS_RE_CONFIG:
 | 
			
		||||
                printf(" RE-CONFIG");
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                printf(" UNKNOWN(0x%02x)", sac->sac_info[i]);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (((sac->sac_state == SCTP_COMM_LOST) ||
 | 
			
		||||
                (sac->sac_state == SCTP_CANT_STR_ASSOC)) && (n > 0)) {
 | 
			
		||||
        printf(", ABORT =");
 | 
			
		||||
        for (i = 0; i < n; i++) {
 | 
			
		||||
            printf(" 0x%02x", sac->sac_info[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    printf(".\n");
 | 
			
		||||
    if ((sac->sac_state == SCTP_CANT_STR_ASSOC) ||
 | 
			
		||||
        (sac->sac_state == SCTP_SHUTDOWN_COMP) ||
 | 
			
		||||
        (sac->sac_state == SCTP_COMM_LOST)) {
 | 
			
		||||
        exit(0);
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_peer_address_change_event(struct sctp_paddr_change *spc)
 | 
			
		||||
{
 | 
			
		||||
    char addr_buf[INET6_ADDRSTRLEN];
 | 
			
		||||
    const char *addr;
 | 
			
		||||
    struct sockaddr_in *sin;
 | 
			
		||||
    struct sockaddr_in6 *sin6;
 | 
			
		||||
    struct sockaddr_conn *sconn;
 | 
			
		||||
 | 
			
		||||
    switch (spc->spc_aaddr.ss_family) {
 | 
			
		||||
    case AF_INET:
 | 
			
		||||
        sin = (struct sockaddr_in *)&spc->spc_aaddr;
 | 
			
		||||
        addr = inet_ntop(AF_INET, &sin->sin_addr, addr_buf, INET_ADDRSTRLEN);
 | 
			
		||||
        break;
 | 
			
		||||
    case AF_INET6:
 | 
			
		||||
        sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
 | 
			
		||||
        addr = inet_ntop(AF_INET6, &sin6->sin6_addr, addr_buf, INET6_ADDRSTRLEN);
 | 
			
		||||
        break;
 | 
			
		||||
    case AF_CONN:
 | 
			
		||||
        sconn = (struct sockaddr_conn *)&spc->spc_aaddr;
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        _snprintf(addr_buf, INET6_ADDRSTRLEN, "%p", sconn->sconn_addr);
 | 
			
		||||
#else
 | 
			
		||||
        snprintf(addr_buf, INET6_ADDRSTRLEN, "%p", sconn->sconn_addr);
 | 
			
		||||
#endif
 | 
			
		||||
        addr = addr_buf;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        _snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family);
 | 
			
		||||
#else
 | 
			
		||||
        snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family);
 | 
			
		||||
#endif
 | 
			
		||||
        addr = addr_buf;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    printf("Peer address %s is now ", addr);
 | 
			
		||||
    switch (spc->spc_state) {
 | 
			
		||||
    case SCTP_ADDR_AVAILABLE:
 | 
			
		||||
        printf("SCTP_ADDR_AVAILABLE");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ADDR_UNREACHABLE:
 | 
			
		||||
        printf("SCTP_ADDR_UNREACHABLE");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ADDR_REMOVED:
 | 
			
		||||
        printf("SCTP_ADDR_REMOVED");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ADDR_ADDED:
 | 
			
		||||
        printf("SCTP_ADDR_ADDED");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ADDR_MADE_PRIM:
 | 
			
		||||
        printf("SCTP_ADDR_MADE_PRIM");
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ADDR_CONFIRMED:
 | 
			
		||||
        printf("SCTP_ADDR_CONFIRMED");
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        printf("UNKNOWN");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    printf(" (error = 0x%08x).\n", spc->spc_error);
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_send_failed_event(struct sctp_send_failed_event *ssfe)
 | 
			
		||||
{
 | 
			
		||||
    size_t i, n;
 | 
			
		||||
 | 
			
		||||
    if (ssfe->ssfe_flags & SCTP_DATA_UNSENT) {
 | 
			
		||||
        printf("Unsent ");
 | 
			
		||||
    }
 | 
			
		||||
    if (ssfe->ssfe_flags & SCTP_DATA_SENT) {
 | 
			
		||||
        printf("Sent ");
 | 
			
		||||
    }
 | 
			
		||||
    if (ssfe->ssfe_flags & ~(SCTP_DATA_SENT | SCTP_DATA_UNSENT)) {
 | 
			
		||||
        printf("(flags = %x) ", ssfe->ssfe_flags);
 | 
			
		||||
    }
 | 
			
		||||
    printf("message with PPID = %u, SID = %u, flags: 0x%04x due to error = 0x%08x",
 | 
			
		||||
           ntohl(ssfe->ssfe_info.snd_ppid), ssfe->ssfe_info.snd_sid,
 | 
			
		||||
           ssfe->ssfe_info.snd_flags, ssfe->ssfe_error);
 | 
			
		||||
    n = ssfe->ssfe_length - sizeof(struct sctp_send_failed_event);
 | 
			
		||||
    for (i = 0; i < n; i++) {
 | 
			
		||||
        printf(" 0x%02x", ssfe->ssfe_data[i]);
 | 
			
		||||
    }
 | 
			
		||||
    printf(".\n");
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_notification(union sctp_notification *notif, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    if (notif->sn_header.sn_length != (uint32_t)n) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    switch (notif->sn_header.sn_type) {
 | 
			
		||||
    case SCTP_ASSOC_CHANGE:
 | 
			
		||||
        handle_association_change_event(&(notif->sn_assoc_change));
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_PEER_ADDR_CHANGE:
 | 
			
		||||
        handle_peer_address_change_event(&(notif->sn_paddr_change));
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_REMOTE_ERROR:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_SHUTDOWN_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ADAPTATION_INDICATION:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_PARTIAL_DELIVERY_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_AUTHENTICATION_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_SENDER_DRY_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_NOTIFICATIONS_STOPPED_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_SEND_FAILED_EVENT:
 | 
			
		||||
        handle_send_failed_event(&(notif->sn_send_failed_event));
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_STREAM_RESET_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_ASSOC_RESET_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    case SCTP_STREAM_CHANGE_EVENT:
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void debug_printf(const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list ap;
 | 
			
		||||
 | 
			
		||||
    va_start(ap, format);
 | 
			
		||||
    vprintf(format, ap);
 | 
			
		||||
    va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
@@ -7,7 +7,9 @@
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "app.h"
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
const char *app_name = "pcrf";
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int others = 0;
 | 
			
		||||
@@ -26,7 +28,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    d_assert(rv == CORE_OK, return rv, "Failed to intialize PCRF");
 | 
			
		||||
    d_trace(1, "PCRF initialize...done\n");
 | 
			
		||||
 | 
			
		||||
    rv = app_did_initialize(config_path, log_path);
 | 
			
		||||
    rv = app_did_initialize();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
 
 | 
			
		||||
@@ -256,31 +256,25 @@ status_t pcrf_db_pdn_data(
 | 
			
		||||
 | 
			
		||||
    mutex_lock(self.db_lock);
 | 
			
		||||
 | 
			
		||||
    query = BCON_NEW(
 | 
			
		||||
            "imsi", BCON_UTF8(imsi_bcd),
 | 
			
		||||
            "pdn.apn", BCON_UTF8(apn));
 | 
			
		||||
#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5
 | 
			
		||||
    opts = BCON_NEW(
 | 
			
		||||
            "projection", "{",
 | 
			
		||||
                "imsi", BCON_INT64(1),
 | 
			
		||||
                "pdn.$", BCON_INT64(1),
 | 
			
		||||
            "}"
 | 
			
		||||
            );
 | 
			
		||||
#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5
 | 
			
		||||
    query = BCON_NEW(
 | 
			
		||||
            "imsi", BCON_UTF8(imsi_bcd),
 | 
			
		||||
            "pdn.apn", BCON_UTF8(apn));
 | 
			
		||||
    cursor = mongoc_collection_find_with_opts(
 | 
			
		||||
            self.subscriberCollection, query, opts, NULL);
 | 
			
		||||
#else
 | 
			
		||||
    query = BCON_NEW(
 | 
			
		||||
            "$query", "{",
 | 
			
		||||
                "imsi", BCON_UTF8(imsi_bcd),
 | 
			
		||||
                "pdn.apn", BCON_UTF8(apn),
 | 
			
		||||
            "}",
 | 
			
		||||
            "$projection", "{",
 | 
			
		||||
                "imsi", BCON_INT64(1),
 | 
			
		||||
                "pdn.$", BCON_INT64(1),
 | 
			
		||||
            "}"
 | 
			
		||||
    opts = BCON_NEW(
 | 
			
		||||
            "imsi", BCON_INT64(1),
 | 
			
		||||
            "pdn.$", BCON_INT64(1)
 | 
			
		||||
            );
 | 
			
		||||
    cursor = mongoc_collection_find(self.subscriberCollection,
 | 
			
		||||
            MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
 | 
			
		||||
            MONGOC_QUERY_NONE, 0, 0, 0, query, opts, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (!mongoc_cursor_next(cursor, &document))
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,9 @@
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "app.h"
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
const char *app_name = "pgw";
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int others = 0;
 | 
			
		||||
@@ -26,7 +28,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    d_assert(rv == CORE_OK, return rv, "Failed to intialize PGW");
 | 
			
		||||
    d_trace(1, "PGW initialize...done\n");
 | 
			
		||||
 | 
			
		||||
    rv = app_did_initialize(config_path, log_path);
 | 
			
		||||
    rv = app_did_initialize();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
 
 | 
			
		||||
@@ -94,8 +94,8 @@ pgw_context_t* pgw_self()
 | 
			
		||||
 | 
			
		||||
static status_t pgw_context_prepare()
 | 
			
		||||
{
 | 
			
		||||
    self.s5c_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.s5u_port = GTPV1_U_UDP_PORT;
 | 
			
		||||
    self.gtpc_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.gtpu_port = GTPV1_U_UDP_PORT;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -108,27 +108,21 @@ static status_t pgw_context_validation()
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.s5c_addr == 0)
 | 
			
		||||
    if (self.gtpc_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No PGW.NEWORK.S5C_IPV4 in '%s'",
 | 
			
		||||
        d_error("No PGW.NEWORK.GTPC_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.s5u_addr == 0)
 | 
			
		||||
    if (self.gtpu_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No PGW.NEWORK.S5U_IPV4 in '%s'",
 | 
			
		||||
        d_error("No PGW.NEWORK.GTPU_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.tun_dev_name == NULL)
 | 
			
		||||
    if (self.num_of_ue_network == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No PGW.TUNNEL.DEV_NAME in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.num_of_ip_pool == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No PGW.IP_POOL.CIDR in '%s'",
 | 
			
		||||
        d_error("No PGW.UE_NETWORK.IPV4_POOL in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
@@ -227,54 +221,30 @@ status_t pgw_context_parse_config()
 | 
			
		||||
                        {
 | 
			
		||||
                            n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "S5C_IPV4") == 0)
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "GTPC_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5c_addr = inet_addr(v);
 | 
			
		||||
                                if (v) self.gtpc_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5C_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPC_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5c_port = atoi(v);
 | 
			
		||||
                                if (v) self.gtpc_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5U_IPV4") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPU_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5u_addr = inet_addr(v);
 | 
			
		||||
                                if (v) self.gtpu_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5U_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPU_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5u_port = atoi(v);
 | 
			
		||||
                                if (v) self.gtpu_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (jsmntok_equal(json, t, "TUNNEL") == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    m = 1;
 | 
			
		||||
                    size = 1;
 | 
			
		||||
 | 
			
		||||
                    if ((t+1)->type == JSMN_ARRAY)
 | 
			
		||||
                    {
 | 
			
		||||
                        m = 2;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    for (arr = 0; arr < size; arr++)
 | 
			
		||||
                    {
 | 
			
		||||
                        for (n = 1; n > 0; m++, n--)
 | 
			
		||||
                        {
 | 
			
		||||
                            n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "DEV_NAME") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                self.tun_dev_name = v;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (jsmntok_equal(json, t, "IP_POOL") == 0)
 | 
			
		||||
                else if (jsmntok_equal(json, t, "UE_NETWORK") == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    m = 1;
 | 
			
		||||
                    size = 1;
 | 
			
		||||
@@ -287,28 +257,42 @@ status_t pgw_context_parse_config()
 | 
			
		||||
 | 
			
		||||
                    for (arr = 0; arr < size; arr++)
 | 
			
		||||
                    {
 | 
			
		||||
                        char *if_name = NULL;
 | 
			
		||||
                        c_uint32_t addr = 0;
 | 
			
		||||
                        c_uint8_t bits = 0;
 | 
			
		||||
                        for (n = 1; n > 0; m++, n--)
 | 
			
		||||
                        {
 | 
			
		||||
                            n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "CIDR") == 0)
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "IF_NAME") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                if_name = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "IPV4_POOL") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v)
 | 
			
		||||
                                {
 | 
			
		||||
                                    char *prefix = strsep(&v, "/");
 | 
			
		||||
                                    if (prefix)
 | 
			
		||||
                                    char *str = strsep(&v, "/");
 | 
			
		||||
                                    if (str)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        self.ip_pool[self.num_of_ip_pool].prefix
 | 
			
		||||
                                            = inet_addr(prefix);
 | 
			
		||||
                                        self.ip_pool[self.num_of_ip_pool].mask
 | 
			
		||||
                                            = atoi(v);
 | 
			
		||||
                                        addr = inet_addr(str);
 | 
			
		||||
                                        bits = atoi(v);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                self.num_of_ip_pool++;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (addr && bits)
 | 
			
		||||
                        {
 | 
			
		||||
                            self.ue_network[self.num_of_ue_network].if_name =
 | 
			
		||||
                                if_name;
 | 
			
		||||
                            self.ue_network[self.num_of_ue_network].ipv4.addr =
 | 
			
		||||
                                addr;
 | 
			
		||||
                            self.ue_network[self.num_of_ue_network].ipv4.bits =
 | 
			
		||||
                                bits;
 | 
			
		||||
                            self.num_of_ue_network++;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (jsmntok_equal(json, t, "DNS") == 0)
 | 
			
		||||
@@ -513,7 +497,7 @@ pgw_sess_t *pgw_sess_add(
 | 
			
		||||
    d_assert(sess, return NULL, "Null param");
 | 
			
		||||
 | 
			
		||||
    sess->pgw_s5c_teid = sess->index;  /* derived from an index */
 | 
			
		||||
    sess->pgw_s5c_addr = pgw_self()->s5c_addr;
 | 
			
		||||
    sess->pgw_s5c_addr = pgw_self()->gtpc_addr;
 | 
			
		||||
 | 
			
		||||
    /* Set IMSI */
 | 
			
		||||
    sess->imsi_len = imsi_len;
 | 
			
		||||
@@ -657,7 +641,7 @@ pgw_bearer_t* pgw_bearer_add(pgw_sess_t *sess)
 | 
			
		||||
    list_init(&bearer->pf_list);
 | 
			
		||||
 | 
			
		||||
    bearer->pgw_s5u_teid = bearer->index;
 | 
			
		||||
    bearer->pgw_s5u_addr = pgw_self()->s5u_addr;
 | 
			
		||||
    bearer->pgw_s5u_addr = pgw_self()->gtpu_addr;
 | 
			
		||||
    
 | 
			
		||||
    bearer->sess = sess;
 | 
			
		||||
    list_append(&sess->bearer_list, bearer);
 | 
			
		||||
@@ -1049,14 +1033,36 @@ pgw_pf_t* pgw_pf_next(pgw_pf_t *pf)
 | 
			
		||||
 | 
			
		||||
status_t pgw_ip_pool_generate()
 | 
			
		||||
{
 | 
			
		||||
    int i, j, k;
 | 
			
		||||
    int i, j;
 | 
			
		||||
    int pool_index = 0;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < self.num_of_ip_pool; i++)
 | 
			
		||||
    for (i = 0; i < self.num_of_ue_network; i++)
 | 
			
		||||
    {
 | 
			
		||||
        c_uint32_t mask = htonl(0xffffffff << (32 - self.ip_pool[i].mask));
 | 
			
		||||
        c_uint32_t prefix = self.ip_pool[i].prefix & mask;
 | 
			
		||||
        c_uint32_t mask = 
 | 
			
		||||
            htonl(0xffffffff << (32 - self.ue_network[i].ipv4.bits));
 | 
			
		||||
        c_uint32_t prefix = self.ue_network[i].ipv4.addr & mask;
 | 
			
		||||
 | 
			
		||||
#if 1   /* Update IP assign rule from bradon's comment */
 | 
			
		||||
        c_uint32_t broadcast = prefix + ~mask;
 | 
			
		||||
 | 
			
		||||
        for (j = 1; j < (0xffffffff >> self.ue_network[i].ipv4.bits) &&
 | 
			
		||||
                pool_index < MAX_POOL_OF_SESS; j++)
 | 
			
		||||
        {
 | 
			
		||||
            pgw_ip_pool_t *ip_pool = &pgw_ip_pool_pool.pool[pool_index];
 | 
			
		||||
            ip_pool->ue_addr = prefix + htonl(j);
 | 
			
		||||
 | 
			
		||||
            /* Exclude Network Address */
 | 
			
		||||
            if (ip_pool->ue_addr == prefix) continue;
 | 
			
		||||
 | 
			
		||||
            /* Exclude Broadcast Address */
 | 
			
		||||
            if (ip_pool->ue_addr == broadcast) continue;
 | 
			
		||||
 | 
			
		||||
            /* Exclude TUN IP Address */
 | 
			
		||||
            if (ip_pool->ue_addr == self.ue_network[i].ipv4.addr) continue;
 | 
			
		||||
 | 
			
		||||
            pool_index++;
 | 
			
		||||
        }
 | 
			
		||||
#else   /* Deprecated */
 | 
			
		||||
        /* Exclude X.X.X.0, X.X.X.255 addresses from ip pool */
 | 
			
		||||
        c_uint32_t exclude_mask[] = { 0, 255 };
 | 
			
		||||
 | 
			
		||||
@@ -1081,6 +1087,7 @@ status_t pgw_ip_pool_generate()
 | 
			
		||||
            }
 | 
			
		||||
            pool_index++;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
 | 
			
		||||
#include "pgw_sm.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_NUM_OF_IP_POOL 16
 | 
			
		||||
#define MAX_NUM_OF_UE_NETWORK 16
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
@@ -22,27 +22,28 @@ typedef gtp_node_t pgw_sgw_t;
 | 
			
		||||
typedef struct _pgw_context_t {
 | 
			
		||||
    c_uint32_t      pgw_addr;  /* PGW local address */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s5c_addr;  /* PGW S5-C local address */
 | 
			
		||||
    c_uint32_t      s5c_port;  /* PGW S5-C local port */
 | 
			
		||||
    net_sock_t*     s5c_sock;  /* PGW S5-C local listen socket */
 | 
			
		||||
    c_uint32_t      gtpc_addr;  /* PGW GTP-C local address */
 | 
			
		||||
    c_uint32_t      gtpc_port;  /* PGW GTP-C local port */
 | 
			
		||||
    net_sock_t*     gtpc_sock;  /* PGW GTP-C local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s5u_addr;  /* PGW S5-U local address */
 | 
			
		||||
    c_uint32_t      s5u_port;  /* PGW S5-U local port */
 | 
			
		||||
    net_sock_t*     s5u_sock;  /* PGW S5-U local listen socket */
 | 
			
		||||
    c_uint32_t      gtpu_addr;  /* PGW GTP-U local address */
 | 
			
		||||
    c_uint32_t      gtpu_port;  /* PGW GTP-U local port */
 | 
			
		||||
    net_sock_t*     gtpu_sock;  /* PGW GTP-U local listen socket */
 | 
			
		||||
 | 
			
		||||
    char*           fd_conf_path;   /* PGW freeDiameter conf path */
 | 
			
		||||
 | 
			
		||||
    msgq_id         queue_id;       /* Qsesssess for processing PGW control plane */
 | 
			
		||||
    tm_service_t    tm_service;     /* Timer Service */
 | 
			
		||||
 | 
			
		||||
    char            *tun_dev_name;  /* PGW Tunnel device name */
 | 
			
		||||
    net_link_t*     tun_link;       /* PGW Tun Interace for U-plane */
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        c_uint32_t prefix;
 | 
			
		||||
        c_uint8_t  mask;
 | 
			
		||||
    } ip_pool[MAX_NUM_OF_IP_POOL];
 | 
			
		||||
    c_uint8_t       num_of_ip_pool;
 | 
			
		||||
        net_link_t* tun_link;       /* PGW Tun Interace for U-plane */
 | 
			
		||||
        char *if_name;
 | 
			
		||||
        struct {
 | 
			
		||||
            c_uint32_t addr;
 | 
			
		||||
            c_uint8_t  bits;
 | 
			
		||||
        } ipv4;
 | 
			
		||||
    } ue_network[MAX_NUM_OF_UE_NETWORK];
 | 
			
		||||
    c_uint8_t       num_of_ue_network;
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      primary_dns_addr;
 | 
			
		||||
    c_uint32_t      secondary_dns_addr;
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ static int _gtpv1_tun_recv_cb(net_link_t *net_link, void *data)
 | 
			
		||||
        /* Send to SGW */
 | 
			
		||||
        gnode.addr = bearer->sgw_s5u_addr;
 | 
			
		||||
        gnode.port = GTPV1_U_UDP_PORT;
 | 
			
		||||
        gnode.sock = pgw_self()->s5u_sock;
 | 
			
		||||
        gnode.sock = pgw_self()->gtpu_sock;
 | 
			
		||||
        d_trace(50, "Send S5U PDU (teid = 0x%x)to SGW(%s)\n",
 | 
			
		||||
                bearer->sgw_s5u_teid,
 | 
			
		||||
                INET_NTOP(&gnode.addr, buf));
 | 
			
		||||
@@ -73,7 +73,7 @@ static int _gtpv1_tun_recv_cb(net_link_t *net_link, void *data)
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can not find bearer");
 | 
			
		||||
        d_trace(3, "Can not find bearer\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pkbuf_free(recvbuf);
 | 
			
		||||
@@ -160,7 +160,8 @@ static int _gtpv1_u_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (net_link_write(pgw_self()->tun_link, pkbuf->payload, pkbuf->len) <= 0)
 | 
			
		||||
    if (net_link_write(pgw_self()->ue_network[(c_uintptr_t)data].tun_link,
 | 
			
		||||
                pkbuf->payload, pkbuf->len) <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can not send packets to tuntap");
 | 
			
		||||
    }
 | 
			
		||||
@@ -173,26 +174,28 @@ static int _gtpv1_u_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
status_t pgw_gtp_open()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int i;
 | 
			
		||||
    int rc;
 | 
			
		||||
    char buf[INET_ADDRSTRLEN];
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&pgw_self()->s5c_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            pgw_self()->s5c_addr, pgw_self()->s5c_port, NULL);
 | 
			
		||||
    rv = gtp_listen(&pgw_self()->gtpc_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            pgw_self()->gtpc_addr, pgw_self()->gtpc_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S5-C Path for PGW");
 | 
			
		||||
        d_error("Can't establish GTP-C Path for PGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&pgw_self()->s5u_sock, _gtpv1_u_recv_cb, 
 | 
			
		||||
            pgw_self()->s5u_addr, pgw_self()->s5u_port, NULL);
 | 
			
		||||
    rv = gtp_listen(&pgw_self()->gtpu_sock, _gtpv1_u_recv_cb, 
 | 
			
		||||
            pgw_self()->gtpu_addr, pgw_self()->gtpu_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S5-U Path for PGW");
 | 
			
		||||
        d_error("Can't establish GTP-U Path for PGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < pgw_self()->num_of_ue_network; i++)
 | 
			
		||||
    {
 | 
			
		||||
        int rc;
 | 
			
		||||
 | 
			
		||||
        /* NOTE : tun device can be created via following command.
 | 
			
		||||
         *
 | 
			
		||||
         * $ sudo ip tuntap add name pgwtun mode tun
 | 
			
		||||
@@ -205,21 +208,47 @@ status_t pgw_gtp_open()
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        /* Open Tun interface */
 | 
			
		||||
        rc = net_tuntap_open(&pgw_self()->tun_link, pgw_self()->tun_dev_name, 0);
 | 
			
		||||
        rc = net_tun_open(&pgw_self()->ue_network[i].tun_link,
 | 
			
		||||
                pgw_self()->ue_network[i].if_name, 0);
 | 
			
		||||
        if (rc != 0)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("Can not open tun(dev : %s)", pgw_self()->tun_dev_name);
 | 
			
		||||
            d_error("Can not open tun(dev : %s)",
 | 
			
		||||
                    pgw_self()->ue_network[i].if_name);
 | 
			
		||||
            return CORE_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        rc = net_register_link(pgw_self()->tun_link, _gtpv1_tun_recv_cb, NULL);
 | 
			
		||||
        /* 
 | 
			
		||||
         * On Linux, it is possible to create a persistent tun/tap 
 | 
			
		||||
         * interface which will continue to exist even if nextepc quit, 
 | 
			
		||||
         * although this is normally not required. 
 | 
			
		||||
         * It can be useful to set up a tun/tap interface owned 
 | 
			
		||||
         * by a non-root user, so nextepc can be started without 
 | 
			
		||||
         * needing any root privileges at all.
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        /* Set P-to-P IP address with Netmask
 | 
			
		||||
         * Note that Linux will skip this configuration */
 | 
			
		||||
        rc = net_tun_set_ipv4(pgw_self()->ue_network[i].tun_link, 
 | 
			
		||||
                pgw_self()->ue_network[i].ipv4.addr,
 | 
			
		||||
                pgw_self()->ue_network[i].ipv4.bits);
 | 
			
		||||
        if (rc != 0)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("Can not register tun(dev : %s)", pgw_self()->tun_dev_name);
 | 
			
		||||
            net_tuntap_close(pgw_self()->tun_link);
 | 
			
		||||
            d_error("Can not configure tun(dev : %s for %s/%d)",
 | 
			
		||||
                    pgw_self()->ue_network[i].if_name,
 | 
			
		||||
                    INET_NTOP(&pgw_self()->ue_network[i].ipv4.addr, buf),
 | 
			
		||||
                    pgw_self()->ue_network[i].ipv4.bits);
 | 
			
		||||
            return CORE_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        rc = net_register_link(pgw_self()->ue_network[i].tun_link,
 | 
			
		||||
                _gtpv1_tun_recv_cb, (void *)(c_uintptr_t)i);
 | 
			
		||||
        if (rc != 0)
 | 
			
		||||
        {
 | 
			
		||||
            d_error("Can not register tun(dev : %s)",
 | 
			
		||||
                    pgw_self()->ue_network[i].if_name);
 | 
			
		||||
            net_tun_close(pgw_self()->ue_network[i].tun_link);
 | 
			
		||||
            return CORE_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
@@ -228,23 +257,27 @@ status_t pgw_gtp_open()
 | 
			
		||||
status_t pgw_gtp_close()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    rv = gtp_close(pgw_self()->s5c_sock);
 | 
			
		||||
    rv = gtp_close(pgw_self()->gtpc_sock);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't close S5-C Path for MME");
 | 
			
		||||
        d_error("Can't close GTP-C Path for MME");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_close(pgw_self()->s5u_sock);
 | 
			
		||||
    rv = gtp_close(pgw_self()->gtpu_sock);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't close S5-U Path for MME");
 | 
			
		||||
        d_error("Can't close GTP-U Path for MME");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    net_unregister_link(pgw_self()->tun_link);
 | 
			
		||||
    net_tuntap_close(pgw_self()->tun_link);
 | 
			
		||||
    for (i = 0; i < pgw_self()->num_of_ue_network; i++)
 | 
			
		||||
    {
 | 
			
		||||
        net_unregister_link(pgw_self()->ue_network[i].tun_link);
 | 
			
		||||
        net_tun_close(pgw_self()->ue_network[i].tun_link);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,9 @@
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "app.h"
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
const char *app_name = "sgw";
 | 
			
		||||
 | 
			
		||||
status_t app_initialize(const char *config_path, const char *log_path)
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    int others = 0;
 | 
			
		||||
@@ -26,7 +28,7 @@ status_t app_initialize(char *config_path, char *log_path)
 | 
			
		||||
    d_assert(rv == CORE_OK, return rv, "Failed to intialize SGW");
 | 
			
		||||
    d_trace(1, "SGW initialize...done\n");
 | 
			
		||||
 | 
			
		||||
    rv = app_did_initialize(config_path, log_path);
 | 
			
		||||
    rv = app_did_initialize();
 | 
			
		||||
    if (rv != CORE_OK) return rv;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
 
 | 
			
		||||
@@ -80,37 +80,23 @@ sgw_context_t* sgw_self()
 | 
			
		||||
 | 
			
		||||
static status_t sgw_context_prepare()
 | 
			
		||||
{
 | 
			
		||||
    self.s11_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.s5c_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.s1u_port = GTPV1_U_UDP_PORT;
 | 
			
		||||
    self.s5u_port = GTPV1_U_UDP_PORT;
 | 
			
		||||
    self.gtpc_port = GTPV2_C_UDP_PORT;
 | 
			
		||||
    self.gtpu_port = GTPV1_U_UDP_PORT;
 | 
			
		||||
 | 
			
		||||
    return CORE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static status_t sgw_context_validation()
 | 
			
		||||
{
 | 
			
		||||
    if (self.s11_addr == 0)
 | 
			
		||||
    if (self.gtpc_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No SGW.NEWORK.S11_IPV4 in '%s'",
 | 
			
		||||
        d_error("No SGW.NEWORK.GTPC_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.s5c_addr == 0)
 | 
			
		||||
    if (self.gtpu_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No SGW.NEWORK.S5C_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.s1u_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No SGW.NEWORK.S1U_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    if (self.s5u_addr == 0)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("No SGW.NEWORK.S5U_IPV4 in '%s'",
 | 
			
		||||
        d_error("No SGW.NEWORK.GTPU_IPV4 in '%s'",
 | 
			
		||||
                context_self()->config.path);
 | 
			
		||||
        return CORE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
@@ -199,45 +185,25 @@ status_t sgw_context_parse_config()
 | 
			
		||||
                        {
 | 
			
		||||
                            n += (t+m)->size;
 | 
			
		||||
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "S11_IPV4") == 0)
 | 
			
		||||
                            if (jsmntok_equal(json, t+m, "GTPC_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s11_addr = inet_addr(v);
 | 
			
		||||
                                if (v) self.gtpc_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S11_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPC_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s11_port = atoi(v);
 | 
			
		||||
                                if (v) self.gtpc_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5C_IPV4") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPU_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5c_addr = inet_addr(v);
 | 
			
		||||
                                if (v) self.gtpu_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5C_PORT") == 0)
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "GTPU_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5c_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S1U_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s1u_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S1U_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s1u_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5U_IPV4") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5u_addr = inet_addr(v);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (jsmntok_equal(json, t+m, "S5U_PORT") == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                char *v = jsmntok_to_string(json, t+m+1);
 | 
			
		||||
                                if (v) self.s5u_port = atoi(v);
 | 
			
		||||
                                if (v) self.gtpu_port = atoi(v);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@@ -472,7 +438,7 @@ sgw_ue_t* sgw_ue_add(
 | 
			
		||||
    d_assert(sgw_ue, return NULL, "Null param");
 | 
			
		||||
 | 
			
		||||
    sgw_ue->sgw_s11_teid = sgw_ue->index;
 | 
			
		||||
    sgw_ue->sgw_s11_addr = sgw_self()->s11_addr;
 | 
			
		||||
    sgw_ue->sgw_s11_addr = sgw_self()->gtpc_addr;
 | 
			
		||||
 | 
			
		||||
    /* Set IMSI */
 | 
			
		||||
    sgw_ue->imsi_len = imsi_len;
 | 
			
		||||
@@ -609,7 +575,7 @@ sgw_sess_t *sgw_sess_add(
 | 
			
		||||
    d_assert(sess, return NULL, "Null param");
 | 
			
		||||
 | 
			
		||||
    sess->sgw_s5c_teid = sess->index;
 | 
			
		||||
    sess->sgw_s5c_addr = sgw_self()->s5c_addr;
 | 
			
		||||
    sess->sgw_s5c_addr = sgw_self()->gtpc_addr;
 | 
			
		||||
 | 
			
		||||
    /* Set APN */
 | 
			
		||||
    core_cpystrn(sess->pdn.apn, apn, MAX_APN_LEN+1);
 | 
			
		||||
@@ -719,9 +685,6 @@ sgw_bearer_t* sgw_bearer_add(sgw_sess_t *sess)
 | 
			
		||||
    index_alloc(&sgw_bearer_pool, &bearer);
 | 
			
		||||
    d_assert(bearer, return NULL, "Bearer context allocation failed");
 | 
			
		||||
 | 
			
		||||
    bearer->sgw_s5u_teid = bearer->index;
 | 
			
		||||
    bearer->sgw_s5u_addr = sgw_self()->s5u_addr;
 | 
			
		||||
 | 
			
		||||
    list_append(&sess->bearer_list, bearer);
 | 
			
		||||
    
 | 
			
		||||
    bearer->sgw_ue = sgw_ue;
 | 
			
		||||
@@ -732,6 +695,9 @@ sgw_bearer_t* sgw_bearer_add(sgw_sess_t *sess)
 | 
			
		||||
    tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S1_U_SGW_GTP_U);
 | 
			
		||||
    d_assert(tunnel, return NULL, "Tunnel context allocation failed");
 | 
			
		||||
 | 
			
		||||
    tunnel = sgw_tunnel_add(bearer, GTP_F_TEID_S5_S8_SGW_GTP_U);
 | 
			
		||||
    d_assert(tunnel, return NULL, "Tunnel context allocation failed");
 | 
			
		||||
 | 
			
		||||
    return bearer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -849,7 +815,7 @@ sgw_tunnel_t* sgw_tunnel_add(sgw_bearer_t *bearer, c_uint8_t interface_type)
 | 
			
		||||
 | 
			
		||||
    tunnel->interface_type = interface_type;
 | 
			
		||||
    tunnel->local_teid = tunnel->index;
 | 
			
		||||
    tunnel->local_addr = sgw_self()->s1u_addr;
 | 
			
		||||
    tunnel->local_addr = sgw_self()->gtpu_addr;
 | 
			
		||||
 | 
			
		||||
    tunnel->bearer = bearer;
 | 
			
		||||
 | 
			
		||||
@@ -901,7 +867,8 @@ sgw_tunnel_t* sgw_tunnel_find_by_teid(c_uint32_t teid)
 | 
			
		||||
    return sgw_tunnel_find(teid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer)
 | 
			
		||||
sgw_tunnel_t* sgw_tunnel_find_by_interface_type(
 | 
			
		||||
        sgw_bearer_t *bearer, c_uint8_t interface_type)
 | 
			
		||||
{
 | 
			
		||||
    sgw_tunnel_t *tunnel = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -910,7 +877,7 @@ sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer)
 | 
			
		||||
    tunnel = sgw_tunnel_first(bearer);
 | 
			
		||||
    while(tunnel)
 | 
			
		||||
    {
 | 
			
		||||
        if (tunnel->interface_type == GTP_F_TEID_S1_U_SGW_GTP_U)
 | 
			
		||||
        if (tunnel->interface_type == interface_type)
 | 
			
		||||
        {
 | 
			
		||||
            return tunnel;
 | 
			
		||||
        }
 | 
			
		||||
@@ -921,6 +888,17 @@ sgw_tunnel_t* sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sgw_tunnel_t* sgw_s1u_tunnel_in_bearer(sgw_bearer_t *bearer)
 | 
			
		||||
{
 | 
			
		||||
    return sgw_tunnel_find_by_interface_type(
 | 
			
		||||
            bearer, GTP_F_TEID_S1_U_SGW_GTP_U);
 | 
			
		||||
}
 | 
			
		||||
sgw_tunnel_t* sgw_s5u_tunnel_in_bearer(sgw_bearer_t *bearer)
 | 
			
		||||
{
 | 
			
		||||
    return sgw_tunnel_find_by_interface_type(
 | 
			
		||||
            bearer, GTP_F_TEID_S5_S8_SGW_GTP_U);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sgw_tunnel_t* sgw_tunnel_first(sgw_bearer_t *bearer)
 | 
			
		||||
{
 | 
			
		||||
    d_assert(bearer, return NULL, "Null param");
 | 
			
		||||
 
 | 
			
		||||
@@ -21,26 +21,16 @@ typedef gtp_node_t sgw_mme_t;
 | 
			
		||||
typedef gtp_node_t sgw_pgw_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _sgw_context_t {
 | 
			
		||||
    c_uint32_t      sgw_addr;     /* SGW local address */
 | 
			
		||||
    c_uint32_t      gtpc_addr; /* GTP-U local address */
 | 
			
		||||
    c_uint32_t      gtpc_port; /* GTP-U local port */
 | 
			
		||||
    net_sock_t*     gtpc_sock; /* GTP-U local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s11_addr;  /* SGW S11 local address */
 | 
			
		||||
    c_uint32_t      s11_port;  /* SGW S11 local port */
 | 
			
		||||
    net_sock_t*     s11_sock;  /* SGW S11 local listen socket */
 | 
			
		||||
    c_uint32_t      gtpu_addr; /* GTP-U local address */
 | 
			
		||||
    c_uint32_t      gtpu_port; /* GTP-U local port */
 | 
			
		||||
    net_sock_t*     gtpu_sock; /* GTP-U local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s5c_addr;  /* SGW S5-C local address */
 | 
			
		||||
    c_uint32_t      s5c_port;  /* SGW S5-C local port */
 | 
			
		||||
    net_sock_t*     s5c_sock;  /* SGW S5-C local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s1u_addr;  /* SGW S1-U local address */
 | 
			
		||||
    c_uint32_t      s1u_port;  /* SGW S1-U local port */
 | 
			
		||||
    net_sock_t*     s1u_sock;  /* SGW S1-U local listen socket */
 | 
			
		||||
 | 
			
		||||
    c_uint32_t      s5u_addr;  /* SGW S5-U local address */
 | 
			
		||||
    c_uint32_t      s5u_port;  /* SGW S5-U local port */
 | 
			
		||||
    net_sock_t*     s5u_sock;  /* SGW S5-U local listen socket */
 | 
			
		||||
 | 
			
		||||
    msgq_id         queue_id;       /* Queue for processing SGW control plane */
 | 
			
		||||
    tm_service_t    tm_service;     /* Timer Service */
 | 
			
		||||
    msgq_id         queue_id;  /* Queue for processing SGW control plane */
 | 
			
		||||
    tm_service_t    tm_service;/* Timer Service */
 | 
			
		||||
 | 
			
		||||
    list_t          mme_list;  /* MME GTP Node List */
 | 
			
		||||
    list_t          pgw_list;  /* PGW GTP Node List */
 | 
			
		||||
@@ -117,13 +107,6 @@ typedef struct _sgw_bearer_t {
 | 
			
		||||
 | 
			
		||||
    c_uint8_t       ebi;
 | 
			
		||||
 | 
			
		||||
    /* IMPORTANT! 
 | 
			
		||||
     * SGW-S5U-TEID is same with an index */
 | 
			
		||||
    c_uint32_t      sgw_s5u_teid;  
 | 
			
		||||
    c_uint32_t      sgw_s5u_addr;
 | 
			
		||||
    c_uint32_t      enb_s1u_teid;
 | 
			
		||||
    c_uint32_t      enb_s1u_addr;
 | 
			
		||||
 | 
			
		||||
    /* User-Lication-Info */
 | 
			
		||||
    tai_t           tai;
 | 
			
		||||
    e_cgi_t         e_cgi;
 | 
			
		||||
@@ -224,7 +207,10 @@ CORE_DECLARE(status_t) sgw_tunnel_remove(sgw_tunnel_t *tunnel);
 | 
			
		||||
CORE_DECLARE(status_t) sgw_tunnel_remove_all(sgw_bearer_t *bearer);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_find(index_t index);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_find_by_teid(c_uint32_t teid);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_direct_tunnel_in_bearer(sgw_bearer_t *bearer);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_find_by_interface_type(
 | 
			
		||||
        sgw_bearer_t *bearer, c_uint8_t interface_type);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_s1u_tunnel_in_bearer(sgw_bearer_t *bearer);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_s5u_tunnel_in_bearer(sgw_bearer_t *bearer);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_first(sgw_bearer_t *bearer);
 | 
			
		||||
CORE_DECLARE(sgw_tunnel_t*) sgw_tunnel_next(sgw_tunnel_t *tunnel);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,13 +15,13 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    event_t e;
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    gtp_header_t *gtp_h = NULL;
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    c_uint32_t addr;
 | 
			
		||||
    c_uint16_t port;
 | 
			
		||||
    event_e event = (event_e)data;
 | 
			
		||||
    c_uint32_t addr = 0;
 | 
			
		||||
    c_uint16_t port = 0;
 | 
			
		||||
    sgw_mme_t *mme = NULL;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return -1, "Null param");
 | 
			
		||||
    d_assert(data, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    pkbuf = gtp_read(sock);
 | 
			
		||||
    if (pkbuf == NULL)
 | 
			
		||||
@@ -32,39 +32,41 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gtp_h = (gtp_header_t *)pkbuf->payload;
 | 
			
		||||
    d_assert(gtp_h, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    addr = sock->remote.sin_addr.s_addr;
 | 
			
		||||
    port = ntohs(sock->remote.sin_port);
 | 
			
		||||
 | 
			
		||||
    event_set(&e, event);
 | 
			
		||||
    event_set_param2(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    if (event == SGW_EVT_S11_MESSAGE)
 | 
			
		||||
    mme = sgw_mme_find(addr, port);
 | 
			
		||||
    if (!mme && gtp_h->teid == 0)
 | 
			
		||||
    {
 | 
			
		||||
        sgw_mme_t *mme = sgw_mme_find(addr, port);
 | 
			
		||||
        if (!mme)
 | 
			
		||||
        {
 | 
			
		||||
            mme = sgw_mme_add();
 | 
			
		||||
            d_assert(mme, return -1, "Can't add MME-GTP node");
 | 
			
		||||
        mme = sgw_mme_add();
 | 
			
		||||
        d_assert(mme, return -1, "Can't add MME-GTP node");
 | 
			
		||||
 | 
			
		||||
            mme->addr = addr;
 | 
			
		||||
            mme->port = port;
 | 
			
		||||
            mme->sock = sock;
 | 
			
		||||
        }
 | 
			
		||||
        mme->addr = addr;
 | 
			
		||||
        mme->port = port;
 | 
			
		||||
        mme->sock = sock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (mme)
 | 
			
		||||
    {
 | 
			
		||||
        d_trace(10, "S11 PDU received from MME\n");
 | 
			
		||||
 | 
			
		||||
        event_set(&e, SGW_EVT_S11_MESSAGE);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)mme);
 | 
			
		||||
    }
 | 
			
		||||
    else if (event == SGW_EVT_S5C_MESSAGE)
 | 
			
		||||
    {
 | 
			
		||||
        sgw_pgw_t *pgw = sgw_pgw_find(addr, port);
 | 
			
		||||
        d_assert(pgw, return -1, "Can't add PGW-GTP node");
 | 
			
		||||
        event_set_param2(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    
 | 
			
		||||
        d_trace(10, "S5-C PDU received from PGW\n");
 | 
			
		||||
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)pgw);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        d_assert(0, pkbuf_free(pkbuf); return -1, "Unknown GTP-Node");
 | 
			
		||||
    {
 | 
			
		||||
        d_trace(10, "S5C PDU received from PGW\n");
 | 
			
		||||
 | 
			
		||||
        event_set(&e, SGW_EVT_S5C_MESSAGE);
 | 
			
		||||
        event_set_param1(&e, (c_uintptr_t)addr);
 | 
			
		||||
        event_set_param2(&e, (c_uintptr_t)port);
 | 
			
		||||
        event_set_param3(&e, (c_uintptr_t)pkbuf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d_trace_hex(10, pkbuf->payload, pkbuf->len);
 | 
			
		||||
 | 
			
		||||
@@ -79,6 +81,168 @@ static int _gtpv2_c_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _gtpv1_u_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    gtp_node_t gnode;
 | 
			
		||||
    gtp_header_t *gtp_h = NULL;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *tunnel = NULL;
 | 
			
		||||
    c_uint32_t teid;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    d_assert(sock, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
    pkbuf = gtp_read(sock);
 | 
			
		||||
    if (pkbuf == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        if (sock->sndrcv_errno == EAGAIN)
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d_trace(50, "GTP-U PDU received\n");
 | 
			
		||||
    d_trace_hex(50, pkbuf->payload, pkbuf->len);
 | 
			
		||||
 | 
			
		||||
    gtp_h = (gtp_header_t *)pkbuf->payload;
 | 
			
		||||
    if (gtp_h->type == GTPU_MSGTYPE_ECHO_REQ)
 | 
			
		||||
    {
 | 
			
		||||
        pkbuf_t *echo_rsp;
 | 
			
		||||
 | 
			
		||||
        d_trace(3, "Received echo-req\n");
 | 
			
		||||
        echo_rsp = gtp_handle_echo_req(pkbuf);
 | 
			
		||||
        if (echo_rsp)
 | 
			
		||||
        {
 | 
			
		||||
            /* Echo reply */
 | 
			
		||||
            d_trace(3, "Send echo-rsp to peer\n");
 | 
			
		||||
 | 
			
		||||
            gnode.addr = sock->remote.sin_addr.s_addr;
 | 
			
		||||
            gnode.port = ntohs(sock->remote.sin_port);
 | 
			
		||||
            gnode.sock = sock;
 | 
			
		||||
 | 
			
		||||
            gtp_send(&gnode, echo_rsp);
 | 
			
		||||
            pkbuf_free(echo_rsp);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (gtp_h->type == GTPU_MSGTYPE_GPDU || 
 | 
			
		||||
                gtp_h->type == GTPU_MSGTYPE_END_MARKER)
 | 
			
		||||
    {
 | 
			
		||||
        teid = ntohl(gtp_h->teid);
 | 
			
		||||
        d_trace(50, "Recv GPDU (teid = 0x%x)\n", teid);
 | 
			
		||||
 | 
			
		||||
        tunnel = sgw_tunnel_find_by_teid(teid);
 | 
			
		||||
        d_assert(tunnel, return -1, "No TEID(0x%x)", teid);
 | 
			
		||||
        bearer = tunnel->bearer;
 | 
			
		||||
        d_assert(bearer, return -1, "Null param");
 | 
			
		||||
 | 
			
		||||
        /* Convert TEID */
 | 
			
		||||
        gnode.port = GTPV1_U_UDP_PORT;
 | 
			
		||||
        gnode.sock = sgw_self()->gtpu_sock;
 | 
			
		||||
            
 | 
			
		||||
        if (tunnel->interface_type == 
 | 
			
		||||
                GTP_F_TEID_S1_U_SGW_GTP_U ||
 | 
			
		||||
            tunnel->interface_type ==
 | 
			
		||||
                GTP_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING ||
 | 
			
		||||
            tunnel->interface_type ==
 | 
			
		||||
                GTP_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING)
 | 
			
		||||
        {
 | 
			
		||||
            sgw_tunnel_t *s5u_tunnel = NULL;
 | 
			
		||||
            d_trace(50, "Recv GPDU (teid = 0x%x) from eNB\n", teid);
 | 
			
		||||
 | 
			
		||||
            s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
 | 
			
		||||
            d_assert(s5u_tunnel, return -1, "Null param");
 | 
			
		||||
            gnode.addr = s5u_tunnel->remote_addr;
 | 
			
		||||
 | 
			
		||||
            gtp_h->teid = htonl(s5u_tunnel->remote_teid);
 | 
			
		||||
            gtp_send(&gnode, pkbuf);
 | 
			
		||||
        }
 | 
			
		||||
        else if (tunnel->interface_type == GTP_F_TEID_S5_S8_SGW_GTP_U)
 | 
			
		||||
        {
 | 
			
		||||
            sgw_tunnel_t *s1u_tunnel = NULL;
 | 
			
		||||
            d_trace(50, "Recv GPDU (teid = 0x%x) from PGW\n", teid);
 | 
			
		||||
 | 
			
		||||
            s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
 | 
			
		||||
            d_assert(s1u_tunnel, return -1, "Null param");
 | 
			
		||||
            gnode.addr = s1u_tunnel->remote_addr;
 | 
			
		||||
 | 
			
		||||
            if (s1u_tunnel->remote_teid)
 | 
			
		||||
            {
 | 
			
		||||
                /* If there is buffered packet, send it first */
 | 
			
		||||
                for (i = 0; i < bearer->num_buffered_pkt; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    gtp_h = (gtp_header_t *)bearer->buffered_pkts[i]->payload;
 | 
			
		||||
                    gtp_h->teid =  htonl(s1u_tunnel->remote_teid);
 | 
			
		||||
 | 
			
		||||
                    gtp_send(&gnode, bearer->buffered_pkts[i]);
 | 
			
		||||
                    pkbuf_free(bearer->buffered_pkts[i]);
 | 
			
		||||
                }
 | 
			
		||||
                bearer->num_buffered_pkt = 0;
 | 
			
		||||
 | 
			
		||||
                gtp_h->teid = htonl(s1u_tunnel->remote_teid);
 | 
			
		||||
                gtp_send(&gnode, pkbuf);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* S1U path is deactivated.
 | 
			
		||||
                 * Send downlink_data_notification to MME.
 | 
			
		||||
                 *
 | 
			
		||||
                 */
 | 
			
		||||
                sgw_ue_t *sgw_ue = NULL;
 | 
			
		||||
 | 
			
		||||
                d_assert(bearer->sess, pkbuf_free(pkbuf); return 0,
 | 
			
		||||
                        "Session is NULL");
 | 
			
		||||
                d_assert(bearer->sess->sgw_ue, pkbuf_free(pkbuf); return 0,
 | 
			
		||||
                        "SGW_UE  is NULL");
 | 
			
		||||
 | 
			
		||||
                sgw_ue = bearer->sess->sgw_ue;
 | 
			
		||||
 | 
			
		||||
                if ((SGW_GET_UE_STATE(sgw_ue) & SGW_S1U_INACTIVE))
 | 
			
		||||
                {
 | 
			
		||||
                    if ( !(SGW_GET_UE_STATE(sgw_ue) & SGW_DL_NOTI_SENT))
 | 
			
		||||
                    {
 | 
			
		||||
                        event_t e;
 | 
			
		||||
                        status_t rv;
 | 
			
		||||
 | 
			
		||||
                        event_set(&e, SGW_EVT_LO_DLDATA_NOTI);
 | 
			
		||||
                        event_set_param1(&e, (c_uintptr_t)bearer->index);
 | 
			
		||||
                        rv = sgw_event_send(&e);
 | 
			
		||||
                        if (rv != CORE_OK)
 | 
			
		||||
                        {
 | 
			
		||||
                            d_error("sgw_event_send error");
 | 
			
		||||
                            pkbuf_free(pkbuf);
 | 
			
		||||
                            return -1;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        SGW_SET_UE_STATE(sgw_ue, SGW_DL_NOTI_SENT);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /* Buffer the packet */
 | 
			
		||||
                    if (bearer->num_buffered_pkt < MAX_NUM_BUFFER_PKT)
 | 
			
		||||
                    {
 | 
			
		||||
                        bearer->buffered_pkts[bearer->num_buffered_pkt++] = 
 | 
			
		||||
                            pkbuf;
 | 
			
		||||
                        return 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    /* UE is S1U_ACTIVE state but there is no s1u teid */
 | 
			
		||||
                    d_warn("UE is ACITVE but there is no matched "
 | 
			
		||||
                            "s1u_teid(tedid = 0x%x)",teid);
 | 
			
		||||
 | 
			
		||||
                    /* Just drop it */
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pkbuf_free(pkbuf);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
{
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
@@ -291,42 +455,25 @@ static int _gtpv1_s1u_recv_cb(net_sock_t *sock, void *data)
 | 
			
		||||
    pkbuf_free(pkbuf);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
status_t sgw_gtp_open()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&sgw_self()->s11_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            sgw_self()->s11_addr, sgw_self()->s11_port,
 | 
			
		||||
            (void*)SGW_EVT_S11_MESSAGE);
 | 
			
		||||
    rv = gtp_listen(&sgw_self()->gtpc_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            sgw_self()->gtpc_addr, sgw_self()->gtpc_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S11 Path for SGW");
 | 
			
		||||
        d_error("Can't establish GTP-C Path for MME/PGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&sgw_self()->s5c_sock, _gtpv2_c_recv_cb, 
 | 
			
		||||
            sgw_self()->s5c_addr, sgw_self()->s5c_port,
 | 
			
		||||
            (void*)SGW_EVT_S5C_MESSAGE);
 | 
			
		||||
    rv = gtp_listen(&sgw_self()->gtpu_sock, _gtpv1_u_recv_cb, 
 | 
			
		||||
            sgw_self()->gtpu_addr, sgw_self()->gtpu_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S5-C Path for SGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&sgw_self()->s5u_sock, _gtpv1_s5u_recv_cb, 
 | 
			
		||||
            sgw_self()->s5u_addr, sgw_self()->s5u_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S5-U Path for SGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_listen(&sgw_self()->s1u_sock, _gtpv1_s1u_recv_cb, 
 | 
			
		||||
            sgw_self()->s1u_addr, sgw_self()->s1u_port, NULL);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't establish S1-U Path for SGW");
 | 
			
		||||
        d_error("Can't establish GTP-U Path for eNB/SGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -337,24 +484,17 @@ status_t sgw_gtp_close()
 | 
			
		||||
{
 | 
			
		||||
    status_t rv;
 | 
			
		||||
 | 
			
		||||
    rv = gtp_close(sgw_self()->s11_sock);
 | 
			
		||||
    rv = gtp_close(sgw_self()->gtpc_sock);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't close S11 Path for MME");
 | 
			
		||||
        d_error("Can't close GTP-C Path for MME/PGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_close(sgw_self()->s5c_sock);
 | 
			
		||||
    rv = gtp_close(sgw_self()->gtpu_sock);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't close S5-C Path for MME");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rv = gtp_close(sgw_self()->s5u_sock);
 | 
			
		||||
    if (rv != CORE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        d_error("Can't close S5-U Path for MME");
 | 
			
		||||
        d_error("Can't close GTP-U Path for eNB/PGW");
 | 
			
		||||
        return rv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -367,8 +507,11 @@ status_t sgw_gtp_send_end_marker(sgw_bearer_t *bearer)
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    gtp_header_t *h = NULL;
 | 
			
		||||
    gtp_node_t gnode;
 | 
			
		||||
    sgw_tunnel_t *s1u_tunnel = NULL;
 | 
			
		||||
 | 
			
		||||
    d_assert(bearer, return CORE_ERROR,);
 | 
			
		||||
    s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s1u_tunnel, return CORE_ERROR,);
 | 
			
		||||
 | 
			
		||||
    pkbuf = pkbuf_alloc(0, 100 /* enough for END_MARKER; use smaller buffer */);
 | 
			
		||||
    d_assert(pkbuf, return CORE_ERROR,);
 | 
			
		||||
@@ -383,11 +526,11 @@ status_t sgw_gtp_send_end_marker(sgw_bearer_t *bearer)
 | 
			
		||||
     */
 | 
			
		||||
    h->flags = 0x30;
 | 
			
		||||
    h->type = GTPU_MSGTYPE_END_MARKER;
 | 
			
		||||
    h->teid =  htonl(bearer->enb_s1u_teid);
 | 
			
		||||
    h->teid =  htonl(s1u_tunnel->remote_teid);
 | 
			
		||||
    
 | 
			
		||||
    gnode.addr = bearer->enb_s1u_addr;
 | 
			
		||||
    gnode.addr = s1u_tunnel->remote_addr;
 | 
			
		||||
    gnode.port = GTPV1_U_UDP_PORT;
 | 
			
		||||
    gnode.sock = sgw_self()->s1u_sock;
 | 
			
		||||
    gnode.sock = sgw_self()->gtpu_sock;
 | 
			
		||||
 | 
			
		||||
    rv = gtp_send(&gnode, pkbuf);
 | 
			
		||||
    d_assert(rv == CORE_OK, , "gtp send failed");
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
 | 
			
		||||
    gtp_xact_t *s5c_xact = NULL;
 | 
			
		||||
    sgw_sess_t *sess = NULL;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *s5u_tunnel = NULL;
 | 
			
		||||
 | 
			
		||||
    d_assert(s11_xact, return, "Null param");
 | 
			
		||||
    d_assert(sgw_ue, return, "Null param");
 | 
			
		||||
@@ -79,6 +80,8 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
 | 
			
		||||
    d_assert(sess, return, "Null param");
 | 
			
		||||
    bearer = sgw_default_bearer_in_sess(sess);
 | 
			
		||||
    d_assert(bearer, return, "Null param");
 | 
			
		||||
    s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s5u_tunnel, return, "Null param");
 | 
			
		||||
 | 
			
		||||
    /* Receive Control Plane(DL) : MME-S11 */
 | 
			
		||||
    mme_s11_teid = req->sender_f_teid_for_control_plane.data;
 | 
			
		||||
@@ -110,7 +113,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
 | 
			
		||||
 | 
			
		||||
        pgw->addr = addr;
 | 
			
		||||
        pgw->port = port;
 | 
			
		||||
        pgw->sock = sgw_self()->s5c_sock;
 | 
			
		||||
        pgw->sock = sgw_self()->gtpc_sock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Setup GTP Node */
 | 
			
		||||
@@ -121,8 +124,8 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
 | 
			
		||||
 | 
			
		||||
    /* Data Plane(DL) : SGW-S5U */
 | 
			
		||||
    memset(&sgw_s5u_teid, 0, sizeof(gtp_f_teid_t));
 | 
			
		||||
    sgw_s5u_teid.teid = htonl(bearer->sgw_s5u_teid);
 | 
			
		||||
    sgw_s5u_teid.ipv4_addr = bearer->sgw_s5u_addr;
 | 
			
		||||
    sgw_s5u_teid.teid = htonl(s5u_tunnel->local_teid);
 | 
			
		||||
    sgw_s5u_teid.ipv4_addr = s5u_tunnel->local_addr;
 | 
			
		||||
    sgw_s5u_teid.interface_type = GTP_F_TEID_S5_S8_SGW_GTP_U;
 | 
			
		||||
    req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.presence = 1;
 | 
			
		||||
    req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid;
 | 
			
		||||
@@ -161,6 +164,7 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    c_uint16_t decoded;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *s1u_tunnel = NULL;
 | 
			
		||||
    gtp_modify_bearer_response_t *rsp = NULL;
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    gtp_message_t gtp_message;
 | 
			
		||||
@@ -192,6 +196,8 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
 | 
			
		||||
    bearer = sgw_bearer_find_by_ue_ebi(sgw_ue, 
 | 
			
		||||
                req->bearer_contexts_to_be_modified.eps_bearer_id.u8);
 | 
			
		||||
    d_assert(bearer, return, "No Bearer Context");
 | 
			
		||||
    s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s1u_tunnel, return, "No S1U Tunnel Context");
 | 
			
		||||
 | 
			
		||||
    /* Set User Location Information */
 | 
			
		||||
    if (req->user_location_information.presence == 1)
 | 
			
		||||
@@ -204,7 +210,8 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
 | 
			
		||||
        if (bearer->e_cgi.cell_id != uli.e_cgi.cell_id)
 | 
			
		||||
        {
 | 
			
		||||
            rv = sgw_gtp_send_end_marker(bearer);
 | 
			
		||||
            d_assert(rv == CORE_OK, return, "gtp send failed");
 | 
			
		||||
            if (rv != CORE_OK)
 | 
			
		||||
                d_error("gtp send end marker failed");
 | 
			
		||||
 | 
			
		||||
            bearer->e_cgi.cell_id = uli.e_cgi.cell_id;
 | 
			
		||||
        }
 | 
			
		||||
@@ -212,8 +219,8 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
 | 
			
		||||
 | 
			
		||||
    /* Data Plane(DL) : eNB-S1U */
 | 
			
		||||
    enb_s1u_teid = req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.data;
 | 
			
		||||
    bearer->enb_s1u_teid = ntohl(enb_s1u_teid->teid);
 | 
			
		||||
    bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr;
 | 
			
		||||
    s1u_tunnel->remote_teid = ntohl(enb_s1u_teid->teid);
 | 
			
		||||
    s1u_tunnel->remote_addr = enb_s1u_teid->ipv4_addr;
 | 
			
		||||
 | 
			
		||||
    /* Reset UE state */
 | 
			
		||||
    SGW_RESET_UE_STATE(sgw_ue, SGW_S1U_INACTIVE);
 | 
			
		||||
@@ -296,7 +303,7 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
 | 
			
		||||
    gtp_xact_t *s5c_xact = NULL;
 | 
			
		||||
    sgw_sess_t *sess = NULL;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *tunnel = NULL;
 | 
			
		||||
    sgw_tunnel_t *s1u_tunnel = NULL, *s5u_tunnel = NULL;
 | 
			
		||||
    gtp_create_bearer_response_t *req = NULL;
 | 
			
		||||
 | 
			
		||||
    gtp_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
 | 
			
		||||
@@ -344,10 +351,12 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
 | 
			
		||||
    req->bearer_contexts.s4_u_sgsn_f_teid.presence = 0;
 | 
			
		||||
 | 
			
		||||
    /* Find the Tunnel by SGW-S1U-TEID */
 | 
			
		||||
    tunnel = sgw_tunnel_find_by_teid(ntohl(sgw_s1u_teid->teid));
 | 
			
		||||
    d_assert(tunnel, return, "Null param");
 | 
			
		||||
    bearer = tunnel->bearer;
 | 
			
		||||
    s1u_tunnel = sgw_tunnel_find_by_teid(ntohl(sgw_s1u_teid->teid));
 | 
			
		||||
    d_assert(s1u_tunnel, return, "Null param");
 | 
			
		||||
    bearer = s1u_tunnel->bearer;
 | 
			
		||||
    d_assert(bearer, return, "Null param");
 | 
			
		||||
    s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s5u_tunnel, return, "Null param");
 | 
			
		||||
    sess = bearer->sess;
 | 
			
		||||
    d_assert(sess, return, "Null param");
 | 
			
		||||
 | 
			
		||||
@@ -356,8 +365,8 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
 | 
			
		||||
 | 
			
		||||
    /* Data Plane(DL) : eNB-S1U */
 | 
			
		||||
    enb_s1u_teid = req->bearer_contexts.s1_u_enodeb_f_teid.data;
 | 
			
		||||
    bearer->enb_s1u_teid = ntohl(enb_s1u_teid->teid);
 | 
			
		||||
    bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr;
 | 
			
		||||
    s1u_tunnel->remote_teid = ntohl(enb_s1u_teid->teid);
 | 
			
		||||
    s1u_tunnel->remote_addr = enb_s1u_teid->ipv4_addr;
 | 
			
		||||
    req->bearer_contexts.s1_u_enodeb_f_teid.presence = 0;
 | 
			
		||||
 | 
			
		||||
    decoded = gtp_parse_uli(&uli, &req->user_location_information);
 | 
			
		||||
@@ -372,8 +381,8 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
 | 
			
		||||
 | 
			
		||||
    /* Data Plane(DL) : SGW-S5U */
 | 
			
		||||
    memset(&sgw_s5u_teid, 0, sizeof(gtp_f_teid_t));
 | 
			
		||||
    sgw_s5u_teid.teid = htonl(bearer->sgw_s5u_teid);
 | 
			
		||||
    sgw_s5u_teid.ipv4_addr = bearer->sgw_s5u_addr;
 | 
			
		||||
    sgw_s5u_teid.teid = htonl(s5u_tunnel->local_teid);
 | 
			
		||||
    sgw_s5u_teid.ipv4_addr = s5u_tunnel->local_addr;
 | 
			
		||||
    sgw_s5u_teid.interface_type = GTP_F_TEID_S5_S8_SGW_GTP_U;
 | 
			
		||||
    req->bearer_contexts.s5_s8_u_sgw_f_teid.presence = 1;
 | 
			
		||||
    req->bearer_contexts.s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid;
 | 
			
		||||
@@ -381,8 +390,8 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
 | 
			
		||||
 | 
			
		||||
    /* Data Plane(DL) : PGW-S5U */
 | 
			
		||||
    memset(&pgw_s5u_teid, 0, sizeof(gtp_f_teid_t));
 | 
			
		||||
    pgw_s5u_teid.teid = htonl(tunnel->remote_teid);
 | 
			
		||||
    pgw_s5u_teid.ipv4_addr = tunnel->remote_addr;
 | 
			
		||||
    pgw_s5u_teid.teid = htonl(s5u_tunnel->remote_teid);
 | 
			
		||||
    pgw_s5u_teid.ipv4_addr = s5u_tunnel->remote_addr;
 | 
			
		||||
    pgw_s5u_teid.interface_type = GTP_F_TEID_S5_S8_PGW_GTP_U;
 | 
			
		||||
    req->bearer_contexts.s5_s8_u_pgw_f_teid.presence = 1;
 | 
			
		||||
    req->bearer_contexts.s5_s8_u_pgw_f_teid.data = &pgw_s5u_teid;
 | 
			
		||||
@@ -412,6 +421,7 @@ void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact,
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    gtp_message_t gtp_message;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL, *next_bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *s1u_tunnel = NULL;
 | 
			
		||||
    sgw_sess_t *sess = NULL;
 | 
			
		||||
    
 | 
			
		||||
    gtp_cause_t cause;
 | 
			
		||||
@@ -434,8 +444,11 @@ void sgw_s11_handle_release_access_bearers_request(gtp_xact_t *s11_xact,
 | 
			
		||||
        {
 | 
			
		||||
            next_bearer = list_next(bearer);
 | 
			
		||||
 | 
			
		||||
            bearer->enb_s1u_teid = 0;
 | 
			
		||||
            bearer->enb_s1u_addr = 0;
 | 
			
		||||
            s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
 | 
			
		||||
            d_assert(s1u_tunnel, return, "Null param");
 | 
			
		||||
 | 
			
		||||
            s1u_tunnel->remote_teid = 0;
 | 
			
		||||
            s1u_tunnel->remote_addr = 0;
 | 
			
		||||
 | 
			
		||||
            bearer = next_bearer;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    gtp_xact_t *s11_xact = NULL;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *tunnel = NULL;
 | 
			
		||||
    sgw_tunnel_t *s1u_tunnel = NULL, *s5u_tunnel = NULL;
 | 
			
		||||
    gtp_create_session_response_t *rsp = NULL;
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    sgw_ue_t *sgw_ue = NULL;
 | 
			
		||||
@@ -61,8 +61,10 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
 | 
			
		||||
    bearer = sgw_bearer_find_by_sess_ebi(sess, 
 | 
			
		||||
                rsp->bearer_contexts_created.eps_bearer_id.u8);
 | 
			
		||||
    d_assert(bearer, return, "No Bearer Context");
 | 
			
		||||
    tunnel = sgw_direct_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(tunnel, return, "No Tunnel Context");
 | 
			
		||||
    s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s1u_tunnel, return, "No Tunnel Context");
 | 
			
		||||
    s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s5u_tunnel, return, "No Tunnel Context");
 | 
			
		||||
 | 
			
		||||
    /* Receive Control Plane(UL) : PGW-S5C */
 | 
			
		||||
    pgw_s5c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
 | 
			
		||||
@@ -76,8 +78,8 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
 | 
			
		||||
    /* Receive Data Plane(UL) : PGW-S5U */
 | 
			
		||||
    pgw_s5u_teid = rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.data;
 | 
			
		||||
    d_assert(pgw_s5u_teid, return, "Null param");
 | 
			
		||||
    tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
 | 
			
		||||
    tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
 | 
			
		||||
    s5u_tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
 | 
			
		||||
    s5u_tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
 | 
			
		||||
    rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.presence = 0;
 | 
			
		||||
 | 
			
		||||
    /* Send Control Plane(UL) : SGW-S11 */
 | 
			
		||||
@@ -93,9 +95,9 @@ void sgw_s5c_handle_create_session_response(gtp_xact_t *s5c_xact,
 | 
			
		||||
    /* Send Data Plane(UL) : SGW-S1U */
 | 
			
		||||
    memset(&sgw_s1u_teid, 0, sizeof(gtp_f_teid_t));
 | 
			
		||||
    sgw_s1u_teid.ipv4 = 1;
 | 
			
		||||
    sgw_s1u_teid.interface_type = tunnel->interface_type;
 | 
			
		||||
    sgw_s1u_teid.ipv4_addr = tunnel->local_addr;
 | 
			
		||||
    sgw_s1u_teid.teid = htonl(tunnel->local_teid);
 | 
			
		||||
    sgw_s1u_teid.interface_type = s1u_tunnel->interface_type;
 | 
			
		||||
    sgw_s1u_teid.ipv4_addr = s1u_tunnel->local_addr;
 | 
			
		||||
    sgw_s1u_teid.teid = htonl(s1u_tunnel->local_teid);
 | 
			
		||||
    rsp->bearer_contexts_created.s1_u_enodeb_f_teid.presence = 1;
 | 
			
		||||
    rsp->bearer_contexts_created.s1_u_enodeb_f_teid.data = &sgw_s1u_teid;
 | 
			
		||||
    rsp->bearer_contexts_created.s1_u_enodeb_f_teid.len = GTP_F_TEID_IPV4_LEN;
 | 
			
		||||
@@ -190,7 +192,7 @@ void sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact,
 | 
			
		||||
    status_t rv;
 | 
			
		||||
    gtp_xact_t *s11_xact = NULL;
 | 
			
		||||
    sgw_bearer_t *bearer = NULL;
 | 
			
		||||
    sgw_tunnel_t *tunnel = NULL;
 | 
			
		||||
    sgw_tunnel_t *s1u_tunnel = NULL, *s5u_tunnel = NULL;
 | 
			
		||||
    gtp_create_bearer_request_t *req = NULL;
 | 
			
		||||
    pkbuf_t *pkbuf = NULL;
 | 
			
		||||
    sgw_ue_t *sgw_ue = NULL;
 | 
			
		||||
@@ -229,22 +231,24 @@ void sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact,
 | 
			
		||||
 | 
			
		||||
    bearer = sgw_bearer_add(sess);
 | 
			
		||||
    d_assert(bearer, return, "No Bearer Context");
 | 
			
		||||
    tunnel = sgw_direct_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(tunnel, return, "No Tunnel Context");
 | 
			
		||||
    s1u_tunnel = sgw_s1u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s1u_tunnel, return, "No Tunnel Context");
 | 
			
		||||
    s5u_tunnel = sgw_s5u_tunnel_in_bearer(bearer);
 | 
			
		||||
    d_assert(s5u_tunnel, return, "No Tunnel Context");
 | 
			
		||||
 | 
			
		||||
    /* Receive Data Plane(UL) : PGW-S5U */
 | 
			
		||||
    pgw_s5u_teid = req->bearer_contexts.s5_s8_u_sgw_f_teid.data;
 | 
			
		||||
    d_assert(pgw_s5u_teid, return, "Null param");
 | 
			
		||||
    tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
 | 
			
		||||
    tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
 | 
			
		||||
    s5u_tunnel->remote_teid = ntohl(pgw_s5u_teid->teid);
 | 
			
		||||
    s5u_tunnel->remote_addr = pgw_s5u_teid->ipv4_addr;
 | 
			
		||||
    req->bearer_contexts.s5_s8_u_sgw_f_teid.presence = 0;
 | 
			
		||||
 | 
			
		||||
    /* Send Data Plane(UL) : SGW-S1U */
 | 
			
		||||
    memset(&sgw_s1u_teid, 0, sizeof(gtp_f_teid_t));
 | 
			
		||||
    sgw_s1u_teid.ipv4 = 1;
 | 
			
		||||
    sgw_s1u_teid.interface_type = tunnel->interface_type;
 | 
			
		||||
    sgw_s1u_teid.ipv4_addr = tunnel->local_addr;
 | 
			
		||||
    sgw_s1u_teid.teid = htonl(tunnel->local_teid);
 | 
			
		||||
    sgw_s1u_teid.interface_type = s1u_tunnel->interface_type;
 | 
			
		||||
    sgw_s1u_teid.ipv4_addr = s1u_tunnel->local_addr;
 | 
			
		||||
    sgw_s1u_teid.teid = htonl(s1u_tunnel->local_teid);
 | 
			
		||||
    req->bearer_contexts.s1_u_enodeb_f_teid.presence = 1;
 | 
			
		||||
    req->bearer_contexts.s1_u_enodeb_f_teid.data = &sgw_s1u_teid;
 | 
			
		||||
    req->bearer_contexts.s1_u_enodeb_f_teid.len = GTP_F_TEID_IPV4_LEN;
 | 
			
		||||
@@ -264,6 +268,6 @@ void sgw_s5c_handle_create_bearer_request(gtp_xact_t *s5c_xact,
 | 
			
		||||
    d_assert(rv == CORE_OK, return, "xact_commit error");
 | 
			
		||||
 | 
			
		||||
    d_trace(3, "[GTP] Create Bearer Request : SGW[%d] <-- PGW[%d]\n",
 | 
			
		||||
            tunnel->local_teid, tunnel->remote_teid);
 | 
			
		||||
            s5u_tunnel->local_teid, s5u_tunnel->remote_teid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -121,13 +121,16 @@ void sgw_state_operational(fsm_t *s, event_t *e)
 | 
			
		||||
        case SGW_EVT_S5C_MESSAGE:
 | 
			
		||||
        {
 | 
			
		||||
            status_t rv;
 | 
			
		||||
            gtp_node_t *gnode = (gtp_node_t *)event_get_param1(e);
 | 
			
		||||
            pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
 | 
			
		||||
            gtp_node_t *gnode = NULL;
 | 
			
		||||
            c_uint32_t addr = (c_uint32_t)event_get_param1(e);
 | 
			
		||||
            c_uint16_t port = (c_uint16_t)event_get_param2(e);
 | 
			
		||||
            pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
 | 
			
		||||
            gtp_xact_t *xact = NULL;
 | 
			
		||||
            gtp_message_t message;
 | 
			
		||||
            sgw_sess_t *sess = NULL;
 | 
			
		||||
 | 
			
		||||
            d_assert(pkbuf, break, "Null param");
 | 
			
		||||
            gnode = sgw_pgw_find(addr, port);
 | 
			
		||||
            d_assert(gnode, pkbuf_free(pkbuf); break, "Null param");
 | 
			
		||||
 | 
			
		||||
            rv = gtp_xact_receive(gnode, pkbuf, &xact, &message);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,3 +25,7 @@ Install FreeDiameter, MongoDB C driver
 | 
			
		||||
===========================================
 | 
			
		||||
 - brew install freediamter
 | 
			
		||||
 - brew install mongo-c-driver
 | 
			
		||||
 | 
			
		||||
Enable IP Fowarding
 | 
			
		||||
====================
 | 
			
		||||
 - sysctl -w net.inet.ip.forwarding=1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								support/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								support/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
SUBDIRS = config freeDiameter systemd logrotate newsyslog
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
							
								
								
									
										15
									
								
								support/config/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								support/config/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
configfiles = \
 | 
			
		||||
	nextepc.conf \
 | 
			
		||||
	mme.conf \
 | 
			
		||||
	sgw.conf \
 | 
			
		||||
	pgw.conf \
 | 
			
		||||
	hss.conf \
 | 
			
		||||
	pcrf.conf \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
configdir = ${sysconfdir}/nextepc
 | 
			
		||||
 | 
			
		||||
config_DATA = ${configfiles}
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
							
								
								
									
										23
									
								
								support/config/hss.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								support/config/hss.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
{
 | 
			
		||||
  "DB_URI" : "mongodb://localhost/nextepc",
 | 
			
		||||
  "LOG" :
 | 
			
		||||
  {
 | 
			
		||||
    "FILE" : "@LOCALSTATE_DIR@/log/nextepc/hss.log",
 | 
			
		||||
    "SOCKET" :
 | 
			
		||||
    {
 | 
			
		||||
      "UNIX_DOMAIN" : "/tmp/nextepc-hssd.sock",
 | 
			
		||||
      "FILE" : 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "TRACE" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD": 1,
 | 
			
		||||
    "OTHERS": 1
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "HSS" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/hss.conf"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								support/config/mme.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								support/config/mme.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
{
 | 
			
		||||
  "LOG" :
 | 
			
		||||
  {
 | 
			
		||||
    "FILE" : "@LOCALSTATE_DIR@/log/nextepc/mme.log",
 | 
			
		||||
    "SOCKET" :
 | 
			
		||||
    {
 | 
			
		||||
      "UNIX_DOMAIN" : "/tmp/nextepc-mmed.sock",
 | 
			
		||||
      "FILE" : 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "TRACE" :
 | 
			
		||||
  {
 | 
			
		||||
    "S1AP": 1,
 | 
			
		||||
    "NAS": 1,
 | 
			
		||||
    "FD": 1,
 | 
			
		||||
    "GTP": 1,
 | 
			
		||||
    "OTHERS": 1
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "MME" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/mme.conf",
 | 
			
		||||
    "DEFAULT_PAGING_DRX" : "v64",
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    {
 | 
			
		||||
      "S1AP_IPV4" : "127.76.0.1",
 | 
			
		||||
      "GTPC_IPV4" : "127.76.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "GUMMEI" :
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "PLMN_ID" : 
 | 
			
		||||
        {
 | 
			
		||||
          "MCC" : "001",
 | 
			
		||||
          "MNC" : "01"
 | 
			
		||||
        },
 | 
			
		||||
        "MME_GID" : 2,
 | 
			
		||||
        "MME_CODE" : 1
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "TAI":
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "PLMN_ID" :
 | 
			
		||||
        {
 | 
			
		||||
          "MCC": "001",
 | 
			
		||||
          "MNC": "01"
 | 
			
		||||
        },
 | 
			
		||||
        "TAC": 12345
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "SECURITY" :
 | 
			
		||||
    {
 | 
			
		||||
      "INTEGRITY_ORDER" : [ "EIA1", "EIA2", "EIA0" ],
 | 
			
		||||
      "CIPHERING_ORDER" : [ "EEA0", "EEA1", "EEA2" ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "SGW" :
 | 
			
		||||
  {
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "GTPC_IPV4" : "127.76.0.2",
 | 
			
		||||
        "GTPU_IPV4" : "127.76.0.2"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "PGW" :
 | 
			
		||||
  {
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    {
 | 
			
		||||
      "GTPC_IPV4" : "127.76.0.3",
 | 
			
		||||
      "GTPU_IPV4" : "127.76.0.3"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								support/config/nextepc.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								support/config/nextepc.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
{
 | 
			
		||||
  "DB_URI" : "mongodb://localhost/nextepc",
 | 
			
		||||
  "LOG" :
 | 
			
		||||
  {
 | 
			
		||||
    "FILE" : "@LOCALSTATE_DIR@/log/nextepc/nextepc.log",
 | 
			
		||||
    "SOCKET" :
 | 
			
		||||
    {
 | 
			
		||||
      "UNIX_DOMAIN" : "/tmp/nextepc-epcd.sock",
 | 
			
		||||
      "FILE" : 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "TRACE" :
 | 
			
		||||
  {
 | 
			
		||||
    "S1AP": 1,
 | 
			
		||||
    "NAS": 1,
 | 
			
		||||
    "FD": 1,
 | 
			
		||||
    "GTP": 1,
 | 
			
		||||
    "OTHERS": 1
 | 
			
		||||
  },
 | 
			
		||||
  "NODE":
 | 
			
		||||
  {
 | 
			
		||||
    "DISABLE_HSS": 0,
 | 
			
		||||
    "DISABLE_SGW": 0,
 | 
			
		||||
    "DISABLE_PGW": 0,
 | 
			
		||||
    "DISABLE_PCRF": 0
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "MME" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/mme.conf",
 | 
			
		||||
    "DEFAULT_PAGING_DRX" : "v64",
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    {
 | 
			
		||||
      "S1AP_IPV4" : "127.76.0.1",
 | 
			
		||||
      "GTPC_IPV4" : "127.76.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "GUMMEI" :
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "PLMN_ID" : 
 | 
			
		||||
        {
 | 
			
		||||
          "MCC" : "001",
 | 
			
		||||
          "MNC" : "01"
 | 
			
		||||
        },
 | 
			
		||||
        "MME_GID" : 2,
 | 
			
		||||
        "MME_CODE" : 1
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "TAI":
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "PLMN_ID" :
 | 
			
		||||
        {
 | 
			
		||||
          "MCC": "001",
 | 
			
		||||
          "MNC": "01"
 | 
			
		||||
        },
 | 
			
		||||
        "TAC": 12345
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "SECURITY" :
 | 
			
		||||
    {
 | 
			
		||||
      "INTEGRITY_ORDER" : [ "EIA1", "EIA2", "EIA0" ],
 | 
			
		||||
      "CIPHERING_ORDER" : [ "EEA0", "EEA1", "EEA2" ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "HSS" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/hss.conf"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "SGW" :
 | 
			
		||||
  {
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "GTPC_IPV4" : "127.76.0.2",
 | 
			
		||||
        "GTPU_IPV4" : "127.76.0.2"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "PGW" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/pgw.conf",
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    {
 | 
			
		||||
      "GTPC_IPV4" : "127.76.0.3",
 | 
			
		||||
      "GTPU_IPV4" : "127.76.0.3"
 | 
			
		||||
    },
 | 
			
		||||
    "UE_NETWORK":
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "IF_NAME" : "pgwtun",
 | 
			
		||||
        "IPV4_POOL" : "45.45.0.1/16"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "DNS" :
 | 
			
		||||
    {
 | 
			
		||||
      "PRIMARY_IPV4" : "8.8.8.8",
 | 
			
		||||
      "SECONDARY_IPV4" : "4.4.4.4"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "PCRF" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/pcrf.conf"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								support/config/pcrf.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								support/config/pcrf.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
{
 | 
			
		||||
  "DB_URI" : "mongodb://localhost/nextepc",
 | 
			
		||||
  "LOG" :
 | 
			
		||||
  {
 | 
			
		||||
    "FILE" : "@LOCALSTATE_DIR@/log/nextepc/pcrf.log",
 | 
			
		||||
    "SOCKET" :
 | 
			
		||||
    {
 | 
			
		||||
      "UNIX_DOMAIN" : "/tmp/nextepc-pcrfd.sock",
 | 
			
		||||
      "FILE" : 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "TRACE" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD": 1,
 | 
			
		||||
    "OTHERS": 1
 | 
			
		||||
  },
 | 
			
		||||
  "PCRF" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/pcrf.conf"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								support/config/pgw.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								support/config/pgw.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "LOG" :
 | 
			
		||||
  {
 | 
			
		||||
    "FILE" : "@LOCALSTATE_DIR@/log/nextepc/pgw.log",
 | 
			
		||||
    "SOCKET" :
 | 
			
		||||
    {
 | 
			
		||||
      "UNIX_DOMAIN" : "/tmp/nextepc-pgwd.sock",
 | 
			
		||||
      "FILE" : 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "TRACE" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD": 1,
 | 
			
		||||
    "GTP": 1,
 | 
			
		||||
    "OTHERS": 1
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "PGW" :
 | 
			
		||||
  {
 | 
			
		||||
    "FD_CONF_PATH" : "@SYSCONF_DIR@/nextepc/freeDiameter/pgw.conf",
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    {
 | 
			
		||||
      "GTPC_IPV4" : "127.76.0.3",
 | 
			
		||||
      "GTPU_IPV4" : "127.76.0.3"
 | 
			
		||||
    },
 | 
			
		||||
    "UE_NETWORK":
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "IF_NAME" : "pgwtun",
 | 
			
		||||
        "IPV4_POOL" : "45.45.0.1/16"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "DNS" :
 | 
			
		||||
    {
 | 
			
		||||
      "PRIMARY_IPV4" : "8.8.8.8",
 | 
			
		||||
      "SECONDARY_IPV4" : "4.4.4.4"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								support/config/sgw.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								support/config/sgw.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
  "LOG" :
 | 
			
		||||
  {
 | 
			
		||||
    "FILE" : "@LOCALSTATE_DIR@/log/nextepc/sgw.log",
 | 
			
		||||
    "SOCKET" :
 | 
			
		||||
    {
 | 
			
		||||
      "UNIX_DOMAIN" : "/tmp/nextepc-sgwd.sock",
 | 
			
		||||
      "FILE" : 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "TRACE" :
 | 
			
		||||
  {
 | 
			
		||||
    "GTP": 1,
 | 
			
		||||
    "OTHERS": 1
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "SGW" :
 | 
			
		||||
  {
 | 
			
		||||
    "NETWORK" :
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        "GTPC_IPV4" : "127.76.0.2",
 | 
			
		||||
        "GTPU_IPV4" : "127.76.0.2"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								support/freeDiameter/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								support/freeDiameter/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
configfiles = \
 | 
			
		||||
	mme.conf \
 | 
			
		||||
	hss.conf \
 | 
			
		||||
	pgw.conf \
 | 
			
		||||
	pcrf.conf \
 | 
			
		||||
    $(NULL)
 | 
			
		||||
 | 
			
		||||
pemfiles = \
 | 
			
		||||
	cacert.pem \
 | 
			
		||||
	mme.key.pem \
 | 
			
		||||
	mme.cert.pem \
 | 
			
		||||
	hss.key.pem \
 | 
			
		||||
	hss.cert.pem \
 | 
			
		||||
	pgw.key.pem \
 | 
			
		||||
	pgw.cert.pem \
 | 
			
		||||
	pcrf.key.pem \
 | 
			
		||||
	pcrf.cert.pem \
 | 
			
		||||
    $(NULL)
 | 
			
		||||
 | 
			
		||||
freeDiameterdir = ${sysconfdir}/nextepc/freeDiameter
 | 
			
		||||
 | 
			
		||||
freeDiameter_DATA = ${configfiles} ${pemfiles}
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
@@ -1,709 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE dictionary SYSTEM "dictionary.dtd">
 | 
			
		||||
 | 
			
		||||
<!--******************* Diccionario Gx === German Barros ******************************************************************* -->
 | 
			
		||||
 | 
			
		||||
<dictionary>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	<!-- ******************************************************** -->
 | 
			
		||||
	<!-- ********************* Vendors ************************** -->
 | 
			
		||||
	<!-- ******************************************************** -->
 | 
			
		||||
 | 
			
		||||
	<vendor id="10415" name="3GPP" />
 | 
			
		||||
 | 
			
		||||
	<!-- ******************************************************** -->
 | 
			
		||||
	<!-- ***************** Gx Application ********************* -->
 | 
			
		||||
	<!-- ******************************************************** -->
 | 
			
		||||
 | 
			
		||||
	<application id="16777238" name="Gx">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- ====================================================================== -->
 | 
			
		||||
		<!-- ========================== COMMAND CODES =========================== -->
 | 
			
		||||
		<!-- ====================================================================== -->
 | 
			
		||||
 | 
			
		||||
		<!-- *** Command-Codes *** -->
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.6.2 and 5.6.3 -->
 | 
			
		||||
		<command name="CC" code="272" vendor-id="10415">
 | 
			
		||||
 | 
			
		||||
		</command>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.6.4 and 5.6.5 -->
 | 
			
		||||
		<command name="RA" code="258" vendor-id="10415" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- ====================================================================== -->
 | 
			
		||||
		<!-- ========================= Gx Specific AVPs ======================== -->
 | 
			
		||||
		<!-- ====================================================================== -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- Ref = [3GPP - 29.214] 5.3.2 -->
 | 
			
		||||
		<avp name="Access-Network-Charging-Address" code="501" mandatory="must"
 | 
			
		||||
			may-encrypt="yes" vendor-id="10415">
 | 
			
		||||
			<type type-name="Address" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.1 -->
 | 
			
		||||
		<avp name="Bearer-Usage" vendor-id="10415" code="1000" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="GENERAL" code="0" />
 | 
			
		||||
			<enum name="IMS_SIGNALLING" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
			<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.23 -->
 | 
			
		||||
		<avp name="Bearer-Control-Mode" vendor-id="10415" code="1023"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="UE_ONLY" code="0" />
 | 
			
		||||
			<enum name="RESERVED" code="1" />
 | 
			
		||||
			<enum name="UE_NW" code="2" />
 | 
			
		||||
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
			<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.8 -->
 | 
			
		||||
		<avp name="Metering-Method" vendor-id="10415" code="1007"
 | 
			
		||||
			mandatory="must" may-encrypt="yes" protected="may" type="Enumerated">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="DURATION" code="0" />
 | 
			
		||||
			<enum name="VOLUME" code="1" />
 | 
			
		||||
			<enum name="DURATION_VOLUME" code="2" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.229 V7.7.0] , clause 6.3.20 -->
 | 
			
		||||
		<avp name="Primary-Event-Charging-Function-Name" vendor-id="10415"
 | 
			
		||||
			code="619" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="DiameterURI" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.229 V7.7.0] , clause 6.3.21 -->
 | 
			
		||||
		<avp name="Secondary-Event-Charging-Function-Name" vendor-id="10415"
 | 
			
		||||
			code="620" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="DiameterURI" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.229 V7.7.0] , clause 6.3.22 -->
 | 
			
		||||
		<avp name="Primary-Charging-Collection-Function-Name" vendor-id="10415"
 | 
			
		||||
			code="621" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="DiameterURI" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.229 V7.7.0] , clause 6.3.23 -->
 | 
			
		||||
		<avp name="Secondary-Charging-Collection-Function-Name" vendor-id="10415"
 | 
			
		||||
			code="622" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="DiameterURI" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.214 v7.3.0] , clause 5.3.4 -->
 | 
			
		||||
		<avp name="Access-Network-Charging-Identifier-Value" vendor-id="10415"
 | 
			
		||||
			code="503" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.9.0] , clause 16.4.7 -->
 | 
			
		||||
		<avp name="3GPP-RAT-Type" vendor-id="10415" code="21" mandatory="mustnot"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			<!-- Ref = RFC 4006 chap 8.48 -->
 | 
			
		||||
		<avp name="Subscription-Id-Data" code="444" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- Ref = RFC 4006 chap 8.47 -->
 | 
			
		||||
		<avp name="Subscription-Id-Type" code="450" mandatory="must"
 | 
			
		||||
			protected="may" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="END_USER_E164" code="0" />
 | 
			
		||||
			<enum name="END_USER_IMSI" code="1" />
 | 
			
		||||
			<enum name="END_USER_SIP_URI" code="2" />
 | 
			
		||||
			<enum name="END_USER_NAI" code="3" />
 | 
			
		||||
			<enum name="END_USER_PRIVATE" code="4" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.2 -->
 | 
			
		||||
		<avp name="CC-Request-Number" code="415" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.3 -->
 | 
			
		||||
		<avp name="CC-Request-Type" code="416" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="INITIAL_REQUEST" code="1" />
 | 
			
		||||
			<enum name="UPDATE_REQUEST" code="2" />
 | 
			
		||||
			<enum name="TERMINATION_REQUEST" code="3" />
 | 
			
		||||
			<enum name="EVENT_REQUEST" code="4" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.38 -->
 | 
			
		||||
		<avp name="Redirect-Address-Type" code="433" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="IPV4_ADDRESS" code="0" />
 | 
			
		||||
			<enum name="IPV6_ADDRESS" code="1" />
 | 
			
		||||
			<enum name="URL" code="2" />
 | 
			
		||||
			<enum name="SIP_URI" code="3" />
 | 
			
		||||
		</avp>
 | 
			
		||||
<!-- [RFC 4006] , clause 8.39 -->
 | 
			
		||||
		<avp name="Redirect-Server-Address" code="435" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
			<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.19 -->
 | 
			
		||||
		<avp name="PCC-Rule-Status" vendor-id="10415" code="1019"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="ACTIVE" code="0" />
 | 
			
		||||
			<enum name="INACTIVE" code="1" />
 | 
			
		||||
			<enum name="TEMPORARILY INACTIVE" code="2" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4005] , clause 6.11.1 -->
 | 
			
		||||
		<avp name="Framed-IP-Address" code="8" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4005] , clause 6.11.6 -->
 | 
			
		||||
		<avp name="Framed-IPv6-Prefix" code="97" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4005] , clause 4.5 -->
 | 
			
		||||
		<avp name="Called-Station-Id" code="30" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4005] , clause 6.7 -->
 | 
			
		||||
		<avp name="Filter-Id" code="11" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.21 -->
 | 
			
		||||
		<avp name="Bearer-Operation" vendor-id="10415" code="1021"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="TERMINATION" code="0" />
 | 
			
		||||
			<enum name="ESTABLISHMENT" code="1" />
 | 
			
		||||
			<enum name="MODIFICATION" code="2" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.24 -->
 | 
			
		||||
		<avp name="Network-Request-Support" vendor-id="10415" code="1024"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated"/>
 | 
			
		||||
      
 | 
			
		||||
				<enum name="NETWORK_REQUEST_NOT_SUPPORTED" code="0" />
 | 
			
		||||
				<enum name="NETWORK_REQUEST_SUPPORTED" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
				<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.5 -->
 | 
			
		||||
		<avp name="Charging-Rule-Base-Name" vendor-id="10415" code="1004"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.15 -->
 | 
			
		||||
		<avp name="ToS-Traffic-Class" vendor-id="10415" code="1014"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.27 -->
 | 
			
		||||
		<avp name="IP-CAN-Type" vendor-id="10415" code="1027" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="3GPP" code="0" />
 | 
			
		||||
			<enum name="DOCSIS" code="1" />
 | 
			
		||||
			<enum name="xDSL" code="2" />
 | 
			
		||||
			<enum name="WiMAX" code="3" />
 | 
			
		||||
			<enum name="3GPP2" code="4" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.28 -->
 | 
			
		||||
		<avp name="QoS-Negotiation" vendor-id="10415" code="1029"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="NO_QOS_NEGOTIATION" code="0" />
 | 
			
		||||
			<enum name="QOS_NEGOTIATION_SUPPORTED" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.29 -->
 | 
			
		||||
		<avp name="QoS-Upgrade" vendor-id="10415" code="1030" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="QOS_UPGRADE_NOT_SUPPORTED" code="0" />
 | 
			
		||||
			<enum name="QOS_UPGRADE_SUPPORTED" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.30 -->
 | 
			
		||||
		<avp name="Rule-Failure-Code" vendor-id="10415" code="1031"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="UNKNOWN_RULE_NAME" code="1" />
 | 
			
		||||
			<enum name="RATING_GROUP_ERROR" code="2" />
 | 
			
		||||
			<enum name="SERVICE_IDENTIFIER_ERROR" code="3" />
 | 
			
		||||
			<enum name="GW/PCEF_MALFUNCTION" code="4" />
 | 
			
		||||
			<enum name="RESOURCES_LIMITATION" code="5" />
 | 
			
		||||
			<enum name="MAX_NR_BEARERS_REACHED" code="6" />
 | 
			
		||||
			<enum name="UNKNOWN_BEARER_ID" code="7" />
 | 
			
		||||
			<enum name="MISSING_BEARER_ID" code="8" />
 | 
			
		||||
			<enum name="MISSING_FLOW_DESCRIPTION" code="9" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.34 -->
 | 
			
		||||
		<avp name="Session-Release-Cause" vendor-id="10415" code="1035"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="UNSPECIFIED_REASONS" code="0" />
 | 
			
		||||
			<enum name="UE_SUBSCRIPTION_REASON" code="1" />
 | 
			
		||||
			<enum name="INSUFFICIENT_SERVER_RESOURCES" code="2" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.9.0] , clause 16.4.7. -->
 | 
			
		||||
		<avp name="3GPP-SGSN-MCC-MNC" vendor-id="10415" code="18"
 | 
			
		||||
			mandatory="mustnot" may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.9.0] , clause 16.4.7 -->
 | 
			
		||||
		<avp name="3GPP-User-Location-Info" vendor-id="10415" code="22"
 | 
			
		||||
			mandatory="mustnot" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.31 -->
 | 
			
		||||
		<avp name="Revalidation-Time" vendor-id="10415" code="1032"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Time" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.32 -->
 | 
			
		||||
		<avp name="Rule-Activation-Time" code="1033" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Time" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.33 -->
 | 
			
		||||
		<avp name="Rule-Deactivation-Time" vendor-id="10415" code="1034"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Time" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.7.0] , clause 16.4.7.1 -->
 | 
			
		||||
		<avp name="3GPP-SGSN-Address" vendor-id="10415" code="6" mandatory="mustnot"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.7.0] , clause 16.4.7.1 -->
 | 
			
		||||
		<avp name="3GPP-SGSN-IPv6-Address" vendor-id="10415" code="15"
 | 
			
		||||
			mandatory="mustnot" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.7.0] , clause 17.7.12 -->
 | 
			
		||||
		<avp name="RAI" vendor-id="10415" code="909" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="UTF8String" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.061 V7.7.0] , clause 16.4.7 -->
 | 
			
		||||
		<avp name="3GPP-MS-TimeZone" vendor-id="10415" code="23" mandatory="mustnot"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.20 -->
 | 
			
		||||
		<avp name="Bearer-Identifier" vendor-id="10415" code="1020"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.6 -->
 | 
			
		||||
		<avp name="Charging-Rule-Name" vendor-id="10415" code="1005"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.28 -->
 | 
			
		||||
		<avp name="Service-Identifier" code="439" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.29 -->
 | 
			
		||||
		<avp name="Rating-Group" code="432" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.214 V7.3.0] , clause 5.3.11 -->
 | 
			
		||||
		<avp name="Flow-Status" vendor-id="10415" code="511" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="ENABLED-UPLINK" code="0" />
 | 
			
		||||
			<enum name="ENABLED-DOWNLINK" code="1" />
 | 
			
		||||
			<enum name="ENABLED" code="2" />
 | 
			
		||||
			<enum name="DISABLED" code="3" />
 | 
			
		||||
			<enum name="REMOVED" code="4" />
 | 
			
		||||
		</avp>
 | 
			
		||||
				<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.17 -->
 | 
			
		||||
		<avp name="QoS-Class-Identifier" vendor-id="10415" code="1028"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="FINAL_SERVICE_INFORMATION" code="0" />
 | 
			
		||||
			<enum name="PRELIMINARY_SERVICE_INFORMATION" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
			<!-- Ref = [3GPP - 29.214] 5.3.15 -->
 | 
			
		||||
		<avp name="Max-Requested-Bandwidth-UL" code="516" vendor-id="10415"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.25 -->
 | 
			
		||||
		<avp name="Guaranteed-Bitrate-DL" vendor-id="10415" code="1025"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.26 -->
 | 
			
		||||
		<avp name="Guaranteed-Bitrate-UL" vendor-id="10415" code="1026"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.20 -->
 | 
			
		||||
		<avp name="Bearer-Identifier" vendor-id="10415" code="1020"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<avp name="Max-Requested-Bandwidth-UL" code="516" mandatory="must" vendor-id="10415" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32"/>
 | 
			
		||||
		</avp>
 | 
			
		||||
		   <avp name="Max-Requested-Bandwidth-DL" code="515" mandatory="must" vendor-id="10415" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32"/>
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.16 -->
 | 
			
		||||
		<avp name="QoS-Information" vendor-id="10415" code="1016"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="QoS-Class-Identifier" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Max-Requested-Bandwidth-UL" minimum="1"
 | 
			
		||||
						maximum="1" />
 | 
			
		||||
					<avprule name="Max-Requested-Bandwidth-DL" minimum="1"
 | 
			
		||||
						maximum="1" />
 | 
			
		||||
					<avprule name="Guaranteed-Bitrate-UL" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Guaranteed-Bitrate-DL" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Bearer-Identifier" minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.214 V7.3.0] , clause 5.3.8 -->
 | 
			
		||||
		<avp name="Flow-Description" vendor-id="10415" code="507"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="IPFilterRule" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.12 -->
 | 
			
		||||
		<avp name="Reporting-Level" vendor-id="10415" code="1011"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="SERVICE_IDENTIFIER_LEVEL" code="0" />
 | 
			
		||||
			<enum name="RATING_GROUP_LEVEL" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.9 -->
 | 
			
		||||
		<avp name="Offline" vendor-id="10415" code="1008" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="DISABLE_OFFLINE" code="0" />
 | 
			
		||||
			<enum name="ENABLE_OFFLINE" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.10 -->
 | 
			
		||||
		<avp name="Online" vendor-id="10415" code="1009" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="DISABLE_ONLINE" code="0" />
 | 
			
		||||
			<enum name="ENABLE_ONLINE" code="1" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.11 -->
 | 
			
		||||
		<avp name="Precedence" vendor-id="10415" code="1010" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [3GPP TS 29.214 V7.3.0] , clause 5.3.6 -->
 | 
			
		||||
		<avp name="AF-Charging-Identifier" vendor-id="10415" code="505"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="OctetString" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- Ref = [3GPP - 29.214] 5.3.14 -->
 | 
			
		||||
		<avp name="Max-Requested-Bandwidth-DL" code="515" vendor-id="10415"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.214 V7.3.0] , clause 5.3.17 -->
 | 
			
		||||
		<avp name="Media-Component-Number" vendor-id="10415" code="518"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.214 V7.3.0] , clause 5.3.9 -->
 | 
			
		||||
		<avp name="Flow-Number" vendor-id="10415" code="509" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Unsigned32" />
 | 
			
		||||
		</avp>
 | 
			
		||||
<!-- [3GPP TS 29.214 V7.3.0] , clause 5.3.10 -->
 | 
			
		||||
		<avp name="Flows" vendor-id="10415" code="510" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Media-Component-Number" minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Flow-Number" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.4 -->
 | 
			
		||||
		<avp name="Charging-Rule-Definition" vendor-id="10415" code="1003"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Charging-Rule-Name" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Service-Identifier" maximum="1" />
 | 
			
		||||
					<avprule name="Rating-Group" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Flow-Description" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Flow-Status" maximum="1" />
 | 
			
		||||
					<avprule name="QoS-Information" maximum="1" />
 | 
			
		||||
					<avprule name="Reporting-Level" maximum="1" />
 | 
			
		||||
					<avprule name="Online" maximum="1" />
 | 
			
		||||
					<avprule name="Offline" maximum="1" />
 | 
			
		||||
					<avprule name="Metering-Method" maximum="1" />
 | 
			
		||||
					<avprule name="Precedence" maximum="1" />
 | 
			
		||||
					<avprule name="AF-Charging-Identifier" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Flows" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.2 -->
 | 
			
		||||
		<avp name="Charging-Rule-Install" vendor-id="10415" code="1001"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Charging-Rule-Definition" maximum="1" />
 | 
			
		||||
					<avprule name="Charging-Rule-Name" maximum="1" />
 | 
			
		||||
					<avprule name="Charging-Rule-Base-Name" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Bearer-Identifier" minumin="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Rule-Activation-Time" maximum="1" />
 | 
			
		||||
					<avprule name="Rule-Deactivation-Time" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.3 -->
 | 
			
		||||
		<avp name="Charging-Rule-Remove" vendor-id="10415" code="1002"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Charging-Rule-Name" maximum="1" />
 | 
			
		||||
					<avprule name="Charging-Rule-Base-Name" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.7 -->
 | 
			
		||||
		<avp name="Event-Trigger" vendor-id="10415" code="1006" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="SGSN_CHANGE" code="0" />
 | 
			
		||||
			<enum name="QOS_CHANGE" code="1" />
 | 
			
		||||
			<enum name="RAT_CHANGE" code="2" />
 | 
			
		||||
			<enum name="TFT_CHANGE" code="3" />
 | 
			
		||||
			<enum name="PLMN_CHANGE" code="4" />
 | 
			
		||||
			<enum name="LOSS_OF_BEARER" code="5" />
 | 
			
		||||
			<enum name="RECOVERY_OF_BEARER" code="6" />
 | 
			
		||||
			<enum name="IP-CAN_CHANGE" code="7" />
 | 
			
		||||
			<enum name="PCEF_MALFUNCTION" code="8" />
 | 
			
		||||
			<enum name="RESOURCES_LIMITATION" code="9" />
 | 
			
		||||
			<enum name="MAX_NR_BEARERS_REACHED" code="10" />
 | 
			
		||||
			<enum name="QOS_CHANGE_EXCEEDING_AUTHORIZATION" code="11" />
 | 
			
		||||
			<enum name="RAI_CHANGE" code="12" />
 | 
			
		||||
			<enum name="USER_LOCATION_CHANGE" code="13" />
 | 
			
		||||
			<enum name="NO_EVENT_TRIGGERS" code="14" />
 | 
			
		||||
			<enum name="OUT_OF_CREDIT" code="15" />
 | 
			
		||||
			<enum name="REALLOCATION_OF_CREDIT" code="16" />
 | 
			
		||||
			<enum name="REVALIDATION_TIMEOUT" code="17" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.13 -->
 | 
			
		||||
		<avp name="TFT-Filter" vendor-id="10415" code="1012" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="IPFilterRule" />
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.14 -->
 | 
			
		||||
		<avp name="TFT-Packet-Filter-Information" vendor-id="10415" code="1013"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Precedence" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="TFT-Filter" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="ToS-Traffic-Class" minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
<!-- [RFC 4006] , clause 8.35 -->
 | 
			
		||||
		<avp name="Final-Unit-Action" code="449" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="Enumerated" />
 | 
			
		||||
			<enum name="TERMINATE" code="0" />
 | 
			
		||||
			<enum name="REDIRECT" code="1" />
 | 
			
		||||
			<enum name="RESTRICT_ACCESS" code="2" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.36 -->
 | 
			
		||||
		<avp name="Restriction-Filter-Rule" code="438" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<type type-name="IPFilterRule" />
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.37 -->
 | 
			
		||||
		<avp name="Redirect-Server" code="434" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Redirect-Address-Type" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Redirect-Server-Address" minimum="1"
 | 
			
		||||
						maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
		<!-- [RFC 4006] , clause 8.34 -->
 | 
			
		||||
		<avp name="Final-Unit-Indication" code="430" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Final-Unit-Action" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Restriction-Filter-Rule" minimum="1"
 | 
			
		||||
						maximum="1" />
 | 
			
		||||
					<avprule name="Filter-Id" minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Redirect-Server" minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
		
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.18 -->
 | 
			
		||||
		<avp name="Charging-Rule-Report" vendor-id="10415" code="1018"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Charging-Rule-Name" maximum="1" />
 | 
			
		||||
					<avprule name="Charging-Rule-Base-Name" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="PCC-Rule-Status" minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Rule-Failure-Code" maximum="1" />
 | 
			
		||||
					<avprule name="Final-Unit-Indication" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.212 V7.7.0] , clause 5.3.22 -->
 | 
			
		||||
		<avp name="Access-Network-Charging-Identifier-Gx" vendor-id="10415"
 | 
			
		||||
			code="1022" mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Access-Network-Charging-Identifier-Value"
 | 
			
		||||
						minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
				<optional>
 | 
			
		||||
					<avprule name="Charging-Rule-Base-Name" maximum="1" />
 | 
			
		||||
					<avprule name="Charging-Rule-Name" maximum="1" />
 | 
			
		||||
				</optional>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
		<!-- [3GPP TS 29.229 V7.7.0] , clause 6.3.19 -->
 | 
			
		||||
		<avp name="Charging-Information" vendor-id="10415" code="618"
 | 
			
		||||
			mandatory="must" may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Primary-Event-Charging-Function-Name"
 | 
			
		||||
						minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Secondary-Event-Charging-Function-Name"
 | 
			
		||||
						minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Primary-Charging-Collection-Function-Name"
 | 
			
		||||
						minimum="1" maximum="1" />
 | 
			
		||||
					<avprule name="Secondary-Charging-Collection-Function-Name"
 | 
			
		||||
						minimum="1" maximum="1" />
 | 
			
		||||
				</required>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- Ref = RFC 4006 chap 8.46 -->
 | 
			
		||||
		<avp name="Subscription-Id" code="443" mandatory="must"
 | 
			
		||||
			may-encrypt="yes">
 | 
			
		||||
			<grouped>
 | 
			
		||||
				<required>
 | 
			
		||||
					<avprule name="Subscription-Id-Type" />
 | 
			
		||||
					<avprule name="Subscription-Id-Data" />
 | 
			
		||||
				</required>
 | 
			
		||||
			</grouped>
 | 
			
		||||
		</avp>
 | 
			
		||||
	
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	</application>
 | 
			
		||||
</dictionary>
 | 
			
		||||
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
# This file documents the configuration format for the dict_legacy_xml.fdx freeDiameter extension.
 | 
			
		||||
# In order to load this extension, please refer to main freeDiameter.conf manual.
 | 
			
		||||
 | 
			
		||||
# This extension allows the use of Diameter dictionary files in XML format,
 | 
			
		||||
# as roughly specified in draft-frascone-xml-dictionary-00.
 | 
			
		||||
# (the actual format is the one from OpenDiameter latest version)
 | 
			
		||||
# Note that this format, although more widely used, is less efficient than the
 | 
			
		||||
# internal freeDiameter format. It is recommended when possible to use the later.
 | 
			
		||||
 | 
			
		||||
# You may refer to the contrib/dict_legacy/README file for information on where to find such resources.
 | 
			
		||||
 | 
			
		||||
# This file simply consists in a list of XML dictionary files that must be parsed.
 | 
			
		||||
# Example:
 | 
			
		||||
#  "/etc/freeDiameter/dictionary.xml";
 | 
			
		||||
"@prefix@/etc/freeDiameter/dict_gx.xml";
 | 
			
		||||
@@ -80,7 +80,7 @@ No_SCTP;
 | 
			
		||||
#ListenOn = "202.249.37.5";
 | 
			
		||||
#ListenOn = "2001:200:903:2::202:1";
 | 
			
		||||
#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0";
 | 
			
		||||
ListenOn = "10.1.35.214";
 | 
			
		||||
ListenOn = "127.76.0.4";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -107,8 +107,7 @@ ListenOn = "10.1.35.214";
 | 
			
		||||
# Default : NO DEFAULT
 | 
			
		||||
#TLS_Cred = "<x509 certif file.PEM>" , "<x509 private key file.PEM>";
 | 
			
		||||
#TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key";
 | 
			
		||||
TLS_Cred = "@prefix@/etc/freeDiameter/hss.cert.pem",
 | 
			
		||||
           "@prefix@/etc/freeDiameter/hss.key.pem";
 | 
			
		||||
TLS_Cred = "@SYSCONF_DIR@/nextepc/freeDiameter/hss.cert.pem", "@SYSCONF_DIR@/nextepc/freeDiameter/hss.key.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate authority / trust anchors
 | 
			
		||||
# The file containing the list of trusted Certificate Authorities (PEM list)
 | 
			
		||||
@@ -116,7 +115,7 @@ TLS_Cred = "@prefix@/etc/freeDiameter/hss.cert.pem",
 | 
			
		||||
# The directive can appear several times to specify several files.
 | 
			
		||||
# Default : GNUTLS default behavior
 | 
			
		||||
#TLS_CA = "<file.PEM>";
 | 
			
		||||
TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
TLS_CA = "@SYSCONF_DIR@/nextepc/freeDiameter/cacert.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate Revocation List file
 | 
			
		||||
# The information about revoked certificates.
 | 
			
		||||
@@ -224,14 +223,14 @@ TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
#  4 - full    - display the complete information on a single long line
 | 
			
		||||
#  8 - tree    - display the complete information in an easier to read format spanning several lines.
 | 
			
		||||
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_s6a.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_s6a.so";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -263,6 +262,6 @@ LoadExtension = "@prefix@/lib/nextepc/dict_s6a.so";
 | 
			
		||||
# Examples:
 | 
			
		||||
#ConnectPeer = "aaa.wide.ad.jp";
 | 
			
		||||
#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ;
 | 
			
		||||
ConnectPeer = "mme.localdomain" { ConnectTo = "10.1.35.215"; No_TLS; };
 | 
			
		||||
ConnectPeer = "mme.localdomain" { ConnectTo = "127.76.0.1"; No_TLS; };
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ No_SCTP;
 | 
			
		||||
#ListenOn = "202.249.37.5";
 | 
			
		||||
#ListenOn = "2001:200:903:2::202:1";
 | 
			
		||||
#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0";
 | 
			
		||||
ListenOn = "10.1.35.215";
 | 
			
		||||
ListenOn = "127.76.0.1";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -107,8 +107,7 @@ ListenOn = "10.1.35.215";
 | 
			
		||||
# Default : NO DEFAULT
 | 
			
		||||
#TLS_Cred = "<x509 certif file.PEM>" , "<x509 private key file.PEM>";
 | 
			
		||||
#TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key";
 | 
			
		||||
TLS_Cred = "@prefix@/etc/freeDiameter/mme.cert.pem",
 | 
			
		||||
           "@prefix@/etc/freeDiameter/mme.key.pem";
 | 
			
		||||
TLS_Cred = "@SYSCONF_DIR@/nextepc/freeDiameter/mme.cert.pem", "@SYSCONF_DIR@/nextepc/freeDiameter/mme.key.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate authority / trust anchors
 | 
			
		||||
# The file containing the list of trusted Certificate Authorities (PEM list)
 | 
			
		||||
@@ -116,7 +115,7 @@ TLS_Cred = "@prefix@/etc/freeDiameter/mme.cert.pem",
 | 
			
		||||
# The directive can appear several times to specify several files.
 | 
			
		||||
# Default : GNUTLS default behavior
 | 
			
		||||
#TLS_CA = "<file.PEM>";
 | 
			
		||||
TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
TLS_CA = "@SYSCONF_DIR@/nextepc/freeDiameter/cacert.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate Revocation List file
 | 
			
		||||
# The information about revoked certificates.
 | 
			
		||||
@@ -224,14 +223,14 @@ TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
#  4 - full    - display the complete information on a single long line
 | 
			
		||||
#  8 - tree    - display the complete information in an easier to read format spanning several lines.
 | 
			
		||||
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_s6a.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_s6a.so";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -263,7 +262,7 @@ LoadExtension = "@prefix@/lib/nextepc/dict_s6a.so";
 | 
			
		||||
# Examples:
 | 
			
		||||
#ConnectPeer = "aaa.wide.ad.jp";
 | 
			
		||||
#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ;
 | 
			
		||||
ConnectPeer = "hss.localdomain" { ConnectTo = "10.1.35.214"; No_TLS; };
 | 
			
		||||
ConnectPeer = "hss.localdomain" { ConnectTo = "127.76.0.4"; No_TLS; };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ No_SCTP;
 | 
			
		||||
#ListenOn = "202.249.37.5";
 | 
			
		||||
#ListenOn = "2001:200:903:2::202:1";
 | 
			
		||||
#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0";
 | 
			
		||||
ListenOn = "10.1.35.218";
 | 
			
		||||
ListenOn = "127.76.0.5";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -107,7 +107,7 @@ ListenOn = "10.1.35.218";
 | 
			
		||||
# Default : NO DEFAULT
 | 
			
		||||
#TLS_Cred = "<x509 certif file.PEM>" , "<x509 private key file.PEM>";
 | 
			
		||||
#TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key";
 | 
			
		||||
TLS_Cred = "@prefix@/etc/freeDiameter/pcrf.cert.pem", "@prefix@/etc/freeDiameter/pcrf.key.pem";
 | 
			
		||||
TLS_Cred = "@SYSCONF_DIR@/nextepc/freeDiameter/pcrf.cert.pem", "@SYSCONF_DIR@/nextepc/freeDiameter/pcrf.key.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate authority / trust anchors
 | 
			
		||||
# The file containing the list of trusted Certificate Authorities (PEM list)
 | 
			
		||||
@@ -115,7 +115,7 @@ TLS_Cred = "@prefix@/etc/freeDiameter/pcrf.cert.pem", "@prefix@/etc/freeDiameter
 | 
			
		||||
# The directive can appear several times to specify several files.
 | 
			
		||||
# Default : GNUTLS default behavior
 | 
			
		||||
#TLS_CA = "<file.PEM>";
 | 
			
		||||
TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
TLS_CA = "@SYSCONF_DIR@/nextepc/freeDiameter/cacert.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate Revocation List file
 | 
			
		||||
# The information about revoked certificates.
 | 
			
		||||
@@ -223,14 +223,14 @@ TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
#  4 - full    - display the complete information on a single long line
 | 
			
		||||
#  8 - tree    - display the complete information in an easier to read format spanning several lines.
 | 
			
		||||
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
#LoadExtension = "@prefix@/lib/nextepc/dict_legacy_xml.so" : "@prefix@/etc/freeDiameter/dict_legacy_xml.conf";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
#LoadExtension = "@LIB_DIR@/nextepc/dict_legacy_xml.so" : "@SYSCONF_DIR@/nextepc/freeDiameter/dict_legacy_xml.conf";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -262,6 +262,6 @@ LoadExtension = "@prefix@/lib/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
# Examples:
 | 
			
		||||
#ConnectPeer = "aaa.wide.ad.jp";
 | 
			
		||||
#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ;
 | 
			
		||||
ConnectPeer = "pgw.localdomain" { ConnectTo = "10.1.35.219"; No_TLS; };
 | 
			
		||||
ConnectPeer = "pgw.localdomain" { ConnectTo = "127.76.0.3"; No_TLS; };
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ No_SCTP;
 | 
			
		||||
#ListenOn = "202.249.37.5";
 | 
			
		||||
#ListenOn = "2001:200:903:2::202:1";
 | 
			
		||||
#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0";
 | 
			
		||||
ListenOn = "10.1.35.219";
 | 
			
		||||
ListenOn = "127.76.0.3";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -107,7 +107,7 @@ ListenOn = "10.1.35.219";
 | 
			
		||||
# Default : NO DEFAULT
 | 
			
		||||
#TLS_Cred = "<x509 certif file.PEM>" , "<x509 private key file.PEM>";
 | 
			
		||||
#TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key";
 | 
			
		||||
TLS_Cred = "@prefix@/etc/freeDiameter/pgw.cert.pem", "@prefix@/etc/freeDiameter/pgw.key.pem";
 | 
			
		||||
TLS_Cred = "@SYSCONF_DIR@/nextepc/freeDiameter/pgw.cert.pem", "@SYSCONF_DIR@/nextepc/freeDiameter/pgw.key.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate authority / trust anchors
 | 
			
		||||
# The file containing the list of trusted Certificate Authorities (PEM list)
 | 
			
		||||
@@ -115,7 +115,7 @@ TLS_Cred = "@prefix@/etc/freeDiameter/pgw.cert.pem", "@prefix@/etc/freeDiameter/
 | 
			
		||||
# The directive can appear several times to specify several files.
 | 
			
		||||
# Default : GNUTLS default behavior
 | 
			
		||||
#TLS_CA = "<file.PEM>";
 | 
			
		||||
TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
TLS_CA = "@SYSCONF_DIR@/nextepc/freeDiameter/cacert.pem";
 | 
			
		||||
 | 
			
		||||
# Certificate Revocation List file
 | 
			
		||||
# The information about revoked certificates.
 | 
			
		||||
@@ -223,14 +223,14 @@ TLS_CA = "@prefix@/etc/freeDiameter/cacert.pem";
 | 
			
		||||
#  4 - full    - display the complete information on a single long line
 | 
			
		||||
#  8 - tree    - display the complete information in an easier to read format spanning several lines.
 | 
			
		||||
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@prefix@/lib/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
#LoadExtension = "@prefix@/lib/nextepc/dict_legacy_xml.so" : "@prefix@/etc/freeDiameter/dict_legacy_xml.conf";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dbg_msg_dumps.so" : "0x8888";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_rfc5777.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_mip6i.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nasreq.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_nas_mipv6.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca.so";
 | 
			
		||||
LoadExtension = "@LIB_DIR@/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
#LoadExtension = "@LIB_DIR@/nextepc/dict_legacy_xml.so" : "@SYSCONF_DIR@/nextepc/freeDiameter/dict_legacy_xml.conf";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
@@ -262,7 +262,7 @@ LoadExtension = "@prefix@/lib/nextepc/dict_dcca_3gpp.so";
 | 
			
		||||
# Examples:
 | 
			
		||||
#ConnectPeer = "aaa.wide.ad.jp";
 | 
			
		||||
#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ;
 | 
			
		||||
ConnectPeer = "pcrf.localdomain" { ConnectTo = "10.1.35.218"; No_TLS; };
 | 
			
		||||
ConnectPeer = "pcrf.localdomain" { ConnectTo = "127.76.0.5"; No_TLS; };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############################################################
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
ifconfig eth1:hss 10.1.35.214/24 up
 | 
			
		||||
ifconfig eth1:mme 10.1.35.215/24 up
 | 
			
		||||
ifconfig eth1:sgw_s5 10.1.35.216/24 up
 | 
			
		||||
ifconfig eth1:sgw_s11 10.1.35.217/24 up
 | 
			
		||||
ifconfig eth1:pcrf 10.1.35.218/24 up
 | 
			
		||||
ifconfig eth1:pgw 10.1.35.219/24 up
 | 
			
		||||
ifconfig pgwtun 45.45.0.1/16 up
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								support/logrotate/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								support/logrotate/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
EXTRA_DIST = nextepc.in
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
							
								
								
									
										16
									
								
								support/logrotate/nextepc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								support/logrotate/nextepc.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
@LOCALSTATE_DIR@/log/nextepc/*.log {
 | 
			
		||||
    daily
 | 
			
		||||
    sharedscripts
 | 
			
		||||
    missingok
 | 
			
		||||
    compress
 | 
			
		||||
    rotate 14
 | 
			
		||||
    create 640 nextepc nextepc
 | 
			
		||||
 | 
			
		||||
    postrotate
 | 
			
		||||
        for i in pcrfd pgwd sgwd hssd mmed epcd; do
 | 
			
		||||
            if [ -e @LOCALSTATE_DIR@/run/nextepc-$i/pid ] ; then
 | 
			
		||||
                kill -HUP `cat @LOCALSTATE_DIR@/run/nextepc-$i/pid`
 | 
			
		||||
            fi
 | 
			
		||||
        done
 | 
			
		||||
    endscript
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
ifconfig en0 alias 10.1.35.214 netmask 255.255.255.255
 | 
			
		||||
ifconfig en0 alias 10.1.35.215 netmask 255.255.255.255
 | 
			
		||||
ifconfig en0 alias 10.1.35.216 netmask 255.255.255.255
 | 
			
		||||
ifconfig en0 alias 10.1.35.217 netmask 255.255.255.255
 | 
			
		||||
ifconfig en0 alias 10.1.35.218 netmask 255.255.255.255
 | 
			
		||||
ifconfig en0 alias 10.1.35.219 netmask 255.255.255.255
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								support/network/nextepc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								support/network/nextepc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
auto pgwtun
 | 
			
		||||
iface pgwtun inet static 
 | 
			
		||||
address 45.45.0.1
 | 
			
		||||
netmask 255.255.0.0
 | 
			
		||||
pre-up ip tuntap add name pgwtun mode tun
 | 
			
		||||
post-down ip tuntap del name pgwtun mode tun
 | 
			
		||||
							
								
								
									
										17
									
								
								support/network/restart.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								support/network/restart.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
SYSTEM=`uname`;
 | 
			
		||||
 | 
			
		||||
if [ "$SYSTEM" = "Linux" ]; then
 | 
			
		||||
    if ! grep "pgwtun" /proc/net/dev > /dev/null; then
 | 
			
		||||
        ip tuntap add name pgwtun mode tun
 | 
			
		||||
        ip addr add 45.45.0.1/16 dev pgwtun
 | 
			
		||||
        ip link set pgwtun up
 | 
			
		||||
    fi
 | 
			
		||||
else
 | 
			
		||||
    ifconfig lo0 alias 127.76.0.1 netmask 255.255.255.255
 | 
			
		||||
    ifconfig lo0 alias 127.76.0.2 netmask 255.255.255.255
 | 
			
		||||
    ifconfig lo0 alias 127.76.0.3 netmask 255.255.255.255
 | 
			
		||||
    ifconfig lo0 alias 127.76.0.4 netmask 255.255.255.255
 | 
			
		||||
    ifconfig lo0 alias 127.76.0.5 netmask 255.255.255.255
 | 
			
		||||
fi
 | 
			
		||||
							
								
								
									
										4
									
								
								support/newsyslog/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								support/newsyslog/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
EXTRA_DIST = nextepc.conf.in
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in 
 | 
			
		||||
MOSTLYCLEANFILES = *.stackdump
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user